summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/matroska
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2012-02-09 09:55:45 -0800
committerAndreas Huber <andih@google.com>2012-02-09 14:32:08 -0800
commit5ec58d925520e6913fba3fc54413881af751c610 (patch)
treed833f4cf3772a3f3b8a68d2cc1060ed58840b82f /media/libstagefright/matroska
parent7ae4a2c130ec2cb5dec69d095b810698acc543b3 (diff)
downloadframeworks_av-5ec58d925520e6913fba3fc54413881af751c610.zip
frameworks_av-5ec58d925520e6913fba3fc54413881af751c610.tar.gz
frameworks_av-5ec58d925520e6913fba3fc54413881af751c610.tar.bz2
Experiment with seeking to closest frame instead of closest syncframe
Also supports SEEK_CLOSEST mode in the Matroska/Webm extractor. Change-Id: I257771648dfe41392a4cf8932f625489dcb9f234
Diffstat (limited to 'media/libstagefright/matroska')
-rw-r--r--media/libstagefright/matroska/MatroskaExtractor.cpp71
1 files changed, 60 insertions, 11 deletions
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;