diff options
author | Marco Nelissen <marcone@google.com> | 2012-03-21 13:36:07 -0700 |
---|---|---|
committer | Marco Nelissen <marcone@google.com> | 2012-03-22 10:06:03 -0700 |
commit | a98478bfbcc0f7fb4b164d3dce40ca96df75667d (patch) | |
tree | 44a6ad7c4a9fb330ebdf560a2d8f446b43278498 /media/libstagefright/OMXCodec.cpp | |
parent | 898b11f2aeaaa2bed84d963a3fcfd3b229e00b99 (diff) | |
download | frameworks_av-a98478bfbcc0f7fb4b164d3dce40ca96df75667d.zip frameworks_av-a98478bfbcc0f7fb4b164d3dce40ca96df75667d.tar.gz frameworks_av-a98478bfbcc0f7fb4b164d3dce40ca96df75667d.tar.bz2 |
Support gapless playback for mp3 and m4a
Gapless playback for appropriately tagged mp3 and m4a files.
Currently this is implemented in OMXCodec, which most players
use, but should be easy to support in other players as well by
using the SkipCutBuffer utility class.
Change-Id: I748c669adc1cfbe5ee9a7dea2fad945d48882551
Diffstat (limited to 'media/libstagefright/OMXCodec.cpp')
-rwxr-xr-x | media/libstagefright/OMXCodec.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index d5e6bec..8b6e9d5 100755 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -38,6 +38,7 @@ #include <media/stagefright/MetaData.h> #include <media/stagefright/OMXCodec.h> #include <media/stagefright/Utils.h> +#include <media/stagefright/SkipCutBuffer.h> #include <utils/Vector.h> #include <OMX_Audio.h> @@ -1303,6 +1304,7 @@ OMXCodec::OMXCodec( mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC), mTargetTimeUs(-1), mOutputPortSettingsChangedPending(false), + mSkipCutBuffer(NULL), mLeftOverBuffer(NULL), mPaused(false), mNativeWindow( @@ -1413,6 +1415,9 @@ OMXCodec::~OMXCodec() { free(mMIME); mMIME = NULL; + + delete mSkipCutBuffer; + mSkipCutBuffer = NULL; } status_t OMXCodec::init() { @@ -1573,6 +1578,34 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { portIndex == kPortIndexInput ? "input" : "output"); } + if (portIndex == kPortIndexOutput) { + + sp<MetaData> meta = mSource->getFormat(); + int32_t delay = 0; + if (!meta->findInt32(kKeyEncoderDelay, &delay)) { + delay = 0; + } + int32_t padding = 0; + if (!meta->findInt32(kKeyEncoderPadding, &padding)) { + padding = 0; + } + int32_t numchannels = 0; + if (delay + padding) { + if (meta->findInt32(kKeyChannelCount, &numchannels)) { + size_t frameSize = numchannels * sizeof(int16_t); + if (mSkipCutBuffer) { + size_t prevbuffersize = mSkipCutBuffer->size(); + if (prevbuffersize != 0) { + ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize); + } + delete mSkipCutBuffer; + } + mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize, + def.nBufferSize); + } + } + } + // dumpPortStatus(portIndex); if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) { @@ -2490,6 +2523,10 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), mPortBuffers[portIndex].size()); + if (mSkipCutBuffer && mPortStatus[kPortIndexOutput] == ENABLED) { + mSkipCutBuffer->clear(); + } + if (mState == RECONFIGURING) { CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); @@ -3800,6 +3837,9 @@ status_t OMXCodec::read( info->mStatus = OWNED_BY_CLIENT; info->mMediaBuffer->add_ref(); + if (mSkipCutBuffer) { + mSkipCutBuffer->submit(info->mMediaBuffer); + } *buffer = info->mMediaBuffer; return OK; |