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