diff options
author | Andreas Huber <andih@google.com> | 2012-02-09 14:52:58 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-02-09 14:52:58 -0800 |
commit | 8f0f10a80a89b2071b949f13ac6ff23514366d23 (patch) | |
tree | 349026885b3756e8eedb90c92c4a61532f6e3ff6 | |
parent | f4aaf1f56247289838f4bb25ee704196464be4f2 (diff) | |
parent | 713f90f3ca03b9c41bcedf1caa729e471fc3964e (diff) | |
download | frameworks_base-8f0f10a80a89b2071b949f13ac6ff23514366d23.zip frameworks_base-8f0f10a80a89b2071b949f13ac6ff23514366d23.tar.gz frameworks_base-8f0f10a80a89b2071b949f13ac6ff23514366d23.tar.bz2 |
Merge "Experiment with seeking to closest frame instead of closest syncframe"
-rw-r--r-- | media/libstagefright/AwesomePlayer.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/matroska/MatroskaExtractor.cpp | 71 |
2 files changed, 61 insertions, 12 deletions
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 8073af8..aacfbdd 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -1609,7 +1609,7 @@ void AwesomePlayer::onVideoEvent() { mSeekTimeUs, mSeeking == SEEK_VIDEO_ONLY ? MediaSource::ReadOptions::SEEK_NEXT_SYNC - : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC); + : MediaSource::ReadOptions::SEEK_CLOSEST); } for (;;) { status_t err = mVideoSource->read(&mVideoBuffer, &options); diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index a1644d2..a0db719 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -93,7 +93,10 @@ struct BlockIterator { void advance(); void reset(); - void seek(int64_t seekTimeUs, bool seekToKeyFrame); + + void seek( + int64_t seekTimeUs, bool seekToKeyFrame, + int64_t *actualFrameTimeUs); const mkvparser::Block *block() const; int64_t blockTimeUs() const; @@ -303,23 +306,53 @@ void BlockIterator::reset() { } while (!eos() && block()->GetTrackNumber() != mTrackNum); } -void BlockIterator::seek(int64_t seekTimeUs, bool seekToKeyFrame) { +void BlockIterator::seek( + int64_t seekTimeUs, bool seekToKeyFrame, + int64_t *actualFrameTimeUs) { Mutex::Autolock autoLock(mExtractor->mLock); - mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll); + *actualFrameTimeUs = -1ll; + + int64_t seekTimeNs = seekTimeUs * 1000ll; + + mCluster = mExtractor->mSegment->FindCluster(seekTimeNs); mBlockEntry = NULL; mBlockEntryIndex = 0; - do { + long prevKeyFrameBlockEntryIndex = -1; + + for (;;) { advance_l(); - } - while (!eos() && block()->GetTrackNumber() != mTrackNum); - if (seekToKeyFrame) { - while (!eos() && !mBlockEntry->GetBlock()->IsKey()) { - advance_l(); + if (eos()) { + break; + } + + if (block()->GetTrackNumber() != mTrackNum) { + continue; + } + + if (block()->IsKey()) { + prevKeyFrameBlockEntryIndex = mBlockEntryIndex - 1; + } + + int64_t timeNs = block()->GetTime(mCluster); + + if (timeNs >= seekTimeNs) { + *actualFrameTimeUs = (timeNs + 500ll) / 1000ll; + break; } } + + if (eos()) { + return; + } + + if (seekToKeyFrame && !block()->IsKey()) { + CHECK_GE(prevKeyFrameBlockEntryIndex, 0); + mBlockEntryIndex = prevKeyFrameBlockEntryIndex; + advance_l(); + } } const mkvparser::Block *BlockIterator::block() const { @@ -397,6 +430,8 @@ status_t MatroskaSource::read( MediaBuffer **out, const ReadOptions *options) { *out = NULL; + int64_t targetSampleTimeUs = -1ll; + int64_t seekTimeUs; ReadOptions::SeekMode mode; if (options && options->getSeekTo(&seekTimeUs, &mode) @@ -406,10 +441,14 @@ status_t MatroskaSource::read( // Apparently keyframe indication in audio tracks is unreliable, // fortunately in all our currently supported audio encodings every // frame is effectively a keyframe. - mBlockIter.seek(seekTimeUs, !mIsAudio); + int64_t actualFrameTimeUs; + mBlockIter.seek(seekTimeUs, !mIsAudio, &actualFrameTimeUs); + + if (mode == ReadOptions::SEEK_CLOSEST) { + targetSampleTimeUs = actualFrameTimeUs; + } } -again: while (mPendingFrames.empty()) { status_t err = readBlock(); @@ -424,6 +463,11 @@ again: mPendingFrames.erase(mPendingFrames.begin()); if (mType != AVC) { + if (targetSampleTimeUs >= 0ll) { + frame->meta_data()->setInt64( + kKeyTargetTime, targetSampleTimeUs); + } + *out = frame; return OK; @@ -506,6 +550,11 @@ again: frame->release(); frame = NULL; + if (targetSampleTimeUs >= 0ll) { + buffer->meta_data()->setInt64( + kKeyTargetTime, targetSampleTimeUs); + } + *out = buffer; return OK; |