diff options
author | Pawit Pornkitprasan <p.pawit@gmail.com> | 2012-01-13 16:16:27 +0700 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2015-10-23 12:38:46 -0500 |
commit | 7c5a700734540a971cbf7f901e201f7750e3027d (patch) | |
tree | 2f3e1d59b29c45f75df931e7db28544a355d88e7 /media/libstagefright/matroska | |
parent | 64718dbe0e1ab4a1acec09f28db83f2838fdfe1f (diff) | |
download | frameworks_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.cpp | 24 |
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; } |