summaryrefslogtreecommitdiff
path: root/media/libstagefright/codecs/mp3dec
diff options
context:
space:
mode:
authorMarco Nelissen <marcone@google.com>2012-03-21 13:36:07 -0700
committerMarco Nelissen <marcone@google.com>2012-03-22 10:06:03 -0700
commita98478bfbcc0f7fb4b164d3dce40ca96df75667d (patch)
tree44a6ad7c4a9fb330ebdf560a2d8f446b43278498 /media/libstagefright/codecs/mp3dec
parent898b11f2aeaaa2bed84d963a3fcfd3b229e00b99 (diff)
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/codecs/mp3dec')
-rw-r--r--media/libstagefright/codecs/mp3dec/SoftMP3.cpp20
-rw-r--r--media/libstagefright/codecs/mp3dec/SoftMP3.h6
2 files changed, 20 insertions, 6 deletions
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index ad552953..92009eeb 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -115,6 +115,7 @@ void SoftMP3::initDecoder() {
mDecoderBuf = malloc(memRequirements);
pvmp3_InitDecoder(mConfig, mDecoderBuf);
+ mIsFirst = true;
}
OMX_ERRORTYPE SoftMP3::internalGetParameter(
@@ -190,7 +191,10 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
inInfo->mOwnedByUs = false;
notifyEmptyBufferDone(inHeader);
- outHeader->nFilledLen = 0;
+ // pad the end of the stream with 529 samples, since that many samples
+ // were trimmed off the beginning when decoding started
+ outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
+ memset(outHeader->pBuffer, 0, outHeader->nFilledLen);
outHeader->nFlags = OMX_BUFFERFLAG_EOS;
outQueue.erase(outQueue.begin());
@@ -251,8 +255,17 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
return;
}
- outHeader->nOffset = 0;
- outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
+ if (mIsFirst) {
+ mIsFirst = false;
+ // The decoder delay is 529 samples, so trim that many samples off
+ // the start of the first output buffer. This essentially makes this
+ // decoder have zero delay, which the rest of the pipeline assumes.
+ outHeader->nOffset = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
+ outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t) - outHeader->nOffset;
+ } else {
+ outHeader->nOffset = 0;
+ outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
+ }
outHeader->nTimeStamp =
mAnchorTimeUs
@@ -288,6 +301,7 @@ void SoftMP3::onPortFlushCompleted(OMX_U32 portIndex) {
// Make sure that the next buffer output does not still
// depend on fragments from the last one decoded.
pvmp3_InitDecoder(mConfig, mDecoderBuf);
+ mIsFirst = true;
}
}
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h
index 70d0682a..3a054664 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.h
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h
@@ -46,7 +46,8 @@ protected:
private:
enum {
kNumBuffers = 4,
- kOutputBufferSize = 4608 * 2
+ kOutputBufferSize = 4608 * 2,
+ kPVMP3DecoderDelay = 529 // frames
};
tPVMP3DecoderExternal *mConfig;
@@ -57,8 +58,7 @@ private:
int32_t mNumChannels;
int32_t mSamplingRate;
- bool mConfigured;
-
+ bool mIsFirst;
bool mSignalledError;
enum {