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