SoftAAC2.cpp revision 6a9ebb41a8084b73e654a25d97a6ae26ff4166d4
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_TAG "SoftAAC2"
18//#define LOG_NDEBUG 0
19#include <utils/Log.h>
20
21#include "SoftAAC2.h"
22
23#include <cutils/properties.h>
24#include <media/stagefright/foundation/ADebug.h>
25#include <media/stagefright/foundation/hexdump.h>
26#include <media/stagefright/MediaErrors.h>
27
28#define FILEREAD_MAX_LAYERS 2
29
30#define DRC_DEFAULT_MOBILE_REF_LEVEL 64  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
31#define DRC_DEFAULT_MOBILE_DRC_CUT   127 /* maximum compression of dynamic range for mobile conf */
32#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
33#define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
34// names of properties that can be used to override the default DRC settings
35#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
36#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
37#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
38
39namespace android {
40
41template<class T>
42static void InitOMXParams(T *params) {
43    params->nSize = sizeof(T);
44    params->nVersion.s.nVersionMajor = 1;
45    params->nVersion.s.nVersionMinor = 0;
46    params->nVersion.s.nRevision = 0;
47    params->nVersion.s.nStep = 0;
48}
49
50SoftAAC2::SoftAAC2(
51        const char *name,
52        const OMX_CALLBACKTYPE *callbacks,
53        OMX_PTR appData,
54        OMX_COMPONENTTYPE **component)
55    : SimpleSoftOMXComponent(name, callbacks, appData, component),
56      mAACDecoder(NULL),
57      mStreamInfo(NULL),
58      mIsADTS(false),
59      mInputBufferCount(0),
60      mSignalledError(false),
61      mSawInputEos(false),
62      mSignalledOutputEos(false),
63      mAnchorTimeUs(0),
64      mNumSamplesOutput(0),
65      mOutputPortSettingsChange(NONE) {
66    initPorts();
67    CHECK_EQ(initDecoder(), (status_t)OK);
68}
69
70SoftAAC2::~SoftAAC2() {
71    aacDecoder_Close(mAACDecoder);
72}
73
74void SoftAAC2::initPorts() {
75    OMX_PARAM_PORTDEFINITIONTYPE def;
76    InitOMXParams(&def);
77
78    def.nPortIndex = 0;
79    def.eDir = OMX_DirInput;
80    def.nBufferCountMin = kNumInputBuffers;
81    def.nBufferCountActual = def.nBufferCountMin;
82    def.nBufferSize = 8192;
83    def.bEnabled = OMX_TRUE;
84    def.bPopulated = OMX_FALSE;
85    def.eDomain = OMX_PortDomainAudio;
86    def.bBuffersContiguous = OMX_FALSE;
87    def.nBufferAlignment = 1;
88
89    def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
90    def.format.audio.pNativeRender = NULL;
91    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
92    def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
93
94    addPort(def);
95
96    def.nPortIndex = 1;
97    def.eDir = OMX_DirOutput;
98    def.nBufferCountMin = kNumOutputBuffers;
99    def.nBufferCountActual = def.nBufferCountMin;
100    def.nBufferSize = 4096 * MAX_CHANNEL_COUNT;
101    def.bEnabled = OMX_TRUE;
102    def.bPopulated = OMX_FALSE;
103    def.eDomain = OMX_PortDomainAudio;
104    def.bBuffersContiguous = OMX_FALSE;
105    def.nBufferAlignment = 2;
106
107    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
108    def.format.audio.pNativeRender = NULL;
109    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
110    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
111
112    addPort(def);
113}
114
115status_t SoftAAC2::initDecoder() {
116    status_t status = UNKNOWN_ERROR;
117    mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
118    if (mAACDecoder != NULL) {
119        mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
120        if (mStreamInfo != NULL) {
121            status = OK;
122        }
123    }
124    mDecoderHasData = false;
125
126    // for streams that contain metadata, use the mobile profile DRC settings unless overridden
127    // by platform properties:
128    char value[PROPERTY_VALUE_MAX];
129    //  * AAC_DRC_REFERENCE_LEVEL
130    if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
131        unsigned refLevel = atoi(value);
132        ALOGV("AAC decoder using AAC_DRC_REFERENCE_LEVEL of %d instead of %d",
133                refLevel, DRC_DEFAULT_MOBILE_REF_LEVEL);
134        aacDecoder_SetParam(mAACDecoder, AAC_DRC_REFERENCE_LEVEL, refLevel);
135    } else {
136        aacDecoder_SetParam(mAACDecoder, AAC_DRC_REFERENCE_LEVEL, DRC_DEFAULT_MOBILE_REF_LEVEL);
137    }
138    //  * AAC_DRC_ATTENUATION_FACTOR
139    if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
140        unsigned cut = atoi(value);
141        ALOGV("AAC decoder using AAC_DRC_ATTENUATION_FACTOR of %d instead of %d",
142                        cut, DRC_DEFAULT_MOBILE_DRC_CUT);
143        aacDecoder_SetParam(mAACDecoder, AAC_DRC_ATTENUATION_FACTOR, cut);
144    } else {
145        aacDecoder_SetParam(mAACDecoder, AAC_DRC_ATTENUATION_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT);
146    }
147    //  * AAC_DRC_BOOST_FACTOR (note: no default, using cut)
148    if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
149        unsigned boost = atoi(value);
150        ALOGV("AAC decoder using AAC_DRC_BOOST_FACTOR of %d", boost);
151        aacDecoder_SetParam(mAACDecoder, AAC_DRC_BOOST_FACTOR, boost);
152    } else {
153        aacDecoder_SetParam(mAACDecoder, AAC_DRC_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST);
154    }
155
156    return status;
157}
158
159OMX_ERRORTYPE SoftAAC2::internalGetParameter(
160        OMX_INDEXTYPE index, OMX_PTR params) {
161    switch (index) {
162        case OMX_IndexParamAudioAac:
163        {
164            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
165                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
166
167            if (aacParams->nPortIndex != 0) {
168                return OMX_ErrorUndefined;
169            }
170
171            aacParams->nBitRate = 0;
172            aacParams->nAudioBandWidth = 0;
173            aacParams->nAACtools = 0;
174            aacParams->nAACERtools = 0;
175            aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
176
177            aacParams->eAACStreamFormat =
178                mIsADTS
179                    ? OMX_AUDIO_AACStreamFormatMP4ADTS
180                    : OMX_AUDIO_AACStreamFormatMP4FF;
181
182            aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
183
184            if (!isConfigured()) {
185                aacParams->nChannels = 1;
186                aacParams->nSampleRate = 44100;
187                aacParams->nFrameLength = 0;
188            } else {
189                aacParams->nChannels = mStreamInfo->numChannels;
190                aacParams->nSampleRate = mStreamInfo->sampleRate;
191                aacParams->nFrameLength = mStreamInfo->frameSize;
192            }
193
194            return OMX_ErrorNone;
195        }
196
197        case OMX_IndexParamAudioPcm:
198        {
199            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
200                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
201
202            if (pcmParams->nPortIndex != 1) {
203                return OMX_ErrorUndefined;
204            }
205
206            pcmParams->eNumData = OMX_NumericalDataSigned;
207            pcmParams->eEndian = OMX_EndianBig;
208            pcmParams->bInterleaved = OMX_TRUE;
209            pcmParams->nBitPerSample = 16;
210            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
211            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
212            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
213            pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
214            pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
215            pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
216            pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
217
218            if (!isConfigured()) {
219                pcmParams->nChannels = 1;
220                pcmParams->nSamplingRate = 44100;
221            } else {
222                pcmParams->nChannels = mStreamInfo->numChannels;
223                pcmParams->nSamplingRate = mStreamInfo->sampleRate;
224            }
225
226            return OMX_ErrorNone;
227        }
228
229        default:
230            return SimpleSoftOMXComponent::internalGetParameter(index, params);
231    }
232}
233
234OMX_ERRORTYPE SoftAAC2::internalSetParameter(
235        OMX_INDEXTYPE index, const OMX_PTR params) {
236    switch (index) {
237        case OMX_IndexParamStandardComponentRole:
238        {
239            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
240                (const OMX_PARAM_COMPONENTROLETYPE *)params;
241
242            if (strncmp((const char *)roleParams->cRole,
243                        "audio_decoder.aac",
244                        OMX_MAX_STRINGNAME_SIZE - 1)) {
245                return OMX_ErrorUndefined;
246            }
247
248            return OMX_ErrorNone;
249        }
250
251        case OMX_IndexParamAudioAac:
252        {
253            const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
254                (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
255
256            if (aacParams->nPortIndex != 0) {
257                return OMX_ErrorUndefined;
258            }
259
260            if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
261                mIsADTS = false;
262            } else if (aacParams->eAACStreamFormat
263                        == OMX_AUDIO_AACStreamFormatMP4ADTS) {
264                mIsADTS = true;
265            } else {
266                return OMX_ErrorUndefined;
267            }
268
269            return OMX_ErrorNone;
270        }
271
272        case OMX_IndexParamAudioPcm:
273        {
274            const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
275                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
276
277            if (pcmParams->nPortIndex != 1) {
278                return OMX_ErrorUndefined;
279            }
280
281            return OMX_ErrorNone;
282        }
283
284        default:
285            return SimpleSoftOMXComponent::internalSetParameter(index, params);
286    }
287}
288
289bool SoftAAC2::isConfigured() const {
290    return mInputBufferCount > 0;
291}
292
293void SoftAAC2::maybeConfigureDownmix() const {
294    if (mStreamInfo->numChannels > 2) {
295        char value[PROPERTY_VALUE_MAX];
296        if (!(property_get("media.aac_51_output_enabled", value, NULL) &&
297                (!strcmp(value, "1") || !strcasecmp(value, "true")))) {
298            ALOGI("Downmixing multichannel AAC to stereo");
299            aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, 2);
300            mStreamInfo->numChannels = 2;
301            // By default, the decoder creates a 5.1 channel downmix signal
302            // for seven and eight channel input streams. To enable 6.1 and 7.1 channel output
303            // use aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1)
304        }
305    }
306}
307
308void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
309    if (mSignalledError || mOutputPortSettingsChange != NONE) {
310        return;
311    }
312
313    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
314    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
315    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
316
317    List<BufferInfo *> &inQueue = getPortQueue(0);
318    List<BufferInfo *> &outQueue = getPortQueue(1);
319
320    if (portIndex == 0 && mInputBufferCount == 0) {
321        ++mInputBufferCount;
322        BufferInfo *info = *inQueue.begin();
323        OMX_BUFFERHEADERTYPE *header = info->mHeader;
324
325        inBuffer[0] = header->pBuffer + header->nOffset;
326        inBufferLength[0] = header->nFilledLen;
327
328        AAC_DECODER_ERROR decoderErr =
329            aacDecoder_ConfigRaw(mAACDecoder,
330                                 inBuffer,
331                                 inBufferLength);
332
333        if (decoderErr != AAC_DEC_OK) {
334            mSignalledError = true;
335            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
336            return;
337        }
338
339        inQueue.erase(inQueue.begin());
340        info->mOwnedByUs = false;
341        notifyEmptyBufferDone(header);
342
343        // Only send out port settings changed event if both sample rate
344        // and numChannels are valid.
345        if (mStreamInfo->sampleRate && mStreamInfo->numChannels) {
346            maybeConfigureDownmix();
347            ALOGI("Initially configuring decoder: %d Hz, %d channels",
348                mStreamInfo->sampleRate,
349                mStreamInfo->numChannels);
350
351            notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
352            mOutputPortSettingsChange = AWAITING_DISABLED;
353        }
354
355        return;
356    }
357
358    while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
359        BufferInfo *inInfo = NULL;
360        OMX_BUFFERHEADERTYPE *inHeader = NULL;
361        if (!inQueue.empty()) {
362            inInfo = *inQueue.begin();
363            inHeader = inInfo->mHeader;
364        }
365
366        BufferInfo *outInfo = *outQueue.begin();
367        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
368        outHeader->nFlags = 0;
369
370        if (inHeader) {
371            if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
372                mSawInputEos = true;
373            }
374
375            if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
376                mAnchorTimeUs = inHeader->nTimeStamp;
377                mNumSamplesOutput = 0;
378            }
379
380            if (mIsADTS && inHeader->nFilledLen) {
381                size_t adtsHeaderSize = 0;
382                // skip 30 bits, aac_frame_length follows.
383                // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
384
385                const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
386
387                bool signalError = false;
388                if (inHeader->nFilledLen < 7) {
389                    ALOGE("Audio data too short to contain even the ADTS header. "
390                          "Got %ld bytes.", inHeader->nFilledLen);
391                    hexdump(adtsHeader, inHeader->nFilledLen);
392                    signalError = true;
393                } else {
394                    bool protectionAbsent = (adtsHeader[1] & 1);
395
396                    unsigned aac_frame_length =
397                        ((adtsHeader[3] & 3) << 11)
398                        | (adtsHeader[4] << 3)
399                        | (adtsHeader[5] >> 5);
400
401                    if (inHeader->nFilledLen < aac_frame_length) {
402                        ALOGE("Not enough audio data for the complete frame. "
403                              "Got %ld bytes, frame size according to the ADTS "
404                              "header is %u bytes.",
405                              inHeader->nFilledLen, aac_frame_length);
406                        hexdump(adtsHeader, inHeader->nFilledLen);
407                        signalError = true;
408                    } else {
409                        adtsHeaderSize = (protectionAbsent ? 7 : 9);
410
411                        inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
412                        inBufferLength[0] = aac_frame_length - adtsHeaderSize;
413
414                        inHeader->nOffset += adtsHeaderSize;
415                        inHeader->nFilledLen -= adtsHeaderSize;
416                    }
417                }
418
419                if (signalError) {
420                    mSignalledError = true;
421
422                    notify(OMX_EventError,
423                           OMX_ErrorStreamCorrupt,
424                           ERROR_MALFORMED,
425                           NULL);
426
427                    return;
428                }
429            } else {
430                inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
431                inBufferLength[0] = inHeader->nFilledLen;
432            }
433        } else {
434            inBufferLength[0] = 0;
435        }
436
437        // Fill and decode
438        INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(
439                outHeader->pBuffer + outHeader->nOffset);
440
441        bytesValid[0] = inBufferLength[0];
442
443        int prevSampleRate = mStreamInfo->sampleRate;
444        int prevNumChannels = mStreamInfo->numChannels;
445
446        AAC_DECODER_ERROR decoderErr = AAC_DEC_NOT_ENOUGH_BITS;
447        while ((bytesValid[0] > 0 || mSawInputEos) && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
448            mDecoderHasData |= (bytesValid[0] > 0);
449            aacDecoder_Fill(mAACDecoder,
450                            inBuffer,
451                            inBufferLength,
452                            bytesValid);
453
454            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
455                                                outBuffer,
456                                                outHeader->nAllocLen,
457                                                0 /* flags */);
458            if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
459                if (mSawInputEos && bytesValid[0] <= 0) {
460                    if (mDecoderHasData) {
461                        // flush out the decoder's delayed data by calling DecodeFrame
462                        // one more time, with the AACDEC_FLUSH flag set
463                        decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
464                                                            outBuffer,
465                                                            outHeader->nAllocLen,
466                                                            AACDEC_FLUSH);
467                        mDecoderHasData = false;
468                    }
469                    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
470                    mSignalledOutputEos = true;
471                    break;
472                } else {
473                    ALOGW("Not enough bits, bytesValid %d", bytesValid[0]);
474                }
475            }
476        }
477
478        size_t numOutBytes =
479            mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
480
481        if (inHeader) {
482            if (decoderErr == AAC_DEC_OK) {
483                UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
484                inHeader->nFilledLen -= inBufferUsedLength;
485                inHeader->nOffset += inBufferUsedLength;
486            } else {
487                ALOGW("AAC decoder returned error %d, substituting silence",
488                      decoderErr);
489
490                memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
491
492                // Discard input buffer.
493                inHeader->nFilledLen = 0;
494
495                aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
496
497                // fall through
498            }
499
500            if (inHeader->nFilledLen == 0) {
501                inInfo->mOwnedByUs = false;
502                inQueue.erase(inQueue.begin());
503                inInfo = NULL;
504                notifyEmptyBufferDone(inHeader);
505                inHeader = NULL;
506            }
507        }
508
509        /*
510         * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
511         * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
512         * rate system and the sampling rate in the final output is actually
513         * doubled compared with the core AAC decoder sampling rate.
514         *
515         * Explicit signalling is done by explicitly defining SBR audio object
516         * type in the bitstream. Implicit signalling is done by embedding
517         * SBR content in AAC extension payload specific to SBR, and hence
518         * requires an AAC decoder to perform pre-checks on actual audio frames.
519         *
520         * Thus, we could not say for sure whether a stream is
521         * AAC+/eAAC+ until the first data frame is decoded.
522         */
523        if (mInputBufferCount <= 2) {
524            if (mStreamInfo->sampleRate != prevSampleRate ||
525                mStreamInfo->numChannels != prevNumChannels) {
526                maybeConfigureDownmix();
527                ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
528                      prevSampleRate, mStreamInfo->sampleRate,
529                      prevNumChannels, mStreamInfo->numChannels);
530
531                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
532                mOutputPortSettingsChange = AWAITING_DISABLED;
533                return;
534            }
535        } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
536            ALOGW("Invalid AAC stream");
537            mSignalledError = true;
538            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
539            return;
540        }
541
542        if (decoderErr == AAC_DEC_OK || mNumSamplesOutput > 0) {
543            // We'll only output data if we successfully decoded it or
544            // we've previously decoded valid data, in the latter case
545            // (decode failed) we'll output a silent frame.
546            outHeader->nFilledLen = numOutBytes;
547
548            outHeader->nTimeStamp =
549                mAnchorTimeUs
550                    + (mNumSamplesOutput * 1000000ll) / mStreamInfo->sampleRate;
551
552            mNumSamplesOutput += mStreamInfo->frameSize;
553
554            outInfo->mOwnedByUs = false;
555            outQueue.erase(outQueue.begin());
556            outInfo = NULL;
557            notifyFillBufferDone(outHeader);
558            outHeader = NULL;
559        }
560
561        if (decoderErr == AAC_DEC_OK) {
562            ++mInputBufferCount;
563        }
564    }
565}
566
567void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
568    if (portIndex == 0) {
569        // Make sure that the next buffer output does not still
570        // depend on fragments from the last one decoded.
571        // drain all existing data
572        drainDecoder();
573        // force decoder loop to drop the first decoded buffer by resetting these state variables,
574        // but only if initialization has already happened.
575        if (mInputBufferCount != 0) {
576            mInputBufferCount = 1;
577            mStreamInfo->sampleRate = 0;
578        }
579    }
580}
581
582void SoftAAC2::drainDecoder() {
583    // a buffer big enough for 6 channels of decoded HE-AAC
584    short buf [2048*6];
585    aacDecoder_DecodeFrame(mAACDecoder,
586            buf, sizeof(buf), AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
587    aacDecoder_DecodeFrame(mAACDecoder,
588            buf, sizeof(buf), AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
589    aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
590    mDecoderHasData = false;
591}
592
593void SoftAAC2::onReset() {
594    drainDecoder();
595    // 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;
601
602    mSignalledError = false;
603    mSawInputEos = false;
604    mSignalledOutputEos = false;
605    mOutputPortSettingsChange = NONE;
606}
607
608void SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
609    if (portIndex != 1) {
610        return;
611    }
612
613    switch (mOutputPortSettingsChange) {
614        case NONE:
615            break;
616
617        case AWAITING_DISABLED:
618        {
619            CHECK(!enabled);
620            mOutputPortSettingsChange = AWAITING_ENABLED;
621            break;
622        }
623
624        default:
625        {
626            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
627            CHECK(enabled);
628            mOutputPortSettingsChange = NONE;
629            break;
630        }
631    }
632}
633
634}  // namespace android
635
636android::SoftOMXComponent *createSoftOMXComponent(
637        const char *name, const OMX_CALLBACKTYPE *callbacks,
638        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
639    return new android::SoftAAC2(name, callbacks, appData, component);
640}
641