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