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:
IntfImpl(const std::shared_ptr<C2ReflectorHelper> & helper)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 
isAdts() const202     bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; }
getBitrate() const203     uint32_t getBitrate() const { return mBitrate->value; }
ProfileLevelSetter(bool mayBlock,C2P<C2StreamProfileLevelInfo::input> & me)204     static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
205         (void)mayBlock;
206         (void)me;  // TODO: validate
207         return C2R::Ok();
208     }
getDrcCompressMode() const209     int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
getDrcTargetRefLevel() const210     int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
getDrcEncTargetLevel() const211     int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
getDrcBoostFactor() const212     int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
getDrcAttenuationFactor() const213     int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
getDrcEffectType() const214     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 
C2SoftXaacDec(const char * name,c2_node_id_t id,const std::shared_ptr<IntfImpl> & intfImpl)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 
~C2SoftXaacDec()243 C2SoftXaacDec::~C2SoftXaacDec() {
244     onRelease();
245 }
246 
onInit()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 
onStop()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 
onReset()293 void C2SoftXaacDec::onReset() {
294     (void)onStop();
295 }
296 
onRelease()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 
initDecoder()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 
fillEmptyWork(const std::unique_ptr<C2Work> & work)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 
finishWork(const std::unique_ptr<C2Work> & work,const std::shared_ptr<C2BlockPool> & pool)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 
process(const std::unique_ptr<C2Work> & work,const std::shared_ptr<C2BlockPool> & pool)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 
drain(uint32_t drainMode,const std::shared_ptr<C2BlockPool> & pool)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 
configflushDecode()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 
onFlush_sm()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 
drainDecoder()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 
initXAACDecoder()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 
initXAACDrc()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 
deInitXAACDecoder()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 
deInitMPEGDDDrc()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 
configXAACDecoder(uint8_t * inBuffer,uint32_t inBufferLength)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 }
initMPEGDDDrc()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 }
configMPEGDDrc()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 
decodeXAACStream(uint8_t * inBuffer,uint32_t inBufferLength,int32_t * bytesConsumed,int32_t * outBytes)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 
getXAACStreamInfo()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 
setXAACDRCInfo(int32_t drcCut,int32_t drcBoost,int32_t drcRefLevel,int32_t drcHeavyCompression,int32_t drEffectType)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:
C2SoftXaacDecFactory()1552     C2SoftXaacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
1553             GetCodec2PlatformComponentStore()->getParamReflector())) {
1554     }
1555 
createComponent(c2_node_id_t id,std::shared_ptr<C2Component> * const component,std::function<void (C2Component *)> deleter)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 
createInterface(c2_node_id_t id,std::shared_ptr<C2ComponentInterface> * const interface,std::function<void (C2ComponentInterface *)> deleter)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 
CreateCodec2Factory()1587 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
1588     ALOGV("in %s", __func__);
1589     return new ::android::C2SoftXaacDecFactory();
1590 }
1591 
DestroyCodec2Factory(::C2ComponentFactory * factory)1592 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
1593     ALOGV("in %s", __func__);
1594     delete factory;
1595 }
1596