summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/matroska
diff options
context:
space:
mode:
authorJohann <johannkoenig@google.com>2012-04-04 16:46:43 -0700
committerJohann <johannkoenig@google.com>2012-04-04 16:46:43 -0700
commitf02a7f5c42db707d20e59ff28f32d1eaebcc5429 (patch)
treef2b0f970e7abee6122333d39fc5da6ca62d63917 /media/libstagefright/matroska
parent4762a5164a986bd6a7ca0e7aba43881b64f146dd (diff)
downloadframeworks_av-f02a7f5c42db707d20e59ff28f32d1eaebcc5429.zip
frameworks_av-f02a7f5c42db707d20e59ff28f32d1eaebcc5429.tar.gz
frameworks_av-f02a7f5c42db707d20e59ff28f32d1eaebcc5429.tar.bz2
Trust the Cues element
With the Cue based seeking we will get the closest previous key frame. For audio, use the Cue file to find the Cluster with the video key frame then incrementally look for the audio Block. Change-Id: Idc934cca1286b1bb48ee7577b27903ca488a0610
Diffstat (limited to 'media/libstagefright/matroska')
-rw-r--r--media/libstagefright/matroska/MatroskaExtractor.cpp66
1 files changed, 22 insertions, 44 deletions
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index f8c272c..8c63df9 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -95,7 +95,7 @@ struct BlockIterator {
void reset();
void seek(
- int64_t seekTimeUs, bool seekToKeyFrame,
+ int64_t seekTimeUs, bool isAudio,
int64_t *actualFrameTimeUs);
const mkvparser::Block *block() const;
@@ -307,7 +307,7 @@ void BlockIterator::reset() {
}
void BlockIterator::seek(
- int64_t seekTimeUs, bool seekToKeyFrame,
+ int64_t seekTimeUs, bool isAudio,
int64_t *actualFrameTimeUs) {
Mutex::Autolock autoLock(mExtractor->mLock);
@@ -372,9 +372,7 @@ void BlockIterator::seek(
}
}
- // Find the video track for seeking. It doesn't make sense to search the
- // audio track because we'd still want to make sure we're jumping to a
- // keyframe in the video track.
+ // The Cue index is built around video keyframes
mkvparser::Tracks const *pTracks = pSegment->GetTracks();
const mkvparser::Track *pTrack = NULL;
for (size_t index = 0; index < pTracks->GetTracksCount(); ++index) {
@@ -385,57 +383,37 @@ void BlockIterator::seek(
}
}
+ // Always *search* based on the video track, but finalize based on mTrackNum
const mkvparser::CuePoint::TrackPosition* pTP;
- if (pTrack) {
+ if (pTrack && pTrack->GetType() == 1) {
pCues->Find(seekTimeNs, pTrack, pCP, pTP);
} else {
- ALOGE("Did not locate a VIDEO_TRACK");
+ ALOGE("Did not locate the video track for seeking");
return;
}
mCluster = pSegment->FindOrPreloadCluster(pTP->m_pos);
- if (pTP->m_block > 0) {
- // m_block starts at 1, but mBlockEntryIndex is expected to start at 0
- mBlockEntryIndex = pTP->m_block - 1;
- } else {
- ALOGE("m_block must be > 0");
- return;
- }
- long prevKeyFrameBlockEntryIndex = -1;
+ CHECK(mCluster);
+ CHECK(!mCluster->EOS());
+
+ // mBlockEntryIndex starts at 0 but m_block starts at 1
+ CHECK_GT(pTP->m_block, 0);
+ mBlockEntryIndex = pTP->m_block - 1;
for (;;) {
advance_l();
- if (eos()) {
- break;
- }
-
- if (block()->GetTrackNumber() != mTrackNum) {
- continue;
- }
-
- if (block()->IsKey()) {
- prevKeyFrameBlockEntryIndex = mBlockEntryIndex - 1;
- }
-
- int64_t timeNs = block()->GetTime(mCluster);
+ if (eos()) break;
- if (timeNs >= seekTimeNs) {
- *actualFrameTimeUs = (timeNs + 500ll) / 1000ll;
+ if (isAudio || block()->IsKey()) {
+ // Accept the first key frame
+ *actualFrameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL;
+ ALOGV("Requested seek point: %lld actual: %lld",
+ seekTimeUs, actualFrameTimeUs);
break;
}
}
-
- if (eos()) {
- return;
- }
-
- if (seekToKeyFrame && !block()->IsKey()) {
- CHECK_GE(prevKeyFrameBlockEntryIndex, 0);
- mBlockEntryIndex = prevKeyFrameBlockEntryIndex;
- advance_l();
- }
}
const mkvparser::Block *BlockIterator::block() const {
@@ -521,11 +499,11 @@ status_t MatroskaSource::read(
&& !mExtractor->isLiveStreaming()) {
clearPendingFrames();
- // Apparently keyframe indication in audio tracks is unreliable,
- // fortunately in all our currently supported audio encodings every
- // frame is effectively a keyframe.
+ // The audio we want is located by using the Cues to seek the video
+ // stream to find the target Cluster then iterating to finalize for
+ // audio.
int64_t actualFrameTimeUs;
- mBlockIter.seek(seekTimeUs, !mIsAudio, &actualFrameTimeUs);
+ mBlockIter.seek(seekTimeUs, mIsAudio, &actualFrameTimeUs);
if (mode == ReadOptions::SEEK_CLOSEST) {
targetSampleTimeUs = actualFrameTimeUs;