Standard Index now handles entries that are absolute offsets instead of relative
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29646 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -57,12 +57,11 @@ status_t
|
|||||||
FallbackIndex::Init()
|
FallbackIndex::Init()
|
||||||
{
|
{
|
||||||
// Attempt to build an index by parsing the movi chunk
|
// Attempt to build an index by parsing the movi chunk
|
||||||
|
TRACE("Constructing a Fallback Index\n");
|
||||||
|
|
||||||
bool end_of_movi = false;
|
bool end_of_movi = false;
|
||||||
chunk aChunk;
|
chunk aChunk;
|
||||||
|
|
||||||
TRACE("Building Fallback index\n");
|
|
||||||
|
|
||||||
int stream_index;
|
int stream_index;
|
||||||
off_t position;
|
off_t position;
|
||||||
uint32 size;
|
uint32 size;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#include "OpenDMLParser.h"
|
#include "OpenDMLParser.h"
|
||||||
#include "avi.h"
|
#include "avi.h"
|
||||||
|
|
||||||
#define TRACE_ODML_PARSER
|
//#define TRACE_ODML_PARSER
|
||||||
#ifdef TRACE_ODML_PARSER
|
#ifdef TRACE_ODML_PARSER
|
||||||
#define TRACE printf
|
#define TRACE printf
|
||||||
#else
|
#else
|
||||||
@@ -636,7 +636,7 @@ OpenDMLParser::ParseChunk_strh(uint64 start, uint32 size)
|
|||||||
|
|
||||||
TRACE("stream_header, Stream %d, is_audio %d, is_video %d:\n", fStreamCount - 1, fCurrentStream->is_audio, fCurrentStream->is_video);
|
TRACE("stream_header, Stream %d, is_audio %d, is_video %d:\n", fStreamCount - 1, fCurrentStream->is_audio, fCurrentStream->is_video);
|
||||||
TRACE("fourcc_type = '"FOURCC_FORMAT"'\n",FOURCC_PARAM(fCurrentStream->stream_header.fourcc_type));
|
TRACE("fourcc_type = '"FOURCC_FORMAT"'\n",FOURCC_PARAM(fCurrentStream->stream_header.fourcc_type));
|
||||||
TRACE("fourcc_handler = '"FOURCC_FORMAT"'\n",FOURCC_PARAM(fCurrentStream->stream_header.fourcc_handler));
|
// TRACE("fourcc_handler = '"FOURCC_FORMAT"'\n",FOURCC_PARAM(fCurrentStream->stream_header.fourcc_handler));
|
||||||
TRACE("flags = 0x%lx\n", fCurrentStream->stream_header.flags);
|
TRACE("flags = 0x%lx\n", fCurrentStream->stream_header.flags);
|
||||||
TRACE("priority = %u\n", fCurrentStream->stream_header.priority);
|
TRACE("priority = %u\n", fCurrentStream->stream_header.priority);
|
||||||
TRACE("language = %u\n", fCurrentStream->stream_header.language);
|
TRACE("language = %u\n", fCurrentStream->stream_header.language);
|
||||||
|
|||||||
@@ -31,8 +31,6 @@
|
|||||||
#include "StandardIndex.h"
|
#include "StandardIndex.h"
|
||||||
#include "OpenDMLParser.h"
|
#include "OpenDMLParser.h"
|
||||||
|
|
||||||
#include <StopWatch.h>
|
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_START_INDEX
|
//#define TRACE_START_INDEX
|
||||||
#ifdef TRACE_START_INDEX
|
#ifdef TRACE_START_INDEX
|
||||||
@@ -43,6 +41,11 @@
|
|||||||
|
|
||||||
#define ERROR(a...) fprintf(stderr, a)
|
#define ERROR(a...) fprintf(stderr, a)
|
||||||
|
|
||||||
|
struct chunk {
|
||||||
|
uint32 chunk_id;
|
||||||
|
uint32 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
StandardIndex::StandardIndex(BPositionIO *source, OpenDMLParser *parser)
|
StandardIndex::StandardIndex(BPositionIO *source, OpenDMLParser *parser)
|
||||||
: Index(source, parser)
|
: Index(source, parser)
|
||||||
@@ -62,14 +65,11 @@ StandardIndex::~StandardIndex()
|
|||||||
status_t
|
status_t
|
||||||
StandardIndex::Init()
|
StandardIndex::Init()
|
||||||
{
|
{
|
||||||
|
TRACE("Constructing a Standard Index\n");
|
||||||
uint32 indexBytes = fParser->StandardIndexSize();
|
uint32 indexBytes = fParser->StandardIndexSize();
|
||||||
fIndexSize = indexBytes / sizeof(avi_standard_index_entry);
|
fIndexSize = indexBytes / sizeof(avi_standard_index_entry);
|
||||||
indexBytes = fIndexSize * sizeof(avi_standard_index_entry);
|
indexBytes = fIndexSize * sizeof(avi_standard_index_entry);
|
||||||
|
|
||||||
#ifdef TRACE_START_INDEX
|
|
||||||
{ BStopWatch w("StandardIndex::Init: malloc");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (indexBytes > 0x1900000) { // 25 MB
|
if (indexBytes > 0x1900000) { // 25 MB
|
||||||
ERROR("libOpenDML: StandardIndex::Init index is way too big\n");
|
ERROR("libOpenDML: StandardIndex::Init index is way too big\n");
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -85,10 +85,6 @@ StandardIndex::Init()
|
|||||||
ERROR("libOpenDML: StandardIndex::Init out of memory\n");
|
ERROR("libOpenDML: StandardIndex::Init out of memory\n");
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
#ifdef TRACE_START_INDEX
|
|
||||||
}
|
|
||||||
{ BStopWatch w("StandardIndex::Init: file read");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((int32)indexBytes != fSource->ReadAt(fParser->StandardIndexStart(),
|
if ((int32)indexBytes != fSource->ReadAt(fParser->StandardIndexStart(),
|
||||||
fIndex, indexBytes)) {
|
fIndex, indexBytes)) {
|
||||||
@@ -97,15 +93,7 @@ StandardIndex::Init()
|
|||||||
fIndex = NULL;
|
fIndex = NULL;
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
}
|
}
|
||||||
#ifdef TRACE_START_INDEX
|
|
||||||
}
|
|
||||||
//DumpIndex();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TRACE_START_INDEX
|
|
||||||
{ BStopWatch w("StandardIndex::Init: scan index");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int stream_index;
|
int stream_index;
|
||||||
off_t position;
|
off_t position;
|
||||||
uint32 size;
|
uint32 size;
|
||||||
@@ -131,7 +119,28 @@ StandardIndex::Init()
|
|||||||
keyframe = (fIndex[i].flags >> AVIIF_KEYFRAME_SHIFT) & 1;
|
keyframe = (fIndex[i].flags >> AVIIF_KEYFRAME_SHIFT) & 1;
|
||||||
size = fIndex[i].chunk_length;
|
size = fIndex[i].chunk_length;
|
||||||
|
|
||||||
// Some muxers write chunk_offset as non-relative, need to handle this case.
|
// Some muxers write chunk_offset as non-relative. So we test if the first index actually points to a chunk
|
||||||
|
if (i == 0) {
|
||||||
|
off_t here = fSource->Position();
|
||||||
|
|
||||||
|
// first try and validate position as relative to the data chunk
|
||||||
|
position = fDataOffset + fIndex[i].chunk_offset;
|
||||||
|
TRACE("Validating chunk position %Ld as relative\n",position);
|
||||||
|
if (!IsValidChunk(position,size)) {
|
||||||
|
|
||||||
|
// then try and validate position as an absolute position that points to a chunk
|
||||||
|
fDataOffset = 0;
|
||||||
|
position = fDataOffset + fIndex[i].chunk_offset;
|
||||||
|
TRACE("Validating chunk position %Ld as absolute\n",position);
|
||||||
|
if (!IsValidChunk(position,size)) {
|
||||||
|
ERROR("Index is invalid, chunk offset does not point to a chunk\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fSource->Seek(here, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
position = fDataOffset + fIndex[i].chunk_offset;
|
position = fDataOffset + fIndex[i].chunk_offset;
|
||||||
frame_no = frame[stream_index];
|
frame_no = frame[stream_index];
|
||||||
|
|
||||||
@@ -177,3 +186,14 @@ StandardIndex::Init()
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StandardIndex::IsValidChunk(off_t position, uint32 size) {
|
||||||
|
|
||||||
|
chunk aChunk;
|
||||||
|
|
||||||
|
if ((int32)8 != fSource->ReadAt(position, &aChunk, 8)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (aChunk.size == size);
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ public:
|
|||||||
status_t Init();
|
status_t Init();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool IsValidChunk(off_t position, uint32 size);
|
||||||
|
|
||||||
avi_standard_index_entry *fIndex;
|
avi_standard_index_entry *fIndex;
|
||||||
uint32 fIndexSize;
|
uint32 fIndexSize;
|
||||||
int64 fDataOffset;
|
int64 fDataOffset;
|
||||||
|
|||||||
Reference in New Issue
Block a user