Home | History | Annotate | Download | only in xaacdec
      1 /*
      2  * Copyright (C) 2018 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 "SoftXAAC"
     19 #include <utils/Log.h>
     20 
     21 #include "SoftXAAC.h"
     22 
     23 #include <OMX_AudioExt.h>
     24 #include <OMX_IndexExt.h>
     25 #include <cutils/properties.h>
     26 #include <math.h>
     27 #include <media/stagefright/MediaErrors.h>
     28 #include <media/stagefright/foundation/ADebug.h>
     29 #include <media/stagefright/foundation/hexdump.h>
     30 #include <utils/misc.h>
     31 
     32 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
     33 #define DRC_DEFAULT_MOBILE_REF_LEVEL 64
     34 /* maximum compression of dynamic range for mobile conf */
     35 #define DRC_DEFAULT_MOBILE_DRC_CUT 127
     36 /* maximum compression of dynamic range for mobile conf */
     37 #define DRC_DEFAULT_MOBILE_DRC_BOOST 127
     38 /* switch for heavy compression for mobile conf */
     39 #define DRC_DEFAULT_MOBILE_DRC_HEAVY 1
     40 /* encoder target level; -1 => the value is unknown,
     41  * otherwise dB step value (e.g. 64 for -16 dB) */
     42 #define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1)
     43 
     44 /* Default Effect type is "Limited playback" */
     45 #define DRC_KEY_AAC_DRC_EFFECT_TYPE (3)
     46 
     47 /* REF_LEVEL of 64 pairs well with EFFECT_TYPE of 3. */
     48 /* Default loudness value for MPEG-D DRC */
     49 #define DRC_DEFAULT_MOBILE_LOUDNESS_LEVEL (64)
     50 
     51 #define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
     52 #define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
     53 #define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
     54 #define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
     55 #define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
     56 #define PROP_DRC_OVERRIDE_EFFECT_TYPE "ro.aac_drc_effect_type"
     57 
     58 /* maximum number of audio channels that can be decoded */
     59 #define MAX_CHANNEL_COUNT 8
     60 
     61 #define RETURN_IF_FATAL(retval, str)                       \
     62     if (retval & IA_FATAL_ERROR) {                         \
     63         ALOGE("Error in %s: Returned: %d", str, retval);   \
     64         return retval;                                     \
     65     } else if (retval != IA_NO_ERROR) {                    \
     66         ALOGW("Warning in %s: Returned: %d", str, retval); \
     67     }
     68 
     69 namespace android {
     70 
     71 template <class T>
     72 static void InitOMXParams(T* params) {
     73     params->nSize = sizeof(T);
     74     params->nVersion.s.nVersionMajor = 1;
     75     params->nVersion.s.nVersionMinor = 0;
     76     params->nVersion.s.nRevision = 0;
     77     params->nVersion.s.nStep = 0;
     78 }
     79 
     80 static const OMX_U32 kSupportedProfiles[] = {
     81     OMX_AUDIO_AACObjectLC, OMX_AUDIO_AACObjectHE,  OMX_AUDIO_AACObjectHE_PS,
     82     OMX_AUDIO_AACObjectLD, OMX_AUDIO_AACObjectELD,
     83 };
     84 
     85 SoftXAAC::SoftXAAC(const char* name, const OMX_CALLBACKTYPE* callbacks, OMX_PTR appData,
     86                    OMX_COMPONENTTYPE** component)
     87     : SimpleSoftOMXComponent(name, callbacks, appData, component),
     88       mIsADTS(false),
     89       mInputBufferCount(0),
     90       mOutputBufferCount(0),
     91       mSignalledError(false),
     92       mLastInHeader(NULL),
     93       mPrevTimestamp(0),
     94       mCurrentTimestamp(0),
     95       mOutputPortSettingsChange(NONE),
     96       mXheaacCodecHandle(NULL),
     97       mMpegDDrcHandle(NULL),
     98       mInputBufferSize(0),
     99       mOutputFrameLength(1024),
    100       mInputBuffer(NULL),
    101       mOutputBuffer(NULL),
    102       mSampFreq(0),
    103       mNumChannels(0),
    104       mPcmWdSz(0),
    105       mChannelMask(0),
    106       mIsCodecInitialized(false),
    107       mIsCodecConfigFlushRequired(false),
    108       mMpegDDRCPresent(0),
    109       mDRCFlag(0)
    110 
    111 {
    112     initPorts();
    113     CHECK_EQ(initDecoder(), (status_t)OK);
    114 }
    115 
    116 SoftXAAC::~SoftXAAC() {
    117     int errCode = deInitXAACDecoder();
    118     if (0 != errCode) {
    119         ALOGE("deInitXAACDecoder() failed %d", errCode);
    120     }
    121 
    122     mIsCodecInitialized = false;
    123     mIsCodecConfigFlushRequired = false;
    124 }
    125 
    126 void SoftXAAC::initPorts() {
    127     OMX_PARAM_PORTDEFINITIONTYPE def;
    128     InitOMXParams(&def);
    129 
    130     def.nPortIndex = 0;
    131     def.eDir = OMX_DirInput;
    132     def.nBufferCountMin = kNumInputBuffers;
    133     def.nBufferCountActual = def.nBufferCountMin;
    134     def.nBufferSize = 8192;
    135     def.bEnabled = OMX_TRUE;
    136     def.bPopulated = OMX_FALSE;
    137     def.eDomain = OMX_PortDomainAudio;
    138     def.bBuffersContiguous = OMX_FALSE;
    139     def.nBufferAlignment = 1;
    140 
    141     def.format.audio.cMIMEType = const_cast<char*>("audio/aac");
    142     def.format.audio.pNativeRender = NULL;
    143     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
    144     def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
    145 
    146     addPort(def);
    147 
    148     def.nPortIndex = 1;
    149     def.eDir = OMX_DirOutput;
    150     def.nBufferCountMin = kNumOutputBuffers;
    151     def.nBufferCountActual = def.nBufferCountMin;
    152     def.nBufferSize = 4096 * MAX_CHANNEL_COUNT;
    153     def.bEnabled = OMX_TRUE;
    154     def.bPopulated = OMX_FALSE;
    155     def.eDomain = OMX_PortDomainAudio;
    156     def.bBuffersContiguous = OMX_FALSE;
    157     def.nBufferAlignment = 2;
    158 
    159     def.format.audio.cMIMEType = const_cast<char*>("audio/raw");
    160     def.format.audio.pNativeRender = NULL;
    161     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
    162     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
    163 
    164     addPort(def);
    165 }
    166 
    167 status_t SoftXAAC::initDecoder() {
    168     status_t status = UNKNOWN_ERROR;
    169 
    170     int ui_drc_val;
    171     IA_ERRORCODE err_code = IA_NO_ERROR;
    172     int loop = 0;
    173 
    174     err_code = initXAACDecoder();
    175     if (err_code != IA_NO_ERROR) {
    176         if (NULL == mXheaacCodecHandle) {
    177             ALOGE("AAC decoder handle is null");
    178         }
    179         if (NULL == mMpegDDrcHandle) {
    180             ALOGE("MPEG-D DRC decoder handle is null");
    181         }
    182         for (loop = 1; loop < mMallocCount; loop++) {
    183             if (mMemoryArray[loop] == NULL) {
    184                 ALOGE(" memory allocation error %d\n", loop);
    185                 break;
    186             }
    187         }
    188         ALOGE("initXAACDecoder Failed");
    189 
    190         for (loop = 0; loop < mMallocCount; loop++) {
    191             if (mMemoryArray[loop]) free(mMemoryArray[loop]);
    192         }
    193         mMallocCount = 0;
    194         return status;
    195     } else {
    196         status = OK;
    197     }
    198 
    199     mEndOfInput = false;
    200     mEndOfOutput = false;
    201 
    202     char value[PROPERTY_VALUE_MAX];
    203     if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
    204         ui_drc_val = atoi(value);
    205         ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d",
    206               ui_drc_val, DRC_DEFAULT_MOBILE_REF_LEVEL);
    207     } else {
    208         ui_drc_val = DRC_DEFAULT_MOBILE_REF_LEVEL;
    209     }
    210 
    211     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
    212                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, &ui_drc_val);
    213 
    214     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
    215 #ifdef ENABLE_MPEG_D_DRC
    216     /* Use ui_drc_val from PROP_DRC_OVERRIDE_REF_LEVEL or DRC_DEFAULT_MOBILE_REF_LEVEL
    217      * for IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS too */
    218 
    219     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
    220                                 IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &ui_drc_val);
    221 
    222     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
    223 #endif
    224 
    225     if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
    226         ui_drc_val = atoi(value);
    227         ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", ui_drc_val,
    228               DRC_DEFAULT_MOBILE_DRC_CUT);
    229     } else {
    230         ui_drc_val = DRC_DEFAULT_MOBILE_DRC_CUT;
    231     }
    232 
    233     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
    234                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &ui_drc_val);
    235 
    236     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
    237 
    238     if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
    239         ui_drc_val = atoi(value);
    240         ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", ui_drc_val,
    241               DRC_DEFAULT_MOBILE_DRC_BOOST);
    242     } else {
    243         ui_drc_val = DRC_DEFAULT_MOBILE_DRC_BOOST;
    244     }
    245 
    246     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
    247                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &ui_drc_val);
    248     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
    249 
    250     if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) {
    251         ui_drc_val = atoi(value);
    252         ALOGV("AAC decoder using desired Heavy compression factor of %d instead of %d", ui_drc_val,
    253               DRC_DEFAULT_MOBILE_DRC_HEAVY);
    254     } else {
    255         ui_drc_val = DRC_DEFAULT_MOBILE_DRC_HEAVY;
    256     }
    257 
    258     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
    259                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP, &ui_drc_val);
    260     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
    261 
    262 #ifdef ENABLE_MPEG_D_DRC
    263     if (property_get(PROP_DRC_OVERRIDE_EFFECT_TYPE, value, NULL)) {
    264         ui_drc_val = atoi(value);
    265         ALOGV("AAC decoder using desired DRC effect type of %d instead of %d", ui_drc_val,
    266               DRC_KEY_AAC_DRC_EFFECT_TYPE);
    267     } else {
    268         ui_drc_val = DRC_KEY_AAC_DRC_EFFECT_TYPE;
    269     }
    270 
    271     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
    272                                 IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &ui_drc_val);
    273 
    274     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
    275 
    276 #endif
    277     return status;
    278 }
    279 
    280 OMX_ERRORTYPE SoftXAAC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) {
    281     switch ((OMX_U32)index) {
    282         case OMX_IndexParamAudioPortFormat: {
    283             OMX_AUDIO_PARAM_PORTFORMATTYPE* formatParams = (OMX_AUDIO_PARAM_PORTFORMATTYPE*)params;
    284 
    285             if (!isValidOMXParam(formatParams)) {
    286                 return OMX_ErrorBadParameter;
    287             }
    288 
    289             if (formatParams->nPortIndex > 1) {
    290                 return OMX_ErrorUndefined;
    291             }
    292 
    293             if (formatParams->nIndex > 0) {
    294                 return OMX_ErrorNoMore;
    295             }
    296 
    297             formatParams->eEncoding =
    298                 (formatParams->nPortIndex == 0) ? OMX_AUDIO_CodingAAC : OMX_AUDIO_CodingPCM;
    299 
    300             return OMX_ErrorNone;
    301         }
    302 
    303         case OMX_IndexParamAudioAac: {
    304             OMX_AUDIO_PARAM_AACPROFILETYPE* aacParams = (OMX_AUDIO_PARAM_AACPROFILETYPE*)params;
    305 
    306             if (!isValidOMXParam(aacParams)) {
    307                 return OMX_ErrorBadParameter;
    308             }
    309 
    310             if (aacParams->nPortIndex != 0) {
    311                 return OMX_ErrorUndefined;
    312             }
    313 
    314             aacParams->nBitRate = 0;
    315             aacParams->nAudioBandWidth = 0;
    316             aacParams->nAACtools = 0;
    317             aacParams->nAACERtools = 0;
    318             aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
    319 
    320             aacParams->eAACStreamFormat =
    321                 mIsADTS ? OMX_AUDIO_AACStreamFormatMP4ADTS : OMX_AUDIO_AACStreamFormatMP4FF;
    322 
    323             aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
    324 
    325             if (!isConfigured()) {
    326                 aacParams->nChannels = 1;
    327                 aacParams->nSampleRate = 44100;
    328                 aacParams->nFrameLength = 0;
    329             } else {
    330                 aacParams->nChannels = mNumChannels;
    331                 aacParams->nSampleRate = mSampFreq;
    332                 aacParams->nFrameLength = mOutputFrameLength;
    333             }
    334 
    335             return OMX_ErrorNone;
    336         }
    337 
    338         case OMX_IndexParamAudioPcm: {
    339             OMX_AUDIO_PARAM_PCMMODETYPE* pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE*)params;
    340 
    341             if (!isValidOMXParam(pcmParams)) {
    342                 return OMX_ErrorBadParameter;
    343             }
    344 
    345             if (pcmParams->nPortIndex != 1) {
    346                 return OMX_ErrorUndefined;
    347             }
    348 
    349             pcmParams->eNumData = OMX_NumericalDataSigned;
    350             pcmParams->eEndian = OMX_EndianBig;
    351             pcmParams->bInterleaved = OMX_TRUE;
    352             pcmParams->nBitPerSample = 16;
    353             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
    354             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
    355             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
    356             pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
    357             pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
    358             pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
    359             pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
    360 
    361             if (!isConfigured()) {
    362                 pcmParams->nChannels = 1;
    363                 pcmParams->nSamplingRate = 44100;
    364             } else {
    365                 pcmParams->nChannels = mNumChannels;
    366                 pcmParams->nSamplingRate = mSampFreq;
    367             }
    368 
    369             return OMX_ErrorNone;
    370         }
    371 
    372         case OMX_IndexParamAudioProfileQuerySupported: {
    373             OMX_AUDIO_PARAM_ANDROID_PROFILETYPE* profileParams =
    374                 (OMX_AUDIO_PARAM_ANDROID_PROFILETYPE*)params;
    375 
    376             if (!isValidOMXParam(profileParams)) {
    377                 return OMX_ErrorBadParameter;
    378             }
    379 
    380             if (profileParams->nPortIndex != 0) {
    381                 return OMX_ErrorUndefined;
    382             }
    383 
    384             if (profileParams->nProfileIndex >= NELEM(kSupportedProfiles)) {
    385                 return OMX_ErrorNoMore;
    386             }
    387 
    388             profileParams->eProfile = kSupportedProfiles[profileParams->nProfileIndex];
    389 
    390             return OMX_ErrorNone;
    391         }
    392 
    393         default:
    394             return SimpleSoftOMXComponent::internalGetParameter(index, params);
    395     }
    396 }
    397 
    398 OMX_ERRORTYPE SoftXAAC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params) {
    399     switch ((int)index) {
    400         case OMX_IndexParamStandardComponentRole: {
    401             const OMX_PARAM_COMPONENTROLETYPE* roleParams =
    402                 (const OMX_PARAM_COMPONENTROLETYPE*)params;
    403 
    404             if (!isValidOMXParam(roleParams)) {
    405                 return OMX_ErrorBadParameter;
    406             }
    407 
    408             if (strncmp((const char*)roleParams->cRole, "audio_decoder.aac",
    409                         OMX_MAX_STRINGNAME_SIZE - 1)) {
    410                 return OMX_ErrorUndefined;
    411             }
    412 
    413             return OMX_ErrorNone;
    414         }
    415 
    416         case OMX_IndexParamAudioPortFormat: {
    417             const OMX_AUDIO_PARAM_PORTFORMATTYPE* formatParams =
    418                 (const OMX_AUDIO_PARAM_PORTFORMATTYPE*)params;
    419 
    420             if (!isValidOMXParam(formatParams)) {
    421                 return OMX_ErrorBadParameter;
    422             }
    423 
    424             if (formatParams->nPortIndex > 1) {
    425                 return OMX_ErrorUndefined;
    426             }
    427 
    428             if ((formatParams->nPortIndex == 0 && formatParams->eEncoding != OMX_AUDIO_CodingAAC) ||
    429                 (formatParams->nPortIndex == 1 && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
    430                 return OMX_ErrorUndefined;
    431             }
    432 
    433             return OMX_ErrorNone;
    434         }
    435 
    436         case OMX_IndexParamAudioAac: {
    437             const OMX_AUDIO_PARAM_AACPROFILETYPE* aacParams =
    438                 (const OMX_AUDIO_PARAM_AACPROFILETYPE*)params;
    439 
    440             if (!isValidOMXParam(aacParams)) {
    441                 return OMX_ErrorBadParameter;
    442             }
    443 
    444             if (aacParams->nPortIndex != 0) {
    445                 return OMX_ErrorUndefined;
    446             }
    447 
    448             if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
    449                 mIsADTS = false;
    450             } else if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4ADTS) {
    451                 mIsADTS = true;
    452             } else {
    453                 return OMX_ErrorUndefined;
    454             }
    455 
    456             return OMX_ErrorNone;
    457         }
    458 
    459         case OMX_IndexParamAudioAndroidAacDrcPresentation: {
    460             const OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE* aacPresParams =
    461                 (const OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE*)params;
    462 
    463             if (!isValidOMXParam(aacPresParams)) {
    464                 ALOGE("set OMX_ErrorBadParameter");
    465                 return OMX_ErrorBadParameter;
    466             }
    467 
    468             // for the following parameters of the OMX_AUDIO_PARAM_AACPROFILETYPE structure,
    469             // a value of -1 implies the parameter is not set by the application:
    470             //   nMaxOutputChannels     -1 by default
    471             //   nDrcCut                uses default platform properties, see initDecoder()
    472             //   nDrcBoost                idem
    473             //   nHeavyCompression        idem
    474             //   nTargetReferenceLevel    idem
    475             //   nEncodedTargetLevel      idem
    476             if (aacPresParams->nMaxOutputChannels >= 0) {
    477                 int max;
    478                 if (aacPresParams->nMaxOutputChannels >= 8) {
    479                     max = 8;
    480                 } else if (aacPresParams->nMaxOutputChannels >= 6) {
    481                     max = 6;
    482                 } else if (aacPresParams->nMaxOutputChannels >= 2) {
    483                     max = 2;
    484                 } else {
    485                     // -1 or 0: disable downmix,  1: mono
    486                     max = aacPresParams->nMaxOutputChannels;
    487                 }
    488             }
    489             /* Apply DRC Changes */
    490             IA_ERRORCODE err_code = setXAACDRCInfo(aacPresParams->nDrcCut, aacPresParams->nDrcBoost,
    491                                                    aacPresParams->nTargetReferenceLevel,
    492                                                    aacPresParams->nHeavyCompression
    493 #ifdef ENABLE_MPEG_D_DRC
    494                                                    ,
    495                                                    aacPresParams->nDrcEffectType
    496 #endif
    497             );  // TOD0 : Revert this change
    498             if (err_code != IA_NO_ERROR) {
    499                 ALOGE("Error in OMX_IndexParamAudioAndroidAacDrcPresentation");
    500                 return OMX_ErrorBadParameter;
    501             }
    502 
    503             return OMX_ErrorNone;
    504         }
    505 
    506         case OMX_IndexParamAudioPcm: {
    507             const OMX_AUDIO_PARAM_PCMMODETYPE* pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE*)params;
    508 
    509             if (!isValidOMXParam(pcmParams)) {
    510                 return OMX_ErrorBadParameter;
    511             }
    512 
    513             if (pcmParams->nPortIndex != 1) {
    514                 return OMX_ErrorUndefined;
    515             }
    516 
    517             return OMX_ErrorNone;
    518         }
    519 
    520         default:
    521             return SimpleSoftOMXComponent::internalSetParameter(index, params);
    522     }
    523 }
    524 
    525 bool SoftXAAC::isConfigured() const {
    526     return mInputBufferCount > 0;
    527 }
    528 
    529 void SoftXAAC::onQueueFilled(OMX_U32 /* portIndex */) {
    530     if (mSignalledError || mOutputPortSettingsChange != NONE) {
    531         ALOGE("onQueueFilled do not process %d %d", mSignalledError, mOutputPortSettingsChange);
    532         return;
    533     }
    534 
    535     uint8_t* inBuffer = NULL;
    536     uint32_t inBufferLength = 0;
    537 
    538     List<BufferInfo*>& inQueue = getPortQueue(0);
    539     List<BufferInfo*>& outQueue = getPortQueue(1);
    540 
    541     signed int numOutBytes = 0;
    542 
    543     /* If decoder call fails in between, then mOutputFrameLength is used  */
    544     /* Decoded output for AAC is 1024/2048 samples / channel             */
    545     /* TODO: For USAC mOutputFrameLength can go up to 4096                 */
    546     /* Note: entire buffer logic to save and retrieve assumes 2 bytes per*/
    547     /* sample currently                                                  */
    548     if (mIsCodecInitialized) {
    549         numOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels;
    550         if ((mPcmWdSz / 8) != 2) {
    551             ALOGE("XAAC assumes 2 bytes per sample! mPcmWdSz %d", mPcmWdSz);
    552         }
    553     }
    554 
    555     while ((!inQueue.empty() || mEndOfInput) && !outQueue.empty()) {
    556         if (!inQueue.empty()) {
    557             BufferInfo* inInfo = *inQueue.begin();
    558             OMX_BUFFERHEADERTYPE* inHeader = inInfo->mHeader;
    559 
    560             /* No need to check inHeader != NULL, as inQueue is not empty */
    561             mEndOfInput = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0;
    562 
    563             if (mInputBufferCount == 0 && !(inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
    564                 ALOGW("first buffer should have OMX_BUFFERFLAG_CODECCONFIG set");
    565                 inHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
    566             }
    567             if ((inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != 0) {
    568                 inBuffer = inHeader->pBuffer + inHeader->nOffset;
    569                 inBufferLength = inHeader->nFilledLen;
    570 
    571                 /* GA header configuration sent to Decoder! */
    572                 int err_code = configXAACDecoder(inBuffer, inBufferLength);
    573                 if (0 != err_code) {
    574                     ALOGW("configXAACDecoder err_code = %d", err_code);
    575                     mSignalledError = true;
    576                     notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
    577                     return;
    578                 }
    579                 mInputBufferCount++;
    580                 mOutputBufferCount++;  // fake increase of outputBufferCount to keep the counters
    581                                        // aligned
    582 
    583                 inInfo->mOwnedByUs = false;
    584                 inQueue.erase(inQueue.begin());
    585                 mLastInHeader = NULL;
    586                 inInfo = NULL;
    587                 notifyEmptyBufferDone(inHeader);
    588                 inHeader = NULL;
    589 
    590                 // Only send out port settings changed event if both sample rate
    591                 // and mNumChannels are valid.
    592                 if (mSampFreq && mNumChannels && !mIsCodecConfigFlushRequired) {
    593                     ALOGV("Configuring decoder: %d Hz, %d channels", mSampFreq, mNumChannels);
    594                     notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
    595                     mOutputPortSettingsChange = AWAITING_DISABLED;
    596                 }
    597 
    598                 return;
    599             }
    600 
    601             if (inHeader->nFilledLen == 0) {
    602                 inInfo->mOwnedByUs = false;
    603                 inQueue.erase(inQueue.begin());
    604                 mLastInHeader = NULL;
    605                 inInfo = NULL;
    606                 notifyEmptyBufferDone(inHeader);
    607                 inHeader = NULL;
    608                 continue;
    609             }
    610 
    611             // Restore Offset and Length for Port reconfig case
    612             size_t tempOffset = inHeader->nOffset;
    613             size_t tempFilledLen = inHeader->nFilledLen;
    614             if (mIsADTS) {
    615                 size_t adtsHeaderSize = 0;
    616                 // skip 30 bits, aac_frame_length follows.
    617                 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
    618 
    619                 const uint8_t* adtsHeader = inHeader->pBuffer + inHeader->nOffset;
    620 
    621                 bool signalError = false;
    622                 if (inHeader->nFilledLen < 7) {
    623                     ALOGE(
    624                         "Audio data too short to contain even the ADTS header. "
    625                         "Got %d bytes.",
    626                         inHeader->nFilledLen);
    627                     hexdump(adtsHeader, inHeader->nFilledLen);
    628                     signalError = true;
    629                 } else {
    630                     bool protectionAbsent = (adtsHeader[1] & 1);
    631 
    632                     unsigned aac_frame_length =
    633                         ((adtsHeader[3] & 3) << 11) | (adtsHeader[4] << 3) | (adtsHeader[5] >> 5);
    634 
    635                     if (inHeader->nFilledLen < aac_frame_length) {
    636                         ALOGE(
    637                             "Not enough audio data for the complete frame. "
    638                             "Got %d bytes, frame size according to the ADTS "
    639                             "header is %u bytes.",
    640                             inHeader->nFilledLen, aac_frame_length);
    641                         hexdump(adtsHeader, inHeader->nFilledLen);
    642                         signalError = true;
    643                     } else {
    644                         adtsHeaderSize = (protectionAbsent ? 7 : 9);
    645                         if (aac_frame_length < adtsHeaderSize) {
    646                             signalError = true;
    647                         } else {
    648                             inBuffer = (uint8_t*)adtsHeader + adtsHeaderSize;
    649                             inBufferLength = aac_frame_length - adtsHeaderSize;
    650 
    651                             inHeader->nOffset += adtsHeaderSize;
    652                             inHeader->nFilledLen -= adtsHeaderSize;
    653                         }
    654                     }
    655                 }
    656 
    657                 if (signalError) {
    658                     mSignalledError = true;
    659                     notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL);
    660                     return;
    661                 }
    662 
    663                 // insert buffer size and time stamp
    664                 if (mLastInHeader != inHeader) {
    665                     mCurrentTimestamp = inHeader->nTimeStamp;
    666                     mLastInHeader = inHeader;
    667                 } else {
    668                     mCurrentTimestamp = mPrevTimestamp + mOutputFrameLength * 1000000ll / mSampFreq;
    669                 }
    670             } else {
    671                 inBuffer = inHeader->pBuffer + inHeader->nOffset;
    672                 inBufferLength = inHeader->nFilledLen;
    673                 mLastInHeader = inHeader;
    674                 mCurrentTimestamp = inHeader->nTimeStamp;
    675             }
    676 
    677             int numLoops = 0;
    678             signed int prevSampleRate = mSampFreq;
    679             signed int prevNumChannels = mNumChannels;
    680 
    681             /* XAAC decoder expects first frame to be fed via configXAACDecoder API */
    682             /* which should initialize the codec. Once this state is reached, call the  */
    683             /* decodeXAACStream API with same frame to decode!                        */
    684             if (!mIsCodecInitialized) {
    685                 int err_code = configXAACDecoder(inBuffer, inBufferLength);
    686                 if (0 != err_code) {
    687                     ALOGW("configXAACDecoder Failed 2 err_code = %d", err_code);
    688                     mSignalledError = true;
    689                     notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
    690                     return;
    691                 }
    692                 mIsCodecConfigFlushRequired = true;
    693             }
    694 
    695             if (!mSampFreq || !mNumChannels) {
    696                 if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
    697                     ALOGW("Invalid AAC stream");
    698                     ALOGW("mSampFreq %d mNumChannels %d ", mSampFreq, mNumChannels);
    699                     mSignalledError = true;
    700                     notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    701                     return;
    702                 }
    703             } else if ((mSampFreq != prevSampleRate) || (mNumChannels != prevNumChannels)) {
    704                 ALOGV("Reconfiguring decoder: %d->%d Hz, %d->%d channels", prevSampleRate,
    705                       mSampFreq, prevNumChannels, mNumChannels);
    706                 inHeader->nOffset = tempOffset;
    707                 inHeader->nFilledLen = tempFilledLen;
    708                 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
    709                 mOutputPortSettingsChange = AWAITING_DISABLED;
    710                 return;
    711             }
    712 
    713             signed int bytesConsumed = 0;
    714             int errorCode = 0;
    715             if (mIsCodecInitialized) {
    716                 errorCode =
    717                     decodeXAACStream(inBuffer, inBufferLength, &bytesConsumed, &numOutBytes);
    718             } else {
    719                 ALOGW("Assumption that first frame after header initializes decoder failed!");
    720             }
    721             inHeader->nFilledLen -= bytesConsumed;
    722             inHeader->nOffset += bytesConsumed;
    723 
    724             if (inHeader->nFilledLen != 0) {
    725                 ALOGE("All data not consumed");
    726             }
    727 
    728             /* In case of error, decoder would have given out empty buffer */
    729             if ((0 != errorCode) && (0 == numOutBytes) && mIsCodecInitialized) {
    730                 numOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels;
    731             }
    732             numLoops++;
    733 
    734             if (0 == bytesConsumed) {
    735                 ALOGW("bytesConsumed is zero");
    736             }
    737 
    738             if (errorCode) {
    739                 /* Clear buffer for output buffer is done inside XAAC codec */
    740                 /* TODO - Check if below memset is on top of reset inside codec */
    741                 memset(mOutputBuffer, 0, numOutBytes);  // TODO: check for overflow, ASAN
    742                 // Discard input buffer.
    743                 inHeader->nFilledLen = 0;
    744                 // fall through
    745             }
    746 
    747             if (inHeader->nFilledLen == 0) {
    748                 inInfo->mOwnedByUs = false;
    749                 mInputBufferCount++;
    750                 inQueue.erase(inQueue.begin());
    751                 mLastInHeader = NULL;
    752                 inInfo = NULL;
    753                 notifyEmptyBufferDone(inHeader);
    754                 inHeader = NULL;
    755             } else {
    756                 ALOGV("inHeader->nFilledLen = %d", inHeader->nFilledLen);
    757             }
    758 
    759             if (!outQueue.empty() && numOutBytes) {
    760                 BufferInfo* outInfo = *outQueue.begin();
    761                 OMX_BUFFERHEADERTYPE* outHeader = outInfo->mHeader;
    762 
    763                 if (outHeader->nOffset != 0) {
    764                     ALOGE("outHeader->nOffset != 0 is not handled");
    765                     mSignalledError = true;
    766                     notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    767                     return;
    768                 }
    769 
    770                 signed short* outBuffer =
    771                     reinterpret_cast<signed short*>(outHeader->pBuffer + outHeader->nOffset);
    772                 int samplesize = mNumChannels * sizeof(int16_t);
    773                 if (outHeader->nOffset + mOutputFrameLength * samplesize > outHeader->nAllocLen) {
    774                     ALOGE("buffer overflow");
    775                     mSignalledError = true;
    776                     notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    777                     return;
    778                 }
    779                 memcpy(outBuffer, mOutputBuffer, numOutBytes);
    780                 outHeader->nFilledLen = numOutBytes;
    781 
    782                 if (mEndOfInput && !outQueue.empty()) {
    783                     outHeader->nFlags = OMX_BUFFERFLAG_EOS;
    784                     mEndOfOutput = true;
    785                 } else {
    786                     outHeader->nFlags = 0;
    787                 }
    788                 outHeader->nTimeStamp = mCurrentTimestamp;
    789                 mPrevTimestamp = mCurrentTimestamp;
    790 
    791                 mOutputBufferCount++;
    792                 outInfo->mOwnedByUs = false;
    793                 outQueue.erase(outQueue.begin());
    794                 outInfo = NULL;
    795                 notifyFillBufferDone(outHeader);
    796                 outHeader = NULL;
    797             }
    798         }
    799 
    800         if (mEndOfInput) {
    801             if (!outQueue.empty()) {
    802                 if (!mEndOfOutput) {
    803                     ALOGV(" empty block signaling EOS");
    804                     // send partial or empty block signaling EOS
    805                     mEndOfOutput = true;
    806                     BufferInfo* outInfo = *outQueue.begin();
    807                     OMX_BUFFERHEADERTYPE* outHeader = outInfo->mHeader;
    808 
    809                     outHeader->nFilledLen = 0;
    810                     outHeader->nFlags = OMX_BUFFERFLAG_EOS;
    811                     outHeader->nTimeStamp = mPrevTimestamp;
    812 
    813                     mOutputBufferCount++;
    814                     outInfo->mOwnedByUs = false;
    815                     outQueue.erase(outQueue.begin());
    816                     outInfo = NULL;
    817                     notifyFillBufferDone(outHeader);
    818                     outHeader = NULL;
    819                 }
    820                 break;  // if outQueue not empty but no more output
    821             }
    822         }
    823     }
    824 }
    825 
    826 void SoftXAAC::onPortFlushCompleted(OMX_U32 portIndex) {
    827     if (portIndex == 0) {
    828         // Make sure that the next buffer output does not still
    829         // depend on fragments from the last one decoded.
    830         // drain all existing data
    831         if (mIsCodecInitialized) {
    832             IA_ERRORCODE err_code = configflushDecode();
    833             if (err_code != IA_NO_ERROR) {
    834                 ALOGE("Error in configflushDecode: Error %d", err_code);
    835             }
    836         }
    837         drainDecoder();
    838         mLastInHeader = NULL;
    839         mEndOfInput = false;
    840     } else {
    841         mEndOfOutput = false;
    842     }
    843 }
    844 
    845 int SoftXAAC::configflushDecode() {
    846     IA_ERRORCODE err_code;
    847     UWORD32 ui_init_done;
    848     uint32_t inBufferLength = 8203;
    849 
    850     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_FLUSH_MEM, NULL);
    851     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_FLUSH_MEM");
    852 
    853     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
    854     RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
    855 
    856     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_FLUSH_MEM, NULL);
    857     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_FLUSH_MEM");
    858 
    859     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_DONE_QUERY,
    860                                 &ui_init_done);
    861     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_DONE_QUERY");
    862 
    863     if (ui_init_done) {
    864         err_code = getXAACStreamInfo();
    865         RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
    866 
    867         ALOGV(
    868             "Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz "
    869             "%d\nchannelMask %d\noutputFrameLength %d",
    870             mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
    871         if (mNumChannels > MAX_CHANNEL_COUNT) {
    872             ALOGE(" No of channels are more than max channels\n");
    873             mIsCodecInitialized = false;
    874         } else
    875             mIsCodecInitialized = true;
    876     }
    877     return err_code;
    878 }
    879 int SoftXAAC::drainDecoder() {
    880     return 0;
    881 }
    882 
    883 void SoftXAAC::onReset() {
    884     drainDecoder();
    885 
    886     // reset the "configured" state
    887     mInputBufferCount = 0;
    888     mOutputBufferCount = 0;
    889     mEndOfInput = false;
    890     mEndOfOutput = false;
    891     mLastInHeader = NULL;
    892 
    893     mSignalledError = false;
    894     mOutputPortSettingsChange = NONE;
    895 }
    896 
    897 void SoftXAAC::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
    898     if (portIndex != 1) {
    899         return;
    900     }
    901 
    902     switch (mOutputPortSettingsChange) {
    903         case NONE:
    904             break;
    905 
    906         case AWAITING_DISABLED: {
    907             CHECK(!enabled);
    908             mOutputPortSettingsChange = AWAITING_ENABLED;
    909             break;
    910         }
    911 
    912         default: {
    913             CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
    914             CHECK(enabled);
    915             mOutputPortSettingsChange = NONE;
    916             break;
    917         }
    918     }
    919 }
    920 
    921 int SoftXAAC::initXAACDecoder() {
    922     LOOPIDX i;
    923 
    924     /* Error code */
    925     IA_ERRORCODE err_code = IA_NO_ERROR;
    926 
    927     /* First part                                        */
    928     /* Error Handler Init                                */
    929     /* Get Library Name, Library Version and API Version */
    930     /* Initialize API structure + Default config set     */
    931     /* Set config params from user                       */
    932     /* Initialize memory tables                          */
    933     /* Get memory information and allocate memory        */
    934 
    935     /* Memory variables */
    936     UWORD32 ui_proc_mem_tabs_size;
    937     /* API size */
    938     UWORD32 pui_api_size;
    939 
    940     mInputBufferSize = 0;
    941     mInputBuffer = 0;
    942     mOutputBuffer = 0;
    943     mMallocCount = 0;
    944 
    945     /* Process struct initing end */
    946     /* ******************************************************************/
    947     /* Initialize API structure and set config params to default        */
    948     /* ******************************************************************/
    949 
    950     /* Get the API size */
    951     err_code = ixheaacd_dec_api(NULL, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
    952     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
    953 
    954     if (mMallocCount == MAX_MEM_ALLOCS) {
    955         ALOGE("mMemoryArray is full");
    956         return IA_FATAL_ERROR;
    957     }
    958 
    959     /* Allocate memory for API */
    960     mMemoryArray[mMallocCount] = memalign(4, pui_api_size);
    961     if (mMemoryArray[mMallocCount] == NULL) {
    962         ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
    963         return IA_FATAL_ERROR;
    964     }
    965     /* Set API object with the memory allocated */
    966     mXheaacCodecHandle = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
    967     mMallocCount++;
    968 
    969     /* Set the config params to default values */
    970     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
    971                                 IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, NULL);
    972     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
    973 #ifdef ENABLE_MPEG_D_DRC
    974     /* Get the API size */
    975     err_code = ia_drc_dec_api(NULL, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
    976 
    977     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
    978 
    979     if (mMallocCount == MAX_MEM_ALLOCS) {
    980         ALOGE("mMemoryArray is full");
    981         return IA_FATAL_ERROR;
    982     }
    983 
    984     /* Allocate memory for API */
    985     mMemoryArray[mMallocCount] = memalign(4, pui_api_size);
    986 
    987     if (mMemoryArray[mMallocCount] == NULL) {
    988         ALOGE("malloc for drc api structure Failed");
    989         return IA_FATAL_ERROR;
    990     }
    991     memset(mMemoryArray[mMallocCount], 0, pui_api_size);
    992 
    993     /* Set API object with the memory allocated */
    994     mMpegDDrcHandle = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
    995     mMallocCount++;
    996 
    997     /* Set the config params to default values */
    998     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
    999                               IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, NULL);
   1000 
   1001     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
   1002 #endif
   1003 
   1004     /* ******************************************************************/
   1005     /* Set config parameters                                            */
   1006     /* ******************************************************************/
   1007     UWORD32 ui_mp4_flag = 1;
   1008     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1009                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4, &ui_mp4_flag);
   1010     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4");
   1011 
   1012     /* ******************************************************************/
   1013     /* Initialize Memory info tables                                    */
   1014     /* ******************************************************************/
   1015 
   1016     /* Get memory info tables size */
   1017     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0,
   1018                                 &ui_proc_mem_tabs_size);
   1019     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
   1020 
   1021     if (mMallocCount == MAX_MEM_ALLOCS) {
   1022         ALOGE("mMemoryArray is full");
   1023         return IA_FATAL_ERROR;
   1024     }
   1025 
   1026     mMemoryArray[mMallocCount] = memalign(4, ui_proc_mem_tabs_size);
   1027     if (mMemoryArray[mMallocCount] == NULL) {
   1028         ALOGE("Malloc for size (ui_proc_mem_tabs_size + 4) = %d failed!",
   1029               ui_proc_mem_tabs_size + 4);
   1030         return IA_FATAL_ERROR;
   1031     }
   1032     mMallocCount++;
   1033     /* Set pointer for process memory tables    */
   1034     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
   1035                                 (pVOID)((WORD8*)mMemoryArray[mMallocCount - 1]));
   1036     RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
   1037 
   1038 
   1039     /* initialize the API, post config, fill memory tables  */
   1040     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
   1041                                 IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, NULL);
   1042     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
   1043 
   1044     /* ******************************************************************/
   1045     /* Allocate Memory with info from library                           */
   1046     /* ******************************************************************/
   1047     /* There are four different types of memories, that needs to be allocated */
   1048     /* persistent,scratch,input and output */
   1049     for (i = 0; i < 4; i++) {
   1050         int ui_size = 0, ui_alignment = 0, ui_type = 0;
   1051         pVOID pv_alloc_ptr;
   1052 
   1053         /* Get memory size */
   1054         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
   1055         RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
   1056 
   1057         /* Get memory alignment */
   1058         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i,
   1059                                     &ui_alignment);
   1060         RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
   1061 
   1062         /* Get memory type */
   1063         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
   1064         RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
   1065 
   1066         if (mMallocCount == MAX_MEM_ALLOCS) {
   1067             ALOGE("mMemoryArray is full");
   1068             return IA_FATAL_ERROR;
   1069         }
   1070         mMemoryArray[mMallocCount] = memalign(ui_alignment, ui_size);
   1071         if (mMemoryArray[mMallocCount] == NULL) {
   1072             ALOGE("Malloc for size (ui_size + ui_alignment) = %d failed!", ui_size + ui_alignment);
   1073             return IA_FATAL_ERROR;
   1074         }
   1075         pv_alloc_ptr = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
   1076         mMallocCount++;
   1077 
   1078         /* Set the buffer pointer */
   1079         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
   1080         RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
   1081         if (ui_type == IA_MEMTYPE_INPUT) {
   1082             mInputBuffer = (pWORD8)pv_alloc_ptr;
   1083             mInputBufferSize = ui_size;
   1084         }
   1085 
   1086         if (ui_type == IA_MEMTYPE_OUTPUT) {
   1087             mOutputBuffer = (pWORD8)pv_alloc_ptr;
   1088         }
   1089     }
   1090     /* End first part */
   1091 
   1092     return IA_NO_ERROR;
   1093 }
   1094 
   1095 int SoftXAAC::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
   1096     UWORD32 ui_init_done;
   1097     int32_t i_bytes_consumed;
   1098 
   1099     if (mInputBufferSize < inBufferLength) {
   1100         ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize,
   1101               inBufferLength);
   1102         return false;
   1103     }
   1104 
   1105     /* Copy the buffer passed by Android plugin to codec input buffer */
   1106     memcpy(mInputBuffer, inBuffer, inBufferLength);
   1107 
   1108     /* Set number of bytes to be processed */
   1109     IA_ERRORCODE err_code =
   1110         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
   1111     RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
   1112 
   1113     if (mIsCodecConfigFlushRequired) {
   1114         /* If codec is already initialized, then GA header is passed again */
   1115         /* Need to call the Flush API instead of INIT_PROCESS */
   1116         mIsCodecInitialized = false; /* Codec needs to be Reinitialized after flush */
   1117         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_GA_HDR, NULL);
   1118         RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_GA_HDR");
   1119     } else {
   1120         /* Initialize the process */
   1121         err_code =
   1122             ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_PROCESS, NULL);
   1123         RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS");
   1124     }
   1125 
   1126     /* Checking for end of initialization */
   1127     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_DONE_QUERY,
   1128                                 &ui_init_done);
   1129     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_DONE_QUERY");
   1130 
   1131     /* How much buffer is used in input buffers */
   1132     err_code =
   1133         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CURIDX_INPUT_BUF, 0, &i_bytes_consumed);
   1134     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_CURIDX_INPUT_BUF");
   1135 
   1136     if (ui_init_done) {
   1137         err_code = getXAACStreamInfo();
   1138         RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
   1139 
   1140         ALOGI(
   1141             "Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz "
   1142             "%d\nchannelMask %d\noutputFrameLength %d",
   1143             mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
   1144         mIsCodecInitialized = true;
   1145 
   1146 #ifdef ENABLE_MPEG_D_DRC
   1147         err_code = configMPEGDDrc();
   1148         RETURN_IF_FATAL(err_code, "configMPEGDDrc");
   1149 #endif
   1150     }
   1151 
   1152     return IA_NO_ERROR;
   1153 }
   1154 int SoftXAAC::configMPEGDDrc() {
   1155     IA_ERRORCODE err_code = IA_NO_ERROR;
   1156     int i_effect_type;
   1157     int i_loud_norm;
   1158     int i_target_loudness;
   1159     unsigned int i_sbr_mode;
   1160     int n_mems;
   1161     int i;
   1162 
   1163 #ifdef ENABLE_MPEG_D_DRC
   1164     {
   1165         /* Sampling Frequency */
   1166         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1167                                   IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
   1168         RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ");
   1169         /* Total Number of Channels */
   1170         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1171                                   IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
   1172         RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
   1173 
   1174         /* PCM word size  */
   1175         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1176                                   IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
   1177         RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ");
   1178 
   1179         /*Set Effect Type*/
   1180 
   1181         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1182                                     IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, &i_effect_type);
   1183         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
   1184 
   1185         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1186                                   IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
   1187         RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
   1188 
   1189         /*Set target loudness */
   1190         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1191                                     IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS,
   1192                                     &i_target_loudness);
   1193         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
   1194 
   1195         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1196                                   IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
   1197         RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
   1198 
   1199         /*Set loud_norm_flag*/
   1200         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1201                                     IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, &i_loud_norm);
   1202         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
   1203 
   1204         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1205                                   IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
   1206         RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
   1207 
   1208         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1209                                     IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode);
   1210         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
   1211 
   1212         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1213                                   IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, NULL);
   1214 
   1215         RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
   1216 
   1217         for (i = 0; i < (WORD32)2; i++) {
   1218             WORD32 ui_size, ui_alignment, ui_type;
   1219             pVOID pv_alloc_ptr;
   1220 
   1221             /* Get memory size */
   1222             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
   1223 
   1224             RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
   1225 
   1226             /* Get memory alignment */
   1227             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i,
   1228                                       &ui_alignment);
   1229 
   1230             RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
   1231 
   1232             /* Get memory type */
   1233             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
   1234             RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
   1235             if (mMallocCount == MAX_MEM_ALLOCS) {
   1236                 ALOGE("mMemoryArray is full");
   1237                 return IA_FATAL_ERROR;
   1238             }
   1239 
   1240             mMemoryArray[mMallocCount] = memalign(4, ui_size);
   1241             if (mMemoryArray[mMallocCount] == NULL) {
   1242                 ALOGE(" Cannot create requested memory  %d", ui_size);
   1243                 return IA_FATAL_ERROR;
   1244             }
   1245             pv_alloc_ptr = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
   1246             mMallocCount++;
   1247 
   1248             /* Set the buffer pointer */
   1249             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
   1250 
   1251             RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
   1252         }
   1253         {
   1254             WORD32 ui_size;
   1255             ui_size = 8192 * 2;
   1256             if (mMallocCount == MAX_MEM_ALLOCS) {
   1257                 ALOGE("mMemoryArray is full");
   1258                 return IA_FATAL_ERROR;
   1259             }
   1260 
   1261             mMemoryArray[mMallocCount] = memalign(4, ui_size);
   1262             if (mMemoryArray[mMallocCount] == NULL) {
   1263                 ALOGE(" Cannot create requested memory  %d", ui_size);
   1264                 return IA_FATAL_ERROR;
   1265             }
   1266 
   1267             mDrcInBuf = (int8_t*)mMemoryArray[mMallocCount];
   1268             mMallocCount++;
   1269             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2,
   1270                                       /*mOutputBuffer*/ mDrcInBuf);
   1271             RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
   1272 
   1273             if (mMallocCount == MAX_MEM_ALLOCS) {
   1274                 ALOGE("mMemoryArray is full");
   1275                 return IA_FATAL_ERROR;
   1276             }
   1277             mMemoryArray[mMallocCount] = memalign(4, ui_size);
   1278             if (mMemoryArray[mMallocCount] == NULL) {
   1279                 ALOGE(" Cannot create requested memory  %d", ui_size);
   1280                 return IA_FATAL_ERROR;
   1281             }
   1282 
   1283             mDrcOutBuf = (int8_t*)mMemoryArray[mMallocCount];
   1284             mMallocCount++;
   1285             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3,
   1286                                       /*mOutputBuffer*/ mDrcOutBuf);
   1287             RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
   1288         }
   1289         /* DRC buffers
   1290             buf[0] - contains extension element pay load loudness related
   1291             buf[1] - contains extension element pay load*/
   1292         {
   1293             VOID* p_array[2][16];
   1294             WORD32 ii;
   1295             WORD32 buf_sizes[2][16];
   1296             WORD32 num_elements;
   1297             WORD32 num_config_ext;
   1298             WORD32 bit_str_fmt = 1;
   1299 
   1300             WORD32 uo_num_chan;
   1301 
   1302             memset(buf_sizes, 0, 32 * sizeof(WORD32));
   1303 
   1304             err_code =
   1305                 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1306                                  IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES, &buf_sizes[0][0]);
   1307             RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES");
   1308 
   1309             err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1310                                         IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR, &p_array);
   1311             RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR");
   1312 
   1313             err_code =
   1314                 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_SET_BUFF_PTR, 0);
   1315             RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_SET_BUFF_PTR");
   1316 
   1317             err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1318                                         IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE, &num_elements);
   1319             RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE");
   1320 
   1321             err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1322                                         IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT, &num_config_ext);
   1323             RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT");
   1324 
   1325             for (ii = 0; ii < num_config_ext; ii++) {
   1326                 /*copy loudness bitstream*/
   1327                 if (buf_sizes[0][ii] > 0) {
   1328                     memcpy(mDrcInBuf, p_array[0][ii], buf_sizes[0][ii]);
   1329 
   1330                     /*Set bitstream_split_format */
   1331                     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1332                                               IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
   1333                     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1334 
   1335                     /* Set number of bytes to be processed */
   1336                     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IL_BS, 0,
   1337                                               &buf_sizes[0][ii]);
   1338                     RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IL_BS");
   1339 
   1340                     /* Execute process */
   1341                     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1342                                               IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF, NULL);
   1343                     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF");
   1344 
   1345                     mDRCFlag = 1;
   1346                 }
   1347             }
   1348 
   1349             for (ii = 0; ii < num_elements; ii++) {
   1350                 /*copy config bitstream*/
   1351                 if (buf_sizes[1][ii] > 0) {
   1352                     memcpy(mDrcInBuf, p_array[1][ii], buf_sizes[1][ii]);
   1353                     /* Set number of bytes to be processed */
   1354 
   1355                     /*Set bitstream_split_format */
   1356                     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1357                                               IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
   1358                     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1359 
   1360                     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IC_BS, 0,
   1361                                               &buf_sizes[1][ii]);
   1362                     RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IC_BS");
   1363 
   1364                     /* Execute process */
   1365                     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1366                                               IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF, NULL);
   1367 
   1368                     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF");
   1369 
   1370                     mDRCFlag = 1;
   1371                 }
   1372             }
   1373 
   1374             if (mDRCFlag == 1) {
   1375                 mMpegDDRCPresent = 1;
   1376             } else {
   1377                 mMpegDDRCPresent = 0;
   1378             }
   1379 
   1380             /*Read interface buffer config file bitstream*/
   1381             if (mMpegDDRCPresent == 1) {
   1382                 WORD32 interface_is_present = 1;
   1383                 WORD32 frame_length;
   1384 
   1385                 if (i_sbr_mode != 0) {
   1386                     if (i_sbr_mode == 1) {
   1387                         frame_length = 2048;
   1388                     } else if (i_sbr_mode == 3) {
   1389                         frame_length = 4096;
   1390                     } else {
   1391                         frame_length = 1024;
   1392                     }
   1393                 } else {
   1394                     frame_length = 4096;
   1395                 }
   1396 
   1397                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1398                                           IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE, &frame_length);
   1399                 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE");
   1400 
   1401                 err_code =
   1402                     ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1403                                    IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT, &interface_is_present);
   1404                 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT");
   1405 
   1406                 /* Execute process */
   1407                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1408                                           IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF, NULL);
   1409                 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF");
   1410 
   1411                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1412                                           IA_CMD_TYPE_INIT_PROCESS, NULL);
   1413                 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS");
   1414 
   1415                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1416                                           IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &uo_num_chan);
   1417                 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
   1418             }
   1419         }
   1420     }
   1421 #endif
   1422 
   1423     return err_code;
   1424 }
   1425 int SoftXAAC::decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength, int32_t* bytesConsumed,
   1426                                int32_t* outBytes) {
   1427     if (mInputBufferSize < inBufferLength) {
   1428         ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize,
   1429               inBufferLength);
   1430         return -1;
   1431     }
   1432 
   1433     /* Copy the buffer passed by Android plugin to codec input buffer */
   1434     memcpy(mInputBuffer, inBuffer, inBufferLength);
   1435 
   1436     /* Set number of bytes to be processed */
   1437     IA_ERRORCODE err_code =
   1438         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
   1439     RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
   1440 
   1441     /* Execute process */
   1442     err_code =
   1443         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DO_EXECUTE, NULL);
   1444     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
   1445 
   1446     UWORD32 ui_exec_done;
   1447     /* Checking for end of processing */
   1448     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DONE_QUERY,
   1449                                 &ui_exec_done);
   1450     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DONE_QUERY");
   1451 
   1452 #ifdef ENABLE_MPEG_D_DRC
   1453     {
   1454         if (ui_exec_done != 1) {
   1455             VOID* p_array;        // ITTIAM:buffer to handle gain payload
   1456             WORD32 buf_size = 0;  // ITTIAM:gain payload length
   1457             WORD32 bit_str_fmt = 1;
   1458             WORD32 gain_stream_flag = 1;
   1459 
   1460             err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1461                                         IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN, &buf_size);
   1462             RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN");
   1463 
   1464             err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1465                                         IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF, &p_array);
   1466             RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF");
   1467 
   1468             if (buf_size > 0) {
   1469                 /*Set bitstream_split_format */
   1470                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1471                                           IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
   1472                 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1473 
   1474                 memcpy(mDrcInBuf, p_array, buf_size);
   1475                 /* Set number of bytes to be processed */
   1476                 err_code =
   1477                     ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_BS, 0, &buf_size);
   1478                 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1479 
   1480                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1481                                           IA_DRC_DEC_CONFIG_GAIN_STREAM_FLAG, &gain_stream_flag);
   1482                 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1483 
   1484                 /* Execute process */
   1485                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1486                                           IA_CMD_TYPE_INIT_CPY_BSF_BUFF, NULL);
   1487                 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1488 
   1489                 mMpegDDRCPresent = 1;
   1490             }
   1491         }
   1492     }
   1493 #endif
   1494     /* How much buffer is used in input buffers */
   1495     err_code =
   1496         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CURIDX_INPUT_BUF, 0, bytesConsumed);
   1497     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_CURIDX_INPUT_BUF");
   1498 
   1499     /* Get the output bytes */
   1500     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_OUTPUT_BYTES, 0, outBytes);
   1501     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_OUTPUT_BYTES");
   1502 #ifdef ENABLE_MPEG_D_DRC
   1503 
   1504     if (mMpegDDRCPresent == 1) {
   1505         memcpy(mDrcInBuf, mOutputBuffer, *outBytes);
   1506         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES, 0, outBytes);
   1507         RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
   1508 
   1509         err_code =
   1510             ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DO_EXECUTE, NULL);
   1511         RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
   1512 
   1513         memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
   1514     }
   1515 #endif
   1516     return err_code;
   1517 }
   1518 
   1519 int SoftXAAC::deInitXAACDecoder() {
   1520     ALOGI("deInitXAACDecoder");
   1521 
   1522     /* Tell that the input is over in this buffer */
   1523     IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INPUT_OVER, 0, NULL);
   1524     RETURN_IF_FATAL(err_code, "IA_API_CMD_INPUT_OVER");
   1525 
   1526     for (int i = 0; i < mMallocCount; i++) {
   1527         if (mMemoryArray[i]) free(mMemoryArray[i]);
   1528     }
   1529     mMallocCount = 0;
   1530 
   1531     return err_code;
   1532 }
   1533 
   1534 IA_ERRORCODE SoftXAAC::getXAACStreamInfo() {
   1535     IA_ERRORCODE err_code = IA_NO_ERROR;
   1536 
   1537     /* Sampling frequency */
   1538     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1539                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
   1540     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ");
   1541 
   1542     /* Total Number of Channels */
   1543     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1544                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
   1545     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS");
   1546 
   1547     /* PCM word size */
   1548     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1549                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
   1550     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ");
   1551 
   1552     /* channel mask to tell the arrangement of channels in bit stream */
   1553     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1554                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK, &mChannelMask);
   1555     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK");
   1556 
   1557     /* Channel mode to tell MONO/STEREO/DUAL-MONO/NONE_OF_THESE */
   1558     UWORD32 ui_channel_mode;
   1559     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1560                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE, &ui_channel_mode);
   1561     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE");
   1562     if (ui_channel_mode == 0)
   1563         ALOGV("Channel Mode: MONO_OR_PS\n");
   1564     else if (ui_channel_mode == 1)
   1565         ALOGV("Channel Mode: STEREO\n");
   1566     else if (ui_channel_mode == 2)
   1567         ALOGV("Channel Mode: DUAL-MONO\n");
   1568     else
   1569         ALOGV("Channel Mode: NONE_OF_THESE or MULTICHANNEL\n");
   1570 
   1571     /* Channel mode to tell SBR PRESENT/NOT_PRESENT */
   1572     UWORD32 ui_sbr_mode;
   1573     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1574                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &ui_sbr_mode);
   1575     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
   1576     if (ui_sbr_mode == 0)
   1577         ALOGV("SBR Mode: NOT_PRESENT\n");
   1578     else if (ui_sbr_mode == 1)
   1579         ALOGV("SBR Mode: PRESENT\n");
   1580     else
   1581         ALOGV("SBR Mode: ILLEGAL\n");
   1582 
   1583     /* mOutputFrameLength = 1024 * (1 + SBR_MODE) for AAC */
   1584     /* For USAC it could be 1024 * 3 , support to query  */
   1585     /* not yet added in codec                            */
   1586     mOutputFrameLength = 1024 * (1 + ui_sbr_mode);
   1587 
   1588     ALOGI("mOutputFrameLength %d ui_sbr_mode %d", mOutputFrameLength, ui_sbr_mode);
   1589 
   1590     return IA_NO_ERROR;
   1591 }
   1592 
   1593 IA_ERRORCODE SoftXAAC::setXAACDRCInfo(int32_t drcCut, int32_t drcBoost, int32_t drcRefLevel,
   1594                                       int32_t drcHeavyCompression
   1595 #ifdef ENABLE_MPEG_D_DRC
   1596                                       ,
   1597                                       int32_t drEffectType
   1598 #endif
   1599 ) {
   1600     IA_ERRORCODE err_code = IA_NO_ERROR;
   1601 
   1602     int32_t ui_drc_enable = 1;
   1603     int32_t i_effect_type, i_target_loudness, i_loud_norm;
   1604     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1605                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE, &ui_drc_enable);
   1606     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE");
   1607     if (drcCut != -1) {
   1608         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1609                                     IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &drcCut);
   1610         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
   1611     }
   1612 
   1613     if (drcBoost != -1) {
   1614         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1615                                     IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &drcBoost);
   1616         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
   1617     }
   1618 
   1619     if (drcRefLevel != -1) {
   1620         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1621                                     IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, &drcRefLevel);
   1622         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
   1623     }
   1624 #ifdef ENABLE_MPEG_D_DRC
   1625     if (drcRefLevel != -1) {
   1626         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1627                                     IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &drcRefLevel);
   1628         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
   1629     }
   1630 #endif
   1631     if (drcHeavyCompression != -1) {
   1632         err_code =
   1633             ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1634                              IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP, &drcHeavyCompression);
   1635         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
   1636     }
   1637 
   1638 #ifdef ENABLE_MPEG_D_DRC
   1639     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1640                                 IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &drEffectType);
   1641     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
   1642 #endif
   1643 
   1644 #ifdef ENABLE_MPEG_D_DRC
   1645     /*Set Effect Type*/
   1646     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1647                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, &i_effect_type);
   1648     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
   1649 
   1650     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1651                               IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
   1652 
   1653     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
   1654 
   1655     /*Set target loudness */
   1656     err_code =
   1657         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1658                          IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
   1659     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
   1660 
   1661     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1662                               IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
   1663     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
   1664 
   1665     /*Set loud_norm_flag*/
   1666     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1667                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, &i_loud_norm);
   1668     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
   1669 
   1670     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1671                               IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
   1672 
   1673     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
   1674 
   1675 #endif
   1676 
   1677     return IA_NO_ERROR;
   1678 }
   1679 
   1680 }  // namespace android
   1681 
   1682 android::SoftOMXComponent* createSoftOMXComponent(const char* name,
   1683                                                   const OMX_CALLBACKTYPE* callbacks,
   1684                                                   OMX_PTR appData, OMX_COMPONENTTYPE** component) {
   1685     ALOGI("createSoftOMXComponent for SoftXAACDEC");
   1686     return new android::SoftXAAC(name, callbacks, appData, component);
   1687 }
   1688