blob: c0ad9920a886e1f5e980c0720364541f37c954b6 [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
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
57namespace android {
58
59constexpr char COMPONENT_NAME[] = "c2.android.xaac.decoder";
60
61class C2SoftXaacDec::IntfImpl : public C2InterfaceHelper {
62public:
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
206 bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; }
207 uint32_t getBitrate() const { return mBitrate->value; }
208 static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
209 (void)mayBlock;
210 (void)me; // TODO: validate
211 return C2R::Ok();
212 }
213 int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
214 int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
215 int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
216 int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
217 int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
218 int32_t getDrcEffectType() const { return mDrcEffectType->value; }
219
220private:
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
240C2SoftXaacDec::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
251C2SoftXaacDec::~C2SoftXaacDec() {
252 onRelease();
253}
254
255c2_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
281c2_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
301void C2SoftXaacDec::onReset() {
302 (void)onStop();
303}
304
305void 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
318IA_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
342static 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
354void 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
395void 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
613c2_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
628IA_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
667c2_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
681IA_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
688IA_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
846status_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
908IA_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
932IA_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
942IA_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}
1004IA_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}
1064int 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;
Rakesh Kumarad3420b2018-10-31 18:20:10 +05301070 uint32_t ui_proc_mem_tabs_size = 0;
1071 pVOID pv_alloc_ptr = NULL;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001072
1073 /* Sampling Frequency */
1074 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1075 IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
1076 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ");
1077 /* Total Number of Channels */
1078 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1079 IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
1080 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
1081
1082 /* PCM word size */
1083 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1084 IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
1085 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ");
1086
1087 /*Set Effect Type*/
1088
1089 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1090 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, &i_effect_type);
1091 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
1092
1093 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1094 IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
1095 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
1096
1097 /*Set target loudness */
1098 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1099 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS,
1100 &i_target_loudness);
1101 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
1102
1103 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1104 IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
1105 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
1106
1107 /*Set loud_norm_flag*/
1108 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1109 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, &i_loud_norm);
1110 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
1111
1112 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1113 IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
1114 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
1115
1116 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1117 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode);
1118 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
1119
Rakesh Kumarad3420b2018-10-31 18:20:10 +05301120 /* Get memory info tables size */
1121 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0,
1122 &ui_proc_mem_tabs_size);
1123 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
1124
1125 pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
1126 if (pv_alloc_ptr == NULL) {
1127 ALOGE(" Cannot create requested memory %d", ui_proc_mem_tabs_size);
1128 return IA_FATAL_ERROR;
1129 }
1130 memset(pv_alloc_ptr, 0, ui_proc_mem_tabs_size);
1131 mMemoryVec.push(pv_alloc_ptr);
1132
1133 /* Set pointer for process memory tables */
1134 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
1135 pv_alloc_ptr);
1136 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
1137
Pawin Vongmasa36653902018-11-15 00:10:25 -08001138 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1139 IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, nullptr);
1140
1141 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
1142
1143 /* Free any memory that is allocated for MPEG D Drc so far */
1144 deInitMPEGDDDrc();
1145
1146 err_code = initMPEGDDDrc();
1147 if (err_code != IA_NO_ERROR) {
1148 ALOGE("initMPEGDDDrc failed with error %d", err_code);
1149 deInitMPEGDDDrc();
1150 return err_code;
1151 }
1152
1153 /* DRC buffers
1154 buf[0] - contains extension element pay load loudness related
1155 buf[1] - contains extension element pay load*/
1156 {
1157 VOID* p_array[2][16];
1158 WORD32 ii;
1159 WORD32 buf_sizes[2][16];
1160 WORD32 num_elements;
1161 WORD32 num_config_ext;
1162 WORD32 bit_str_fmt = 1;
1163
1164 WORD32 uo_num_chan;
1165
1166 memset(buf_sizes, 0, 32 * sizeof(WORD32));
1167
1168 err_code =
1169 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1170 IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES, &buf_sizes[0][0]);
1171 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES");
1172
1173 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1174 IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR, &p_array);
1175 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR");
1176
1177 err_code =
1178 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_SET_BUFF_PTR, nullptr);
1179 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_SET_BUFF_PTR");
1180
1181 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1182 IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE, &num_elements);
1183 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE");
1184
1185 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1186 IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT, &num_config_ext);
1187 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT");
1188
1189 for (ii = 0; ii < num_config_ext; ii++) {
1190 /*copy loudness bitstream*/
1191 if (buf_sizes[0][ii] > 0) {
1192 memcpy(mDrcInBuf, p_array[0][ii], buf_sizes[0][ii]);
1193
1194 /*Set bitstream_split_format */
1195 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1196 IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
1197 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1198
1199 /* Set number of bytes to be processed */
1200 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IL_BS, 0,
1201 &buf_sizes[0][ii]);
1202 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IL_BS");
1203
1204 /* Execute process */
1205 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1206 IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF, nullptr);
1207 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF");
1208
1209 mDRCFlag = 1;
1210 }
1211 }
1212
1213 for (ii = 0; ii < num_elements; ii++) {
1214 /*copy config bitstream*/
1215 if (buf_sizes[1][ii] > 0) {
1216 memcpy(mDrcInBuf, p_array[1][ii], buf_sizes[1][ii]);
1217 /* Set number of bytes to be processed */
1218
1219 /*Set bitstream_split_format */
1220 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1221 IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
1222 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1223
1224 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IC_BS, 0,
1225 &buf_sizes[1][ii]);
1226 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IC_BS");
1227
1228 /* Execute process */
1229 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1230 IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF, nullptr);
1231
1232 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF");
1233
1234 mDRCFlag = 1;
1235 }
1236 }
1237
1238 if (mDRCFlag == 1) {
1239 mMpegDDRCPresent = 1;
1240 } else {
1241 mMpegDDRCPresent = 0;
1242 }
1243
1244 /*Read interface buffer config file bitstream*/
1245 if (mMpegDDRCPresent == 1) {
1246 WORD32 interface_is_present = 1;
1247
1248 if (i_sbr_mode != 0) {
1249 if (i_sbr_mode == 1) {
1250 mOutputFrameLength = 2048;
1251 } else if (i_sbr_mode == 3) {
1252 mOutputFrameLength = 4096;
1253 } else {
1254 mOutputFrameLength = 1024;
1255 }
1256 } else {
1257 mOutputFrameLength = 4096;
1258 }
1259
1260 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1261 IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE, (WORD32 *)&mOutputFrameLength);
1262 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE");
1263
1264 err_code =
1265 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1266 IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT, &interface_is_present);
1267 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT");
1268
1269 /* Execute process */
1270 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1271 IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF, nullptr);
1272 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF");
1273
1274 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1275 IA_CMD_TYPE_INIT_PROCESS, nullptr);
1276 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS");
1277
1278 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_CONFIG_PARAM,
1279 IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &uo_num_chan);
1280 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
1281 }
1282 }
1283
1284 return err_code;
1285}
1286
1287IA_ERRORCODE C2SoftXaacDec::decodeXAACStream(uint8_t* inBuffer,
1288 uint32_t inBufferLength,
1289 int32_t* bytesConsumed,
1290 int32_t* outBytes) {
1291 if (mInputBufferSize < inBufferLength) {
1292 ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize, inBufferLength);
1293 return -1;
1294 }
1295 /* Copy the buffer passed by Android plugin to codec input buffer */
1296 memcpy(mInputBuffer, inBuffer, inBufferLength);
1297
1298 /* Set number of bytes to be processed */
1299 IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1300 IA_API_CMD_SET_INPUT_BYTES,
1301 0,
1302 &inBufferLength);
1303 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
1304
1305 /* Execute process */
1306 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1307 IA_API_CMD_EXECUTE,
1308 IA_CMD_TYPE_DO_EXECUTE,
1309 nullptr);
1310 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
1311
1312 /* Checking for end of processing */
1313 uint32_t ui_exec_done;
1314 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1315 IA_API_CMD_EXECUTE,
1316 IA_CMD_TYPE_DONE_QUERY,
1317 &ui_exec_done);
1318 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DONE_QUERY");
1319
1320 if (ui_exec_done != 1) {
1321 VOID* p_array; // ITTIAM:buffer to handle gain payload
1322 WORD32 buf_size = 0; // ITTIAM:gain payload length
1323 WORD32 bit_str_fmt = 1;
1324 WORD32 gain_stream_flag = 1;
1325
1326 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1327 IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN, &buf_size);
1328 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN");
1329
1330 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1331 IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF, &p_array);
1332 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF");
1333
1334 if (buf_size > 0) {
1335 /*Set bitstream_split_format */
1336 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1337 IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
1338 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1339
1340 memcpy(mDrcInBuf, p_array, buf_size);
1341 /* Set number of bytes to be processed */
1342 err_code =
1343 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_BS, 0, &buf_size);
1344 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1345
1346 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1347 IA_DRC_DEC_CONFIG_GAIN_STREAM_FLAG, &gain_stream_flag);
1348 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1349
1350 /* Execute process */
1351 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1352 IA_CMD_TYPE_INIT_CPY_BSF_BUFF, nullptr);
1353 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1354
1355 mMpegDDRCPresent = 1;
1356 }
1357 }
1358
1359 /* How much buffer is used in input buffers */
1360 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1361 IA_API_CMD_GET_CURIDX_INPUT_BUF,
1362 0,
1363 bytesConsumed);
1364 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_CURIDX_INPUT_BUF");
1365
1366 /* Get the output bytes */
1367 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1368 IA_API_CMD_GET_OUTPUT_BYTES,
1369 0,
1370 outBytes);
1371 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_OUTPUT_BYTES");
1372
1373 if (mMpegDDRCPresent == 1) {
1374 memcpy(mDrcInBuf, mOutputBuffer, *outBytes);
1375 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES, 0, outBytes);
1376 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
1377
1378 err_code =
1379 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DO_EXECUTE, nullptr);
1380 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
1381
1382 memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
1383 }
1384 return IA_NO_ERROR;
1385}
1386
1387IA_ERRORCODE C2SoftXaacDec::getXAACStreamInfo() {
1388 IA_ERRORCODE err_code = IA_NO_ERROR;
1389
1390 /* Sampling frequency */
1391 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1392 IA_API_CMD_GET_CONFIG_PARAM,
1393 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ,
1394 &mSampFreq);
1395 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ");
1396
1397 /* Total Number of Channels */
1398 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1399 IA_API_CMD_GET_CONFIG_PARAM,
1400 IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS,
1401 &mNumChannels);
1402 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS");
1403 if (mNumChannels > MAX_CHANNEL_COUNT) {
1404 ALOGE(" No of channels are more than max channels\n");
1405 return IA_FATAL_ERROR;
1406 }
1407
1408 /* PCM word size */
1409 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1410 IA_API_CMD_GET_CONFIG_PARAM,
1411 IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ,
1412 &mPcmWdSz);
1413 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ");
1414 if ((mPcmWdSz / 8) != 2) {
1415 ALOGE(" No of channels are more than max channels\n");
1416 return IA_FATAL_ERROR;
1417 }
1418
1419 /* channel mask to tell the arrangement of channels in bit stream */
1420 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1421 IA_API_CMD_GET_CONFIG_PARAM,
1422 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK,
1423 &mChannelMask);
1424 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK");
1425
1426 /* Channel mode to tell MONO/STEREO/DUAL-MONO/NONE_OF_THESE */
1427 uint32_t ui_channel_mode;
1428 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1429 IA_API_CMD_GET_CONFIG_PARAM,
1430 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE,
1431 &ui_channel_mode);
1432 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE");
1433 if (ui_channel_mode == 0)
1434 ALOGV("Channel Mode: MONO_OR_PS\n");
1435 else if (ui_channel_mode == 1)
1436 ALOGV("Channel Mode: STEREO\n");
1437 else if (ui_channel_mode == 2)
1438 ALOGV("Channel Mode: DUAL-MONO\n");
1439 else
1440 ALOGV("Channel Mode: NONE_OF_THESE or MULTICHANNEL\n");
1441
1442 /* Channel mode to tell SBR PRESENT/NOT_PRESENT */
1443 uint32_t ui_sbr_mode;
1444 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1445 IA_API_CMD_GET_CONFIG_PARAM,
1446 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE,
1447 &ui_sbr_mode);
1448 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
1449 if (ui_sbr_mode == 0)
1450 ALOGV("SBR Mode: NOT_PRESENT\n");
1451 else if (ui_sbr_mode == 1)
1452 ALOGV("SBR Mode: PRESENT\n");
1453 else
1454 ALOGV("SBR Mode: ILLEGAL\n");
1455
1456 /* mOutputFrameLength = 1024 * (1 + SBR_MODE) for AAC */
1457 /* For USAC it could be 1024 * 3 , support to query */
1458 /* not yet added in codec */
1459 mOutputFrameLength = 1024 * (1 + ui_sbr_mode);
1460 ALOGI("mOutputFrameLength %d ui_sbr_mode %d", mOutputFrameLength, ui_sbr_mode);
1461
1462 return IA_NO_ERROR;
1463}
1464
1465IA_ERRORCODE C2SoftXaacDec::setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
1466 int32_t drcRefLevel,
1467 int32_t drcHeavyCompression,
1468 int32_t drEffectType) {
1469 IA_ERRORCODE err_code = IA_NO_ERROR;
1470
1471 int32_t ui_drc_enable = 1;
1472 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1473 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE,
1474 &ui_drc_enable);
1475 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE");
1476 if (drcCut != -1) {
1477 err_code =
1478 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1479 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &drcCut);
1480 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
1481 }
1482
1483 if (drcBoost != -1) {
1484 err_code = ixheaacd_dec_api(
1485 mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1486 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &drcBoost);
1487 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
1488 }
1489
1490 if (drcRefLevel != -1) {
1491 err_code = ixheaacd_dec_api(
1492 mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1493 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, &drcRefLevel);
1494 RETURN_IF_FATAL(err_code,
1495 "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
1496 }
1497
1498 if (drcRefLevel != -1) {
1499 err_code = ixheaacd_dec_api(
1500 mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1501 IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &drcRefLevel);
1502 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
1503 }
1504
1505 if (drcHeavyCompression != -1) {
1506 err_code =
1507 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1508 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
1509 &drcHeavyCompression);
1510 RETURN_IF_FATAL(err_code,
1511 "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
1512 }
1513
1514 err_code =
1515 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1516 IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &drEffectType);
1517 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
1518
1519 int32_t i_effect_type, i_target_loudness, i_loud_norm;
1520 /*Set Effect Type*/
1521 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1522 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE,
1523 &i_effect_type);
1524 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
1525
1526 err_code =
1527 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1528 IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
1529
1530 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
1531
1532 /*Set target loudness */
1533 err_code = ixheaacd_dec_api(
1534 mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1535 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
1536 RETURN_IF_FATAL(err_code,
1537 "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
1538
1539 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1540 IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS,
1541 &i_target_loudness);
1542 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
1543
1544 /*Set loud_norm_flag*/
1545 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1546 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM,
1547 &i_loud_norm);
1548 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
1549
1550 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1551 IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
1552
1553 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
1554
1555 return IA_NO_ERROR;
1556}
1557
1558class C2SoftXaacDecFactory : public C2ComponentFactory {
1559public:
1560 C2SoftXaacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
1561 GetCodec2PlatformComponentStore()->getParamReflector())) {
1562 }
1563
1564 virtual c2_status_t createComponent(
1565 c2_node_id_t id,
1566 std::shared_ptr<C2Component>* const component,
1567 std::function<void(C2Component*)> deleter) override {
1568 *component = std::shared_ptr<C2Component>(
1569 new C2SoftXaacDec(COMPONENT_NAME,
1570 id,
1571 std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)),
1572 deleter);
1573 return C2_OK;
1574 }
1575
1576 virtual c2_status_t createInterface(
1577 c2_node_id_t id,
1578 std::shared_ptr<C2ComponentInterface>* const interface,
1579 std::function<void(C2ComponentInterface*)> deleter) override {
1580 *interface = std::shared_ptr<C2ComponentInterface>(
1581 new SimpleInterface<C2SoftXaacDec::IntfImpl>(
1582 COMPONENT_NAME, id, std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)),
1583 deleter);
1584 return C2_OK;
1585 }
1586
1587 virtual ~C2SoftXaacDecFactory() override = default;
1588
1589private:
1590 std::shared_ptr<C2ReflectorHelper> mHelper;
1591};
1592
1593} // namespace android
1594
1595extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
1596 ALOGV("in %s", __func__);
1597 return new ::android::C2SoftXaacDecFactory();
1598}
1599
1600extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
1601 ALOGV("in %s", __func__);
1602 delete factory;
1603}