diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.cpp b/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.cpp index 60080064db..33d5054f3a 100644 --- a/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.cpp +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.cpp @@ -57,12 +57,11 @@ status_t FallbackIndex::Init() { // Attempt to build an index by parsing the movi chunk + TRACE("Constructing a Fallback Index\n"); bool end_of_movi = false; chunk aChunk; - TRACE("Building Fallback index\n"); - int stream_index; off_t position; uint32 size; diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLParser.cpp b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLParser.cpp index e900a53df9..813613d353 100644 --- a/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLParser.cpp +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLParser.cpp @@ -27,7 +27,7 @@ #include "OpenDMLParser.h" #include "avi.h" -#define TRACE_ODML_PARSER +//#define TRACE_ODML_PARSER #ifdef TRACE_ODML_PARSER #define TRACE printf #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("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("priority = %u\n", fCurrentStream->stream_header.priority); TRACE("language = %u\n", fCurrentStream->stream_header.language); diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.cpp b/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.cpp index fabdb9b0a2..6189303c70 100644 --- a/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.cpp +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.cpp @@ -31,8 +31,6 @@ #include "StandardIndex.h" #include "OpenDMLParser.h" -#include - //#define TRACE_START_INDEX #ifdef TRACE_START_INDEX @@ -43,6 +41,11 @@ #define ERROR(a...) fprintf(stderr, a) +struct chunk { + uint32 chunk_id; + uint32 size; +}; + StandardIndex::StandardIndex(BPositionIO *source, OpenDMLParser *parser) : Index(source, parser) @@ -62,14 +65,11 @@ StandardIndex::~StandardIndex() status_t StandardIndex::Init() { + TRACE("Constructing a Standard Index\n"); uint32 indexBytes = fParser->StandardIndexSize(); fIndexSize = indexBytes / 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 ERROR("libOpenDML: StandardIndex::Init index is way too big\n"); return B_NO_MEMORY; @@ -85,10 +85,6 @@ StandardIndex::Init() ERROR("libOpenDML: StandardIndex::Init out of memory\n"); return B_NO_MEMORY; } -#ifdef TRACE_START_INDEX -} -{ BStopWatch w("StandardIndex::Init: file read"); -#endif if ((int32)indexBytes != fSource->ReadAt(fParser->StandardIndexStart(), fIndex, indexBytes)) { @@ -97,15 +93,7 @@ StandardIndex::Init() fIndex = NULL; return B_IO_ERROR; } -#ifdef TRACE_START_INDEX -} - //DumpIndex(); -#endif -#ifdef TRACE_START_INDEX -{ BStopWatch w("StandardIndex::Init: scan index"); -#endif - int stream_index; off_t position; uint32 size; @@ -131,7 +119,28 @@ StandardIndex::Init() keyframe = (fIndex[i].flags >> AVIIF_KEYFRAME_SHIFT) & 1; 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; frame_no = frame[stream_index]; @@ -177,3 +186,14 @@ StandardIndex::Init() 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); +} diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.h b/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.h index 5db4d303af..e303dd7416 100644 --- a/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.h +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.h @@ -37,6 +37,8 @@ public: status_t Init(); private: + bool IsValidChunk(off_t position, uint32 size); + avi_standard_index_entry *fIndex; uint32 fIndexSize; int64 fDataOffset;