From 8bf59e735760af0b6a85747fd90bf8cf1e5388d7 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Fri, 6 Aug 2010 14:13:10 -0700 Subject: Support for communicating if a buffer read from the _extractor_ is a sync sample or not. Change-Id: Ie71506224d937cfff1fa1273bfac31c47db8845f related-to-bug: 2900534 --- media/libstagefright/AMRExtractor.cpp | 1 + media/libstagefright/MP3Extractor.cpp | 1 + media/libstagefright/MPEG4Extractor.cpp | 11 +++- media/libstagefright/OggExtractor.cpp | 2 + media/libstagefright/SampleTable.cpp | 76 +++++++++++++--------- media/libstagefright/WAVExtractor.cpp | 1 + media/libstagefright/include/SampleTable.h | 5 +- .../libstagefright/matroska/MatroskaExtractor.cpp | 1 + 8 files changed, 65 insertions(+), 33 deletions(-) diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp index 9fc1d27..70af2da 100644 --- a/media/libstagefright/AMRExtractor.cpp +++ b/media/libstagefright/AMRExtractor.cpp @@ -263,6 +263,7 @@ status_t AMRSource::read( buffer->set_range(0, frameSize); buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); + buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); mOffset += frameSize; mCurrentTimeUs += 20000; // Each frame is 20ms diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp index 2248e23..4058fbc 100644 --- a/media/libstagefright/MP3Extractor.cpp +++ b/media/libstagefright/MP3Extractor.cpp @@ -683,6 +683,7 @@ status_t MP3Source::read( buffer->set_range(0, frame_size); buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); + buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); mCurrentPos += frame_size; mCurrentTimeUs += frame_size * 8000ll / bitrate; diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index d937838..6af3a7f 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -1551,13 +1551,14 @@ status_t MPEG4Source::read( off_t offset; size_t size; uint32_t dts; + bool isSyncSample; bool newBuffer = false; if (mBuffer == NULL) { newBuffer = true; status_t err = mSampleTable->getMetaDataForSample( - mCurrentSampleIndex, &offset, &size, &dts); + mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample); if (err != OK) { return err; @@ -1594,6 +1595,10 @@ status_t MPEG4Source::read( kKeyTargetTime, targetSampleTimeUs); } + if (isSyncSample) { + mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + } + ++mCurrentSampleIndex; } @@ -1696,6 +1701,10 @@ status_t MPEG4Source::read( kKeyTargetTime, targetSampleTimeUs); } + if (isSyncSample) { + mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + } + ++mCurrentSampleIndex; *out = mBuffer; diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp index 641a876..b699d8f 100644 --- a/media/libstagefright/OggExtractor.cpp +++ b/media/libstagefright/OggExtractor.cpp @@ -181,6 +181,8 @@ status_t OggSource::read( } #endif + packet->meta_data()->setInt32(kKeyIsSyncFrame, 1); + *out = packet; return OK; diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index 2e62f9f..27faf4f 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -55,6 +55,8 @@ SampleTable::SampleTable(const sp &source) mTimeToSample(NULL), mSyncSampleOffset(-1), mNumSyncSamples(0), + mSyncSamples(NULL), + mLastSyncSampleIndex(0), mSampleToChunkEntries(NULL) { mSampleIterator = new SampleIterator(this); } @@ -63,6 +65,9 @@ SampleTable::~SampleTable() { delete[] mSampleToChunkEntries; mSampleToChunkEntries = NULL; + delete[] mSyncSamples; + mSyncSamples = NULL; + delete[] mTimeToSample; mTimeToSample = NULL; @@ -278,6 +283,18 @@ status_t SampleTable::setSyncSampleParams(off_t data_offset, size_t data_size) { if (mNumSyncSamples < 2) { LOGW("Table of sync samples is empty or has only a single entry!"); } + + mSyncSamples = new uint32_t[mNumSyncSamples]; + size_t size = mNumSyncSamples * sizeof(uint32_t); + if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) + != (ssize_t)size) { + return ERROR_IO; + } + + for (size_t i = 0; i < mNumSyncSamples; ++i) { + mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; + } + return OK; } @@ -394,14 +411,7 @@ status_t SampleTable::findSyncSampleNear( uint32_t left = 0; while (left < mNumSyncSamples) { - uint32_t x; - if (mDataSource->readAt( - mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) { - return ERROR_IO; - } - - x = ntohl(x); - --x; + uint32_t x = mSyncSamples[left]; if (x >= start_sample_index) { break; @@ -421,14 +431,7 @@ status_t SampleTable::findSyncSampleNear( --x; if (left + 1 < mNumSyncSamples) { - uint32_t y; - if (mDataSource->readAt( - mSyncSampleOffset + 8 + (left + 1) * 4, &y, 4) != 4) { - return ERROR_IO; - } - - y = ntohl(y); - --y; + uint32_t y = mSyncSamples[left + 1]; // our sample lies between sync samples x and y. @@ -486,13 +489,7 @@ status_t SampleTable::findSyncSampleNear( return ERROR_OUT_OF_RANGE; } - if (mDataSource->readAt( - mSyncSampleOffset + 8 + (left + 1) * 4, &x, 4) != 4) { - return ERROR_IO; - } - - x = ntohl(x); - --x; + x = mSyncSamples[left + 1]; CHECK(x >= start_sample_index); } @@ -532,13 +529,7 @@ status_t SampleTable::findThumbnailSample(uint32_t *sample_index) { } for (size_t i = 0; i < numSamplesToScan; ++i) { - uint32_t x; - if (mDataSource->readAt( - mSyncSampleOffset + 8 + i * 4, &x, 4) != 4) { - return ERROR_IO; - } - x = ntohl(x); - --x; + uint32_t x = mSyncSamples[i]; // Now x is a sample index. size_t sampleSize; @@ -568,7 +559,8 @@ status_t SampleTable::getMetaDataForSample( uint32_t sampleIndex, off_t *offset, size_t *size, - uint32_t *decodingTime) { + uint32_t *decodingTime, + bool *isSyncSample) { Mutex::Autolock autoLock(mLock); status_t err; @@ -588,6 +580,28 @@ status_t SampleTable::getMetaDataForSample( *decodingTime = mSampleIterator->getSampleTime(); } + if (isSyncSample) { + *isSyncSample = false; + if (mSyncSampleOffset < 0) { + // Every sample is a sync sample. + *isSyncSample = true; + } else { + size_t i = (mLastSyncSampleIndex < mNumSyncSamples) + && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) + ? mLastSyncSampleIndex : 0; + + while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { + ++i; + } + + if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { + *isSyncSample = true; + } + + mLastSyncSampleIndex = i; + } + } + return OK; } diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp index 7c2b07e..39b1b96 100644 --- a/media/libstagefright/WAVExtractor.cpp +++ b/media/libstagefright/WAVExtractor.cpp @@ -358,6 +358,7 @@ status_t WAVSource::read( 1000000LL * (mCurrentPos - mOffset) / (mNumChannels * bytesPerSample) / mSampleRate); + buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); *out = buffer; diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h index a2b2c99..f830690 100644 --- a/media/libstagefright/include/SampleTable.h +++ b/media/libstagefright/include/SampleTable.h @@ -60,7 +60,8 @@ public: uint32_t sampleIndex, off_t *offset, size_t *size, - uint32_t *decodingTime); + uint32_t *decodingTime, + bool *isSyncSample = NULL); enum { kFlagBefore, @@ -105,6 +106,8 @@ private: off_t mSyncSampleOffset; uint32_t mNumSyncSamples; + uint32_t *mSyncSamples; + size_t mLastSyncSampleIndex; SampleIterator *mSampleIterator; diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index 3739be1..71f6587 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -296,6 +296,7 @@ status_t MatroskaSource::read( MediaBuffer *buffer = new MediaBuffer(size + 2); buffer->meta_data()->setInt64(kKeyTime, timeUs); + buffer->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey()); long res = block->Read( mExtractor->mReader, (unsigned char *)buffer->data() + 2); -- cgit v1.1