diff options
author | Andreas Huber <andih@google.com> | 2010-07-20 10:46:12 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2010-07-20 10:46:12 -0700 |
commit | 0ef7da159d2dcb469985291aaaedcd717c1c02b8 (patch) | |
tree | aeed8e6b22af451acbaa2ea87d5e5f76fa7529b3 /media/libstagefright | |
parent | 99a518ffabacb10171621d0293bf982b85505e66 (diff) | |
parent | ff45709fbd1f24de1cf75ce9ce9ac8694ff1abbe (diff) | |
download | frameworks_base-0ef7da159d2dcb469985291aaaedcd717c1c02b8.zip frameworks_base-0ef7da159d2dcb469985291aaaedcd717c1c02b8.tar.gz frameworks_base-0ef7da159d2dcb469985291aaaedcd717c1c02b8.tar.bz2 |
am ff45709f: am cc14a839: Support a single format change at the beginning of audio playback. This way the AAC+ decoder may change its output format from what is originally encoded in the audio stream and we\'ll still play it back correctly.
Merge commit 'ff45709fbd1f24de1cf75ce9ce9ac8694ff1abbe'
* commit 'ff45709fbd1f24de1cf75ce9ce9ac8694ff1abbe':
Support a single format change at the beginning of audio playback. This way the AAC+ decoder may change its output format from what is originally encoded in the audio stream and we'll still play it back correctly.
Diffstat (limited to 'media/libstagefright')
-rw-r--r-- | media/libstagefright/AudioPlayer.cpp | 57 | ||||
-rw-r--r-- | media/libstagefright/MPEG4Extractor.cpp | 70 |
2 files changed, 60 insertions, 67 deletions
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp index b79ba13..b7bde6b 100644 --- a/media/libstagefright/AudioPlayer.cpp +++ b/media/libstagefright/AudioPlayer.cpp @@ -41,6 +41,9 @@ AudioPlayer::AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink) mReachedEOS(false), mFinalStatus(OK), mStarted(false), + mIsFirstBuffer(false), + mFirstBufferResult(OK), + mFirstBuffer(NULL), mAudioSink(audioSink) { } @@ -68,6 +71,24 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) { } } + // We allow an optional INFO_FORMAT_CHANGED at the very beginning + // of playback, if there is one, getFormat below will retrieve the + // updated format, if there isn't, we'll stash away the valid buffer + // of data to be used on the first audio callback. + + CHECK(mFirstBuffer == NULL); + + mFirstBufferResult = mSource->read(&mFirstBuffer); + if (mFirstBufferResult == INFO_FORMAT_CHANGED) { + LOGV("INFO_FORMAT_CHANGED!!!"); + + CHECK(mFirstBuffer == NULL); + mFirstBufferResult = OK; + mIsFirstBuffer = false; + } else { + mIsFirstBuffer = true; + } + sp<MetaData> format = mSource->getFormat(); const char *mime; bool success = format->findCString(kKeyMIMEType, &mime); @@ -87,6 +108,11 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) { DEFAULT_AUDIOSINK_BUFFERCOUNT, &AudioPlayer::AudioSinkCallback, this); if (err != OK) { + if (mFirstBuffer != NULL) { + mFirstBuffer->release(); + mFirstBuffer = NULL; + } + if (!sourceAlreadyStarted) { mSource->stop(); } @@ -110,6 +136,11 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) { delete mAudioTrack; mAudioTrack = NULL; + if (mFirstBuffer != NULL) { + mFirstBuffer->release(); + mFirstBuffer = NULL; + } + if (!sourceAlreadyStarted) { mSource->stop(); } @@ -163,6 +194,12 @@ void AudioPlayer::stop() { // Make sure to release any buffer we hold onto so that the // source is able to stop(). + + if (mFirstBuffer != NULL) { + mFirstBuffer->release(); + mFirstBuffer = NULL; + } + if (mInputBuffer != NULL) { LOGV("AudioPlayer releasing input buffer."); @@ -247,6 +284,14 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) { Mutex::Autolock autoLock(mLock); if (mSeeking) { + if (mIsFirstBuffer) { + if (mFirstBuffer != NULL) { + mFirstBuffer->release(); + mFirstBuffer = NULL; + } + mIsFirstBuffer = false; + } + options.setSeekTo(mSeekTimeUs); if (mInputBuffer != NULL) { @@ -259,7 +304,17 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) { } if (mInputBuffer == NULL) { - status_t err = mSource->read(&mInputBuffer, &options); + status_t err; + + if (mIsFirstBuffer) { + mInputBuffer = mFirstBuffer; + mFirstBuffer = NULL; + err = mFirstBufferResult; + + mIsFirstBuffer = false; + } else { + err = mSource->read(&mInputBuffer, &options); + } CHECK((err == OK && mInputBuffer != NULL) || (err != OK && mInputBuffer == NULL)); diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 65d0146..0c2f1e6 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -1287,11 +1287,6 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); int32_t sampleRate = 0; int32_t numChannels = 0; - uint8_t offset = 0; - static uint32_t kSamplingRate[] = { - 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, - 16000, 12000, 11025, 8000, 7350 - }; if (freqIndex == 15) { if (csd_size < 5) { return ERROR_MALFORMED; @@ -1303,8 +1298,11 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( | (csd[4] >> 7); numChannels = (csd[4] >> 3) & 15; - offset = 4; } else { + static uint32_t kSamplingRate[] = { + 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, + 16000, 12000, 11025, 8000, 7350 + }; if (freqIndex == 13 || freqIndex == 14) { return ERROR_MALFORMED; @@ -1312,66 +1310,6 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( sampleRate = kSamplingRate[freqIndex]; numChannels = (csd[1] >> 3) & 15; - offset = 1; - } - - uint8_t sbrPresentFlag = -1; - uint8_t extensionAudioObjectType = 0; - if (objectType == 5) { - extensionAudioObjectType = objectType; - sbrPresentFlag = 1; - freqIndex = ((csd[offset] & 7) << 1) | (csd[offset + 1] >> 7); - offset += 1; - if (freqIndex == 15) { - sampleRate = (((csd[offset] & 0x7f) << 17) - | (csd[offset + 1] << 9) - | (csd[offset + 2] << 1) - | (csd[offset + 3] >> 7)); - offset += 3; - } - objectType = csd[offset] >> 3; - } - - if (((objectType >= 1 && objectType <= 4) || - (objectType >= 6 && objectType <= 7) || - (objectType == 17) || - (objectType >= 19 || objectType <= 23)) && - (0x00 == (csd[offset] & 7)) && - numChannels != 0) { - - // XXX: We are not handling coreCoderDelay, - // program_config_element(), - // extensionFlag, scalable profile, etc. - if (objectType != 6 && objectType != 20) { - if (objectType != 5 && csd_size - offset >= 2) { - uint32_t syncExtensionType = - (csd[offset + 1] << 3) | (csd[offset + 2] >> 5); - if (syncExtensionType == 0x2b7) { - extensionAudioObjectType = - csd[offset + 2] & 0x1F; - if (extensionAudioObjectType == 0x05) { - if (csd_size - offset < 3) { - return ERROR_MALFORMED; - } - uint8_t sbrPresentFlag = csd[offset + 3] & 0x80; - if (sbrPresentFlag) { - freqIndex = (csd[offset + 3] & 0x78) >> 3; - if (freqIndex == 15) { - if (csd_size - offset < 6) { - return ERROR_MALFORMED; - } - sampleRate = (csd[offset + 3] & 0x07) << 21 - | csd[offset + 4] << 13 - | csd[offset + 5] << 5 - | csd[offset + 6] >> 3; - } else { - sampleRate = kSamplingRate[freqIndex]; - } - } - } - } - } - } } if (numChannels == 0) { |