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