blob: 536cfdeb5bc3e741ccc1cf9a57a63048cdee7f83 [file] [log] [blame]
Dave Burkeb7ddcc92012-04-02 13:54:42 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "SoftAAC2"
Jean-Michel Trivi4213e9d2012-10-02 11:18:16 -070018//#define LOG_NDEBUG 0
Dave Burkeb7ddcc92012-04-02 13:54:42 -070019#include <utils/Log.h>
20
21#include "SoftAAC2.h"
22
Dave Burke1adacd92012-05-23 00:00:53 -070023#include <cutils/properties.h>
Dave Burkeb7ddcc92012-04-02 13:54:42 -070024#include <media/stagefright/foundation/ADebug.h>
25#include <media/stagefright/foundation/hexdump.h>
Andreas Huber8370c7a2012-05-18 13:08:14 -070026#include <media/stagefright/MediaErrors.h>
Dave Burkeb7ddcc92012-04-02 13:54:42 -070027
28#define FILEREAD_MAX_LAYERS 2
29
Jean-Michel Trivi347f3542012-10-19 14:52:16 -070030#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
Jean-Michel Trivi4213e9d2012-10-02 11:18:16 -070031#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */
32#define MAX_CHANNEL_COUNT 6 /* maximum number of audio channels that can be decoded */
33// names of properties that can be used to override the default DRC settings
34#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
35#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
36#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
Jean-Michel Trivi5696a4e2012-08-10 12:24:59 -070037
Dave Burkeb7ddcc92012-04-02 13:54:42 -070038namespace android {
39
Dave Burkeb7ddcc92012-04-02 13:54:42 -070040template<class T>
41static void InitOMXParams(T *params) {
42 params->nSize = sizeof(T);
43 params->nVersion.s.nVersionMajor = 1;
44 params->nVersion.s.nVersionMinor = 0;
45 params->nVersion.s.nRevision = 0;
46 params->nVersion.s.nStep = 0;
47}
48
49SoftAAC2::SoftAAC2(
50 const char *name,
51 const OMX_CALLBACKTYPE *callbacks,
52 OMX_PTR appData,
53 OMX_COMPONENTTYPE **component)
54 : SimpleSoftOMXComponent(name, callbacks, appData, component),
55 mAACDecoder(NULL),
56 mStreamInfo(NULL),
57 mIsADTS(false),
58 mInputBufferCount(0),
59 mSignalledError(false),
60 mAnchorTimeUs(0),
61 mNumSamplesOutput(0),
62 mOutputPortSettingsChange(NONE) {
Dave Burkeb7ddcc92012-04-02 13:54:42 -070063 initPorts();
64 CHECK_EQ(initDecoder(), (status_t)OK);
65}
66
67SoftAAC2::~SoftAAC2() {
68 aacDecoder_Close(mAACDecoder);
Dave Burkeb7ddcc92012-04-02 13:54:42 -070069}
70
71void SoftAAC2::initPorts() {
72 OMX_PARAM_PORTDEFINITIONTYPE def;
73 InitOMXParams(&def);
74
75 def.nPortIndex = 0;
76 def.eDir = OMX_DirInput;
Andreas Hubereb614312012-05-10 16:43:19 -070077 def.nBufferCountMin = kNumInputBuffers;
Dave Burkeb7ddcc92012-04-02 13:54:42 -070078 def.nBufferCountActual = def.nBufferCountMin;
79 def.nBufferSize = 8192;
80 def.bEnabled = OMX_TRUE;
81 def.bPopulated = OMX_FALSE;
82 def.eDomain = OMX_PortDomainAudio;
83 def.bBuffersContiguous = OMX_FALSE;
84 def.nBufferAlignment = 1;
85
86 def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
87 def.format.audio.pNativeRender = NULL;
88 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
89 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
90
91 addPort(def);
92
93 def.nPortIndex = 1;
94 def.eDir = OMX_DirOutput;
Andreas Hubereb614312012-05-10 16:43:19 -070095 def.nBufferCountMin = kNumOutputBuffers;
Dave Burkeb7ddcc92012-04-02 13:54:42 -070096 def.nBufferCountActual = def.nBufferCountMin;
Jean-Michel Trivi888f63b2012-09-09 10:27:08 -070097 def.nBufferSize = 4096 * MAX_CHANNEL_COUNT;
Dave Burkeb7ddcc92012-04-02 13:54:42 -070098 def.bEnabled = OMX_TRUE;
99 def.bPopulated = OMX_FALSE;
100 def.eDomain = OMX_PortDomainAudio;
101 def.bBuffersContiguous = OMX_FALSE;
102 def.nBufferAlignment = 2;
103
104 def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
105 def.format.audio.pNativeRender = NULL;
106 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
107 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
108
109 addPort(def);
110}
111
112status_t SoftAAC2::initDecoder() {
113 status_t status = UNKNOWN_ERROR;
Andreas Hubere672a0e2012-05-17 16:06:01 -0700114 mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700115 if (mAACDecoder != NULL) {
116 mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
117 if (mStreamInfo != NULL) {
118 status = OK;
119 }
120 }
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700121 mDecoderHasData = false;
Jean-Michel Trivi4213e9d2012-10-02 11:18:16 -0700122
123 // for streams that contain metadata, use the mobile profile DRC settings unless overridden
124 // by platform properties:
125 char value[PROPERTY_VALUE_MAX];
126 // * AAC_DRC_REFERENCE_LEVEL
127 if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
128 unsigned refLevel = atoi(value);
129 ALOGV("AAC decoder using AAC_DRC_REFERENCE_LEVEL of %d instead of %d",
130 refLevel, DRC_DEFAULT_MOBILE_REF_LEVEL);
131 aacDecoder_SetParam(mAACDecoder, AAC_DRC_REFERENCE_LEVEL, refLevel);
132 } else {
133 aacDecoder_SetParam(mAACDecoder, AAC_DRC_REFERENCE_LEVEL, DRC_DEFAULT_MOBILE_REF_LEVEL);
134 }
135 // * AAC_DRC_ATTENUATION_FACTOR
136 if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
137 unsigned cut = atoi(value);
138 ALOGV("AAC decoder using AAC_DRC_ATTENUATION_FACTOR of %d instead of %d",
139 cut, DRC_DEFAULT_MOBILE_DRC_CUT);
140 aacDecoder_SetParam(mAACDecoder, AAC_DRC_ATTENUATION_FACTOR, cut);
141 } else {
142 aacDecoder_SetParam(mAACDecoder, AAC_DRC_ATTENUATION_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT);
143 }
144 // * AAC_DRC_BOOST_FACTOR (note: no default, using cut)
145 if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
146 unsigned boost = atoi(value);
147 ALOGV("AAC decoder using AAC_DRC_BOOST_FACTOR of %d", boost);
148 aacDecoder_SetParam(mAACDecoder, AAC_DRC_BOOST_FACTOR, boost);
149 }
150
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700151 return status;
152}
153
154OMX_ERRORTYPE SoftAAC2::internalGetParameter(
155 OMX_INDEXTYPE index, OMX_PTR params) {
156 switch (index) {
157 case OMX_IndexParamAudioAac:
158 {
159 OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
160 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
161
162 if (aacParams->nPortIndex != 0) {
163 return OMX_ErrorUndefined;
164 }
165
166 aacParams->nBitRate = 0;
167 aacParams->nAudioBandWidth = 0;
168 aacParams->nAACtools = 0;
169 aacParams->nAACERtools = 0;
170 aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
171
172 aacParams->eAACStreamFormat =
173 mIsADTS
174 ? OMX_AUDIO_AACStreamFormatMP4ADTS
175 : OMX_AUDIO_AACStreamFormatMP4FF;
176
177 aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
178
Dave Burkebf2461e2012-05-18 10:46:11 -0700179 if (!isConfigured()) {
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700180 aacParams->nChannels = 1;
181 aacParams->nSampleRate = 44100;
182 aacParams->nFrameLength = 0;
183 } else {
Dave Burkef60c6602012-04-28 21:58:22 -0700184 aacParams->nChannels = mStreamInfo->numChannels;
185 aacParams->nSampleRate = mStreamInfo->sampleRate;
186 aacParams->nFrameLength = mStreamInfo->frameSize;
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700187 }
188
189 return OMX_ErrorNone;
190 }
191
192 case OMX_IndexParamAudioPcm:
193 {
194 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
195 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
196
197 if (pcmParams->nPortIndex != 1) {
198 return OMX_ErrorUndefined;
199 }
200
201 pcmParams->eNumData = OMX_NumericalDataSigned;
202 pcmParams->eEndian = OMX_EndianBig;
203 pcmParams->bInterleaved = OMX_TRUE;
204 pcmParams->nBitPerSample = 16;
205 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
206 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
207 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
Dave Burke095c2da2012-04-12 17:09:00 -0700208 pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
209 pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
210 pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
211 pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700212
Dave Burkebf2461e2012-05-18 10:46:11 -0700213 if (!isConfigured()) {
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700214 pcmParams->nChannels = 1;
215 pcmParams->nSamplingRate = 44100;
216 } else {
Dave Burkef60c6602012-04-28 21:58:22 -0700217 pcmParams->nChannels = mStreamInfo->numChannels;
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700218 pcmParams->nSamplingRate = mStreamInfo->sampleRate;
219 }
220
221 return OMX_ErrorNone;
222 }
223
224 default:
225 return SimpleSoftOMXComponent::internalGetParameter(index, params);
226 }
227}
228
229OMX_ERRORTYPE SoftAAC2::internalSetParameter(
230 OMX_INDEXTYPE index, const OMX_PTR params) {
231 switch (index) {
232 case OMX_IndexParamStandardComponentRole:
233 {
234 const OMX_PARAM_COMPONENTROLETYPE *roleParams =
235 (const OMX_PARAM_COMPONENTROLETYPE *)params;
236
237 if (strncmp((const char *)roleParams->cRole,
238 "audio_decoder.aac",
239 OMX_MAX_STRINGNAME_SIZE - 1)) {
240 return OMX_ErrorUndefined;
241 }
242
243 return OMX_ErrorNone;
244 }
245
246 case OMX_IndexParamAudioAac:
247 {
248 const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
249 (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
250
251 if (aacParams->nPortIndex != 0) {
252 return OMX_ErrorUndefined;
253 }
254
255 if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
256 mIsADTS = false;
257 } else if (aacParams->eAACStreamFormat
258 == OMX_AUDIO_AACStreamFormatMP4ADTS) {
259 mIsADTS = true;
260 } else {
261 return OMX_ErrorUndefined;
262 }
263
264 return OMX_ErrorNone;
265 }
266
267 case OMX_IndexParamAudioPcm:
268 {
269 const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
270 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
271
272 if (pcmParams->nPortIndex != 1) {
273 return OMX_ErrorUndefined;
274 }
275
276 return OMX_ErrorNone;
277 }
278
279 default:
280 return SimpleSoftOMXComponent::internalSetParameter(index, params);
281 }
282}
283
284bool SoftAAC2::isConfigured() const {
285 return mInputBufferCount > 0;
286}
287
Dave Burke1adacd92012-05-23 00:00:53 -0700288void SoftAAC2::maybeConfigureDownmix() const {
289 if (mStreamInfo->numChannels > 2) {
290 char value[PROPERTY_VALUE_MAX];
291 if (!(property_get("media.aac_51_output_enabled", value, NULL) &&
292 (!strcmp(value, "1") || !strcasecmp(value, "true")))) {
293 ALOGI("Downmixing multichannel AAC to stereo");
294 aacDecoder_SetParam(mAACDecoder, AAC_PCM_OUTPUT_CHANNELS, 2);
295 mStreamInfo->numChannels = 2;
296 }
297 }
298}
299
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700300void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
301 if (mSignalledError || mOutputPortSettingsChange != NONE) {
302 return;
303 }
304
305 UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
306 UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
307 UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700308
309 List<BufferInfo *> &inQueue = getPortQueue(0);
310 List<BufferInfo *> &outQueue = getPortQueue(1);
311
312 if (portIndex == 0 && mInputBufferCount == 0) {
313 ++mInputBufferCount;
314 BufferInfo *info = *inQueue.begin();
315 OMX_BUFFERHEADERTYPE *header = info->mHeader;
316
317 inBuffer[0] = header->pBuffer + header->nOffset;
318 inBufferLength[0] = header->nFilledLen;
319
320 AAC_DECODER_ERROR decoderErr =
321 aacDecoder_ConfigRaw(mAACDecoder,
322 inBuffer,
323 inBufferLength);
324
325 if (decoderErr != AAC_DEC_OK) {
326 mSignalledError = true;
327 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
328 return;
329 }
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700330
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700331 inQueue.erase(inQueue.begin());
332 info->mOwnedByUs = false;
333 notifyEmptyBufferDone(header);
334
James Dongcc9833b2012-05-30 10:26:31 -0700335 // Only send out port settings changed event if both sample rate
336 // and numChannels are valid.
337 if (mStreamInfo->sampleRate && mStreamInfo->numChannels) {
338 maybeConfigureDownmix();
339 ALOGI("Initially configuring decoder: %d Hz, %d channels",
340 mStreamInfo->sampleRate,
341 mStreamInfo->numChannels);
342
343 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
344 mOutputPortSettingsChange = AWAITING_DISABLED;
345 }
346
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700347 return;
348 }
349
350 while (!inQueue.empty() && !outQueue.empty()) {
351 BufferInfo *inInfo = *inQueue.begin();
352 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
353
354 BufferInfo *outInfo = *outQueue.begin();
355 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
356
357 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
358 inQueue.erase(inQueue.begin());
359 inInfo->mOwnedByUs = false;
360 notifyEmptyBufferDone(inHeader);
361
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700362 if (mDecoderHasData) {
Andreas Huber51d75472012-08-07 14:24:00 -0700363 // flush out the decoder's delayed data by calling DecodeFrame
364 // one more time, with the AACDEC_FLUSH flag set
365 INT_PCM *outBuffer =
366 reinterpret_cast<INT_PCM *>(
367 outHeader->pBuffer + outHeader->nOffset);
368
369 AAC_DECODER_ERROR decoderErr =
370 aacDecoder_DecodeFrame(mAACDecoder,
371 outBuffer,
372 outHeader->nAllocLen,
373 AACDEC_FLUSH);
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700374 mDecoderHasData = false;
Andreas Huber51d75472012-08-07 14:24:00 -0700375
376 if (decoderErr != AAC_DEC_OK) {
377 mSignalledError = true;
378
379 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr,
380 NULL);
381
382 return;
383 }
384
385 outHeader->nFilledLen =
386 mStreamInfo->frameSize
387 * sizeof(int16_t)
388 * mStreamInfo->numChannels;
389 } else {
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700390 // we never submitted any data to the decoder, so there's nothing to flush out
Andreas Huber51d75472012-08-07 14:24:00 -0700391 outHeader->nFilledLen = 0;
Dave Burkef60c6602012-04-28 21:58:22 -0700392 }
393
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700394 outHeader->nFlags = OMX_BUFFERFLAG_EOS;
395
396 outQueue.erase(outQueue.begin());
397 outInfo->mOwnedByUs = false;
398 notifyFillBufferDone(outHeader);
399 return;
400 }
401
402 if (inHeader->nOffset == 0) {
403 mAnchorTimeUs = inHeader->nTimeStamp;
404 mNumSamplesOutput = 0;
405 }
406
Andreas Huber6b7b8222012-04-20 15:47:48 -0700407 size_t adtsHeaderSize = 0;
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700408 if (mIsADTS) {
409 // skip 30 bits, aac_frame_length follows.
410 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
411
412 const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
413
Andreas Huber8370c7a2012-05-18 13:08:14 -0700414 bool signalError = false;
415 if (inHeader->nFilledLen < 7) {
416 ALOGE("Audio data too short to contain even the ADTS header. "
417 "Got %ld bytes.", inHeader->nFilledLen);
418 hexdump(adtsHeader, inHeader->nFilledLen);
419 signalError = true;
420 } else {
421 bool protectionAbsent = (adtsHeader[1] & 1);
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700422
Andreas Huber8370c7a2012-05-18 13:08:14 -0700423 unsigned aac_frame_length =
424 ((adtsHeader[3] & 3) << 11)
425 | (adtsHeader[4] << 3)
426 | (adtsHeader[5] >> 5);
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700427
Andreas Huber8370c7a2012-05-18 13:08:14 -0700428 if (inHeader->nFilledLen < aac_frame_length) {
429 ALOGE("Not enough audio data for the complete frame. "
430 "Got %ld bytes, frame size according to the ADTS "
431 "header is %u bytes.",
432 inHeader->nFilledLen, aac_frame_length);
433 hexdump(adtsHeader, inHeader->nFilledLen);
434 signalError = true;
435 } else {
436 adtsHeaderSize = (protectionAbsent ? 7 : 9);
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700437
Andreas Huber8370c7a2012-05-18 13:08:14 -0700438 inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
439 inBufferLength[0] = aac_frame_length - adtsHeaderSize;
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700440
Andreas Huber8370c7a2012-05-18 13:08:14 -0700441 inHeader->nOffset += adtsHeaderSize;
442 inHeader->nFilledLen -= adtsHeaderSize;
443 }
Andreas Hubere35ac282012-05-21 10:02:14 -0700444 }
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700445
Andreas Hubere35ac282012-05-21 10:02:14 -0700446 if (signalError) {
447 mSignalledError = true;
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700448
Andreas Hubere35ac282012-05-21 10:02:14 -0700449 notify(OMX_EventError,
450 OMX_ErrorStreamCorrupt,
451 ERROR_MALFORMED,
452 NULL);
Andreas Huber8370c7a2012-05-18 13:08:14 -0700453
Andreas Hubere35ac282012-05-21 10:02:14 -0700454 return;
Andreas Huber8370c7a2012-05-18 13:08:14 -0700455 }
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700456 } else {
457 inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
458 inBufferLength[0] = inHeader->nFilledLen;
459 }
460
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700461 // Fill and decode
Andreas Huber51d75472012-08-07 14:24:00 -0700462 INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(
463 outHeader->pBuffer + outHeader->nOffset);
464
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700465 bytesValid[0] = inBufferLength[0];
466
467 int prevSampleRate = mStreamInfo->sampleRate;
Dave Burkef60c6602012-04-28 21:58:22 -0700468 int prevNumChannels = mStreamInfo->numChannels;
Andreas Huber6b7b8222012-04-20 15:47:48 -0700469
Dave Burkef60c6602012-04-28 21:58:22 -0700470 AAC_DECODER_ERROR decoderErr = AAC_DEC_NOT_ENOUGH_BITS;
471 while (bytesValid[0] > 0 && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
472 aacDecoder_Fill(mAACDecoder,
473 inBuffer,
474 inBufferLength,
475 bytesValid);
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700476 mDecoderHasData = true;
Andreas Huber6b7b8222012-04-20 15:47:48 -0700477
Dave Burkef60c6602012-04-28 21:58:22 -0700478 decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
479 outBuffer,
480 outHeader->nAllocLen,
Dave Burke3748b712012-05-17 23:08:08 -0700481 0 /* flags */);
Dave Burkef60c6602012-04-28 21:58:22 -0700482
Dave Burke503775e2012-05-29 16:41:49 -0700483 if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
484 ALOGW("Not enough bits, bytesValid %d", bytesValid[0]);
485 }
Dave Burkef60c6602012-04-28 21:58:22 -0700486 }
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700487
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700488 size_t numOutBytes =
489 mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
490
491 if (decoderErr == AAC_DEC_OK) {
492 UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
493 inHeader->nFilledLen -= inBufferUsedLength;
494 inHeader->nOffset += inBufferUsedLength;
495 } else {
496 ALOGW("AAC decoder returned error %d, substituting silence",
497 decoderErr);
498
499 memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
500
501 // Discard input buffer.
502 inHeader->nFilledLen = 0;
503
Andreas Hubere672a0e2012-05-17 16:06:01 -0700504 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
505
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700506 // fall through
507 }
508
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700509 if (inHeader->nFilledLen == 0) {
510 inInfo->mOwnedByUs = false;
511 inQueue.erase(inQueue.begin());
512 inInfo = NULL;
513 notifyEmptyBufferDone(inHeader);
514 inHeader = NULL;
515 }
516
517 /*
518 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
519 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
520 * rate system and the sampling rate in the final output is actually
521 * doubled compared with the core AAC decoder sampling rate.
522 *
523 * Explicit signalling is done by explicitly defining SBR audio object
524 * type in the bitstream. Implicit signalling is done by embedding
525 * SBR content in AAC extension payload specific to SBR, and hence
526 * requires an AAC decoder to perform pre-checks on actual audio frames.
527 *
528 * Thus, we could not say for sure whether a stream is
529 * AAC+/eAAC+ until the first data frame is decoded.
530 */
531 if (mInputBufferCount <= 2) {
532 if (mStreamInfo->sampleRate != prevSampleRate ||
533 mStreamInfo->numChannels != prevNumChannels) {
534 maybeConfigureDownmix();
535 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
536 prevSampleRate, mStreamInfo->sampleRate,
537 prevNumChannels, mStreamInfo->numChannels);
538
539 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
540 mOutputPortSettingsChange = AWAITING_DISABLED;
541 return;
542 }
543 } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
544 ALOGW("Invalid AAC stream");
545 mSignalledError = true;
546 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
547 return;
548 }
549
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700550 if (decoderErr == AAC_DEC_OK || mNumSamplesOutput > 0) {
551 // We'll only output data if we successfully decoded it or
552 // we've previously decoded valid data, in the latter case
553 // (decode failed) we'll output a silent frame.
554 outHeader->nFilledLen = numOutBytes;
555 outHeader->nFlags = 0;
556
557 outHeader->nTimeStamp =
558 mAnchorTimeUs
559 + (mNumSamplesOutput * 1000000ll) / mStreamInfo->sampleRate;
560
561 mNumSamplesOutput += mStreamInfo->frameSize;
562
563 outInfo->mOwnedByUs = false;
564 outQueue.erase(outQueue.begin());
565 outInfo = NULL;
566 notifyFillBufferDone(outHeader);
567 outHeader = NULL;
568 }
569
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700570 if (decoderErr == AAC_DEC_OK) {
571 ++mInputBufferCount;
572 }
573 }
574}
575
576void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
577 if (portIndex == 0) {
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700578 // Make sure that the next buffer output does not still
579 // depend on fragments from the last one decoded.
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700580 // drain all existing data
581 drainDecoder();
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700582 }
583}
584
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700585void SoftAAC2::drainDecoder() {
586 short buf [2048];
587 aacDecoder_DecodeFrame(mAACDecoder, buf, 4096, AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
588 aacDecoder_DecodeFrame(mAACDecoder, buf, 4096, AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
Marco Nelissen6fc72b02012-12-17 16:35:08 -0800589 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
Marco Nelissenf3bd1972013-04-09 14:57:38 -0700590 mDecoderHasData = false;
591}
592
593void SoftAAC2::onReset() {
594 drainDecoder();
Marco Nelissen7c5abbb2013-04-15 12:06:18 -0700595 // reset the "configured" state
596 mInputBufferCount = 0;
597 mNumSamplesOutput = 0;
598 // To make the codec behave the same before and after a reset, we need to invalidate the
599 // streaminfo struct. This does that:
600 mStreamInfo->sampleRate = 0;
Marco Nelissen6fc72b02012-12-17 16:35:08 -0800601}
602
Dave Burkeb7ddcc92012-04-02 13:54:42 -0700603void SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
604 if (portIndex != 1) {
605 return;
606 }
607
608 switch (mOutputPortSettingsChange) {
609 case NONE:
610 break;
611
612 case AWAITING_DISABLED:
613 {
614 CHECK(!enabled);
615 mOutputPortSettingsChange = AWAITING_ENABLED;
616 break;
617 }
618
619 default:
620 {
621 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
622 CHECK(enabled);
623 mOutputPortSettingsChange = NONE;
624 break;
625 }
626 }
627}
628
629} // namespace android
630
631android::SoftOMXComponent *createSoftOMXComponent(
632 const char *name, const OMX_CALLBACKTYPE *callbacks,
633 OMX_PTR appData, OMX_COMPONENTTYPE **component) {
634 return new android::SoftAAC2(name, callbacks, appData, component);
635}