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