Skip to content

Commit 16263d9

Browse files
committed
Squashed commit of the following:
commit 4abf16bb04dc9695fedf4007a84f903074312ccd Author: Andreas Huber <andih@google.com> Date: Tue Jul 20 09:21:17 2010 -0700 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 commit 09c74da63e6ad5cb5dafb70f62696d75d2978967 Author: James Dong <jdong@google.com> Date: Sun Jul 18 17:57:01 2010 -0700 Fix MPEG4Extractor to extract sampling frequency correctly when SBR is enabled. Change-Id: I883c81dad3ea465e71cb5590e89d763671a90ff8 commit f672bf2a782dc7d5fb6325d611a7fe17045dfe9a Author: James Dong <jdong@google.com> Date: Thu Jul 8 20:56:13 2010 -0700 Enable the support for decoding audio with AAC+ and eAAC+ features bug - 282684 Change-Id: I73c8377af3cc4edd3ee7cea86dc3b1c369fbd78b Change-Id: I012f1179e933b6d1345d2368f357576c722485f7
1 parent 3bf5c4c commit 16263d9

File tree

4 files changed

+136
-48
lines changed

4 files changed

+136
-48
lines changed

include/media/stagefright/AudioPlayer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ class AudioPlayer : public TimeSource {
8686

8787
bool mStarted;
8888

89+
bool mIsFirstBuffer;
90+
status_t mFirstBufferResult;
91+
MediaBuffer *mFirstBuffer;
92+
8993
sp<MediaPlayerBase::AudioSink> mAudioSink;
9094

9195
static void AudioCallback(int event, void *user, void *info);

media/libstagefright/AudioPlayer.cpp

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <media/stagefright/AudioPlayer.h>
2424
#include <media/stagefright/MediaDebug.h>
2525
#include <media/stagefright/MediaDefs.h>
26+
#include <media/stagefright/MediaErrors.h>
2627
#include <media/stagefright/MediaSource.h>
2728
#include <media/stagefright/MetaData.h>
2829

@@ -41,6 +42,9 @@ AudioPlayer::AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink)
4142
mReachedEOS(false),
4243
mFinalStatus(OK),
4344
mStarted(false),
45+
mIsFirstBuffer(false),
46+
mFirstBufferResult(OK),
47+
mFirstBuffer(NULL),
4448
mAudioSink(audioSink) {
4549
}
4650

@@ -68,6 +72,24 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
6872
}
6973
}
7074

75+
// We allow an optional INFO_FORMAT_CHANGED at the very beginning
76+
// of playback, if there is one, getFormat below will retrieve the
77+
// updated format, if there isn't, we'll stash away the valid buffer
78+
// of data to be used on the first audio callback.
79+
80+
CHECK(mFirstBuffer == NULL);
81+
82+
mFirstBufferResult = mSource->read(&mFirstBuffer);
83+
if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
84+
LOGV("INFO_FORMAT_CHANGED!!!");
85+
86+
CHECK(mFirstBuffer == NULL);
87+
mFirstBufferResult = OK;
88+
mIsFirstBuffer = false;
89+
} else {
90+
mIsFirstBuffer = true;
91+
}
92+
7193
sp<MetaData> format = mSource->getFormat();
7294
const char *mime;
7395
bool success = format->findCString(kKeyMIMEType, &mime);
@@ -87,7 +109,14 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
87109
DEFAULT_AUDIOSINK_BUFFERCOUNT,
88110
&AudioPlayer::AudioSinkCallback, this);
89111
if (err != OK) {
90-
mSource->stop();
112+
if (mFirstBuffer != NULL) {
113+
mFirstBuffer->release();
114+
mFirstBuffer = NULL;
115+
}
116+
117+
if (!sourceAlreadyStarted) {
118+
mSource->stop();
119+
}
91120

92121
return err;
93122
}
@@ -108,7 +137,14 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
108137
delete mAudioTrack;
109138
mAudioTrack = NULL;
110139

111-
mSource->stop();
140+
if (mFirstBuffer != NULL) {
141+
mFirstBuffer->release();
142+
mFirstBuffer = NULL;
143+
}
144+
145+
if (!sourceAlreadyStarted) {
146+
mSource->stop();
147+
}
112148

113149
return err;
114150
}
@@ -159,6 +195,12 @@ void AudioPlayer::stop() {
159195

160196
// Make sure to release any buffer we hold onto so that the
161197
// source is able to stop().
198+
199+
if (mFirstBuffer != NULL) {
200+
mFirstBuffer->release();
201+
mFirstBuffer = NULL;
202+
}
203+
162204
if (mInputBuffer != NULL) {
163205
LOGV("AudioPlayer releasing input buffer.");
164206

@@ -243,6 +285,14 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {
243285
Mutex::Autolock autoLock(mLock);
244286

245287
if (mSeeking) {
288+
if (mIsFirstBuffer) {
289+
if (mFirstBuffer != NULL) {
290+
mFirstBuffer->release();
291+
mFirstBuffer = NULL;
292+
}
293+
mIsFirstBuffer = false;
294+
}
295+
246296
options.setSeekTo(mSeekTimeUs);
247297

248298
if (mInputBuffer != NULL) {
@@ -255,7 +305,17 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {
255305
}
256306

257307
if (mInputBuffer == NULL) {
258-
status_t err = mSource->read(&mInputBuffer, &options);
308+
status_t err;
309+
310+
if (mIsFirstBuffer) {
311+
mInputBuffer = mFirstBuffer;
312+
mFirstBuffer = NULL;
313+
err = mFirstBufferResult;
314+
315+
mIsFirstBuffer = false;
316+
} else {
317+
err = mSource->read(&mInputBuffer, &options);
318+
}
259319

260320
CHECK((err == OK && mInputBuffer != NULL)
261321
|| (err != OK && mInputBuffer == NULL));

media/libstagefright/codecs/aacdec/AACDecoder.cpp

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#include "AACDecoder.h"
18+
#define LOG_TAG "AACDecoder"
1819

1920
#include "../../include/ESDS.h"
2021

@@ -36,26 +37,33 @@ AACDecoder::AACDecoder(const sp<MediaSource> &source)
3637
mAnchorTimeUs(0),
3738
mNumSamplesOutput(0),
3839
mInputBuffer(NULL) {
39-
}
4040

41-
AACDecoder::~AACDecoder() {
42-
if (mStarted) {
43-
stop();
44-
}
41+
sp<MetaData> srcFormat = mSource->getFormat();
4542

46-
delete mConfig;
47-
mConfig = NULL;
48-
}
43+
int32_t sampleRate;
44+
CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
4945

50-
status_t AACDecoder::start(MetaData *params) {
51-
CHECK(!mStarted);
46+
mMeta = new MetaData;
47+
mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
5248

53-
mBufferGroup = new MediaBufferGroup;
54-
mBufferGroup->add_buffer(new MediaBuffer(2048 * 2));
49+
// We'll always output stereo, regardless of how many channels are
50+
// present in the input due to decoder limitations.
51+
mMeta->setInt32(kKeyChannelCount, 2);
52+
mMeta->setInt32(kKeySampleRate, sampleRate);
5553

54+
int64_t durationUs;
55+
if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
56+
mMeta->setInt64(kKeyDuration, durationUs);
57+
}
58+
mMeta->setCString(kKeyDecoderComponent, "AACDecoder");
59+
60+
mInitCheck = initCheck();
61+
}
62+
63+
status_t AACDecoder::initCheck() {
64+
memset(mConfig, 0, sizeof(tPVMP4AudioDecoderExternal));
5665
mConfig->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
57-
mConfig->aacPlusUpsamplingFactor = 0;
58-
mConfig->aacPlusEnabled = false;
66+
mConfig->aacPlusEnabled = 1;
5967

6068
// The software decoder doesn't properly support mono output on
6169
// AACplus files. Always output stereo.
@@ -64,8 +72,11 @@ status_t AACDecoder::start(MetaData *params) {
6472
UInt32 memRequirements = PVMP4AudioDecoderGetMemRequirements();
6573
mDecoderBuf = malloc(memRequirements);
6674

67-
CHECK_EQ(PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf),
68-
MP4AUDEC_SUCCESS);
75+
status_t err = PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf);
76+
if (err != MP4AUDEC_SUCCESS) {
77+
LOGE("Failed to initialize MP4 audio decoder");
78+
return UNKNOWN_ERROR;
79+
}
6980

7081
uint32_t type;
7182
const void *data;
@@ -83,18 +94,29 @@ status_t AACDecoder::start(MetaData *params) {
8394
mConfig->pInputBuffer = (UChar *)codec_specific_data;
8495
mConfig->inputBufferCurrentLength = codec_specific_data_size;
8596
mConfig->inputBufferMaxLength = 0;
86-
mConfig->inputBufferUsedLength = 0;
87-
mConfig->remainderBits = 0;
88-
89-
mConfig->pOutputBuffer = NULL;
90-
mConfig->pOutputBuffer_plus = NULL;
91-
mConfig->repositionFlag = false;
9297

9398
if (PVMP4AudioDecoderConfig(mConfig, mDecoderBuf)
9499
!= MP4AUDEC_SUCCESS) {
95100
return ERROR_UNSUPPORTED;
96101
}
97102
}
103+
return OK;
104+
}
105+
106+
AACDecoder::~AACDecoder() {
107+
if (mStarted) {
108+
stop();
109+
}
110+
111+
delete mConfig;
112+
mConfig = NULL;
113+
}
114+
115+
status_t AACDecoder::start(MetaData *params) {
116+
CHECK(!mStarted);
117+
118+
mBufferGroup = new MediaBufferGroup;
119+
mBufferGroup->add_buffer(new MediaBuffer(4096 * 2));
98120

99121
mSource->start();
100122

@@ -127,28 +149,7 @@ status_t AACDecoder::stop() {
127149
}
128150

129151
sp<MetaData> AACDecoder::getFormat() {
130-
sp<MetaData> srcFormat = mSource->getFormat();
131-
132-
int32_t sampleRate;
133-
CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
134-
135-
sp<MetaData> meta = new MetaData;
136-
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
137-
138-
// We'll always output stereo, regardless of how many channels are
139-
// present in the input due to decoder limitations.
140-
meta->setInt32(kKeyChannelCount, 2);
141-
142-
meta->setInt32(kKeySampleRate, sampleRate);
143-
144-
int64_t durationUs;
145-
if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
146-
meta->setInt64(kKeyDuration, durationUs);
147-
}
148-
149-
meta->setCString(kKeyDecoderComponent, "AACDecoder");
150-
151-
return meta;
152+
return mMeta;
152153
}
153154

154155
status_t AACDecoder::read(
@@ -200,13 +201,32 @@ status_t AACDecoder::read(
200201
mConfig->remainderBits = 0;
201202

202203
mConfig->pOutputBuffer = static_cast<Int16 *>(buffer->data());
203-
mConfig->pOutputBuffer_plus = NULL;
204+
mConfig->pOutputBuffer_plus = &mConfig->pOutputBuffer[2048];
204205
mConfig->repositionFlag = false;
205206

206207
Int decoderErr = PVMP4AudioDecodeFrame(mConfig, mDecoderBuf);
207208

209+
// Check on the sampling rate to see whether it is changed.
210+
int32_t sampleRate;
211+
CHECK(mMeta->findInt32(kKeySampleRate, &sampleRate));
212+
if (mConfig->samplingRate != sampleRate) {
213+
mMeta->setInt32(kKeySampleRate, mConfig->samplingRate);
214+
LOGW("Sample rate was %d, but now is %d",
215+
sampleRate, mConfig->samplingRate);
216+
buffer->release();
217+
mInputBuffer->release();
218+
mInputBuffer = NULL;
219+
return INFO_FORMAT_CHANGED;
220+
}
221+
208222
size_t numOutBytes =
209223
mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels;
224+
if (mConfig->aacPlusUpsamplingFactor == 2) {
225+
if (mConfig->desiredChannels == 1) {
226+
memcpy(&mConfig->pOutputBuffer[1024], &mConfig->pOutputBuffer[2048], numOutBytes * 2);
227+
}
228+
numOutBytes *= 2;
229+
}
210230

211231
if (decoderErr != MP4AUDEC_SUCCESS) {
212232
LOGW("AAC decoder returned error %d, substituting silence", decoderErr);

media/libstagefright/include/AACDecoder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ struct tPVMP4AudioDecoderExternal;
2525
namespace android {
2626

2727
struct MediaBufferGroup;
28+
struct MetaData;
2829

2930
struct AACDecoder : public MediaSource {
3031
AACDecoder(const sp<MediaSource> &source);
@@ -41,6 +42,7 @@ struct AACDecoder : public MediaSource {
4142
virtual ~AACDecoder();
4243

4344
private:
45+
sp<MetaData> mMeta;
4446
sp<MediaSource> mSource;
4547
bool mStarted;
4648

@@ -50,9 +52,11 @@ struct AACDecoder : public MediaSource {
5052
void *mDecoderBuf;
5153
int64_t mAnchorTimeUs;
5254
int64_t mNumSamplesOutput;
55+
status_t mInitCheck;
5356

5457
MediaBuffer *mInputBuffer;
5558

59+
status_t initCheck();
5660
AACDecoder(const AACDecoder &);
5761
AACDecoder &operator=(const AACDecoder &);
5862
};

0 commit comments

Comments
 (0)