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