summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-07-20 09:21:17 -0700
committerAndreas Huber <andih@google.com>2010-07-20 09:25:38 -0700
commit3c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8 (patch)
tree6003c16314885bf515785ba2648334434bff2762 /media
parent95c2580db188dee19cab05d29351c7ca5973cf3b (diff)
downloadframeworks_av-3c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8.zip
frameworks_av-3c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8.tar.gz
frameworks_av-3c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8.tar.bz2
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.
Change-Id: Icc790122744745e9a88099788d4818ca1e265a82 related-to-bug: 2826841
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/AudioPlayer.cpp57
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp70
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) {