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