diff options
author | Robert Shih <robertshih@google.com> | 2015-06-02 19:25:13 -0700 |
---|---|---|
committer | Robert Shih <robertshih@google.com> | 2015-06-08 18:04:22 -0700 |
commit | 819bcef03907c8df8fc0fa78c0d43db98279ffa9 (patch) | |
tree | 7849c9ad8d41f3341968e89dfe18022a995d52a3 /media/libstagefright/OggExtractor.cpp | |
parent | 8c10a80cf1af68f15eb39552ca116ec6f04fc173 (diff) | |
download | frameworks_av-819bcef03907c8df8fc0fa78c0d43db98279ffa9.zip frameworks_av-819bcef03907c8df8fc0fa78c0d43db98279ffa9.tar.gz frameworks_av-819bcef03907c8df8fc0fa78c0d43db98279ffa9.tar.bz2 |
Ogg Opus: handle cases where first sample has non 0 time
Bug: 19286916
Change-Id: I660daae57e7b7e793f55154c74347e9d53627324
Diffstat (limited to 'media/libstagefright/OggExtractor.cpp')
-rw-r--r-- | media/libstagefright/OggExtractor.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp index 2451641..1c663a3 100644 --- a/media/libstagefright/OggExtractor.cpp +++ b/media/libstagefright/OggExtractor.cpp @@ -191,7 +191,8 @@ struct MyOpusExtractor : public MyOggExtractor { MyOpusExtractor(const sp<DataSource> &source) : MyOggExtractor(source, MEDIA_MIMETYPE_AUDIO_OPUS, /*numHeaders*/ 2, kOpusSeekPreRollUs), mChannelCount(0), - mCodecDelay(0) { + mCodecDelay(0), + mStartGranulePosition(-1) { } virtual uint64_t approxBitrate() const { @@ -211,6 +212,7 @@ private: uint8_t mChannelCount; uint16_t mCodecDelay; + int64_t mStartGranulePosition; }; static void extractAlbumArt( @@ -557,6 +559,37 @@ ssize_t MyOggExtractor::readPage(off64_t offset, Page *page) { } status_t MyOpusExtractor::readNextPacket(MediaBuffer **out) { + if (mOffset <= mFirstDataOffset && mStartGranulePosition < 0) { + // The first sample might not start at time 0; find out where by subtracting + // the number of samples on the first page from the granule position + // (position of last complete sample) of the first page. This happens + // the first time before we attempt to read a packet from the first page. + MediaBuffer *mBuf; + uint32_t numSamples = 0; + uint64_t curGranulePosition = 0; + while (true) { + status_t err = _readNextPacket(&mBuf, /* calcVorbisTimestamp = */false); + if (err != OK && err != ERROR_END_OF_STREAM) { + return err; + } + // First two pages are header pages. + if (err == ERROR_END_OF_STREAM || mCurrentPage.mPageNo > 2) { + break; + } + curGranulePosition = mCurrentPage.mGranulePosition; + numSamples += getNumSamplesInPacket(mBuf); + mBuf->release(); + mBuf = NULL; + } + + if (curGranulePosition > numSamples) { + mStartGranulePosition = curGranulePosition - numSamples; + } else { + mStartGranulePosition = 0; + } + seekToOffset(0); + } + status_t err = _readNextPacket(out, /* calcVorbisTimestamp = */false); if (err != OK) { return err; @@ -567,6 +600,10 @@ status_t MyOpusExtractor::readNextPacket(MediaBuffer **out) { // We assume that we only seek to page boundaries. if ((*out)->meta_data()->findInt32(kKeyValidSamples, ¤tPageSamples)) { // first packet in page + if (mOffset == mFirstDataOffset) { + currentPageSamples -= mStartGranulePosition; + (*out)->meta_data()->setInt32(kKeyValidSamples, currentPageSamples); + } mCurGranulePosition = mCurrentPage.mGranulePosition - currentPageSamples; } |