diff options
Diffstat (limited to 'media/libstagefright/MPEG4Extractor.cpp')
-rwxr-xr-x | media/libstagefright/MPEG4Extractor.cpp | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 5d97181034..8c66c29d91 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -67,6 +67,7 @@ public: Vector<SidxEntry> &sidx, const Trex *trex, off64_t firstMoofOffset); + virtual status_t init(); virtual status_t start(MetaData *params = NULL); virtual status_t stop(); @@ -2046,7 +2047,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { *offset += chunk_size; if (underQTMetaPath(mPath, 3)) { - parseQTMetaKey(data_offset, chunk_data_size); + status_t err = parseQTMetaKey(data_offset, chunk_data_size); + if (err != OK) { + return err; + } } break; } @@ -2190,7 +2194,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('s', 'i', 'd', 'x'): { - parseSegmentIndex(data_offset, chunk_data_size); + status_t err = parseSegmentIndex(data_offset, chunk_data_size); + if (err != OK) { + return err; + } *offset += chunk_size; return UNKNOWN_ERROR; // stop parsing after sidx } @@ -2200,7 +2207,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { // check if we're parsing 'ilst' for meta keys // if so, treat type as a number (key-id). if (underQTMetaPath(mPath, 3)) { - parseQTMetaVal(chunk_type, data_offset, chunk_data_size); + status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size); + if (err != OK) { + return err; + } } *offset += chunk_size; @@ -2940,9 +2950,13 @@ sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { ALOGV("getTrack called, pssh: %zu", mPssh.size()); - return new MPEG4Source(this, + sp<MPEG4Source> source = new MPEG4Source(this, track->meta, mDataSource, track->timescale, track->sampleTable, mSidxEntries, trex, mMoofOffset); + if (source->init() != OK) { + return NULL; + } + return source; } // static @@ -3339,6 +3353,7 @@ MPEG4Source::MPEG4Source( mTrex(trex), mFirstMoofOffset(firstMoofOffset), mCurrentMoofOffset(firstMoofOffset), + mNextMoofOffset(-1), mCurrentTime(0), mCurrentSampleInfoAllocSize(0), mCurrentSampleInfoSizes(NULL), @@ -3405,10 +3420,14 @@ MPEG4Source::MPEG4Source( CHECK(format->findInt32(kKeyTrackID, &mTrackId)); +} + +status_t MPEG4Source::init() { if (mFirstMoofOffset != 0) { off64_t offset = mFirstMoofOffset; - parseChunk(&offset); + return parseChunk(&offset); } + return OK; } MPEG4Source::~MPEG4Source() { @@ -3532,9 +3551,30 @@ status_t MPEG4Source::parseChunk(off64_t *offset) { } chunk_size = ntohl(hdr[0]); chunk_type = ntohl(hdr[1]); + if (chunk_size == 1) { + // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box + // which is defined in 4.2 Object Structure. + // When chunk_size==1, 8 bytes follows as "largesize". + if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { + return ERROR_IO; + } + chunk_size = ntoh64(chunk_size); + if (chunk_size < 16) { + // The smallest valid chunk is 16 bytes long in this case. + return ERROR_MALFORMED; + } + } else if (chunk_size == 0) { + // next box extends to end of file. + } else if (chunk_size < 8) { + // The smallest valid chunk is 8 bytes long in this case. + return ERROR_MALFORMED; + } + if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { mNextMoofOffset = *offset; break; + } else if (chunk_size == 0) { + break; } *offset += chunk_size; } @@ -4399,17 +4439,25 @@ status_t MPEG4Source::fragmentedRead( totalOffset += se->mSize; } mCurrentMoofOffset = totalOffset; + mNextMoofOffset = -1; mCurrentSamples.clear(); mCurrentSampleIndex = 0; - parseChunk(&totalOffset); + status_t err = parseChunk(&totalOffset); + if (err != OK) { + return err; + } mCurrentTime = totalTime * mTimescale / 1000000ll; } else { // without sidx boxes, we can only seek to 0 mCurrentMoofOffset = mFirstMoofOffset; + mNextMoofOffset = -1; mCurrentSamples.clear(); mCurrentSampleIndex = 0; off64_t tmp = mCurrentMoofOffset; - parseChunk(&tmp); + status_t err = parseChunk(&tmp); + if (err != OK) { + return err; + } mCurrentTime = 0; } @@ -4438,7 +4486,10 @@ status_t MPEG4Source::fragmentedRead( mCurrentMoofOffset = nextMoof; mCurrentSamples.clear(); mCurrentSampleIndex = 0; - parseChunk(&nextMoof); + status_t err = parseChunk(&nextMoof); + if (err != OK) { + return err; + } if (mCurrentSampleIndex >= mCurrentSamples.size()) { return ERROR_END_OF_STREAM; } |