summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/matroska
diff options
context:
space:
mode:
authorPawit Pornkitprasan <p.pawit@gmail.com>2012-01-13 16:16:27 +0700
committerSteve Kondik <steve@cyngn.com>2015-10-23 12:38:46 -0500
commit7c5a700734540a971cbf7f901e201f7750e3027d (patch)
tree2f3e1d59b29c45f75df931e7db28544a355d88e7 /media/libstagefright/matroska
parent64718dbe0e1ab4a1acec09f28db83f2838fdfe1f (diff)
downloadframeworks_av-7c5a700734540a971cbf7f901e201f7750e3027d.zip
frameworks_av-7c5a700734540a971cbf7f901e201f7750e3027d.tar.gz
frameworks_av-7c5a700734540a971cbf7f901e201f7750e3027d.tar.bz2
stagefright: Fix playback for mkv files with lacing
Most mkv files having 'lacing' in their audio section to save space. Android did not handle this properly, sending all frames in the block with the same time code, which causes stuttery playback. Change-Id: I4dc76e7c2a53126c7fbdd3628fe7d339d2e3364e
Diffstat (limited to 'media/libstagefright/matroska')
-rw-r--r--media/libstagefright/matroska/MatroskaExtractor.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index ecc2573..e6ed900 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -521,8 +521,9 @@ status_t MatroskaSource::readBlock() {
const mkvparser::Block *block = mBlockIter.block();
int64_t timeUs = mBlockIter.blockTimeUs();
+ int frameCount = block->GetFrameCount();
- for (int i = 0; i < block->GetFrameCount(); ++i) {
+ for (int i = 0; i < frameCount; ++i) {
const mkvparser::Block::Frame &frame = block->GetFrame(i);
MediaBuffer *mbuf = new MediaBuffer(frame.len);
@@ -542,6 +543,27 @@ status_t MatroskaSource::readBlock() {
mBlockIter.advance();
+ if (!mBlockIter.eos() && frameCount > 1) {
+ // For files with lacing enabled, we need to amend they kKeyTime of
+ // each frame so that their kKeyTime are advanced accordingly (instead
+ // of being set to the same value). To do this, we need to find out
+ // the duration of the block using the start time of the next block.
+ int64_t duration = mBlockIter.blockTimeUs() - timeUs;
+ int64_t durationPerFrame = duration / frameCount;
+ int64_t durationRemainder = duration % frameCount;
+
+ // We split duration to each of the frame, distributing the remainder (if any)
+ // to the later frames. The later frames are processed first due to the
+ // use of the iterator for the doubly linked list
+ List<MediaBuffer *>::iterator it = mPendingFrames.end();
+ for (int i = frameCount - 1; i >= 0; --i) {
+ --it;
+ int64_t frameRemainder = durationRemainder >= frameCount - i ? 1 : 0;
+ int64_t frameTimeUs = timeUs + durationPerFrame * i + frameRemainder;
+ (*it)->meta_data()->setInt64(kKeyTime, frameTimeUs);
+ }
+ }
+
return OK;
}