diff options
-rw-r--r-- | media/libstagefright/MPEG4Extractor.cpp | 14 | ||||
-rw-r--r-- | media/libstagefright/SampleIterator.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/SampleTable.cpp | 73 | ||||
-rw-r--r-- | media/libstagefright/include/SampleTable.h | 8 |
4 files changed, 97 insertions, 0 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index e6e98aa..108a1d1 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -1074,6 +1074,20 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { break; } + case FOURCC('c', 't', 't', 's'): + { + status_t err = + mLastTrack->sampleTable->setCompositionTimeToSampleParams( + data_offset, chunk_data_size); + + if (err != OK) { + return err; + } + + *offset += chunk_size; + break; + } + case FOURCC('s', 't', 's', 's'): { status_t err = diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp index 062ab9b..c7b00b1 100644 --- a/media/libstagefright/SampleIterator.cpp +++ b/media/libstagefright/SampleIterator.cpp @@ -307,6 +307,8 @@ status_t SampleIterator::findSampleTime( *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex); + *time += mTable->getCompositionTimeOffset(sampleIndex); + return OK; } diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index a9163fc..423df70 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -53,6 +53,8 @@ SampleTable::SampleTable(const sp<DataSource> &source) mNumSampleSizes(0), mTimeToSampleCount(0), mTimeToSample(NULL), + mCompositionTimeDeltaEntries(NULL), + mNumCompositionTimeDeltaEntries(0), mSyncSampleOffset(-1), mNumSyncSamples(0), mSyncSamples(NULL), @@ -68,6 +70,9 @@ SampleTable::~SampleTable() { delete[] mSyncSamples; mSyncSamples = NULL; + delete[] mCompositionTimeDeltaEntries; + mCompositionTimeDeltaEntries = NULL; + delete[] mTimeToSample; mTimeToSample = NULL; @@ -260,6 +265,51 @@ status_t SampleTable::setTimeToSampleParams( return OK; } +status_t SampleTable::setCompositionTimeToSampleParams( + off64_t data_offset, size_t data_size) { + LOGI("There are reordered frames present."); + + if (mCompositionTimeDeltaEntries != NULL || data_size < 8) { + return ERROR_MALFORMED; + } + + uint8_t header[8]; + if (mDataSource->readAt( + data_offset, header, sizeof(header)) + < (ssize_t)sizeof(header)) { + return ERROR_IO; + } + + if (U32_AT(header) != 0) { + // Expected version = 0, flags = 0. + return ERROR_MALFORMED; + } + + size_t numEntries = U32_AT(&header[4]); + + if (data_size != (numEntries + 1) * 8) { + return ERROR_MALFORMED; + } + + mNumCompositionTimeDeltaEntries = numEntries; + mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries]; + + if (mDataSource->readAt( + data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) + < (ssize_t)numEntries * 8) { + delete[] mCompositionTimeDeltaEntries; + mCompositionTimeDeltaEntries = NULL; + + return ERROR_IO; + } + + for (size_t i = 0; i < 2 * numEntries; ++i) { + mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]); + } + + return OK; +} + status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) { if (mSyncSampleOffset >= 0 || data_size < 8) { return ERROR_MALFORMED; @@ -333,6 +383,8 @@ uint32_t abs_difference(uint32_t time1, uint32_t time2) { status_t SampleTable::findSampleAtTime( uint32_t req_time, uint32_t *sample_index, uint32_t flags) { + // XXX this currently uses decoding time, instead of composition time. + *sample_index = 0; Mutex::Autolock autoLock(mLock); @@ -607,5 +659,26 @@ status_t SampleTable::getMetaDataForSample( return OK; } +uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) const { + if (mCompositionTimeDeltaEntries == NULL) { + return 0; + } + + uint32_t curSample = 0; + for (size_t i = 0; i < mNumCompositionTimeDeltaEntries; ++i) { + uint32_t sampleCount = mCompositionTimeDeltaEntries[2 * i]; + + if (sampleIndex < curSample + sampleCount) { + uint32_t sampleDelta = mCompositionTimeDeltaEntries[2 * i + 1]; + + return sampleDelta; + } + + curSample += sampleCount; + } + + return 0; +} + } // namespace android diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h index c5e8136..2f95de9 100644 --- a/media/libstagefright/include/SampleTable.h +++ b/media/libstagefright/include/SampleTable.h @@ -46,6 +46,9 @@ public: status_t setTimeToSampleParams(off64_t data_offset, size_t data_size); + status_t setCompositionTimeToSampleParams( + off64_t data_offset, size_t data_size); + status_t setSyncSampleParams(off64_t data_offset, size_t data_size); //////////////////////////////////////////////////////////////////////////// @@ -104,6 +107,9 @@ private: uint32_t mTimeToSampleCount; uint32_t *mTimeToSample; + uint32_t *mCompositionTimeDeltaEntries; + size_t mNumCompositionTimeDeltaEntries; + off64_t mSyncSampleOffset; uint32_t mNumSyncSamples; uint32_t *mSyncSamples; @@ -122,6 +128,8 @@ private: status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size); + uint32_t getCompositionTimeOffset(uint32_t sampleIndex) const; + SampleTable(const SampleTable &); SampleTable &operator=(const SampleTable &); }; |