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