SoftAAC2.cpp revision dfb280d3975afdce4da87602577d2814cb9eb30d
1/*
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_NDEBUG 0
18#define LOG_TAG "SoftAAC2"
19#include <utils/Log.h>
20
21#include "SoftAAC2.h"
22#include <OMX_AudioExt.h>
23#include <OMX_IndexExt.h>
24
25#include <cutils/properties.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/foundation/hexdump.h>
28#include <media/stagefright/MediaErrors.h>
29
30#include <math.h>
31
32#define FILEREAD_MAX_LAYERS 2
33
34#define DRC_DEFAULT_MOBILE_REF_LEVEL 64  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
35#define DRC_DEFAULT_MOBILE_DRC_CUT   127 /* maximum compression of dynamic range for mobile conf */
36#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
37#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1   /* switch for heavy compression for mobile conf */
38#define DRC_DEFAULT_MOBILE_ENC_LEVEL -1 /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
39#define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
40// names of properties that can be used to override the default DRC settings
41#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
42#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
43#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
44#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
45#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
46
47namespace android {
48
49template<class T>
50static void InitOMXParams(T *params) {
51    params->nSize = sizeof(T);
52    params->nVersion.s.nVersionMajor = 1;
53    params->nVersion.s.nVersionMinor = 0;
54    params->nVersion.s.nRevision = 0;
55    params->nVersion.s.nStep = 0;
56}
57
58SoftAAC2::SoftAAC2(
59        const char *name,
60        const OMX_CALLBACKTYPE *callbacks,
61        OMX_PTR appData,
62        OMX_COMPONENTTYPE **component)
63    : SimpleSoftOMXComponent(name, callbacks, appData, component),
64      mAACDecoder(NULL),
65      mStreamInfo(NULL),
66      mIsADTS(false),
67      mInputBufferCount(0),
68      mOutputBufferCount(0),
69      mSignalledError(false),
70      mLastInHeader(NULL),
71      mOutputPortSettingsChange(NONE) {
72    initPorts();
73    CHECK_EQ(initDecoder(), (status_t)OK);
74}
75
76SoftAAC2::~SoftAAC2() {
77    aacDecoder_Close(mAACDecoder);
78    delete mOutputDelayRingBuffer;
79}
80
81void SoftAAC2::initPorts() {
82    OMX_PARAM_PORTDEFINITIONTYPE def;
83    InitOMXParams(&def);
84
85    def.nPortIndex = 0;
86    def.eDir = OMX_DirInput;
87    def.nBufferCountMin = kNumInputBuffers;
88    def.nBufferCountActual = def.nBufferCountMin;
89    def.nBufferSize = 8192;
90    def.bEnabled = OMX_TRUE;
91    def.bPopulated = OMX_FALSE;
92    def.eDomain = OMX_PortDomainAudio;
93    def.bBuffersContiguous = OMX_FALSE;
94    def.nBufferAlignment = 1;
95
96    def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
97    def.format.audio.pNativeRender = NULL;
98    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
99    def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
100
101    addPort(def);
102
103    def.nPortIndex = 1;
104    def.eDir = OMX_DirOutput;
105    def.nBufferCountMin = kNumOutputBuffers;
106    def.nBufferCountActual = def.nBufferCountMin;
107    def.nBufferSize = 4096 * MAX_CHANNEL_COUNT;
108    def.bEnabled = OMX_TRUE;
109    def.bPopulated = OMX_FALSE;
110    def.eDomain = OMX_PortDomainAudio;
111    def.bBuffersContiguous = OMX_FALSE;
112    def.nBufferAlignment = 2;
113
114    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
115    def.format.audio.pNativeRender = NULL;
116    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
117    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
118
119    addPort(def);
120}
121
122status_t SoftAAC2::initDecoder() {
123    ALOGV("initDecoder()");
124    status_t status = UNKNOWN_ERROR;
125    mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
126    if (mAACDecoder != NULL) {
127        mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
128        if (mStreamInfo != NULL) {
129            status = OK;
130        }
131    }
132
133    mEndOfInput = false;
134    mEndOfOutput = false;
135    mOutputDelayCompensated = 0;
136    mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
137    mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
138    mOutputDelayRingBufferWritePos = 0;
139    mOutputDelayRingBufferReadPos = 0;
140    mOutputDelayRingBufferFilled = 0;
141
142    if (mAACDecoder == NULL) {
143        ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
144    }
145
146    //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
147
148    //init DRC wrapper
149    mDrcWrap.setDecoderHandle(mAACDecoder);
150    mDrcWrap.submitStreamData(mStreamInfo);
151
152    // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
153    // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
154    char value[PROPERTY_VALUE_MAX];
155    //  DRC_PRES_MODE_WRAP_DESIRED_TARGET
156    if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
157        unsigned refLevel = atoi(value);
158        ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d", refLevel,
159                DRC_DEFAULT_MOBILE_REF_LEVEL);
160        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, refLevel);
161    } else {
162        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, DRC_DEFAULT_MOBILE_REF_LEVEL);
163    }
164    //  DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
165    if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
166        unsigned cut = atoi(value);
167        ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", cut,
168                DRC_DEFAULT_MOBILE_DRC_CUT);
169        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, cut);
170    } else {
171        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT);
172    }
173    //  DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
174    if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
175        unsigned boost = atoi(value);
176        ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", boost,
177                DRC_DEFAULT_MOBILE_DRC_BOOST);
178        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, boost);
179    } else {
180        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST);
181    }
182    //  DRC_PRES_MODE_WRAP_DESIRED_HEAVY
183    if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) {
184        unsigned heavy = atoi(value);
185        ALOGV("AAC decoder using desried DRC heavy compression switch of %d instead of %d", heavy,
186                DRC_DEFAULT_MOBILE_DRC_HEAVY);
187        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, heavy);
188    } else {
189        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
190    }
191    // DRC_PRES_MODE_WRAP_ENCODER_TARGET
192    if (property_get(PROP_DRC_OVERRIDE_ENC_LEVEL, value, NULL)) {
193        unsigned encoderRefLevel = atoi(value);
194        ALOGV("AAC decoder using encoder-side DRC reference level of %d instead of %d",
195                encoderRefLevel, DRC_DEFAULT_MOBILE_ENC_LEVEL);
196        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, encoderRefLevel);
197    } else {
198        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, DRC_DEFAULT_MOBILE_ENC_LEVEL);
199    }
200
201    return status;
202}
203
204OMX_ERRORTYPE SoftAAC2::internalGetParameter(
205        OMX_INDEXTYPE index, OMX_PTR params) {
206    switch (index) {
207        case OMX_IndexParamAudioAac:
208        {
209            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
210                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
211
212            if (!isValidOMXParam(aacParams)) {
213                return OMX_ErrorBadParameter;
214            }
215
216            if (aacParams->nPortIndex != 0) {
217                return OMX_ErrorUndefined;
218            }
219
220            aacParams->nBitRate = 0;
221            aacParams->nAudioBandWidth = 0;
222            aacParams->nAACtools = 0;
223            aacParams->nAACERtools = 0;
224            aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
225
226            aacParams->eAACStreamFormat =
227                mIsADTS
228                    ? OMX_AUDIO_AACStreamFormatMP4ADTS
229                    : OMX_AUDIO_AACStreamFormatMP4FF;
230
231            aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
232
233            if (!isConfigured()) {
234                aacParams->nChannels = 1;
235                aacParams->nSampleRate = 44100;
236                aacParams->nFrameLength = 0;
237            } else {
238                aacParams->nChannels = mStreamInfo->numChannels;
239                aacParams->nSampleRate = mStreamInfo->sampleRate;
240                aacParams->nFrameLength = mStreamInfo->frameSize;
241            }
242
243            return OMX_ErrorNone;
244        }
245
246        case OMX_IndexParamAudioPcm:
247        {
248            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
249                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
250
251            if (!isValidOMXParam(pcmParams)) {
252                return OMX_ErrorBadParameter;
253            }
254
255            if (pcmParams->nPortIndex != 1) {
256                return OMX_ErrorUndefined;
257            }
258
259            pcmParams->eNumData = OMX_NumericalDataSigned;
260            pcmParams->eEndian = OMX_EndianBig;
261            pcmParams->bInterleaved = OMX_TRUE;
262            pcmParams->nBitPerSample = 16;
263            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
264            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
265            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
266            pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
267            pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
268            pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
269            pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
270
271            if (!isConfigured()) {
272                pcmParams->nChannels = 1;
273                pcmParams->nSamplingRate = 44100;
274            } else {
275                pcmParams->nChannels = mStreamInfo->numChannels;
276                pcmParams->nSamplingRate = mStreamInfo->sampleRate;
277            }
278
279            return OMX_ErrorNone;
280        }
281
282        default:
283            return SimpleSoftOMXComponent::internalGetParameter(index, params);
284    }
285}
286
287OMX_ERRORTYPE SoftAAC2::internalSetParameter(
288        OMX_INDEXTYPE index, const OMX_PTR params) {
289    switch ((int)index) {
290        case OMX_IndexParamStandardComponentRole:
291        {
292            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
293                (const OMX_PARAM_COMPONENTROLETYPE *)params;
294
295            if (!isValidOMXParam(roleParams)) {
296                return OMX_ErrorBadParameter;
297            }
298
299            if (strncmp((const char *)roleParams->cRole,
300                        "audio_decoder.aac",
301                        OMX_MAX_STRINGNAME_SIZE - 1)) {
302                return OMX_ErrorUndefined;
303            }
304
305            return OMX_ErrorNone;
306        }
307
308        case OMX_IndexParamAudioAac:
309        {
310            const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
311                (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
312
313            if (!isValidOMXParam(aacParams)) {
314                return OMX_ErrorBadParameter;
315            }
316
317            if (aacParams->nPortIndex != 0) {
318                return OMX_ErrorUndefined;
319            }
320
321            if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
322                mIsADTS = false;
323            } else if (aacParams->eAACStreamFormat
324                        == OMX_AUDIO_AACStreamFormatMP4ADTS) {
325                mIsADTS = true;
326            } else {
327                return OMX_ErrorUndefined;
328            }
329
330            return OMX_ErrorNone;
331        }
332
333        case OMX_IndexParamAudioAndroidAacPresentation:
334        {
335            const OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE *aacPresParams =
336                    (const OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE *)params;
337
338            if (!isValidOMXParam(aacPresParams)) {
339                return OMX_ErrorBadParameter;
340            }
341
342            // for the following parameters of the OMX_AUDIO_PARAM_AACPROFILETYPE structure,
343            // a value of -1 implies the parameter is not set by the application:
344            //   nMaxOutputChannels     uses default platform properties, see configureDownmix()
345            //   nDrcCut                uses default platform properties, see initDecoder()
346            //   nDrcBoost                idem
347            //   nHeavyCompression        idem
348            //   nTargetReferenceLevel    idem
349            //   nEncodedTargetLevel      idem
350            if (aacPresParams->nMaxOutputChannels >= 0) {
351                int max;
352                if (aacPresParams->nMaxOutputChannels >= 8) { max = 8; }
353                else if (aacPresParams->nMaxOutputChannels >= 6) { max = 6; }
354                else if (aacPresParams->nMaxOutputChannels >= 2) { max = 2; }
355                else {
356                    // -1 or 0: disable downmix,  1: mono
357                    max = aacPresParams->nMaxOutputChannels;
358                }
359                ALOGV("set nMaxOutputChannels=%d", max);
360                aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, max);
361            }
362            bool updateDrcWrapper = false;
363            if (aacPresParams->nDrcBoost >= 0) {
364                ALOGV("set nDrcBoost=%d", aacPresParams->nDrcBoost);
365                mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR,
366                        aacPresParams->nDrcBoost);
367                updateDrcWrapper = true;
368            }
369            if (aacPresParams->nDrcCut >= 0) {
370                ALOGV("set nDrcCut=%d", aacPresParams->nDrcCut);
371                mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, aacPresParams->nDrcCut);
372                updateDrcWrapper = true;
373            }
374            if (aacPresParams->nHeavyCompression >= 0) {
375                ALOGV("set nHeavyCompression=%d", aacPresParams->nHeavyCompression);
376                mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY,
377                        aacPresParams->nHeavyCompression);
378                updateDrcWrapper = true;
379            }
380            if (aacPresParams->nTargetReferenceLevel >= 0) {
381                ALOGV("set nTargetReferenceLevel=%d", aacPresParams->nTargetReferenceLevel);
382                mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET,
383                        aacPresParams->nTargetReferenceLevel);
384                updateDrcWrapper = true;
385            }
386            if (aacPresParams->nEncodedTargetLevel >= 0) {
387                ALOGV("set nEncodedTargetLevel=%d", aacPresParams->nEncodedTargetLevel);
388                mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET,
389                        aacPresParams->nEncodedTargetLevel);
390                updateDrcWrapper = true;
391            }
392            if (aacPresParams->nPCMLimiterEnable >= 0) {
393                aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE,
394                        (aacPresParams->nPCMLimiterEnable != 0));
395            }
396            if (updateDrcWrapper) {
397                mDrcWrap.update();
398            }
399
400            return OMX_ErrorNone;
401        }
402
403        case OMX_IndexParamAudioPcm:
404        {
405            const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
406                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
407
408            if (!isValidOMXParam(pcmParams)) {
409                return OMX_ErrorBadParameter;
410            }
411
412            if (pcmParams->nPortIndex != 1) {
413                return OMX_ErrorUndefined;
414            }
415
416            return OMX_ErrorNone;
417        }
418
419        default:
420            return SimpleSoftOMXComponent::internalSetParameter(index, params);
421    }
422}
423
424bool SoftAAC2::isConfigured() const {
425    return mInputBufferCount > 0;
426}
427
428void SoftAAC2::configureDownmix() const {
429    char value[PROPERTY_VALUE_MAX];
430    if (!(property_get("media.aac_51_output_enabled", value, NULL)
431            && (!strcmp(value, "1") || !strcasecmp(value, "true")))) {
432        ALOGI("limiting to stereo output");
433        aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, 2);
434        // By default, the decoder creates a 5.1 channel downmix signal
435        // for seven and eight channel input streams. To enable 6.1 and 7.1 channel output
436        // use aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1)
437    }
438}
439
440bool SoftAAC2::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
441    if (numSamples == 0) {
442        return true;
443    }
444    if (outputDelayRingBufferSpaceLeft() < numSamples) {
445        ALOGE("RING BUFFER WOULD OVERFLOW");
446        return false;
447    }
448    if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
449            && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
450                    || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
451        // faster memcopy loop without checks, if the preconditions allow this
452        for (int32_t i = 0; i < numSamples; i++) {
453            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
454        }
455
456        if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
457            mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
458        }
459    } else {
460        ALOGV("slow SoftAAC2::outputDelayRingBufferPutSamples()");
461
462        for (int32_t i = 0; i < numSamples; i++) {
463            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
464            mOutputDelayRingBufferWritePos++;
465            if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
466                mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
467            }
468        }
469    }
470    mOutputDelayRingBufferFilled += numSamples;
471    return true;
472}
473
474int32_t SoftAAC2::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
475
476    if (numSamples > mOutputDelayRingBufferFilled) {
477        ALOGE("RING BUFFER WOULD UNDERRUN");
478        return -1;
479    }
480
481    if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
482            && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
483                    || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
484        // faster memcopy loop without checks, if the preconditions allow this
485        if (samples != 0) {
486            for (int32_t i = 0; i < numSamples; i++) {
487                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
488            }
489        } else {
490            mOutputDelayRingBufferReadPos += numSamples;
491        }
492        if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
493            mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
494        }
495    } else {
496        ALOGV("slow SoftAAC2::outputDelayRingBufferGetSamples()");
497
498        for (int32_t i = 0; i < numSamples; i++) {
499            if (samples != 0) {
500                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
501            }
502            mOutputDelayRingBufferReadPos++;
503            if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
504                mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
505            }
506        }
507    }
508    mOutputDelayRingBufferFilled -= numSamples;
509    return numSamples;
510}
511
512int32_t SoftAAC2::outputDelayRingBufferSamplesAvailable() {
513    return mOutputDelayRingBufferFilled;
514}
515
516int32_t SoftAAC2::outputDelayRingBufferSpaceLeft() {
517    return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
518}
519
520
521void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
522    if (mSignalledError || mOutputPortSettingsChange != NONE) {
523        return;
524    }
525
526    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
527    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
528    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
529
530    List<BufferInfo *> &inQueue = getPortQueue(0);
531    List<BufferInfo *> &outQueue = getPortQueue(1);
532
533    while ((!inQueue.empty() || mEndOfInput) && !outQueue.empty()) {
534        if (!inQueue.empty()) {
535            INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
536            BufferInfo *inInfo = *inQueue.begin();
537            OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
538
539            mEndOfInput = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0;
540
541            if (mInputBufferCount == 0 && !(inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
542                ALOGE("first buffer should have OMX_BUFFERFLAG_CODECCONFIG set");
543                inHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
544            }
545            if ((inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != 0) {
546                BufferInfo *inInfo = *inQueue.begin();
547                OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
548
549                inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
550                inBufferLength[0] = inHeader->nFilledLen;
551
552                AAC_DECODER_ERROR decoderErr =
553                    aacDecoder_ConfigRaw(mAACDecoder,
554                                         inBuffer,
555                                         inBufferLength);
556
557                if (decoderErr != AAC_DEC_OK) {
558                    ALOGW("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
559                    mSignalledError = true;
560                    notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
561                    return;
562                }
563
564                mInputBufferCount++;
565                mOutputBufferCount++; // fake increase of outputBufferCount to keep the counters aligned
566
567                inInfo->mOwnedByUs = false;
568                inQueue.erase(inQueue.begin());
569                mLastInHeader = NULL;
570                inInfo = NULL;
571                notifyEmptyBufferDone(inHeader);
572                inHeader = NULL;
573
574                configureDownmix();
575                // Only send out port settings changed event if both sample rate
576                // and numChannels are valid.
577                if (mStreamInfo->sampleRate && mStreamInfo->numChannels) {
578                    ALOGI("Initially configuring decoder: %d Hz, %d channels",
579                        mStreamInfo->sampleRate,
580                        mStreamInfo->numChannels);
581
582                    notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
583                    mOutputPortSettingsChange = AWAITING_DISABLED;
584                }
585                return;
586            }
587
588            if (inHeader->nFilledLen == 0) {
589                inInfo->mOwnedByUs = false;
590                inQueue.erase(inQueue.begin());
591                mLastInHeader = NULL;
592                inInfo = NULL;
593                notifyEmptyBufferDone(inHeader);
594                inHeader = NULL;
595                continue;
596            }
597
598            if (mIsADTS) {
599                size_t adtsHeaderSize = 0;
600                // skip 30 bits, aac_frame_length follows.
601                // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
602
603                const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
604
605                bool signalError = false;
606                if (inHeader->nFilledLen < 7) {
607                    ALOGE("Audio data too short to contain even the ADTS header. "
608                            "Got %d bytes.", inHeader->nFilledLen);
609                    hexdump(adtsHeader, inHeader->nFilledLen);
610                    signalError = true;
611                } else {
612                    bool protectionAbsent = (adtsHeader[1] & 1);
613
614                    unsigned aac_frame_length =
615                        ((adtsHeader[3] & 3) << 11)
616                        | (adtsHeader[4] << 3)
617                        | (adtsHeader[5] >> 5);
618
619                    if (inHeader->nFilledLen < aac_frame_length) {
620                        ALOGE("Not enough audio data for the complete frame. "
621                                "Got %d bytes, frame size according to the ADTS "
622                                "header is %u bytes.",
623                                inHeader->nFilledLen, aac_frame_length);
624                        hexdump(adtsHeader, inHeader->nFilledLen);
625                        signalError = true;
626                    } else {
627                        adtsHeaderSize = (protectionAbsent ? 7 : 9);
628
629                        inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
630                        inBufferLength[0] = aac_frame_length - adtsHeaderSize;
631
632                        inHeader->nOffset += adtsHeaderSize;
633                        inHeader->nFilledLen -= adtsHeaderSize;
634                    }
635                }
636
637                if (signalError) {
638                    mSignalledError = true;
639                    notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL);
640                    return;
641                }
642
643                // insert buffer size and time stamp
644                mBufferSizes.add(inBufferLength[0]);
645                if (mLastInHeader != inHeader) {
646                    mBufferTimestamps.add(inHeader->nTimeStamp);
647                    mLastInHeader = inHeader;
648                } else {
649                    int64_t currentTime = mBufferTimestamps.top();
650                    currentTime += mStreamInfo->aacSamplesPerFrame *
651                            1000000ll / mStreamInfo->sampleRate;
652                    mBufferTimestamps.add(currentTime);
653                }
654            } else {
655                inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
656                inBufferLength[0] = inHeader->nFilledLen;
657                mLastInHeader = inHeader;
658                mBufferTimestamps.add(inHeader->nTimeStamp);
659                mBufferSizes.add(inHeader->nFilledLen);
660            }
661
662            // Fill and decode
663            bytesValid[0] = inBufferLength[0];
664
665            INT prevSampleRate = mStreamInfo->sampleRate;
666            INT prevNumChannels = mStreamInfo->numChannels;
667
668            aacDecoder_Fill(mAACDecoder,
669                            inBuffer,
670                            inBufferLength,
671                            bytesValid);
672
673            // run DRC check
674            mDrcWrap.submitStreamData(mStreamInfo);
675            mDrcWrap.update();
676
677            UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
678            inHeader->nFilledLen -= inBufferUsedLength;
679            inHeader->nOffset += inBufferUsedLength;
680
681            AAC_DECODER_ERROR decoderErr;
682            int numLoops = 0;
683            do {
684                if (outputDelayRingBufferSpaceLeft() <
685                        (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
686                    ALOGV("skipping decode: not enough space left in ringbuffer");
687                    break;
688                }
689
690                int numConsumed = mStreamInfo->numTotalBytes;
691                decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
692                                           tmpOutBuffer,
693                                           2048 * MAX_CHANNEL_COUNT,
694                                           0 /* flags */);
695
696                numConsumed = mStreamInfo->numTotalBytes - numConsumed;
697                numLoops++;
698
699                if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
700                    break;
701                }
702                mDecodedSizes.add(numConsumed);
703
704                if (decoderErr != AAC_DEC_OK) {
705                    ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
706                }
707
708                if (bytesValid[0] != 0) {
709                    ALOGE("bytesValid[0] != 0 should never happen");
710                    mSignalledError = true;
711                    notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
712                    return;
713                }
714
715                size_t numOutBytes =
716                    mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
717
718                if (decoderErr == AAC_DEC_OK) {
719                    if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
720                            mStreamInfo->frameSize * mStreamInfo->numChannels)) {
721                        mSignalledError = true;
722                        notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
723                        return;
724                    }
725                } else {
726                    ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
727
728                    memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
729
730                    if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
731                            mStreamInfo->frameSize * mStreamInfo->numChannels)) {
732                        mSignalledError = true;
733                        notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
734                        return;
735                    }
736
737                    // Discard input buffer.
738                    if (inHeader) {
739                        inHeader->nFilledLen = 0;
740                    }
741
742                    aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
743
744                    // After an error, replace the last entry in mBufferSizes with the sum of the
745                    // last <numLoops> entries from mDecodedSizes to resynchronize the in/out lists.
746                    mBufferSizes.pop();
747                    int n = 0;
748                    for (int i = 0; i < numLoops; i++) {
749                        n += mDecodedSizes.itemAt(mDecodedSizes.size() - numLoops + i);
750                    }
751                    mBufferSizes.add(n);
752
753                    // fall through
754                }
755
756                /*
757                 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
758                 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
759                 * rate system and the sampling rate in the final output is actually
760                 * doubled compared with the core AAC decoder sampling rate.
761                 *
762                 * Explicit signalling is done by explicitly defining SBR audio object
763                 * type in the bitstream. Implicit signalling is done by embedding
764                 * SBR content in AAC extension payload specific to SBR, and hence
765                 * requires an AAC decoder to perform pre-checks on actual audio frames.
766                 *
767                 * Thus, we could not say for sure whether a stream is
768                 * AAC+/eAAC+ until the first data frame is decoded.
769                 */
770                if (mInputBufferCount <= 2 || mOutputBufferCount > 1) { // TODO: <= 1
771                    if (mStreamInfo->sampleRate != prevSampleRate ||
772                        mStreamInfo->numChannels != prevNumChannels) {
773                        ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
774                              prevSampleRate, mStreamInfo->sampleRate,
775                              prevNumChannels, mStreamInfo->numChannels);
776
777                        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
778                        mOutputPortSettingsChange = AWAITING_DISABLED;
779
780                        if (inHeader && inHeader->nFilledLen == 0) {
781                            inInfo->mOwnedByUs = false;
782                            mInputBufferCount++;
783                            inQueue.erase(inQueue.begin());
784                            mLastInHeader = NULL;
785                            inInfo = NULL;
786                            notifyEmptyBufferDone(inHeader);
787                            inHeader = NULL;
788                        }
789                        return;
790                    }
791                } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
792                    ALOGW("Invalid AAC stream");
793                    mSignalledError = true;
794                    notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
795                    return;
796                }
797                if (inHeader && inHeader->nFilledLen == 0) {
798                    inInfo->mOwnedByUs = false;
799                    mInputBufferCount++;
800                    inQueue.erase(inQueue.begin());
801                    mLastInHeader = NULL;
802                    inInfo = NULL;
803                    notifyEmptyBufferDone(inHeader);
804                    inHeader = NULL;
805                } else {
806                    ALOGV("inHeader->nFilledLen = %d", inHeader ? inHeader->nFilledLen : 0);
807                }
808            } while (decoderErr == AAC_DEC_OK);
809        }
810
811        int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
812
813        if (!mEndOfInput && mOutputDelayCompensated < outputDelay) {
814            // discard outputDelay at the beginning
815            int32_t toCompensate = outputDelay - mOutputDelayCompensated;
816            int32_t discard = outputDelayRingBufferSamplesAvailable();
817            if (discard > toCompensate) {
818                discard = toCompensate;
819            }
820            int32_t discarded = outputDelayRingBufferGetSamples(0, discard);
821            mOutputDelayCompensated += discarded;
822            continue;
823        }
824
825        if (mEndOfInput) {
826            while (mOutputDelayCompensated > 0) {
827                // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
828                INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
829
830                 // run DRC check
831                 mDrcWrap.submitStreamData(mStreamInfo);
832                 mDrcWrap.update();
833
834                AAC_DECODER_ERROR decoderErr =
835                    aacDecoder_DecodeFrame(mAACDecoder,
836                                           tmpOutBuffer,
837                                           2048 * MAX_CHANNEL_COUNT,
838                                           AACDEC_FLUSH);
839                if (decoderErr != AAC_DEC_OK) {
840                    ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
841                }
842
843                int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
844                if (tmpOutBufferSamples > mOutputDelayCompensated) {
845                    tmpOutBufferSamples = mOutputDelayCompensated;
846                }
847                outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
848                mOutputDelayCompensated -= tmpOutBufferSamples;
849            }
850        }
851
852        while (!outQueue.empty()
853                && outputDelayRingBufferSamplesAvailable()
854                        >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
855            BufferInfo *outInfo = *outQueue.begin();
856            OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
857
858            if (outHeader->nOffset != 0) {
859                ALOGE("outHeader->nOffset != 0 is not handled");
860                mSignalledError = true;
861                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
862                return;
863            }
864
865            INT_PCM *outBuffer =
866                    reinterpret_cast<INT_PCM *>(outHeader->pBuffer + outHeader->nOffset);
867            int samplesize = mStreamInfo->numChannels * sizeof(int16_t);
868            if (outHeader->nOffset
869                    + mStreamInfo->frameSize * samplesize
870                    > outHeader->nAllocLen) {
871                ALOGE("buffer overflow");
872                mSignalledError = true;
873                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
874                return;
875
876            }
877
878            int available = outputDelayRingBufferSamplesAvailable();
879            int numSamples = outHeader->nAllocLen / sizeof(int16_t);
880            if (numSamples > available) {
881                numSamples = available;
882            }
883            int64_t currentTime = 0;
884            if (available) {
885
886                int numFrames = numSamples / (mStreamInfo->frameSize * mStreamInfo->numChannels);
887                numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
888
889                ALOGV("%d samples available (%d), or %d frames",
890                        numSamples, available, numFrames);
891                int64_t *nextTimeStamp = &mBufferTimestamps.editItemAt(0);
892                currentTime = *nextTimeStamp;
893                int32_t *currentBufLeft = &mBufferSizes.editItemAt(0);
894                for (int i = 0; i < numFrames; i++) {
895                    int32_t decodedSize = mDecodedSizes.itemAt(0);
896                    mDecodedSizes.removeAt(0);
897                    ALOGV("decoded %d of %d", decodedSize, *currentBufLeft);
898                    if (*currentBufLeft > decodedSize) {
899                        // adjust/interpolate next time stamp
900                        *currentBufLeft -= decodedSize;
901                        *nextTimeStamp += mStreamInfo->aacSamplesPerFrame *
902                                1000000ll / mStreamInfo->sampleRate;
903                        ALOGV("adjusted nextTimeStamp/size to %lld/%d",
904                                *nextTimeStamp, *currentBufLeft);
905                    } else {
906                        // move to next timestamp in list
907                        if (mBufferTimestamps.size() > 0) {
908                            mBufferTimestamps.removeAt(0);
909                            nextTimeStamp = &mBufferTimestamps.editItemAt(0);
910                            mBufferSizes.removeAt(0);
911                            currentBufLeft = &mBufferSizes.editItemAt(0);
912                            ALOGV("moved to next time/size: %lld/%d",
913                                    *nextTimeStamp, *currentBufLeft);
914                        }
915                        // try to limit output buffer size to match input buffers
916                        // (e.g when an input buffer contained 4 "sub" frames, output
917                        // at most 4 decoded units in the corresponding output buffer)
918                        // This is optional. Remove the next three lines to fill the output
919                        // buffer with as many units as available.
920                        numFrames = i + 1;
921                        numSamples = numFrames * mStreamInfo->frameSize * mStreamInfo->numChannels;
922                        break;
923                    }
924                }
925
926                ALOGV("getting %d from ringbuffer", numSamples);
927                int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
928                if (ns != numSamples) {
929                    ALOGE("not a complete frame of samples available");
930                    mSignalledError = true;
931                    notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
932                    return;
933                }
934            }
935
936            outHeader->nFilledLen = numSamples * sizeof(int16_t);
937
938            if (mEndOfInput && !outQueue.empty() && outputDelayRingBufferSamplesAvailable() == 0) {
939                outHeader->nFlags = OMX_BUFFERFLAG_EOS;
940                mEndOfOutput = true;
941            } else {
942                outHeader->nFlags = 0;
943            }
944
945            outHeader->nTimeStamp = currentTime;
946
947            mOutputBufferCount++;
948            outInfo->mOwnedByUs = false;
949            outQueue.erase(outQueue.begin());
950            outInfo = NULL;
951            ALOGV("out timestamp %lld / %d", outHeader->nTimeStamp, outHeader->nFilledLen);
952            notifyFillBufferDone(outHeader);
953            outHeader = NULL;
954        }
955
956        if (mEndOfInput) {
957            if (outputDelayRingBufferSamplesAvailable() > 0
958                    && outputDelayRingBufferSamplesAvailable()
959                            < mStreamInfo->frameSize * mStreamInfo->numChannels) {
960                ALOGE("not a complete frame of samples available");
961                mSignalledError = true;
962                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
963                return;
964            }
965
966            if (mEndOfInput && !outQueue.empty() && outputDelayRingBufferSamplesAvailable() == 0) {
967                if (!mEndOfOutput) {
968                    // send empty block signaling EOS
969                    mEndOfOutput = true;
970                    BufferInfo *outInfo = *outQueue.begin();
971                    OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
972
973                    if (outHeader->nOffset != 0) {
974                        ALOGE("outHeader->nOffset != 0 is not handled");
975                        mSignalledError = true;
976                        notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
977                        return;
978                    }
979
980                    INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(outHeader->pBuffer
981                            + outHeader->nOffset);
982                    int32_t ns = 0;
983                    outHeader->nFilledLen = 0;
984                    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
985
986                    outHeader->nTimeStamp = mBufferTimestamps.itemAt(0);
987                    mBufferTimestamps.clear();
988                    mBufferSizes.clear();
989                    mDecodedSizes.clear();
990
991                    mOutputBufferCount++;
992                    outInfo->mOwnedByUs = false;
993                    outQueue.erase(outQueue.begin());
994                    outInfo = NULL;
995                    notifyFillBufferDone(outHeader);
996                    outHeader = NULL;
997                }
998                break; // if outQueue not empty but no more output
999            }
1000        }
1001    }
1002}
1003
1004void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
1005    if (portIndex == 0) {
1006        // Make sure that the next buffer output does not still
1007        // depend on fragments from the last one decoded.
1008        // drain all existing data
1009        drainDecoder();
1010        mBufferTimestamps.clear();
1011        mBufferSizes.clear();
1012        mDecodedSizes.clear();
1013        mLastInHeader = NULL;
1014    } else {
1015        int avail;
1016        while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
1017            if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
1018                avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
1019            }
1020            int32_t ns = outputDelayRingBufferGetSamples(0, avail);
1021            if (ns != avail) {
1022                ALOGE("not a complete frame of samples available");
1023                break;
1024            }
1025            mOutputBufferCount++;
1026        }
1027        mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
1028    }
1029}
1030
1031void SoftAAC2::drainDecoder() {
1032    int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
1033
1034    // flush decoder until outputDelay is compensated
1035    while (mOutputDelayCompensated > 0) {
1036        // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
1037        INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
1038
1039        // run DRC check
1040        mDrcWrap.submitStreamData(mStreamInfo);
1041        mDrcWrap.update();
1042
1043        AAC_DECODER_ERROR decoderErr =
1044            aacDecoder_DecodeFrame(mAACDecoder,
1045                                   tmpOutBuffer,
1046                                   2048 * MAX_CHANNEL_COUNT,
1047                                   AACDEC_FLUSH);
1048        if (decoderErr != AAC_DEC_OK) {
1049            ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
1050        }
1051
1052        int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
1053        if (tmpOutBufferSamples > mOutputDelayCompensated) {
1054            tmpOutBufferSamples = mOutputDelayCompensated;
1055        }
1056        outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
1057
1058        mOutputDelayCompensated -= tmpOutBufferSamples;
1059    }
1060}
1061
1062void SoftAAC2::onReset() {
1063    drainDecoder();
1064    // reset the "configured" state
1065    mInputBufferCount = 0;
1066    mOutputBufferCount = 0;
1067    mOutputDelayCompensated = 0;
1068    mOutputDelayRingBufferWritePos = 0;
1069    mOutputDelayRingBufferReadPos = 0;
1070    mOutputDelayRingBufferFilled = 0;
1071    mEndOfInput = false;
1072    mEndOfOutput = false;
1073    mBufferTimestamps.clear();
1074    mBufferSizes.clear();
1075    mDecodedSizes.clear();
1076    mLastInHeader = NULL;
1077
1078    // To make the codec behave the same before and after a reset, we need to invalidate the
1079    // streaminfo struct. This does that:
1080    mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only
1081
1082    mSignalledError = false;
1083    mOutputPortSettingsChange = NONE;
1084}
1085
1086void SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
1087    if (portIndex != 1) {
1088        return;
1089    }
1090
1091    switch (mOutputPortSettingsChange) {
1092        case NONE:
1093            break;
1094
1095        case AWAITING_DISABLED:
1096        {
1097            CHECK(!enabled);
1098            mOutputPortSettingsChange = AWAITING_ENABLED;
1099            break;
1100        }
1101
1102        default:
1103        {
1104            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
1105            CHECK(enabled);
1106            mOutputPortSettingsChange = NONE;
1107            break;
1108        }
1109    }
1110}
1111
1112}  // namespace android
1113
1114android::SoftOMXComponent *createSoftOMXComponent(
1115        const char *name, const OMX_CALLBACKTYPE *callbacks,
1116        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
1117    return new android::SoftAAC2(name, callbacks, appData, component);
1118}
1119