Home | History | Annotate | Download | only in xaac
      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 "C2SoftXaacDec"
     19 #include <log/log.h>
     20 
     21 #include <inttypes.h>
     22 
     23 #include <cutils/properties.h>
     24 #include <media/stagefright/foundation/ADebug.h>
     25 #include <media/stagefright/foundation/MediaDefs.h>
     26 #include <media/stagefright/foundation/hexdump.h>
     27 
     28 #include <C2PlatformSupport.h>
     29 #include <SimpleC2Interface.h>
     30 
     31 #include "C2SoftXaacDec.h"
     32 
     33 #define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0   /* 64*-0.25dB = -16 dB below full scale for mobile conf */
     34 #define DRC_DEFAULT_MOBILE_DRC_CUT   1.0  /* maximum compression of dynamic range for mobile conf */
     35 #define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */
     36 #define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY   /* switch for heavy compression for mobile conf */
     37 #define DRC_DEFAULT_MOBILE_DRC_EFFECT 3  /* MPEG-D DRC effect type; 3 => Limited playback range */
     38 #define DRC_DEFAULT_MOBILE_ENC_LEVEL (0.25) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
     39 #define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
     40 // names of properties that can be used to override the default DRC settings
     41 #define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
     42 #define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
     43 #define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
     44 #define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
     45 #define PROP_DRC_OVERRIDE_ENC_LEVEL  "aac_drc_enc_target_level"
     46 #define PROP_DRC_OVERRIDE_EFFECT_TYPE "ro.aac_drc_effect_type"
     47 
     48 #define RETURN_IF_FATAL(retval, str)                       \
     49     if (retval & IA_FATAL_ERROR) {                         \
     50         ALOGE("Error in %s: Returned: %d", str, retval);   \
     51         return retval;                                     \
     52     } else if (retval != IA_NO_ERROR) {                    \
     53         ALOGW("Warning in %s: Returned: %d", str, retval); \
     54     }
     55 
     56 
     57 namespace android {
     58 
     59 namespace {
     60 
     61 constexpr char COMPONENT_NAME[] = "c2.android.xaac.decoder";
     62 
     63 }  // namespace
     64 
     65 class C2SoftXaacDec::IntfImpl : public SimpleInterface<void>::BaseParams {
     66 public:
     67     explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
     68         : SimpleInterface<void>::BaseParams(
     69                 helper,
     70                 COMPONENT_NAME,
     71                 C2Component::KIND_DECODER,
     72                 C2Component::DOMAIN_AUDIO,
     73                 MEDIA_MIMETYPE_AUDIO_AAC) {
     74         noPrivateBuffers();
     75         noInputReferences();
     76         noOutputReferences();
     77         noInputLatency();
     78         noTimeStretch();
     79 
     80         addParameter(
     81                 DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
     82                 .withConstValue(new C2ComponentAttributesSetting(
     83                     C2Component::ATTRIB_IS_TEMPORAL))
     84                 .build());
     85 
     86         addParameter(
     87                 DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
     88                 .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
     89                 .withFields({C2F(mSampleRate, value).oneOf({
     90                     7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
     91                 })})
     92                 .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
     93                 .build());
     94 
     95         addParameter(
     96                 DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
     97                 .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
     98                 .withFields({C2F(mChannelCount, value).inRange(1, 8)})
     99                 .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
    100                 .build());
    101 
    102         addParameter(
    103                 DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
    104                 .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
    105                 .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
    106                 .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
    107                 .build());
    108 
    109         addParameter(
    110                 DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
    111                 .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
    112                 .build());
    113 
    114         addParameter(
    115                 DefineParam(mAacFormat, C2_PARAMKEY_AAC_PACKAGING)
    116                 .withDefault(new C2StreamAacFormatInfo::input(0u, C2Config::AAC_PACKAGING_RAW))
    117                 .withFields({C2F(mAacFormat, value).oneOf({
    118                     C2Config::AAC_PACKAGING_RAW, C2Config::AAC_PACKAGING_ADTS
    119                 })})
    120                 .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
    121                 .build());
    122 
    123         addParameter(
    124                 DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
    125                 .withDefault(new C2StreamProfileLevelInfo::input(0u,
    126                         C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
    127                 .withFields({
    128                     C2F(mProfileLevel, profile).oneOf({
    129                             C2Config::PROFILE_AAC_LC,
    130                             C2Config::PROFILE_AAC_HE,
    131                             C2Config::PROFILE_AAC_HE_PS,
    132                             C2Config::PROFILE_AAC_LD,
    133                             C2Config::PROFILE_AAC_ELD,
    134                             C2Config::PROFILE_AAC_XHE}),
    135                     C2F(mProfileLevel, level).oneOf({
    136                             C2Config::LEVEL_UNUSED
    137                     })
    138                 })
    139                 .withSetter(ProfileLevelSetter)
    140                 .build());
    141 
    142         addParameter(
    143                 DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
    144                 .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
    145                 .withFields({
    146                     C2F(mDrcCompressMode, value).oneOf({
    147                             C2Config::DRC_COMPRESSION_ODM_DEFAULT,
    148                             C2Config::DRC_COMPRESSION_NONE,
    149                             C2Config::DRC_COMPRESSION_LIGHT,
    150                             C2Config::DRC_COMPRESSION_HEAVY})
    151                 })
    152                 .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
    153                 .build());
    154 
    155         addParameter(
    156                 DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
    157                 .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
    158                 .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
    159                 .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
    160                 .build());
    161 
    162         addParameter(
    163                 DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
    164                 .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
    165                 .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
    166                 .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
    167                 .build());
    168 
    169         addParameter(
    170                 DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
    171                 .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
    172                 .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
    173                 .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
    174                 .build());
    175 
    176         addParameter(
    177                 DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
    178                 .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
    179                 .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
    180                 .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
    181                 .build());
    182 
    183         addParameter(
    184                 DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
    185                 .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
    186                 .withFields({
    187                     C2F(mDrcEffectType, value).oneOf({
    188                             C2Config::DRC_EFFECT_ODM_DEFAULT,
    189                             C2Config::DRC_EFFECT_OFF,
    190                             C2Config::DRC_EFFECT_NONE,
    191                             C2Config::DRC_EFFECT_LATE_NIGHT,
    192                             C2Config::DRC_EFFECT_NOISY_ENVIRONMENT,
    193                             C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
    194                             C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL,
    195                             C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT,
    196                             C2Config::DRC_EFFECT_GENERAL_COMPRESSION})
    197                 })
    198                 .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps)
    199                 .build());
    200     }
    201 
    202     bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; }
    203     uint32_t getBitrate() const { return mBitrate->value; }
    204     static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
    205         (void)mayBlock;
    206         (void)me;  // TODO: validate
    207         return C2R::Ok();
    208     }
    209     int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
    210     int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
    211     int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
    212     int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
    213     int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
    214     int32_t getDrcEffectType() const { return mDrcEffectType->value; }
    215 
    216 private:
    217     std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
    218     std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
    219     std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
    220     std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
    221     std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
    222     std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
    223     std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode;
    224     std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel;
    225     std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel;
    226     std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
    227     std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
    228     std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
    229     // TODO Add : C2StreamAacSbrModeTuning
    230 };
    231 
    232 C2SoftXaacDec::C2SoftXaacDec(
    233         const char* name,
    234         c2_node_id_t id,
    235         const std::shared_ptr<IntfImpl> &intfImpl)
    236     : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
    237         mIntf(intfImpl),
    238         mXheaacCodecHandle(nullptr),
    239         mMpegDDrcHandle(nullptr),
    240         mOutputDrainBuffer(nullptr) {
    241 }
    242 
    243 C2SoftXaacDec::~C2SoftXaacDec() {
    244     onRelease();
    245 }
    246 
    247 c2_status_t C2SoftXaacDec::onInit() {
    248     mOutputFrameLength = 1024;
    249     mInputBuffer = nullptr;
    250     mOutputBuffer = nullptr;
    251     mSampFreq = 0;
    252     mNumChannels = 0;
    253     mPcmWdSz = 0;
    254     mChannelMask = 0;
    255     mNumOutBytes = 0;
    256     mCurFrameIndex = 0;
    257     mCurTimestamp = 0;
    258     mIsCodecInitialized = false;
    259     mIsCodecConfigFlushRequired = false;
    260     mSignalledOutputEos = false;
    261     mSignalledError = false;
    262     mOutputDrainBufferWritePos = 0;
    263     mDRCFlag = 0;
    264     mMpegDDRCPresent = 0;
    265     mMemoryVec.clear();
    266     mDrcMemoryVec.clear();
    267 
    268     IA_ERRORCODE err = initDecoder();
    269     return err == IA_NO_ERROR ? C2_OK : C2_CORRUPTED;
    270 
    271 }
    272 
    273 c2_status_t C2SoftXaacDec::onStop() {
    274     mOutputFrameLength = 1024;
    275     drainDecoder();
    276     // reset the "configured" state
    277     mSampFreq = 0;
    278     mNumChannels = 0;
    279     mPcmWdSz = 0;
    280     mChannelMask = 0;
    281     mNumOutBytes = 0;
    282     mCurFrameIndex = 0;
    283     mCurTimestamp = 0;
    284     mSignalledOutputEos = false;
    285     mSignalledError = false;
    286     mOutputDrainBufferWritePos = 0;
    287     mDRCFlag = 0;
    288     mMpegDDRCPresent = 0;
    289 
    290     return C2_OK;
    291 }
    292 
    293 void C2SoftXaacDec::onReset() {
    294     (void)onStop();
    295 }
    296 
    297 void C2SoftXaacDec::onRelease() {
    298     IA_ERRORCODE errCode = deInitXAACDecoder();
    299     if (IA_NO_ERROR != errCode) ALOGE("deInitXAACDecoder() failed %d", errCode);
    300 
    301     errCode = deInitMPEGDDDrc();
    302     if (IA_NO_ERROR != errCode) ALOGE("deInitMPEGDDDrc() failed %d", errCode);
    303 
    304     if (mOutputDrainBuffer) {
    305         delete[] mOutputDrainBuffer;
    306         mOutputDrainBuffer = nullptr;
    307     }
    308 }
    309 
    310 IA_ERRORCODE C2SoftXaacDec::initDecoder() {
    311     ALOGV("initDecoder()");
    312     IA_ERRORCODE err_code = IA_NO_ERROR;
    313 
    314     err_code = initXAACDecoder();
    315     if (err_code != IA_NO_ERROR) {
    316         ALOGE("initXAACDecoder Failed");
    317         /* Call deInit to free any allocated memory */
    318         deInitXAACDecoder();
    319         return IA_FATAL_ERROR;
    320     }
    321 
    322     if (!mOutputDrainBuffer) {
    323         mOutputDrainBuffer = new (std::nothrow) char[kOutputDrainBufferSize];
    324         if (!mOutputDrainBuffer) return IA_FATAL_ERROR;
    325     }
    326 
    327     err_code = initXAACDrc();
    328     RETURN_IF_FATAL(err_code,  "initXAACDrc");
    329 
    330 
    331     return IA_NO_ERROR;
    332 }
    333 
    334 static void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
    335     uint32_t flags = 0;
    336     if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
    337         flags |= C2FrameData::FLAG_END_OF_STREAM;
    338         ALOGV("signalling eos");
    339     }
    340     work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
    341     work->worklets.front()->output.buffers.clear();
    342     work->worklets.front()->output.ordinal = work->input.ordinal;
    343     work->workletsProcessed = 1u;
    344 }
    345 
    346 void C2SoftXaacDec::finishWork(const std::unique_ptr<C2Work>& work,
    347                             const std::shared_ptr<C2BlockPool>& pool) {
    348     ALOGV("mCurFrameIndex = %" PRIu64, mCurFrameIndex);
    349 
    350     std::shared_ptr<C2LinearBlock> block;
    351     C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
    352     // TODO: error handling, proper usage, etc.
    353     c2_status_t err =
    354         pool->fetchLinearBlock(mOutputDrainBufferWritePos, usage, &block);
    355     if (err != C2_OK) {
    356         ALOGE("fetchLinearBlock failed : err = %d", err);
    357         work->result = C2_NO_MEMORY;
    358         return;
    359     }
    360     C2WriteView wView = block->map().get();
    361     int16_t* outBuffer = reinterpret_cast<int16_t*>(wView.data());
    362     memcpy(outBuffer, mOutputDrainBuffer, mOutputDrainBufferWritePos);
    363     mOutputDrainBufferWritePos = 0;
    364 
    365     auto fillWork = [buffer = createLinearBuffer(block)](
    366         const std::unique_ptr<C2Work>& work) {
    367         uint32_t flags = 0;
    368         if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
    369             flags |= C2FrameData::FLAG_END_OF_STREAM;
    370             ALOGV("signalling eos");
    371         }
    372         work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
    373         work->worklets.front()->output.buffers.clear();
    374         work->worklets.front()->output.buffers.push_back(buffer);
    375         work->worklets.front()->output.ordinal = work->input.ordinal;
    376         work->workletsProcessed = 1u;
    377     };
    378     if (work && work->input.ordinal.frameIndex == c2_cntr64_t(mCurFrameIndex)) {
    379         fillWork(work);
    380     } else {
    381         finish(mCurFrameIndex, fillWork);
    382     }
    383 
    384     ALOGV("out timestamp %" PRIu64 " / %u", mCurTimestamp, block->capacity());
    385 }
    386 
    387 void C2SoftXaacDec::process(const std::unique_ptr<C2Work>& work,
    388                          const std::shared_ptr<C2BlockPool>& pool) {
    389     // Initialize output work
    390     work->result = C2_OK;
    391     work->workletsProcessed = 1u;
    392     work->worklets.front()->output.configUpdate.clear();
    393     work->worklets.front()->output.flags = work->input.flags;
    394 
    395     if (mSignalledError || mSignalledOutputEos) {
    396         work->result = C2_BAD_VALUE;
    397         return;
    398     }
    399     uint8_t* inBuffer = nullptr;
    400     uint32_t inBufferLength = 0;
    401     C2ReadView view = mDummyReadView;
    402     size_t offset = 0u;
    403     size_t size = 0u;
    404     if (!work->input.buffers.empty()) {
    405         view = work->input.buffers[0]->data().linearBlocks().front().map().get();
    406         size = view.capacity();
    407     }
    408     if (size && view.error()) {
    409         ALOGE("read view map failed %d", view.error());
    410         work->result = view.error();
    411         return;
    412     }
    413 
    414     bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
    415     bool codecConfig =
    416         (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
    417     if (codecConfig) {
    418         if (size == 0u) {
    419             ALOGE("empty codec config");
    420             mSignalledError = true;
    421             work->result = C2_CORRUPTED;
    422             return;
    423         }
    424         // const_cast because of libAACdec method signature.
    425         inBuffer = const_cast<uint8_t*>(view.data() + offset);
    426         inBufferLength = size;
    427 
    428         /* GA header configuration sent to Decoder! */
    429         IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
    430         if (IA_NO_ERROR != err_code) {
    431             ALOGE("configXAACDecoder err_code = %d", err_code);
    432             mSignalledError = true;
    433             work->result = C2_CORRUPTED;
    434             return;
    435         }
    436         work->worklets.front()->output.flags = work->input.flags;
    437         work->worklets.front()->output.ordinal = work->input.ordinal;
    438         work->worklets.front()->output.buffers.clear();
    439         return;
    440     }
    441 
    442     mCurFrameIndex = work->input.ordinal.frameIndex.peeku();
    443     mCurTimestamp = work->input.ordinal.timestamp.peeku();
    444     mOutputDrainBufferWritePos = 0;
    445     char* tempOutputDrainBuffer = mOutputDrainBuffer;
    446     while (size > 0u) {
    447         if ((kOutputDrainBufferSize * sizeof(int16_t) -
    448              mOutputDrainBufferWritePos) <
    449             (mOutputFrameLength * sizeof(int16_t) * mNumChannels)) {
    450             ALOGV("skipping decode: not enough space left in DrainBuffer");
    451             break;
    452         }
    453 
    454         ALOGV("inAttribute size = %zu", size);
    455         if (mIntf->isAdts()) {
    456             ALOGV("ADTS");
    457             size_t adtsHeaderSize = 0;
    458             // skip 30 bits, aac_frame_length follows.
    459             // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
    460 
    461             const uint8_t* adtsHeader = view.data() + offset;
    462             bool signalError = false;
    463             if (size < 7) {
    464                 ALOGE("Audio data too short to contain even the ADTS header. "
    465                       "Got %zu bytes.", size);
    466                 hexdump(adtsHeader, size);
    467                 signalError = true;
    468             } else {
    469                 bool protectionAbsent = (adtsHeader[1] & 1);
    470                 unsigned aac_frame_length = ((adtsHeader[3] & 3) << 11) |
    471                                             (adtsHeader[4] << 3) |
    472                                             (adtsHeader[5] >> 5);
    473 
    474                 if (size < aac_frame_length) {
    475                     ALOGE("Not enough audio data for the complete frame. "
    476                           "Got %zu bytes, frame size according to the ADTS "
    477                           "header is %u bytes.", size, aac_frame_length);
    478                     hexdump(adtsHeader, size);
    479                     signalError = true;
    480                 } else {
    481                     adtsHeaderSize = (protectionAbsent ? 7 : 9);
    482                     if (aac_frame_length < adtsHeaderSize) {
    483                         signalError = true;
    484                     } else {
    485                         // const_cast because of libAACdec method signature.
    486                         inBuffer =
    487                             const_cast<uint8_t*>(adtsHeader + adtsHeaderSize);
    488                         inBufferLength = aac_frame_length - adtsHeaderSize;
    489 
    490                         offset += adtsHeaderSize;
    491                         size -= adtsHeaderSize;
    492                     }
    493                 }
    494             }
    495 
    496             if (signalError) {
    497                 mSignalledError = true;
    498                 work->result = C2_CORRUPTED;
    499                 return;
    500             }
    501         } else {
    502             ALOGV("Non ADTS");
    503             // const_cast because of libAACdec method signature.
    504             inBuffer = const_cast<uint8_t*>(view.data() + offset);
    505             inBufferLength = size;
    506         }
    507 
    508         signed int prevSampleRate = mSampFreq;
    509         signed int prevNumChannels = mNumChannels;
    510 
    511         /* XAAC decoder expects first frame to be fed via configXAACDecoder API
    512          * which should initialize the codec. Once this state is reached, call the
    513          * decodeXAACStream API with same frame to decode! */
    514         if (!mIsCodecInitialized) {
    515             IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
    516             if (IA_NO_ERROR != err_code) {
    517                 ALOGE("configXAACDecoder Failed 2 err_code = %d", err_code);
    518                 mSignalledError = true;
    519                 work->result = C2_CORRUPTED;
    520                 return;
    521             }
    522 
    523             if ((mSampFreq != prevSampleRate) ||
    524                 (mNumChannels != prevNumChannels)) {
    525                 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
    526                       prevSampleRate, mSampFreq, prevNumChannels, mNumChannels);
    527 
    528                 C2StreamSampleRateInfo::output sampleRateInfo(0u, mSampFreq);
    529                 C2StreamChannelCountInfo::output channelCountInfo(0u, mNumChannels);
    530                 std::vector<std::unique_ptr<C2SettingResult>> failures;
    531                 c2_status_t err = mIntf->config(
    532                         { &sampleRateInfo, &channelCountInfo },
    533                         C2_MAY_BLOCK,
    534                         &failures);
    535                 if (err == OK) {
    536                     work->worklets.front()->output.configUpdate.push_back(
    537                         C2Param::Copy(sampleRateInfo));
    538                     work->worklets.front()->output.configUpdate.push_back(
    539                         C2Param::Copy(channelCountInfo));
    540                 } else {
    541                     ALOGE("Config Update failed");
    542                     mSignalledError = true;
    543                     work->result = C2_CORRUPTED;
    544                     return;
    545                 }
    546             }
    547         }
    548 
    549         signed int bytesConsumed = 0;
    550         IA_ERRORCODE errorCode = IA_NO_ERROR;
    551         if (mIsCodecInitialized) {
    552             mIsCodecConfigFlushRequired = true;
    553             errorCode = decodeXAACStream(inBuffer, inBufferLength,
    554                                          &bytesConsumed, &mNumOutBytes);
    555         } else if (!mIsCodecConfigFlushRequired) {
    556             ALOGW("Assumption that first frame after header initializes decoder Failed!");
    557             mSignalledError = true;
    558             work->result = C2_CORRUPTED;
    559             return;
    560         }
    561         size -= bytesConsumed;
    562         offset += bytesConsumed;
    563 
    564         if (inBufferLength != (uint32_t)bytesConsumed)
    565             ALOGW("All data not consumed");
    566 
    567         /* In case of error, decoder would have given out empty buffer */
    568         if ((IA_NO_ERROR != errorCode) && (0 == mNumOutBytes) && mIsCodecInitialized)
    569             mNumOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels;
    570 
    571         if (!bytesConsumed) {
    572             ALOGW("bytesConsumed = 0 should never happen");
    573         }
    574 
    575         if ((uint32_t)mNumOutBytes >
    576             mOutputFrameLength * sizeof(int16_t) * mNumChannels) {
    577             ALOGE("mNumOutBytes > mOutputFrameLength * sizeof(int16_t) * mNumChannels, should never happen");
    578             mSignalledError = true;
    579             work->result = C2_CORRUPTED;
    580             return;
    581         }
    582 
    583         if (IA_NO_ERROR != errorCode) {
    584             // TODO: check for overflow, ASAN
    585             memset(mOutputBuffer, 0, mNumOutBytes);
    586 
    587             // Discard input buffer.
    588             size = 0;
    589 
    590             // fall through
    591         }
    592         memcpy(tempOutputDrainBuffer, mOutputBuffer, mNumOutBytes);
    593         tempOutputDrainBuffer += mNumOutBytes;
    594         mOutputDrainBufferWritePos += mNumOutBytes;
    595     }
    596 
    597     if (mOutputDrainBufferWritePos) {
    598         finishWork(work, pool);
    599     } else {
    600         fillEmptyWork(work);
    601     }
    602     if (eos) mSignalledOutputEos = true;
    603 }
    604 
    605 c2_status_t C2SoftXaacDec::drain(uint32_t drainMode,
    606                               const std::shared_ptr<C2BlockPool>& pool) {
    607     (void)pool;
    608     if (drainMode == NO_DRAIN) {
    609         ALOGW("drain with NO_DRAIN: no-op");
    610         return C2_OK;
    611     }
    612     if (drainMode == DRAIN_CHAIN) {
    613         ALOGW("DRAIN_CHAIN not supported");
    614         return C2_OMITTED;
    615     }
    616 
    617     return C2_OK;
    618 }
    619 
    620 IA_ERRORCODE C2SoftXaacDec::configflushDecode() {
    621     IA_ERRORCODE err_code;
    622     uint32_t ui_init_done;
    623     uint32_t inBufferLength = 8203;
    624 
    625     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    626                                 IA_API_CMD_INIT,
    627                                 IA_CMD_TYPE_FLUSH_MEM,
    628                                 nullptr);
    629     RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_FLUSH_MEM");
    630 
    631     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    632                                 IA_API_CMD_SET_INPUT_BYTES,
    633                                 0,
    634                                 &inBufferLength);
    635     RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_INPUT_BYTES");
    636 
    637     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    638                                 IA_API_CMD_INIT,
    639                                 IA_CMD_TYPE_FLUSH_MEM,
    640                                 nullptr);
    641     RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_FLUSH_MEM");
    642 
    643     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    644                                 IA_API_CMD_INIT,
    645                                 IA_CMD_TYPE_INIT_DONE_QUERY,
    646                                 &ui_init_done);
    647     RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_DONE_QUERY");
    648 
    649     if (ui_init_done) {
    650         err_code = getXAACStreamInfo();
    651         RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
    652         ALOGV("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d",
    653                mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
    654         mIsCodecInitialized = true;
    655     }
    656     return IA_NO_ERROR;
    657 }
    658 
    659 c2_status_t C2SoftXaacDec::onFlush_sm() {
    660     if (mIsCodecInitialized) {
    661         IA_ERRORCODE err_code = configflushDecode();
    662         if (err_code != IA_NO_ERROR) {
    663             ALOGE("Error in configflushDecode: Error %d", err_code);
    664         }
    665     }
    666     drainDecoder();
    667     mSignalledOutputEos = false;
    668     mSignalledError = false;
    669 
    670     return C2_OK;
    671 }
    672 
    673 IA_ERRORCODE C2SoftXaacDec::drainDecoder() {
    674     /* Output delay compensation logic should sit here. */
    675     /* Nothing to be done as XAAC decoder does not introduce output buffer delay */
    676 
    677     return 0;
    678 }
    679 
    680 IA_ERRORCODE C2SoftXaacDec::initXAACDecoder() {
    681     /* First part                                        */
    682     /* Error Handler Init                                */
    683     /* Get Library Name, Library Version and API Version */
    684     /* Initialize API structure + Default config set     */
    685     /* Set config params from user                       */
    686     /* Initialize memory tables                          */
    687     /* Get memory information and allocate memory        */
    688 
    689     mInputBufferSize = 0;
    690     mInputBuffer = nullptr;
    691     mOutputBuffer = nullptr;
    692     /* Process struct initing end */
    693 
    694     /* ******************************************************************/
    695     /* Initialize API structure and set config params to default        */
    696     /* ******************************************************************/
    697     /* API size */
    698     uint32_t pui_api_size;
    699     /* Get the API size */
    700     IA_ERRORCODE err_code = ixheaacd_dec_api(nullptr,
    701                                              IA_API_CMD_GET_API_SIZE,
    702                                              0,
    703                                              &pui_api_size);
    704     RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_API_SIZE");
    705 
    706     /* Allocate memory for API */
    707     mXheaacCodecHandle = memalign(4, pui_api_size);
    708     if (!mXheaacCodecHandle) {
    709         ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
    710         return IA_FATAL_ERROR;
    711     }
    712     mMemoryVec.push(mXheaacCodecHandle);
    713 
    714     /* Set the config params to default values */
    715     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    716                                 IA_API_CMD_INIT,
    717                                 IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS,
    718                                 nullptr);
    719     RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
    720 
    721     /* Get the API size */
    722     err_code = ia_drc_dec_api(nullptr, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
    723 
    724     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
    725 
    726     /* Allocate memory for API */
    727     mMpegDDrcHandle = memalign(4, pui_api_size);
    728     if (!mMpegDDrcHandle) {
    729         ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
    730         return IA_FATAL_ERROR;
    731     }
    732     mMemoryVec.push(mMpegDDrcHandle);
    733 
    734     /* Set the config params to default values */
    735     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
    736                               IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, nullptr);
    737 
    738     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
    739 
    740     /* ******************************************************************/
    741     /* Set config parameters                                            */
    742     /* ******************************************************************/
    743     uint32_t ui_mp4_flag = 1;
    744     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    745                                 IA_API_CMD_SET_CONFIG_PARAM,
    746                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4,
    747                                 &ui_mp4_flag);
    748     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4");
    749 
    750     /* ******************************************************************/
    751     /* Initialize Memory info tables                                    */
    752     /* ******************************************************************/
    753     uint32_t ui_proc_mem_tabs_size;
    754     pVOID pv_alloc_ptr;
    755     /* Get memory info tables size */
    756     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    757                                 IA_API_CMD_GET_MEMTABS_SIZE,
    758                                 0,
    759                                 &ui_proc_mem_tabs_size);
    760     RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_MEMTABS_SIZE");
    761 
    762     pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
    763     if (!pv_alloc_ptr) {
    764         ALOGE("Malloc for size (ui_proc_mem_tabs_size + 4) = %d failed!", ui_proc_mem_tabs_size + 4);
    765         return IA_FATAL_ERROR;
    766     }
    767     mMemoryVec.push(pv_alloc_ptr);
    768 
    769     /* Set pointer for process memory tables    */
    770     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    771                                 IA_API_CMD_SET_MEMTABS_PTR,
    772                                 0,
    773                                 pv_alloc_ptr);
    774     RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_MEMTABS_PTR");
    775 
    776     /* initialize the API, post config, fill memory tables  */
    777     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    778                                 IA_API_CMD_INIT,
    779                                 IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS,
    780                                 nullptr);
    781     RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
    782 
    783     /* ******************************************************************/
    784     /* Allocate Memory with info from library                           */
    785     /* ******************************************************************/
    786     /* There are four different types of memories, that needs to be allocated */
    787     /* persistent,scratch,input and output */
    788     for (int i = 0; i < 4; i++) {
    789         int ui_size = 0, ui_alignment = 0, ui_type = 0;
    790 
    791         /* Get memory size */
    792         err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    793                                     IA_API_CMD_GET_MEM_INFO_SIZE,
    794                                     i,
    795                                     &ui_size);
    796         RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_MEM_INFO_SIZE");
    797 
    798         /* Get memory alignment */
    799         err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    800                                     IA_API_CMD_GET_MEM_INFO_ALIGNMENT,
    801                                     i,
    802                                     &ui_alignment);
    803         RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
    804 
    805         /* Get memory type */
    806         err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    807                                     IA_API_CMD_GET_MEM_INFO_TYPE,
    808                                     i,
    809                                     &ui_type);
    810         RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_MEM_INFO_TYPE");
    811 
    812         pv_alloc_ptr = memalign(ui_alignment, ui_size);
    813         if (!pv_alloc_ptr) {
    814             ALOGE("Malloc for size (ui_size + ui_alignment) = %d failed!",
    815                    ui_size + ui_alignment);
    816             return IA_FATAL_ERROR;
    817         }
    818         mMemoryVec.push(pv_alloc_ptr);
    819 
    820         /* Set the buffer pointer */
    821         err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    822                                     IA_API_CMD_SET_MEM_PTR,
    823                                     i,
    824                                     pv_alloc_ptr);
    825         RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_MEM_PTR");
    826         if (ui_type == IA_MEMTYPE_INPUT) {
    827             mInputBuffer = (pWORD8)pv_alloc_ptr;
    828             mInputBufferSize = ui_size;
    829         }
    830         if (ui_type == IA_MEMTYPE_OUTPUT)
    831             mOutputBuffer = (pWORD8)pv_alloc_ptr;
    832     }
    833     /* End first part */
    834 
    835     return IA_NO_ERROR;
    836 }
    837 
    838 status_t C2SoftXaacDec::initXAACDrc() {
    839     IA_ERRORCODE err_code = IA_NO_ERROR;
    840     unsigned int ui_drc_val;
    841     //  DRC_PRES_MODE_WRAP_DESIRED_TARGET
    842     int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
    843     ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
    844     ui_drc_val = (unsigned int)targetRefLevel;
    845     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    846                                 IA_API_CMD_SET_CONFIG_PARAM,
    847                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL,
    848                                 &ui_drc_val);
    849     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
    850 
    851     /* Use ui_drc_val from PROP_DRC_OVERRIDE_REF_LEVEL or DRC_DEFAULT_MOBILE_REF_LEVEL
    852      * for IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS too */
    853     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
    854                                 IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &ui_drc_val);
    855 
    856     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
    857 
    858     int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
    859     ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
    860     ui_drc_val = (unsigned int)attenuationFactor;
    861     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    862                                 IA_API_CMD_SET_CONFIG_PARAM,
    863                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT,
    864                                 &ui_drc_val);
    865     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
    866 
    867     //  DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
    868     int32_t boostFactor = mIntf->getDrcBoostFactor();
    869     ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
    870     ui_drc_val = (unsigned int)boostFactor;
    871     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    872                                 IA_API_CMD_SET_CONFIG_PARAM,
    873                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST,
    874                                 &ui_drc_val);
    875     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
    876 
    877     //  DRC_PRES_MODE_WRAP_DESIRED_HEAVY
    878     int32_t compressMode = mIntf->getDrcCompressMode();
    879     ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode);
    880     ui_drc_val = (unsigned int)compressMode;
    881 
    882     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    883                                 IA_API_CMD_SET_CONFIG_PARAM,
    884                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
    885                                 &ui_drc_val);
    886     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
    887 
    888     // AAC_UNIDRC_SET_EFFECT
    889     int32_t effectType = mIntf->getDrcEffectType();
    890     ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
    891     ui_drc_val = (unsigned int)effectType;
    892     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
    893                                 IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &ui_drc_val);
    894 
    895     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
    896 
    897     return IA_NO_ERROR;
    898 }
    899 
    900 IA_ERRORCODE C2SoftXaacDec::deInitXAACDecoder() {
    901     ALOGV("deInitXAACDecoder");
    902 
    903     /* Error code */
    904     IA_ERRORCODE err_code = IA_NO_ERROR;
    905 
    906     if (mXheaacCodecHandle) {
    907         /* Tell that the input is over in this buffer */
    908         err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    909                                     IA_API_CMD_INPUT_OVER,
    910                                     0,
    911                                     nullptr);
    912     }
    913 
    914     /* Irrespective of error returned in IA_API_CMD_INPUT_OVER, free allocated memory */
    915     for (void* buf : mMemoryVec) {
    916         if (buf) free(buf);
    917     }
    918     mMemoryVec.clear();
    919     mXheaacCodecHandle = nullptr;
    920 
    921     return err_code;
    922 }
    923 
    924 IA_ERRORCODE C2SoftXaacDec::deInitMPEGDDDrc() {
    925     ALOGV("deInitMPEGDDDrc");
    926 
    927     for (void* buf : mDrcMemoryVec) {
    928         if (buf) free(buf);
    929     }
    930     mDrcMemoryVec.clear();
    931     return IA_NO_ERROR;
    932 }
    933 
    934 IA_ERRORCODE C2SoftXaacDec::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
    935     if (mInputBufferSize < inBufferLength) {
    936         ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize, inBufferLength);
    937         return false;
    938     }
    939     /* Copy the buffer passed by Android plugin to codec input buffer */
    940     memcpy(mInputBuffer, inBuffer, inBufferLength);
    941 
    942     /* Set number of bytes to be processed */
    943     IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    944                                              IA_API_CMD_SET_INPUT_BYTES,
    945                                              0,
    946                                              &inBufferLength);
    947     RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_INPUT_BYTES");
    948 
    949     if (mIsCodecConfigFlushRequired) {
    950         /* If codec is already initialized, then GA header is passed again */
    951         /* Need to call the Flush API instead of INIT_PROCESS */
    952         mIsCodecInitialized = false; /* Codec needs to be Reinitialized after flush */
    953         err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    954                                     IA_API_CMD_INIT,
    955                                     IA_CMD_TYPE_GA_HDR,
    956                                     nullptr);
    957         RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_GA_HDR");
    958     } else {
    959         /* Initialize the process */
    960         err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    961                                     IA_API_CMD_INIT,
    962                                     IA_CMD_TYPE_INIT_PROCESS,
    963                                     nullptr);
    964         RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_PROCESS");
    965     }
    966 
    967     uint32_t ui_init_done;
    968     /* Checking for end of initialization */
    969     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    970                                 IA_API_CMD_INIT,
    971                                 IA_CMD_TYPE_INIT_DONE_QUERY,
    972                                 &ui_init_done);
    973     RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_INIT_DONE_QUERY");
    974 
    975     /* How much buffer is used in input buffers */
    976     int32_t i_bytes_consumed;
    977     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
    978                                 IA_API_CMD_GET_CURIDX_INPUT_BUF,
    979                                 0,
    980                                 &i_bytes_consumed);
    981     RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_CURIDX_INPUT_BUF");
    982 
    983     if (ui_init_done) {
    984         err_code = getXAACStreamInfo();
    985         RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
    986         ALOGI("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d",
    987                mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
    988         mIsCodecInitialized = true;
    989 
    990         err_code = configMPEGDDrc();
    991         RETURN_IF_FATAL(err_code, "configMPEGDDrc");
    992     }
    993 
    994     return IA_NO_ERROR;
    995 }
    996 IA_ERRORCODE C2SoftXaacDec::initMPEGDDDrc() {
    997     IA_ERRORCODE err_code = IA_NO_ERROR;
    998 
    999     for (int i = 0; i < (WORD32)2; i++) {
   1000         WORD32 ui_size, ui_alignment, ui_type;
   1001         pVOID pv_alloc_ptr;
   1002 
   1003         /* Get memory size */
   1004         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
   1005 
   1006         RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
   1007 
   1008         /* Get memory alignment */
   1009         err_code =
   1010             ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment);
   1011 
   1012         RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
   1013 
   1014         /* Get memory type */
   1015         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
   1016         RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
   1017 
   1018         pv_alloc_ptr = memalign(4, ui_size);
   1019         if (pv_alloc_ptr == nullptr) {
   1020             ALOGE(" Cannot create requested memory  %d", ui_size);
   1021             return IA_FATAL_ERROR;
   1022         }
   1023         mDrcMemoryVec.push(pv_alloc_ptr);
   1024 
   1025         /* Set the buffer pointer */
   1026         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
   1027 
   1028         RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
   1029     }
   1030 
   1031     WORD32 ui_size;
   1032     ui_size = 8192 * 2;
   1033 
   1034     mDrcInBuf = (int8_t*)memalign(4, ui_size);
   1035     if (mDrcInBuf == nullptr) {
   1036         ALOGE(" Cannot create requested memory  %d", ui_size);
   1037         return IA_FATAL_ERROR;
   1038     }
   1039     mDrcMemoryVec.push(mDrcInBuf);
   1040 
   1041     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2, mDrcInBuf);
   1042     RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
   1043 
   1044     mDrcOutBuf = (int8_t*)memalign(4, ui_size);
   1045     if (mDrcOutBuf == nullptr) {
   1046         ALOGE(" Cannot create requested memory  %d", ui_size);
   1047         return IA_FATAL_ERROR;
   1048     }
   1049     mDrcMemoryVec.push(mDrcOutBuf);
   1050 
   1051     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3, mDrcOutBuf);
   1052     RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
   1053 
   1054     return IA_NO_ERROR;
   1055 }
   1056 int C2SoftXaacDec::configMPEGDDrc() {
   1057     IA_ERRORCODE err_code = IA_NO_ERROR;
   1058     int i_effect_type;
   1059     int i_loud_norm;
   1060     int i_target_loudness;
   1061     unsigned int i_sbr_mode;
   1062     uint32_t ui_proc_mem_tabs_size = 0;
   1063     pVOID pv_alloc_ptr = NULL;
   1064 
   1065     /* Sampling Frequency */
   1066     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1067                               IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
   1068     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ");
   1069     /* Total Number of Channels */
   1070     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1071                               IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
   1072     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
   1073 
   1074     /* PCM word size  */
   1075     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1076                               IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
   1077     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ");
   1078 
   1079     /*Set Effect Type*/
   1080 
   1081     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1082                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, &i_effect_type);
   1083     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
   1084 
   1085     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1086                               IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
   1087     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
   1088 
   1089     /*Set target loudness */
   1090     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1091                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS,
   1092                                 &i_target_loudness);
   1093     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
   1094 
   1095     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1096                               IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
   1097     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
   1098 
   1099     /*Set loud_norm_flag*/
   1100     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1101                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, &i_loud_norm);
   1102     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
   1103 
   1104     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1105                               IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
   1106     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
   1107 
   1108     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1109                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode);
   1110     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
   1111 
   1112     /* Get memory info tables size */
   1113     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0,
   1114                               &ui_proc_mem_tabs_size);
   1115     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
   1116 
   1117     pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
   1118     if (pv_alloc_ptr == NULL) {
   1119         ALOGE(" Cannot create requested memory  %d", ui_proc_mem_tabs_size);
   1120         return IA_FATAL_ERROR;
   1121     }
   1122     memset(pv_alloc_ptr, 0, ui_proc_mem_tabs_size);
   1123     mMemoryVec.push(pv_alloc_ptr);
   1124 
   1125     /* Set pointer for process memory tables */
   1126     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
   1127                               pv_alloc_ptr);
   1128     RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
   1129 
   1130     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1131                               IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, nullptr);
   1132 
   1133     RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
   1134 
   1135     /* Free any memory that is allocated for MPEG D Drc so far */
   1136     deInitMPEGDDDrc();
   1137 
   1138     err_code = initMPEGDDDrc();
   1139     if (err_code != IA_NO_ERROR) {
   1140         ALOGE("initMPEGDDDrc failed with error %d", err_code);
   1141         deInitMPEGDDDrc();
   1142         return err_code;
   1143     }
   1144 
   1145     /* DRC buffers
   1146         buf[0] - contains extension element pay load loudness related
   1147         buf[1] - contains extension element pay load*/
   1148     {
   1149         VOID* p_array[2][16];
   1150         WORD32 ii;
   1151         WORD32 buf_sizes[2][16];
   1152         WORD32 num_elements;
   1153         WORD32 num_config_ext;
   1154         WORD32 bit_str_fmt = 1;
   1155 
   1156         WORD32 uo_num_chan;
   1157 
   1158         memset(buf_sizes, 0, 32 * sizeof(WORD32));
   1159 
   1160         err_code =
   1161             ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1162                              IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES, &buf_sizes[0][0]);
   1163         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES");
   1164 
   1165         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1166                                     IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR, &p_array);
   1167         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR");
   1168 
   1169         err_code =
   1170             ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_SET_BUFF_PTR, nullptr);
   1171         RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_SET_BUFF_PTR");
   1172 
   1173         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1174                                     IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE, &num_elements);
   1175         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE");
   1176 
   1177         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1178                                     IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT, &num_config_ext);
   1179         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT");
   1180 
   1181         for (ii = 0; ii < num_config_ext; ii++) {
   1182             /*copy loudness bitstream*/
   1183             if (buf_sizes[0][ii] > 0) {
   1184                 memcpy(mDrcInBuf, p_array[0][ii], buf_sizes[0][ii]);
   1185 
   1186                 /*Set bitstream_split_format */
   1187                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1188                                           IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
   1189                 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1190 
   1191                 /* Set number of bytes to be processed */
   1192                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IL_BS, 0,
   1193                                           &buf_sizes[0][ii]);
   1194                 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IL_BS");
   1195 
   1196                 /* Execute process */
   1197                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1198                                           IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF, nullptr);
   1199                 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF");
   1200 
   1201                 mDRCFlag = 1;
   1202             }
   1203         }
   1204 
   1205         for (ii = 0; ii < num_elements; ii++) {
   1206             /*copy config bitstream*/
   1207             if (buf_sizes[1][ii] > 0) {
   1208                 memcpy(mDrcInBuf, p_array[1][ii], buf_sizes[1][ii]);
   1209                 /* Set number of bytes to be processed */
   1210 
   1211                 /*Set bitstream_split_format */
   1212                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1213                                           IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
   1214                 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1215 
   1216                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IC_BS, 0,
   1217                                           &buf_sizes[1][ii]);
   1218                 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IC_BS");
   1219 
   1220                 /* Execute process */
   1221                 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1222                                           IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF, nullptr);
   1223 
   1224                 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF");
   1225 
   1226                 mDRCFlag = 1;
   1227             }
   1228         }
   1229 
   1230         if (mDRCFlag == 1) {
   1231             mMpegDDRCPresent = 1;
   1232         } else {
   1233             mMpegDDRCPresent = 0;
   1234         }
   1235 
   1236         /*Read interface buffer config file bitstream*/
   1237         if (mMpegDDRCPresent == 1) {
   1238             WORD32 interface_is_present = 1;
   1239 
   1240             if (i_sbr_mode != 0) {
   1241                 if (i_sbr_mode == 1) {
   1242                     mOutputFrameLength = 2048;
   1243                 } else if (i_sbr_mode == 3) {
   1244                     mOutputFrameLength = 4096;
   1245                 } else {
   1246                     mOutputFrameLength = 1024;
   1247                 }
   1248             } else {
   1249                 mOutputFrameLength = 4096;
   1250             }
   1251 
   1252             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1253                                       IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE, (WORD32 *)&mOutputFrameLength);
   1254             RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE");
   1255 
   1256             err_code =
   1257                 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1258                                IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT, &interface_is_present);
   1259             RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT");
   1260 
   1261             /* Execute process */
   1262             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1263                                       IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF, nullptr);
   1264             RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF");
   1265 
   1266             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1267                                       IA_CMD_TYPE_INIT_PROCESS, nullptr);
   1268             RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS");
   1269 
   1270             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1271                                       IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &uo_num_chan);
   1272             RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
   1273         }
   1274     }
   1275 
   1276     return err_code;
   1277 }
   1278 
   1279 IA_ERRORCODE C2SoftXaacDec::decodeXAACStream(uint8_t* inBuffer,
   1280                                  uint32_t inBufferLength,
   1281                                  int32_t* bytesConsumed,
   1282                                  int32_t* outBytes) {
   1283     if (mInputBufferSize < inBufferLength) {
   1284         ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize, inBufferLength);
   1285         return -1;
   1286     }
   1287     /* Copy the buffer passed by Android plugin to codec input buffer */
   1288     memcpy(mInputBuffer, inBuffer, inBufferLength);
   1289 
   1290     /* Set number of bytes to be processed */
   1291     IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1292                                              IA_API_CMD_SET_INPUT_BYTES,
   1293                                              0,
   1294                                              &inBufferLength);
   1295     RETURN_IF_FATAL(err_code,  "IA_API_CMD_SET_INPUT_BYTES");
   1296 
   1297     /* Execute process */
   1298     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1299                                 IA_API_CMD_EXECUTE,
   1300                                 IA_CMD_TYPE_DO_EXECUTE,
   1301                                 nullptr);
   1302     RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_DO_EXECUTE");
   1303 
   1304     /* Checking for end of processing */
   1305     uint32_t ui_exec_done;
   1306     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1307                                 IA_API_CMD_EXECUTE,
   1308                                 IA_CMD_TYPE_DONE_QUERY,
   1309                                 &ui_exec_done);
   1310     RETURN_IF_FATAL(err_code,  "IA_CMD_TYPE_DONE_QUERY");
   1311 
   1312     if (ui_exec_done != 1) {
   1313         VOID* p_array;        // ITTIAM:buffer to handle gain payload
   1314         WORD32 buf_size = 0;  // ITTIAM:gain payload length
   1315         WORD32 bit_str_fmt = 1;
   1316         WORD32 gain_stream_flag = 1;
   1317 
   1318         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1319                                     IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN, &buf_size);
   1320         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN");
   1321 
   1322         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1323                                     IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF, &p_array);
   1324         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF");
   1325 
   1326         if (buf_size > 0) {
   1327             /*Set bitstream_split_format */
   1328             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1329                                       IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
   1330             RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1331 
   1332             memcpy(mDrcInBuf, p_array, buf_size);
   1333             /* Set number of bytes to be processed */
   1334             err_code =
   1335                 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_BS, 0, &buf_size);
   1336             RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1337 
   1338             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1339                                       IA_DRC_DEC_CONFIG_GAIN_STREAM_FLAG, &gain_stream_flag);
   1340             RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1341 
   1342             /* Execute process */
   1343             err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
   1344                                       IA_CMD_TYPE_INIT_CPY_BSF_BUFF, nullptr);
   1345             RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
   1346 
   1347             mMpegDDRCPresent = 1;
   1348         }
   1349     }
   1350 
   1351     /* How much buffer is used in input buffers */
   1352     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1353                                 IA_API_CMD_GET_CURIDX_INPUT_BUF,
   1354                                 0,
   1355                                 bytesConsumed);
   1356     RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_CURIDX_INPUT_BUF");
   1357 
   1358     /* Get the output bytes */
   1359     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1360                                 IA_API_CMD_GET_OUTPUT_BYTES,
   1361                                 0,
   1362                                 outBytes);
   1363     RETURN_IF_FATAL(err_code,  "IA_API_CMD_GET_OUTPUT_BYTES");
   1364 
   1365     if (mMpegDDRCPresent == 1) {
   1366         memcpy(mDrcInBuf, mOutputBuffer, *outBytes);
   1367         err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES, 0, outBytes);
   1368         RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
   1369 
   1370         err_code =
   1371             ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DO_EXECUTE, nullptr);
   1372         RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
   1373 
   1374         memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
   1375     }
   1376     return IA_NO_ERROR;
   1377 }
   1378 
   1379 IA_ERRORCODE C2SoftXaacDec::getXAACStreamInfo() {
   1380     IA_ERRORCODE err_code = IA_NO_ERROR;
   1381 
   1382     /* Sampling frequency */
   1383     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1384                                 IA_API_CMD_GET_CONFIG_PARAM,
   1385                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ,
   1386                                 &mSampFreq);
   1387     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ");
   1388 
   1389     /* Total Number of Channels */
   1390     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1391                                 IA_API_CMD_GET_CONFIG_PARAM,
   1392                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS,
   1393                                 &mNumChannels);
   1394     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS");
   1395     if (mNumChannels > MAX_CHANNEL_COUNT) {
   1396         ALOGE(" No of channels are more than max channels\n");
   1397         return IA_FATAL_ERROR;
   1398     }
   1399 
   1400     /* PCM word size */
   1401     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1402                                 IA_API_CMD_GET_CONFIG_PARAM,
   1403                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ,
   1404                                 &mPcmWdSz);
   1405     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ");
   1406     if ((mPcmWdSz / 8) != 2) {
   1407         ALOGE(" No of channels are more than max channels\n");
   1408         return IA_FATAL_ERROR;
   1409     }
   1410 
   1411     /* channel mask to tell the arrangement of channels in bit stream */
   1412     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1413                                 IA_API_CMD_GET_CONFIG_PARAM,
   1414                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK,
   1415                                 &mChannelMask);
   1416     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK");
   1417 
   1418     /* Channel mode to tell MONO/STEREO/DUAL-MONO/NONE_OF_THESE */
   1419     uint32_t ui_channel_mode;
   1420     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1421                                 IA_API_CMD_GET_CONFIG_PARAM,
   1422                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE,
   1423                                 &ui_channel_mode);
   1424     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE");
   1425     if (ui_channel_mode == 0)
   1426         ALOGV("Channel Mode: MONO_OR_PS\n");
   1427     else if (ui_channel_mode == 1)
   1428         ALOGV("Channel Mode: STEREO\n");
   1429     else if (ui_channel_mode == 2)
   1430         ALOGV("Channel Mode: DUAL-MONO\n");
   1431     else
   1432         ALOGV("Channel Mode: NONE_OF_THESE or MULTICHANNEL\n");
   1433 
   1434     /* Channel mode to tell SBR PRESENT/NOT_PRESENT */
   1435     uint32_t ui_sbr_mode;
   1436     err_code = ixheaacd_dec_api(mXheaacCodecHandle,
   1437                                 IA_API_CMD_GET_CONFIG_PARAM,
   1438                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE,
   1439                                 &ui_sbr_mode);
   1440     RETURN_IF_FATAL(err_code,  "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
   1441     if (ui_sbr_mode == 0)
   1442         ALOGV("SBR Mode: NOT_PRESENT\n");
   1443     else if (ui_sbr_mode == 1)
   1444         ALOGV("SBR Mode: PRESENT\n");
   1445     else
   1446         ALOGV("SBR Mode: ILLEGAL\n");
   1447 
   1448     /* mOutputFrameLength = 1024 * (1 + SBR_MODE) for AAC */
   1449     /* For USAC it could be 1024 * 3 , support to query  */
   1450     /* not yet added in codec                            */
   1451     mOutputFrameLength = 1024 * (1 + ui_sbr_mode);
   1452     ALOGI("mOutputFrameLength %d ui_sbr_mode %d", mOutputFrameLength, ui_sbr_mode);
   1453 
   1454     return IA_NO_ERROR;
   1455 }
   1456 
   1457 IA_ERRORCODE C2SoftXaacDec::setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
   1458                                            int32_t drcRefLevel,
   1459                                            int32_t drcHeavyCompression,
   1460                                            int32_t drEffectType) {
   1461     IA_ERRORCODE err_code = IA_NO_ERROR;
   1462 
   1463     int32_t ui_drc_enable = 1;
   1464     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1465                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE,
   1466                                 &ui_drc_enable);
   1467     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE");
   1468     if (drcCut != -1) {
   1469         err_code =
   1470             ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1471                              IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &drcCut);
   1472         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
   1473     }
   1474 
   1475     if (drcBoost != -1) {
   1476         err_code = ixheaacd_dec_api(
   1477             mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1478             IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &drcBoost);
   1479         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
   1480     }
   1481 
   1482     if (drcRefLevel != -1) {
   1483         err_code = ixheaacd_dec_api(
   1484             mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1485             IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, &drcRefLevel);
   1486         RETURN_IF_FATAL(err_code,
   1487                         "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
   1488     }
   1489 
   1490     if (drcRefLevel != -1) {
   1491         err_code = ixheaacd_dec_api(
   1492             mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1493             IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &drcRefLevel);
   1494         RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
   1495     }
   1496 
   1497     if (drcHeavyCompression != -1) {
   1498         err_code =
   1499             ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1500                              IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
   1501                              &drcHeavyCompression);
   1502         RETURN_IF_FATAL(err_code,
   1503                         "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
   1504     }
   1505 
   1506     err_code =
   1507         ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1508                          IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &drEffectType);
   1509     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
   1510 
   1511     int32_t i_effect_type, i_target_loudness, i_loud_norm;
   1512     /*Set Effect Type*/
   1513     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1514                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE,
   1515                                 &i_effect_type);
   1516     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
   1517 
   1518     err_code =
   1519         ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1520                        IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
   1521 
   1522     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
   1523 
   1524     /*Set target loudness */
   1525     err_code = ixheaacd_dec_api(
   1526         mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1527         IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
   1528     RETURN_IF_FATAL(err_code,
   1529                     "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
   1530 
   1531     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1532                               IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS,
   1533                               &i_target_loudness);
   1534     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
   1535 
   1536     /*Set loud_norm_flag*/
   1537     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
   1538                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM,
   1539                                 &i_loud_norm);
   1540     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
   1541 
   1542     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
   1543                               IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
   1544 
   1545     RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
   1546 
   1547     return IA_NO_ERROR;
   1548 }
   1549 
   1550 class C2SoftXaacDecFactory : public C2ComponentFactory {
   1551 public:
   1552     C2SoftXaacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
   1553             GetCodec2PlatformComponentStore()->getParamReflector())) {
   1554     }
   1555 
   1556     virtual c2_status_t createComponent(
   1557             c2_node_id_t id,
   1558             std::shared_ptr<C2Component>* const component,
   1559             std::function<void(C2Component*)> deleter) override {
   1560         *component = std::shared_ptr<C2Component>(
   1561                 new C2SoftXaacDec(COMPONENT_NAME,
   1562                                id,
   1563                                std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)),
   1564                 deleter);
   1565         return C2_OK;
   1566     }
   1567 
   1568     virtual c2_status_t createInterface(
   1569             c2_node_id_t id,
   1570             std::shared_ptr<C2ComponentInterface>* const interface,
   1571             std::function<void(C2ComponentInterface*)> deleter) override {
   1572         *interface = std::shared_ptr<C2ComponentInterface>(
   1573                 new SimpleInterface<C2SoftXaacDec::IntfImpl>(
   1574                         COMPONENT_NAME, id, std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)),
   1575                 deleter);
   1576         return C2_OK;
   1577     }
   1578 
   1579     virtual ~C2SoftXaacDecFactory() override = default;
   1580 
   1581 private:
   1582     std::shared_ptr<C2ReflectorHelper> mHelper;
   1583 };
   1584 
   1585 }  // namespace android
   1586 
   1587 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
   1588     ALOGV("in %s", __func__);
   1589     return new ::android::C2SoftXaacDecFactory();
   1590 }
   1591 
   1592 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
   1593     ALOGV("in %s", __func__);
   1594     delete factory;
   1595 }
   1596