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