From 7567469034fd9032cc32b3b8366467704ac4a06b Mon Sep 17 00:00:00 2001 From: Anthony Jones Date: Tue, 16 Dec 2014 18:10:44 +1300 Subject: [PATCH] Bug 1098126 - Remove duplication in MP4 demuxer seek; r=mattwoodrow --- .../media/libstagefright/MPEG4Extractor.cpp | 102 ++++++++---------- 1 file changed, 42 insertions(+), 60 deletions(-) diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp index 7adcb6f6e22..4b22bf3db71 100644 --- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp @@ -112,6 +112,7 @@ private: status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); void lookForMoof(); + status_t moveToNextFragment(); struct TrackFragmentHeaderInfo { enum Flags { @@ -3583,6 +3584,34 @@ status_t MPEG4Source::read( } } +status_t MPEG4Source::moveToNextFragment() { + off64_t nextMoof = mNextMoofOffset; + mCurrentSamples.clear(); + mDeferredSaio.clear(); + mDeferredSaiz.clear(); + mCurrentSampleIndex = 0; + uint32_t hdr[2]; + do { + if (mDataSource->readAt(nextMoof, hdr, 8) < 8) { + return ERROR_END_OF_STREAM; + } + uint64_t chunk_size = ntohl(hdr[0]); + uint32_t chunk_type = ntohl(hdr[1]); + + // Skip over anything that isn't a moof + if (chunk_type != FOURCC('m', 'o', 'o', 'f')) { + nextMoof += chunk_size; + continue; + } + mCurrentMoofOffset = nextMoof; + status_t ret = parseChunk(&nextMoof); + if (ret != OK) { + return ret; + } + } while (mCurrentSamples.size() == 0); + return OK; +} + status_t MPEG4Source::fragmentedRead( MediaBuffer **out, const ReadOptions *options) { @@ -3598,10 +3627,6 @@ status_t MPEG4Source::fragmentedRead( ReadOptions::SeekMode mode; if (options && options->getSeekTo(&seekTimeUs, &mode)) { - mCurrentSamples.clear(); - mDeferredSaio.clear(); - mDeferredSaiz.clear(); - mCurrentSampleIndex = 0; int numSidxEntries = mSegments.size(); if (numSidxEntries != 0) { int64_t totalTime = 0; @@ -3624,37 +3649,21 @@ status_t MPEG4Source::fragmentedRead( totalOffset += se->mSize; } mCurrentMoofOffset = totalOffset; - mNextMoofOffset = totalOffset; + mCurrentSamples.clear(); + mDeferredSaio.clear(); + mDeferredSaiz.clear(); + mCurrentSampleIndex = 0; mCurrentTime = totalTime * mTimescale / 1000000ll; + mNextMoofOffset = totalOffset; } else { mNextMoofOffset = mFirstMoofOffset; uint32_t seekTime = (int32_t) ((seekTimeUs * mTimescale) / 1000000ll); while (true) { - - uint32_t hdr[2]; - do { - off64_t moofOffset = mNextMoofOffset; // lastSample.offset + lastSample.size; - if (mDataSource->readAt(moofOffset, hdr, 8) < 8) { - ALOGV("Seek ERROR_END_OF_STREAM\n"); - return ERROR_END_OF_STREAM; - } - uint64_t chunk_size = ntohl(hdr[0]); - uint32_t chunk_type = ntohl(hdr[1]); - char chunk[5]; - MakeFourCCString(chunk_type, chunk); - - // If we're pointing to a segment type or sidx box then we skip them. - if (chunk_type != FOURCC('m', 'o', 'o', 'f')) { - mNextMoofOffset += chunk_size; - continue; - } - mCurrentMoofOffset = moofOffset; - status_t ret = parseChunk(&moofOffset); - if (ret != OK) { - return ret; - } - } while (mCurrentSamples.size() == 0); + status_t ret = moveToNextFragment(); + if (ret != OK) { + return ret; + } uint32_t time = mCurrentTime; int i; for (i = 0; i < mCurrentSamples.size() && time <= seekTime; i++) { @@ -3668,11 +3677,6 @@ status_t MPEG4Source::fragmentedRead( if (i != mCurrentSamples.size()) { break; } - - mCurrentSamples.clear(); - mDeferredSaio.clear(); - mDeferredSaiz.clear(); - mCurrentSampleIndex = 0; } ALOGV("Seeking offset %d; %ldus\n", mCurrentTime - seekTime, (((int64_t) mCurrentTime - seekTime) * 1000000ll) / mTimescale); @@ -3697,32 +3701,10 @@ status_t MPEG4Source::fragmentedRead( newBuffer = true; if (mCurrentSampleIndex >= mCurrentSamples.size()) { - // move to next fragment - off64_t nextMoof = mNextMoofOffset; // lastSample.offset + lastSample.size; - mCurrentSamples.clear(); - mDeferredSaio.clear(); - mDeferredSaiz.clear(); - mCurrentSampleIndex = 0; - uint32_t hdr[2]; - do { - if (mDataSource->readAt(nextMoof, hdr, 8) < 8) { - return ERROR_END_OF_STREAM; - } - uint64_t chunk_size = ntohl(hdr[0]); - uint32_t chunk_type = ntohl(hdr[1]); - - // If we're pointing to a segment type or sidx box then we skip them. - if (chunk_type == FOURCC('s', 't', 'y', 'p') || - chunk_type == FOURCC('s', 'i', 'd', 'x')) { - nextMoof += chunk_size; - continue; - } - mCurrentMoofOffset = nextMoof; - status_t ret = parseChunk(&nextMoof); - if (ret != OK) { - return ret; - } - } while (mCurrentSamples.size() == 0); + status_t ret = moveToNextFragment(); + if (ret != OK) { + return ret; + } } const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];