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