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 "SoftXAAC"
19 #include <utils/Log.h>
20
21 #include "SoftXAAC.h"
22
23 #include <OMX_AudioExt.h>
24 #include <OMX_IndexExt.h>
25 #include <cutils/properties.h>
26 #include <math.h>
27 #include <media/stagefright/MediaErrors.h>
28 #include <media/stagefright/foundation/ADebug.h>
29 #include <media/stagefright/foundation/hexdump.h>
30 #include <utils/misc.h>
31
32 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
33 #define DRC_DEFAULT_MOBILE_REF_LEVEL 64
34 /* maximum compression of dynamic range for mobile conf */
35 #define DRC_DEFAULT_MOBILE_DRC_CUT 127
36 /* maximum compression of dynamic range for mobile conf */
37 #define DRC_DEFAULT_MOBILE_DRC_BOOST 127
38 /* switch for heavy compression for mobile conf */
39 #define DRC_DEFAULT_MOBILE_DRC_HEAVY 1
40 /* encoder target level; -1 => the value is unknown,
41 * otherwise dB step value (e.g. 64 for -16 dB) */
42 #define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1)
43
44 /* Default Effect type is "Limited playback" */
45 #define DRC_KEY_AAC_DRC_EFFECT_TYPE (3)
46
47 /* REF_LEVEL of 64 pairs well with EFFECT_TYPE of 3. */
48 /* Default loudness value for MPEG-D DRC */
49 #define DRC_DEFAULT_MOBILE_LOUDNESS_LEVEL (64)
50
51 #define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
52 #define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
53 #define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
54 #define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
55 #define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
56 #define PROP_DRC_OVERRIDE_EFFECT_TYPE "ro.aac_drc_effect_type"
57
58 /* maximum number of audio channels that can be decoded */
59 #define MAX_CHANNEL_COUNT 8
60
61 #define RETURN_IF_FATAL(retval, str) \
62 if (retval & IA_FATAL_ERROR) { \
63 ALOGE("Error in %s: Returned: %d", str, retval); \
64 return retval; \
65 } else if (retval != IA_NO_ERROR) { \
66 ALOGW("Warning in %s: Returned: %d", str, retval); \
67 }
68
69 namespace android {
70
71 template <class T>
InitOMXParams(T * params)72 static void InitOMXParams(T* params) {
73 params->nSize = sizeof(T);
74 params->nVersion.s.nVersionMajor = 1;
75 params->nVersion.s.nVersionMinor = 0;
76 params->nVersion.s.nRevision = 0;
77 params->nVersion.s.nStep = 0;
78 }
79
80 static const OMX_U32 kSupportedProfiles[] = {
81 OMX_AUDIO_AACObjectLC, OMX_AUDIO_AACObjectHE, OMX_AUDIO_AACObjectHE_PS,
82 OMX_AUDIO_AACObjectLD, OMX_AUDIO_AACObjectELD, OMX_AUDIO_AACObjectXHE
83 };
84
SoftXAAC(const char * name,const OMX_CALLBACKTYPE * callbacks,OMX_PTR appData,OMX_COMPONENTTYPE ** component)85 SoftXAAC::SoftXAAC(const char* name, const OMX_CALLBACKTYPE* callbacks, OMX_PTR appData,
86 OMX_COMPONENTTYPE** component)
87 : SimpleSoftOMXComponent(name, callbacks, appData, component),
88 mIsADTS(false),
89 mInputBufferCount(0),
90 mOutputBufferCount(0),
91 mSignalledError(false),
92 mLastInHeader(NULL),
93 mPrevTimestamp(0),
94 mCurrentTimestamp(0),
95 mOutputPortSettingsChange(NONE),
96 mXheaacCodecHandle(NULL),
97 mMpegDDrcHandle(NULL),
98 mInputBufferSize(0),
99 mOutputFrameLength(1024),
100 mInputBuffer(NULL),
101 mOutputBuffer(NULL),
102 mSampFreq(0),
103 mNumChannels(0),
104 mPcmWdSz(0),
105 mChannelMask(0),
106 mIsCodecInitialized(false),
107 mIsCodecConfigFlushRequired(false),
108 mMpegDDRCPresent(0),
109 mDRCFlag(0)
110
111 {
112 initPorts();
113 mMemoryVec.clear();
114 mDrcMemoryVec.clear();
115
116 CHECK_EQ(initDecoder(), IA_NO_ERROR);
117 }
118
~SoftXAAC()119 SoftXAAC::~SoftXAAC() {
120 IA_ERRORCODE err_code = deInitXAACDecoder();
121 if (IA_NO_ERROR != err_code) {
122 ALOGE("deInitXAACDecoder() failed %d", err_code);
123 }
124
125 err_code = deInitMPEGDDDrc();
126 if (IA_NO_ERROR != err_code) {
127 ALOGE("deInitMPEGDDDrc() failed %d", err_code);
128 }
129 mIsCodecInitialized = false;
130 mIsCodecConfigFlushRequired = false;
131 }
132
initPorts()133 void SoftXAAC::initPorts() {
134 OMX_PARAM_PORTDEFINITIONTYPE def;
135 InitOMXParams(&def);
136
137 def.nPortIndex = 0;
138 def.eDir = OMX_DirInput;
139 def.nBufferCountMin = kNumInputBuffers;
140 def.nBufferCountActual = def.nBufferCountMin;
141 def.nBufferSize = 8192;
142 def.bEnabled = OMX_TRUE;
143 def.bPopulated = OMX_FALSE;
144 def.eDomain = OMX_PortDomainAudio;
145 def.bBuffersContiguous = OMX_FALSE;
146 def.nBufferAlignment = 1;
147
148 def.format.audio.cMIMEType = const_cast<char*>("audio/aac");
149 def.format.audio.pNativeRender = NULL;
150 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
151 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
152
153 addPort(def);
154
155 def.nPortIndex = 1;
156 def.eDir = OMX_DirOutput;
157 def.nBufferCountMin = kNumOutputBuffers;
158 def.nBufferCountActual = def.nBufferCountMin;
159 def.nBufferSize = 4096 * MAX_CHANNEL_COUNT;
160 def.bEnabled = OMX_TRUE;
161 def.bPopulated = OMX_FALSE;
162 def.eDomain = OMX_PortDomainAudio;
163 def.bBuffersContiguous = OMX_FALSE;
164 def.nBufferAlignment = 2;
165
166 def.format.audio.cMIMEType = const_cast<char*>("audio/raw");
167 def.format.audio.pNativeRender = NULL;
168 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
169 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
170
171 addPort(def);
172 }
173
initDecoder()174 IA_ERRORCODE SoftXAAC::initDecoder() {
175 int ui_drc_val;
176 IA_ERRORCODE err_code = IA_NO_ERROR;
177 int loop = 0;
178
179 err_code = initXAACDecoder();
180 if (err_code != IA_NO_ERROR) {
181 ALOGE("initXAACDecoder failed with error %d", err_code);
182 deInitXAACDecoder();
183 return err_code;
184 }
185
186 mEndOfInput = false;
187 mEndOfOutput = false;
188
189 char value[PROPERTY_VALUE_MAX];
190 if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
191 ui_drc_val = atoi(value);
192 ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d",
193 ui_drc_val, DRC_DEFAULT_MOBILE_REF_LEVEL);
194 } else {
195 ui_drc_val = DRC_DEFAULT_MOBILE_REF_LEVEL;
196 }
197
198 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
199 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, &ui_drc_val);
200
201 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
202 #ifdef ENABLE_MPEG_D_DRC
203 /* Use ui_drc_val from PROP_DRC_OVERRIDE_REF_LEVEL or DRC_DEFAULT_MOBILE_REF_LEVEL
204 * for IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS too */
205
206 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
207 IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &ui_drc_val);
208
209 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
210 #endif
211
212 if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
213 ui_drc_val = atoi(value);
214 ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", ui_drc_val,
215 DRC_DEFAULT_MOBILE_DRC_CUT);
216 } else {
217 ui_drc_val = DRC_DEFAULT_MOBILE_DRC_CUT;
218 }
219
220 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
221 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &ui_drc_val);
222
223 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
224
225 if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
226 ui_drc_val = atoi(value);
227 ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", ui_drc_val,
228 DRC_DEFAULT_MOBILE_DRC_BOOST);
229 } else {
230 ui_drc_val = DRC_DEFAULT_MOBILE_DRC_BOOST;
231 }
232
233 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
234 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &ui_drc_val);
235 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
236
237 if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) {
238 ui_drc_val = atoi(value);
239 ALOGV("AAC decoder using desired Heavy compression factor of %d instead of %d", ui_drc_val,
240 DRC_DEFAULT_MOBILE_DRC_HEAVY);
241 } else {
242 ui_drc_val = DRC_DEFAULT_MOBILE_DRC_HEAVY;
243 }
244
245 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
246 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP, &ui_drc_val);
247 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
248
249 #ifdef ENABLE_MPEG_D_DRC
250 if (property_get(PROP_DRC_OVERRIDE_EFFECT_TYPE, value, NULL)) {
251 ui_drc_val = atoi(value);
252 ALOGV("AAC decoder using desired DRC effect type of %d instead of %d", ui_drc_val,
253 DRC_KEY_AAC_DRC_EFFECT_TYPE);
254 } else {
255 ui_drc_val = DRC_KEY_AAC_DRC_EFFECT_TYPE;
256 }
257
258 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
259 IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &ui_drc_val);
260
261 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
262
263 #endif
264 return IA_NO_ERROR;
265 }
266
internalGetParameter(OMX_INDEXTYPE index,OMX_PTR params)267 OMX_ERRORTYPE SoftXAAC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) {
268 switch ((OMX_U32)index) {
269 case OMX_IndexParamAudioPortFormat: {
270 OMX_AUDIO_PARAM_PORTFORMATTYPE* formatParams = (OMX_AUDIO_PARAM_PORTFORMATTYPE*)params;
271
272 if (!isValidOMXParam(formatParams)) {
273 return OMX_ErrorBadParameter;
274 }
275
276 if (formatParams->nPortIndex > 1) {
277 return OMX_ErrorUndefined;
278 }
279
280 if (formatParams->nIndex > 0) {
281 return OMX_ErrorNoMore;
282 }
283
284 formatParams->eEncoding =
285 (formatParams->nPortIndex == 0) ? OMX_AUDIO_CodingAAC : OMX_AUDIO_CodingPCM;
286
287 return OMX_ErrorNone;
288 }
289
290 case OMX_IndexParamAudioAac: {
291 OMX_AUDIO_PARAM_AACPROFILETYPE* aacParams = (OMX_AUDIO_PARAM_AACPROFILETYPE*)params;
292
293 if (!isValidOMXParam(aacParams)) {
294 return OMX_ErrorBadParameter;
295 }
296
297 if (aacParams->nPortIndex != 0) {
298 return OMX_ErrorUndefined;
299 }
300
301 aacParams->nBitRate = 0;
302 aacParams->nAudioBandWidth = 0;
303 aacParams->nAACtools = 0;
304 aacParams->nAACERtools = 0;
305 aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
306
307 aacParams->eAACStreamFormat =
308 mIsADTS ? OMX_AUDIO_AACStreamFormatMP4ADTS : OMX_AUDIO_AACStreamFormatMP4FF;
309
310 aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
311
312 if (!isConfigured()) {
313 aacParams->nChannels = 1;
314 aacParams->nSampleRate = 44100;
315 aacParams->nFrameLength = 0;
316 } else {
317 aacParams->nChannels = mNumChannels;
318 aacParams->nSampleRate = mSampFreq;
319 aacParams->nFrameLength = mOutputFrameLength;
320 }
321
322 return OMX_ErrorNone;
323 }
324
325 case OMX_IndexParamAudioPcm: {
326 OMX_AUDIO_PARAM_PCMMODETYPE* pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE*)params;
327
328 if (!isValidOMXParam(pcmParams)) {
329 return OMX_ErrorBadParameter;
330 }
331
332 if (pcmParams->nPortIndex != 1) {
333 return OMX_ErrorUndefined;
334 }
335
336 pcmParams->eNumData = OMX_NumericalDataSigned;
337 pcmParams->eEndian = OMX_EndianBig;
338 pcmParams->bInterleaved = OMX_TRUE;
339 pcmParams->nBitPerSample = 16;
340 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
341 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
342 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
343 pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
344 pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
345 pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
346 pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
347
348 if (!isConfigured()) {
349 pcmParams->nChannels = 1;
350 pcmParams->nSamplingRate = 44100;
351 } else {
352 pcmParams->nChannels = mNumChannels;
353 pcmParams->nSamplingRate = mSampFreq;
354 }
355
356 return OMX_ErrorNone;
357 }
358
359 case OMX_IndexParamAudioProfileQuerySupported: {
360 OMX_AUDIO_PARAM_ANDROID_PROFILETYPE* profileParams =
361 (OMX_AUDIO_PARAM_ANDROID_PROFILETYPE*)params;
362
363 if (!isValidOMXParam(profileParams)) {
364 return OMX_ErrorBadParameter;
365 }
366
367 if (profileParams->nPortIndex != 0) {
368 return OMX_ErrorUndefined;
369 }
370
371 if (profileParams->nProfileIndex >= NELEM(kSupportedProfiles)) {
372 return OMX_ErrorNoMore;
373 }
374
375 profileParams->eProfile = kSupportedProfiles[profileParams->nProfileIndex];
376
377 return OMX_ErrorNone;
378 }
379
380 default:
381 return SimpleSoftOMXComponent::internalGetParameter(index, params);
382 }
383 }
384
internalSetParameter(OMX_INDEXTYPE index,const OMX_PTR params)385 OMX_ERRORTYPE SoftXAAC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params) {
386 switch ((int)index) {
387 case OMX_IndexParamStandardComponentRole: {
388 const OMX_PARAM_COMPONENTROLETYPE* roleParams =
389 (const OMX_PARAM_COMPONENTROLETYPE*)params;
390
391 if (!isValidOMXParam(roleParams)) {
392 return OMX_ErrorBadParameter;
393 }
394
395 if (strncmp((const char*)roleParams->cRole, "audio_decoder.aac",
396 OMX_MAX_STRINGNAME_SIZE - 1)) {
397 return OMX_ErrorUndefined;
398 }
399
400 return OMX_ErrorNone;
401 }
402
403 case OMX_IndexParamAudioPortFormat: {
404 const OMX_AUDIO_PARAM_PORTFORMATTYPE* formatParams =
405 (const OMX_AUDIO_PARAM_PORTFORMATTYPE*)params;
406
407 if (!isValidOMXParam(formatParams)) {
408 return OMX_ErrorBadParameter;
409 }
410
411 if (formatParams->nPortIndex > 1) {
412 return OMX_ErrorUndefined;
413 }
414
415 if ((formatParams->nPortIndex == 0 && formatParams->eEncoding != OMX_AUDIO_CodingAAC) ||
416 (formatParams->nPortIndex == 1 && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
417 return OMX_ErrorUndefined;
418 }
419
420 return OMX_ErrorNone;
421 }
422
423 case OMX_IndexParamAudioAac: {
424 const OMX_AUDIO_PARAM_AACPROFILETYPE* aacParams =
425 (const OMX_AUDIO_PARAM_AACPROFILETYPE*)params;
426
427 if (!isValidOMXParam(aacParams)) {
428 return OMX_ErrorBadParameter;
429 }
430
431 if (aacParams->nPortIndex != 0) {
432 return OMX_ErrorUndefined;
433 }
434
435 if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
436 mIsADTS = false;
437 } else if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4ADTS) {
438 mIsADTS = true;
439 } else {
440 return OMX_ErrorUndefined;
441 }
442
443 return OMX_ErrorNone;
444 }
445
446 case OMX_IndexParamAudioAndroidAacDrcPresentation: {
447 const OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE* aacPresParams =
448 (const OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE*)params;
449
450 if (!isValidOMXParam(aacPresParams)) {
451 ALOGE("set OMX_ErrorBadParameter");
452 return OMX_ErrorBadParameter;
453 }
454
455 // for the following parameters of the OMX_AUDIO_PARAM_AACPROFILETYPE structure,
456 // a value of -1 implies the parameter is not set by the application:
457 // nMaxOutputChannels -1 by default
458 // nDrcCut uses default platform properties, see initDecoder()
459 // nDrcBoost idem
460 // nHeavyCompression idem
461 // nTargetReferenceLevel idem
462 // nEncodedTargetLevel idem
463 if (aacPresParams->nMaxOutputChannels >= 0) {
464 int max;
465 if (aacPresParams->nMaxOutputChannels >= 8) {
466 max = 8;
467 } else if (aacPresParams->nMaxOutputChannels >= 6) {
468 max = 6;
469 } else if (aacPresParams->nMaxOutputChannels >= 2) {
470 max = 2;
471 } else {
472 // -1 or 0: disable downmix, 1: mono
473 max = aacPresParams->nMaxOutputChannels;
474 }
475 }
476 /* Apply DRC Changes */
477 IA_ERRORCODE err_code = setXAACDRCInfo(aacPresParams->nDrcCut, aacPresParams->nDrcBoost,
478 aacPresParams->nTargetReferenceLevel,
479 aacPresParams->nHeavyCompression
480 #ifdef ENABLE_MPEG_D_DRC
481 ,
482 aacPresParams->nDrcEffectType
483 #endif
484 ); // TOD0 : Revert this change
485 if (err_code != IA_NO_ERROR) {
486 ALOGE("Error in OMX_IndexParamAudioAndroidAacDrcPresentation");
487 return OMX_ErrorBadParameter;
488 }
489
490 return OMX_ErrorNone;
491 }
492
493 case OMX_IndexParamAudioPcm: {
494 const OMX_AUDIO_PARAM_PCMMODETYPE* pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE*)params;
495
496 if (!isValidOMXParam(pcmParams)) {
497 return OMX_ErrorBadParameter;
498 }
499
500 if (pcmParams->nPortIndex != 1) {
501 return OMX_ErrorUndefined;
502 }
503
504 return OMX_ErrorNone;
505 }
506
507 default:
508 return SimpleSoftOMXComponent::internalSetParameter(index, params);
509 }
510 }
511
isConfigured() const512 bool SoftXAAC::isConfigured() const {
513 return mInputBufferCount > 0;
514 }
515
onQueueFilled(OMX_U32)516 void SoftXAAC::onQueueFilled(OMX_U32 /* portIndex */) {
517 if (mSignalledError || mOutputPortSettingsChange != NONE) {
518 ALOGE("onQueueFilled do not process %d %d", mSignalledError, mOutputPortSettingsChange);
519 return;
520 }
521
522 uint8_t* inBuffer = NULL;
523 uint32_t inBufferLength = 0;
524
525 List<BufferInfo*>& inQueue = getPortQueue(0);
526 List<BufferInfo*>& outQueue = getPortQueue(1);
527
528 signed int numOutBytes = 0;
529
530 /* If decoder call fails in between, then mOutputFrameLength is used */
531 /* Decoded output for AAC is 1024/2048 samples / channel */
532 /* TODO: For USAC mOutputFrameLength can go up to 4096 */
533 /* Note: entire buffer logic to save and retrieve assumes 2 bytes per*/
534 /* sample currently */
535 if (mIsCodecInitialized) {
536 numOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels;
537 }
538
539 while ((!inQueue.empty() || mEndOfInput) && !outQueue.empty()) {
540 if (!inQueue.empty()) {
541 BufferInfo* inInfo = *inQueue.begin();
542 OMX_BUFFERHEADERTYPE* inHeader = inInfo->mHeader;
543
544 /* No need to check inHeader != NULL, as inQueue is not empty */
545 mEndOfInput = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0;
546
547 if (mInputBufferCount == 0 && !(inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
548 ALOGW("first buffer should have OMX_BUFFERFLAG_CODECCONFIG set");
549 inHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
550 }
551 if ((inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != 0) {
552 inBuffer = inHeader->pBuffer + inHeader->nOffset;
553 inBufferLength = inHeader->nFilledLen;
554
555 /* GA header configuration sent to Decoder! */
556 IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
557 if (IA_NO_ERROR != err_code) {
558 ALOGW("configXAACDecoder err_code = %d", err_code);
559 mSignalledError = true;
560 notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
561 return;
562 }
563 mInputBufferCount++;
564 mOutputBufferCount++; // fake increase of outputBufferCount to keep the counters
565 // aligned
566
567 inInfo->mOwnedByUs = false;
568 inQueue.erase(inQueue.begin());
569 mLastInHeader = NULL;
570 inInfo = NULL;
571 notifyEmptyBufferDone(inHeader);
572 inHeader = NULL;
573
574 // Only send out port settings changed event if both sample rate
575 // and mNumChannels are valid.
576 if (mSampFreq && mNumChannels && !mIsCodecConfigFlushRequired) {
577 ALOGV("Configuring decoder: %d Hz, %d channels", mSampFreq, mNumChannels);
578 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
579 mOutputPortSettingsChange = AWAITING_DISABLED;
580 }
581
582 return;
583 }
584
585 if (inHeader->nFilledLen == 0) {
586 inInfo->mOwnedByUs = false;
587 inQueue.erase(inQueue.begin());
588 mLastInHeader = NULL;
589 inInfo = NULL;
590 notifyEmptyBufferDone(inHeader);
591 inHeader = NULL;
592 continue;
593 }
594
595 // Restore Offset and Length for Port reconfig case
596 size_t tempOffset = inHeader->nOffset;
597 size_t tempFilledLen = inHeader->nFilledLen;
598 if (mIsADTS) {
599 size_t adtsHeaderSize = 0;
600 // skip 30 bits, aac_frame_length follows.
601 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
602
603 const uint8_t* adtsHeader = inHeader->pBuffer + inHeader->nOffset;
604
605 bool signalError = false;
606 if (inHeader->nFilledLen < 7) {
607 ALOGE(
608 "Audio data too short to contain even the ADTS header. "
609 "Got %d bytes.",
610 inHeader->nFilledLen);
611 hexdump(adtsHeader, inHeader->nFilledLen);
612 signalError = true;
613 } else {
614 bool protectionAbsent = (adtsHeader[1] & 1);
615
616 unsigned aac_frame_length =
617 ((adtsHeader[3] & 3) << 11) | (adtsHeader[4] << 3) | (adtsHeader[5] >> 5);
618
619 if (inHeader->nFilledLen < aac_frame_length) {
620 ALOGE(
621 "Not enough audio data for the complete frame. "
622 "Got %d bytes, frame size according to the ADTS "
623 "header is %u bytes.",
624 inHeader->nFilledLen, aac_frame_length);
625 hexdump(adtsHeader, inHeader->nFilledLen);
626 signalError = true;
627 } else {
628 adtsHeaderSize = (protectionAbsent ? 7 : 9);
629 if (aac_frame_length < adtsHeaderSize) {
630 signalError = true;
631 } else {
632 inBuffer = (uint8_t*)adtsHeader + adtsHeaderSize;
633 inBufferLength = aac_frame_length - adtsHeaderSize;
634
635 inHeader->nOffset += adtsHeaderSize;
636 inHeader->nFilledLen -= adtsHeaderSize;
637 }
638 }
639 }
640
641 if (signalError) {
642 mSignalledError = true;
643 notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL);
644 return;
645 }
646
647 // insert buffer size and time stamp
648 if (mLastInHeader != inHeader) {
649 mCurrentTimestamp = inHeader->nTimeStamp;
650 mLastInHeader = inHeader;
651 } else {
652 mCurrentTimestamp = mPrevTimestamp + mOutputFrameLength * 1000000LL / mSampFreq;
653 }
654 } else {
655 inBuffer = inHeader->pBuffer + inHeader->nOffset;
656 inBufferLength = inHeader->nFilledLen;
657 mLastInHeader = inHeader;
658 mCurrentTimestamp = inHeader->nTimeStamp;
659 }
660
661 int numLoops = 0;
662 signed int prevSampleRate = mSampFreq;
663 signed int prevNumChannels = mNumChannels;
664
665 /* XAAC decoder expects first frame to be fed via configXAACDecoder API */
666 /* which should initialize the codec. Once this state is reached, call the */
667 /* decodeXAACStream API with same frame to decode! */
668 if (!mIsCodecInitialized) {
669 IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
670 if (IA_NO_ERROR != err_code) {
671 ALOGW("configXAACDecoder Failed 2 err_code = %d", err_code);
672 mSignalledError = true;
673 notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
674 return;
675 }
676 }
677
678 if (!mSampFreq || !mNumChannels) {
679 if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
680 ALOGW("Invalid AAC stream");
681 ALOGW("mSampFreq %d mNumChannels %d ", mSampFreq, mNumChannels);
682 mSignalledError = true;
683 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
684 return;
685 }
686 } else if ((mSampFreq != prevSampleRate) || (mNumChannels != prevNumChannels)) {
687 ALOGV("Reconfiguring decoder: %d->%d Hz, %d->%d channels", prevSampleRate,
688 mSampFreq, prevNumChannels, mNumChannels);
689 inHeader->nOffset = tempOffset;
690 inHeader->nFilledLen = tempFilledLen;
691 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
692 mOutputPortSettingsChange = AWAITING_DISABLED;
693 return;
694 }
695
696 signed int bytesConsumed = 0;
697 int errorCode = 0;
698 if (mIsCodecInitialized) {
699 mIsCodecConfigFlushRequired = true;
700 errorCode =
701 decodeXAACStream(inBuffer, inBufferLength, &bytesConsumed, &numOutBytes);
702 } else if (!mIsCodecConfigFlushRequired) {
703 ALOGW("Assumption that first frame after header initializes decoder failed!");
704 mSignalledError = true;
705 notify(OMX_EventError, OMX_ErrorUndefined, -1, NULL);
706 return;
707 }
708 inHeader->nFilledLen -= bytesConsumed;
709 inHeader->nOffset += bytesConsumed;
710
711 if (inHeader->nFilledLen != 0) {
712 ALOGE("All data not consumed");
713 }
714
715 /* In case of error, decoder would have given out empty buffer */
716 if ((0 != errorCode) && (0 == numOutBytes) && mIsCodecInitialized) {
717 numOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels;
718 }
719 numLoops++;
720
721 if (0 == bytesConsumed) {
722 ALOGW("bytesConsumed is zero");
723 }
724
725 if (errorCode) {
726 /* Clear buffer for output buffer is done inside XAAC codec */
727 /* TODO - Check if below memset is on top of reset inside codec */
728 memset(mOutputBuffer, 0, numOutBytes); // TODO: check for overflow, ASAN
729 // Discard input buffer.
730 inHeader->nFilledLen = 0;
731 // fall through
732 }
733
734 if (inHeader->nFilledLen == 0) {
735 inInfo->mOwnedByUs = false;
736 mInputBufferCount++;
737 inQueue.erase(inQueue.begin());
738 mLastInHeader = NULL;
739 inInfo = NULL;
740 notifyEmptyBufferDone(inHeader);
741 inHeader = NULL;
742 } else {
743 ALOGV("inHeader->nFilledLen = %d", inHeader->nFilledLen);
744 }
745
746 if (!outQueue.empty() && numOutBytes) {
747 BufferInfo* outInfo = *outQueue.begin();
748 OMX_BUFFERHEADERTYPE* outHeader = outInfo->mHeader;
749
750 if (outHeader->nOffset != 0) {
751 ALOGE("outHeader->nOffset != 0 is not handled");
752 mSignalledError = true;
753 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
754 return;
755 }
756
757 signed short* outBuffer =
758 reinterpret_cast<signed short*>(outHeader->pBuffer + outHeader->nOffset);
759 int samplesize = mNumChannels * sizeof(int16_t);
760 if (outHeader->nOffset + mOutputFrameLength * samplesize > outHeader->nAllocLen) {
761 ALOGE("buffer overflow");
762 mSignalledError = true;
763 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
764 return;
765 }
766 memcpy(outBuffer, mOutputBuffer, numOutBytes);
767 outHeader->nFilledLen = numOutBytes;
768
769 if (mEndOfInput && !outQueue.empty()) {
770 outHeader->nFlags = OMX_BUFFERFLAG_EOS;
771 mEndOfOutput = true;
772 } else {
773 outHeader->nFlags = 0;
774 }
775 outHeader->nTimeStamp = mCurrentTimestamp;
776 mPrevTimestamp = mCurrentTimestamp;
777
778 mOutputBufferCount++;
779 outInfo->mOwnedByUs = false;
780 outQueue.erase(outQueue.begin());
781 outInfo = NULL;
782 notifyFillBufferDone(outHeader);
783 outHeader = NULL;
784 }
785 }
786
787 if (mEndOfInput) {
788 if (!outQueue.empty()) {
789 if (!mEndOfOutput) {
790 ALOGV(" empty block signaling EOS");
791 // send partial or empty block signaling EOS
792 mEndOfOutput = true;
793 BufferInfo* outInfo = *outQueue.begin();
794 OMX_BUFFERHEADERTYPE* outHeader = outInfo->mHeader;
795
796 outHeader->nFilledLen = 0;
797 outHeader->nFlags = OMX_BUFFERFLAG_EOS;
798 outHeader->nTimeStamp = mPrevTimestamp;
799
800 mOutputBufferCount++;
801 outInfo->mOwnedByUs = false;
802 outQueue.erase(outQueue.begin());
803 outInfo = NULL;
804 notifyFillBufferDone(outHeader);
805 outHeader = NULL;
806 }
807 break; // if outQueue not empty but no more output
808 }
809 }
810 }
811 }
812
onPortFlushCompleted(OMX_U32 portIndex)813 void SoftXAAC::onPortFlushCompleted(OMX_U32 portIndex) {
814 if (portIndex == 0) {
815 // Make sure that the next buffer output does not still
816 // depend on fragments from the last one decoded.
817 // drain all existing data
818 if (mIsCodecInitialized) {
819 IA_ERRORCODE err_code = configflushDecode();
820 if (err_code != IA_NO_ERROR) {
821 ALOGE("Error in configflushDecode: Error %d", err_code);
822 }
823 }
824 drainDecoder();
825 mLastInHeader = NULL;
826 mEndOfInput = false;
827 } else {
828 mEndOfOutput = false;
829 }
830 }
831
configflushDecode()832 IA_ERRORCODE SoftXAAC::configflushDecode() {
833 IA_ERRORCODE err_code;
834 UWORD32 ui_init_done;
835 uint32_t inBufferLength = 8203;
836
837 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_FLUSH_MEM, NULL);
838 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_FLUSH_MEM");
839
840 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
841 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
842
843 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_FLUSH_MEM, NULL);
844 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_FLUSH_MEM");
845
846 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_DONE_QUERY,
847 &ui_init_done);
848 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_DONE_QUERY");
849
850 if (ui_init_done) {
851 err_code = getXAACStreamInfo();
852 RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
853
854 ALOGV(
855 "Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz "
856 "%d\nchannelMask %d\noutputFrameLength %d",
857 mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
858
859 mIsCodecInitialized = true;
860 }
861 return IA_NO_ERROR;
862 }
drainDecoder()863 IA_ERRORCODE SoftXAAC::drainDecoder() {
864 return IA_NO_ERROR;
865 }
866
onReset()867 void SoftXAAC::onReset() {
868 drainDecoder();
869
870 // reset the "configured" state
871 mInputBufferCount = 0;
872 mOutputBufferCount = 0;
873 mEndOfInput = false;
874 mEndOfOutput = false;
875 mLastInHeader = NULL;
876
877 mSignalledError = false;
878 mOutputPortSettingsChange = NONE;
879 }
880
onPortEnableCompleted(OMX_U32 portIndex,bool enabled)881 void SoftXAAC::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
882 if (portIndex != 1) {
883 return;
884 }
885
886 switch (mOutputPortSettingsChange) {
887 case NONE:
888 break;
889
890 case AWAITING_DISABLED: {
891 CHECK(!enabled);
892 mOutputPortSettingsChange = AWAITING_ENABLED;
893 break;
894 }
895
896 default: {
897 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
898 CHECK(enabled);
899 mOutputPortSettingsChange = NONE;
900 break;
901 }
902 }
903 }
904
initXAACDecoder()905 IA_ERRORCODE SoftXAAC::initXAACDecoder() {
906 LOOPIDX i;
907
908 /* Error code */
909 IA_ERRORCODE err_code = IA_NO_ERROR;
910
911 /* First part */
912 /* Error Handler Init */
913 /* Get Library Name, Library Version and API Version */
914 /* Initialize API structure + Default config set */
915 /* Set config params from user */
916 /* Initialize memory tables */
917 /* Get memory information and allocate memory */
918
919 /* Memory variables */
920 UWORD32 ui_proc_mem_tabs_size;
921 /* API size */
922 UWORD32 pui_api_size;
923 pVOID pv_alloc_ptr;
924
925 mInputBufferSize = 0;
926 mInputBuffer = 0;
927 mOutputBuffer = 0;
928
929 /* Process struct initing end */
930 /* ******************************************************************/
931 /* Initialize API structure and set config params to default */
932 /* ******************************************************************/
933
934 /* Get the API size */
935 err_code = ixheaacd_dec_api(NULL, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
936 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
937
938 /* Allocate memory for API */
939 mXheaacCodecHandle = memalign(4, pui_api_size);
940 if (mXheaacCodecHandle == NULL) {
941 ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
942 return IA_FATAL_ERROR;
943 }
944 mMemoryVec.push(mXheaacCodecHandle);
945
946 /* Set the config params to default values */
947 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
948 IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, NULL);
949 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
950 #ifdef ENABLE_MPEG_D_DRC
951 /* Get the API size */
952 err_code = ia_drc_dec_api(NULL, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
953
954 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
955
956 /* Allocate memory for API */
957 mMpegDDrcHandle = memalign(4, pui_api_size);
958
959 if (mMpegDDrcHandle == NULL) {
960 ALOGE("malloc for drc api structure Failed");
961 return IA_FATAL_ERROR;
962 }
963 mMemoryVec.push(mMpegDDrcHandle);
964
965 memset(mMpegDDrcHandle, 0, pui_api_size);
966
967 /* Set the config params to default values */
968 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
969 IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, NULL);
970
971 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
972 #endif
973
974 /* ******************************************************************/
975 /* Set config parameters */
976 /* ******************************************************************/
977 UWORD32 ui_mp4_flag = 1;
978 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
979 IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4, &ui_mp4_flag);
980 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4");
981
982 /* ******************************************************************/
983 /* Initialize Memory info tables */
984 /* ******************************************************************/
985
986 /* Get memory info tables size */
987 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0,
988 &ui_proc_mem_tabs_size);
989 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
990
991 pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
992 if (pv_alloc_ptr == NULL) {
993 ALOGE("Malloc for size (ui_proc_mem_tabs_size + 4) = %d failed!",
994 ui_proc_mem_tabs_size + 4);
995 return IA_FATAL_ERROR;
996 }
997 mMemoryVec.push(pv_alloc_ptr);
998
999 /* Set pointer for process memory tables */
1000 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEMTABS_PTR, 0, pv_alloc_ptr);
1001 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
1002
1003 /* initialize the API, post config, fill memory tables */
1004 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
1005 IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, NULL);
1006 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
1007
1008 /* ******************************************************************/
1009 /* Allocate Memory with info from library */
1010 /* ******************************************************************/
1011 /* There are four different types of memories, that needs to be allocated */
1012 /* persistent,scratch,input and output */
1013 for (i = 0; i < 4; i++) {
1014 int ui_size = 0, ui_alignment = 0, ui_type = 0;
1015 pVOID pv_alloc_ptr;
1016
1017 /* Get memory size */
1018 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
1019 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
1020
1021 /* Get memory alignment */
1022 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i,
1023 &ui_alignment);
1024 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
1025
1026 /* Get memory type */
1027 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
1028 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
1029
1030 pv_alloc_ptr = memalign(ui_alignment, ui_size);
1031 if (pv_alloc_ptr == NULL) {
1032 ALOGE("Malloc for size (ui_size + ui_alignment) = %d failed!", ui_size + ui_alignment);
1033 return IA_FATAL_ERROR;
1034 }
1035 mMemoryVec.push(pv_alloc_ptr);
1036
1037 /* Set the buffer pointer */
1038 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
1039 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
1040 if (ui_type == IA_MEMTYPE_INPUT) {
1041 mInputBuffer = (pWORD8)pv_alloc_ptr;
1042 mInputBufferSize = ui_size;
1043 }
1044
1045 if (ui_type == IA_MEMTYPE_OUTPUT) {
1046 mOutputBuffer = (pWORD8)pv_alloc_ptr;
1047 }
1048 }
1049 /* End first part */
1050
1051 return IA_NO_ERROR;
1052 }
1053
configXAACDecoder(uint8_t * inBuffer,uint32_t inBufferLength)1054 IA_ERRORCODE SoftXAAC::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
1055 UWORD32 ui_init_done;
1056 int32_t i_bytes_consumed;
1057
1058 if (mInputBufferSize < inBufferLength) {
1059 ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize,
1060 inBufferLength);
1061 return false;
1062 }
1063
1064 /* Copy the buffer passed by Android plugin to codec input buffer */
1065 memcpy(mInputBuffer, inBuffer, inBufferLength);
1066
1067 /* Set number of bytes to be processed */
1068 IA_ERRORCODE err_code =
1069 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
1070 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
1071
1072 if (mIsCodecConfigFlushRequired) {
1073 /* If codec is already initialized, then GA header is passed again */
1074 /* Need to call the Flush API instead of INIT_PROCESS */
1075 mIsCodecInitialized = false; /* Codec needs to be Reinitialized after flush */
1076 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_GA_HDR, NULL);
1077 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_GA_HDR");
1078 } else {
1079 /* Initialize the process */
1080 err_code =
1081 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_PROCESS, NULL);
1082 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS");
1083 }
1084
1085 /* Checking for end of initialization */
1086 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_DONE_QUERY,
1087 &ui_init_done);
1088 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_DONE_QUERY");
1089
1090 /* How much buffer is used in input buffers */
1091 err_code =
1092 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CURIDX_INPUT_BUF, 0, &i_bytes_consumed);
1093 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_CURIDX_INPUT_BUF");
1094
1095 if (ui_init_done) {
1096 err_code = getXAACStreamInfo();
1097 RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
1098
1099 ALOGI(
1100 "Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz "
1101 "%d\nchannelMask %d\noutputFrameLength %d",
1102 mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
1103 mIsCodecInitialized = true;
1104
1105 #ifdef ENABLE_MPEG_D_DRC
1106 err_code = configMPEGDDrc();
1107 RETURN_IF_FATAL(err_code, "configMPEGDDrc");
1108 #endif
1109 }
1110
1111 return IA_NO_ERROR;
1112 }
initMPEGDDDrc()1113 IA_ERRORCODE SoftXAAC::initMPEGDDDrc() {
1114 IA_ERRORCODE err_code = IA_NO_ERROR;
1115 int i;
1116
1117 for (i = 0; i < (WORD32)2; i++) {
1118 WORD32 ui_size, ui_alignment, ui_type;
1119 pVOID pv_alloc_ptr;
1120
1121 /* Get memory size */
1122 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
1123
1124 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
1125
1126 /* Get memory alignment */
1127 err_code =
1128 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment);
1129
1130 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
1131
1132 /* Get memory type */
1133 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
1134 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
1135
1136 pv_alloc_ptr = memalign(4, ui_size);
1137 if (pv_alloc_ptr == NULL) {
1138 ALOGE(" Cannot create requested memory %d", ui_size);
1139 return IA_FATAL_ERROR;
1140 }
1141 mDrcMemoryVec.push(pv_alloc_ptr);
1142
1143 /* Set the buffer pointer */
1144 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
1145
1146 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
1147 }
1148
1149 WORD32 ui_size;
1150 ui_size = 8192 * 2;
1151
1152 mDrcInBuf = (int8_t*)memalign(4, ui_size);
1153 if (mDrcInBuf == NULL) {
1154 ALOGE(" Cannot create requested memory %d", ui_size);
1155 return IA_FATAL_ERROR;
1156 }
1157 mDrcMemoryVec.push(mDrcInBuf);
1158
1159 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2, mDrcInBuf);
1160 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
1161
1162 mDrcOutBuf = (int8_t*)memalign(4, ui_size);
1163 if (mDrcOutBuf == NULL) {
1164 ALOGE(" Cannot create requested memory %d", ui_size);
1165 return IA_FATAL_ERROR;
1166 }
1167 mDrcMemoryVec.push(mDrcOutBuf);
1168
1169 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3, mDrcOutBuf);
1170 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
1171
1172 return IA_NO_ERROR;
1173 }
configMPEGDDrc()1174 IA_ERRORCODE SoftXAAC::configMPEGDDrc() {
1175 IA_ERRORCODE err_code = IA_NO_ERROR;
1176 int i_effect_type;
1177 int i_loud_norm;
1178 int i_target_loudness;
1179 unsigned int i_sbr_mode;
1180 int i;
1181 int ui_proc_mem_tabs_size = 0;
1182 pVOID pv_alloc_ptr = NULL;
1183
1184 #ifdef ENABLE_MPEG_D_DRC
1185 {
1186 /* Sampling Frequency */
1187 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1188 IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
1189 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ");
1190 /* Total Number of Channels */
1191 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1192 IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
1193 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
1194
1195 /* PCM word size */
1196 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1197 IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
1198 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ");
1199
1200 /*Set Effect Type*/
1201
1202 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1203 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, &i_effect_type);
1204 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
1205
1206 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1207 IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
1208 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
1209
1210 /*Set target loudness */
1211 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1212 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS,
1213 &i_target_loudness);
1214 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
1215
1216 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1217 IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
1218 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
1219
1220 /*Set loud_norm_flag*/
1221 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1222 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, &i_loud_norm);
1223 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
1224
1225 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1226 IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
1227 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
1228
1229 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1230 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode);
1231 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
1232
1233 /* Get memory info tables size */
1234 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0,
1235 &ui_proc_mem_tabs_size);
1236
1237 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
1238
1239 pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
1240
1241 if (pv_alloc_ptr == NULL) {
1242 ALOGE("Cannot create requested memory %d", ui_proc_mem_tabs_size);
1243 return IA_FATAL_ERROR;
1244 }
1245
1246 memset(pv_alloc_ptr, 0, ui_proc_mem_tabs_size);
1247
1248 mMemoryVec.push(pv_alloc_ptr);
1249
1250 /* Set pointer for process memory tables */
1251 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
1252 pv_alloc_ptr);
1253
1254 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
1255
1256 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1257 IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, NULL);
1258
1259 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
1260
1261 /* Free any memory that is allocated for MPEG D Drc so far */
1262 deInitMPEGDDDrc();
1263
1264 err_code = initMPEGDDDrc();
1265 if (err_code != IA_NO_ERROR) {
1266 ALOGE("initMPEGDDDrc failed with error %d", err_code);
1267 deInitMPEGDDDrc();
1268 return err_code;
1269 }
1270
1271 /* DRC buffers
1272 buf[0] - contains extension element pay load loudness related
1273 buf[1] - contains extension element pay load*/
1274 {
1275 VOID* p_array[2][16];
1276 WORD32 ii;
1277 WORD32 buf_sizes[2][16];
1278 WORD32 num_elements;
1279 WORD32 num_config_ext;
1280 WORD32 bit_str_fmt = 1;
1281
1282 WORD32 uo_num_chan;
1283
1284 memset(buf_sizes, 0, 32 * sizeof(WORD32));
1285
1286 err_code =
1287 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1288 IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES, &buf_sizes[0][0]);
1289 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES");
1290
1291 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1292 IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR, &p_array);
1293 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR");
1294
1295 err_code =
1296 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_SET_BUFF_PTR, 0);
1297 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_SET_BUFF_PTR");
1298
1299 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1300 IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE, &num_elements);
1301 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE");
1302
1303 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1304 IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT, &num_config_ext);
1305 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT");
1306
1307 for (ii = 0; ii < num_config_ext; ii++) {
1308 /*copy loudness bitstream*/
1309 if (buf_sizes[0][ii] > 0) {
1310 memcpy(mDrcInBuf, p_array[0][ii], buf_sizes[0][ii]);
1311
1312 /*Set bitstream_split_format */
1313 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1314 IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
1315 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1316
1317 /* Set number of bytes to be processed */
1318 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IL_BS, 0,
1319 &buf_sizes[0][ii]);
1320 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IL_BS");
1321
1322 /* Execute process */
1323 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1324 IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF, NULL);
1325 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF");
1326
1327 mDRCFlag = 1;
1328 }
1329 }
1330
1331 for (ii = 0; ii < num_elements; ii++) {
1332 /*copy config bitstream*/
1333 if (buf_sizes[1][ii] > 0) {
1334 memcpy(mDrcInBuf, p_array[1][ii], buf_sizes[1][ii]);
1335 /* Set number of bytes to be processed */
1336
1337 /*Set bitstream_split_format */
1338 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1339 IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
1340 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1341
1342 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IC_BS, 0,
1343 &buf_sizes[1][ii]);
1344 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IC_BS");
1345
1346 /* Execute process */
1347 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1348 IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF, NULL);
1349
1350 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF");
1351
1352 mDRCFlag = 1;
1353 }
1354 }
1355
1356 if (mDRCFlag == 1) {
1357 mMpegDDRCPresent = 1;
1358 } else {
1359 mMpegDDRCPresent = 0;
1360 }
1361
1362 /*Read interface buffer config file bitstream*/
1363 if (mMpegDDRCPresent == 1) {
1364 WORD32 interface_is_present = 1;
1365 WORD32 frame_length;
1366
1367 if (i_sbr_mode != 0) {
1368 if (i_sbr_mode == 1) {
1369 frame_length = 2048;
1370 } else if (i_sbr_mode == 3) {
1371 frame_length = 4096;
1372 } else {
1373 frame_length = 1024;
1374 }
1375 } else {
1376 frame_length = 4096;
1377 }
1378
1379 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1380 IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE, &frame_length);
1381 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE");
1382
1383 err_code =
1384 ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1385 IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT, &interface_is_present);
1386 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT");
1387
1388 /* Execute process */
1389 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1390 IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF, NULL);
1391 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF");
1392
1393 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1394 IA_CMD_TYPE_INIT_PROCESS, NULL);
1395 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS");
1396
1397 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_CONFIG_PARAM,
1398 IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &uo_num_chan);
1399 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
1400 }
1401 }
1402 }
1403 #endif
1404
1405 return IA_NO_ERROR;
1406 }
decodeXAACStream(uint8_t * inBuffer,uint32_t inBufferLength,int32_t * bytesConsumed,int32_t * outBytes)1407 IA_ERRORCODE SoftXAAC::decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength,
1408 int32_t* bytesConsumed, int32_t* outBytes) {
1409 if (mInputBufferSize < inBufferLength) {
1410 ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize,
1411 inBufferLength);
1412 return -1;
1413 }
1414
1415 /* Copy the buffer passed by Android plugin to codec input buffer */
1416 memcpy(mInputBuffer, inBuffer, inBufferLength);
1417
1418 /* Set number of bytes to be processed */
1419 IA_ERRORCODE err_code =
1420 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
1421 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
1422
1423 /* Execute process */
1424 err_code =
1425 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DO_EXECUTE, NULL);
1426 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
1427
1428 UWORD32 ui_exec_done;
1429 WORD32 i_num_preroll = 0;
1430 /* Checking for end of processing */
1431 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DONE_QUERY,
1432 &ui_exec_done);
1433 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DONE_QUERY");
1434
1435 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1436 IA_ENHAACPLUS_DEC_CONFIG_GET_NUM_PRE_ROLL_FRAMES,
1437 &i_num_preroll);
1438
1439 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GET_NUM_PRE_ROLL_FRAMES");
1440 {
1441 int32_t pi_preroll_frame_offset = 0;
1442 do {
1443 #ifdef ENABLE_MPEG_D_DRC
1444 if (ui_exec_done != 1) {
1445 VOID* p_array; // ITTIAM:buffer to handle gain payload
1446 WORD32 buf_size = 0; // ITTIAM:gain payload length
1447 WORD32 bit_str_fmt = 1;
1448 WORD32 gain_stream_flag = 1;
1449
1450 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1451 IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN, &buf_size);
1452 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN");
1453
1454 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1455 IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF, &p_array);
1456 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF");
1457
1458 if (buf_size > 0) {
1459 /*Set bitstream_split_format */
1460 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1461 IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
1462 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1463
1464 memcpy(mDrcInBuf, p_array, buf_size);
1465 /* Set number of bytes to be processed */
1466 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_BS,
1467 0, &buf_size);
1468 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1469
1470 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1471 IA_DRC_DEC_CONFIG_GAIN_STREAM_FLAG,
1472 &gain_stream_flag);
1473 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1474
1475 /* Execute process */
1476 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
1477 IA_CMD_TYPE_INIT_CPY_BSF_BUFF, NULL);
1478 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
1479
1480 mMpegDDRCPresent = 1;
1481 }
1482 }
1483 #endif
1484 /* How much buffer is used in input buffers */
1485 err_code =
1486 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CURIDX_INPUT_BUF,
1487 0, bytesConsumed);
1488 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_CURIDX_INPUT_BUF");
1489
1490 /* Get the output bytes */
1491 err_code = ixheaacd_dec_api(mXheaacCodecHandle,
1492 IA_API_CMD_GET_OUTPUT_BYTES, 0, outBytes);
1493 RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_OUTPUT_BYTES");
1494 #ifdef ENABLE_MPEG_D_DRC
1495
1496 if (mMpegDDRCPresent == 1) {
1497 memcpy(mDrcInBuf, mOutputBuffer + pi_preroll_frame_offset, *outBytes);
1498 pi_preroll_frame_offset += *outBytes;
1499 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES,
1500 0, outBytes);
1501 RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
1502
1503 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_EXECUTE,
1504 IA_CMD_TYPE_DO_EXECUTE, NULL);
1505 RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
1506
1507 memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
1508 }
1509 #endif
1510 i_num_preroll--;
1511 } while (i_num_preroll > 0);
1512 }
1513 return IA_NO_ERROR;
1514 }
1515
deInitXAACDecoder()1516 IA_ERRORCODE SoftXAAC::deInitXAACDecoder() {
1517 ALOGI("deInitXAACDecoder");
1518
1519 /* Tell that the input is over in this buffer */
1520 IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INPUT_OVER, 0, NULL);
1521
1522 /* Irrespective of error returned in IA_API_CMD_INPUT_OVER, free allocated memory */
1523 for (void* buf : mMemoryVec) {
1524 free(buf);
1525 }
1526 mMemoryVec.clear();
1527 return err_code;
1528 }
1529
deInitMPEGDDDrc()1530 IA_ERRORCODE SoftXAAC::deInitMPEGDDDrc() {
1531 ALOGI("deInitMPEGDDDrc");
1532
1533 for (void* buf : mDrcMemoryVec) {
1534 free(buf);
1535 }
1536 mDrcMemoryVec.clear();
1537 return IA_NO_ERROR;
1538 }
1539
getXAACStreamInfo()1540 IA_ERRORCODE SoftXAAC::getXAACStreamInfo() {
1541 IA_ERRORCODE err_code = IA_NO_ERROR;
1542
1543 /* Sampling frequency */
1544 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1545 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
1546 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ");
1547
1548 /* Total Number of Channels */
1549 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1550 IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
1551 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS");
1552 if (mNumChannels > MAX_CHANNEL_COUNT) {
1553 ALOGE(" No of channels are more than max channels\n");
1554 return IA_FATAL_ERROR;
1555 }
1556
1557 /* PCM word size */
1558 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1559 IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
1560 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ");
1561 if ((mPcmWdSz / 8) != 2) {
1562 ALOGE("Invalid Number of bytes per sample: %d, Expected is 2", mPcmWdSz);
1563 return IA_FATAL_ERROR;
1564 }
1565
1566 /* channel mask to tell the arrangement of channels in bit stream */
1567 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1568 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK, &mChannelMask);
1569 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK");
1570
1571 /* Channel mode to tell MONO/STEREO/DUAL-MONO/NONE_OF_THESE */
1572 UWORD32 ui_channel_mode;
1573 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1574 IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE, &ui_channel_mode);
1575 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE");
1576 if (ui_channel_mode == 0)
1577 ALOGV("Channel Mode: MONO_OR_PS\n");
1578 else if (ui_channel_mode == 1)
1579 ALOGV("Channel Mode: STEREO\n");
1580 else if (ui_channel_mode == 2)
1581 ALOGV("Channel Mode: DUAL-MONO\n");
1582 else
1583 ALOGV("Channel Mode: NONE_OF_THESE or MULTICHANNEL\n");
1584
1585 /* Channel mode to tell SBR PRESENT/NOT_PRESENT */
1586 UWORD32 ui_sbr_mode;
1587 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1588 IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &ui_sbr_mode);
1589 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
1590 if (ui_sbr_mode == 0)
1591 ALOGV("SBR Mode: NOT_PRESENT\n");
1592 else if (ui_sbr_mode == 1)
1593 ALOGV("SBR Mode: PRESENT\n");
1594 else
1595 ALOGV("SBR Mode: ILLEGAL\n");
1596
1597 /* mOutputFrameLength = 1024 * (1 + SBR_MODE) for AAC */
1598 /* For USAC it could be 1024 * 3 , support to query */
1599 /* not yet added in codec */
1600 mOutputFrameLength = 1024 * (1 + ui_sbr_mode);
1601
1602 ALOGI("mOutputFrameLength %d ui_sbr_mode %d", mOutputFrameLength, ui_sbr_mode);
1603
1604 return IA_NO_ERROR;
1605 }
1606
setXAACDRCInfo(int32_t drcCut,int32_t drcBoost,int32_t drcRefLevel,int32_t drcHeavyCompression,int32_t drEffectType)1607 IA_ERRORCODE SoftXAAC::setXAACDRCInfo(int32_t drcCut, int32_t drcBoost, int32_t drcRefLevel,
1608 int32_t drcHeavyCompression
1609 #ifdef ENABLE_MPEG_D_DRC
1610 ,
1611 int32_t drEffectType
1612 #endif
1613 ) {
1614 IA_ERRORCODE err_code = IA_NO_ERROR;
1615
1616 int32_t ui_drc_enable = 1;
1617 int32_t i_effect_type, i_target_loudness, i_loud_norm;
1618 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1619 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE, &ui_drc_enable);
1620 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE");
1621 if (drcCut != -1) {
1622 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1623 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &drcCut);
1624 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
1625 }
1626
1627 if (drcBoost != -1) {
1628 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1629 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &drcBoost);
1630 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
1631 }
1632
1633 if (drcRefLevel != -1) {
1634 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1635 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, &drcRefLevel);
1636 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
1637 }
1638 #ifdef ENABLE_MPEG_D_DRC
1639 if (drcRefLevel != -1) {
1640 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1641 IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &drcRefLevel);
1642 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
1643 }
1644 #endif
1645 if (drcHeavyCompression != -1) {
1646 err_code =
1647 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1648 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP, &drcHeavyCompression);
1649 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
1650 }
1651
1652 #ifdef ENABLE_MPEG_D_DRC
1653 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
1654 IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &drEffectType);
1655 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
1656 #endif
1657
1658 #ifdef ENABLE_MPEG_D_DRC
1659 /*Set Effect Type*/
1660 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1661 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, &i_effect_type);
1662 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
1663
1664 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1665 IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
1666
1667 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
1668
1669 /*Set target loudness */
1670 err_code =
1671 ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1672 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
1673 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
1674
1675 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1676 IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
1677 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
1678
1679 /*Set loud_norm_flag*/
1680 err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
1681 IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, &i_loud_norm);
1682 RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
1683
1684 err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
1685 IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
1686
1687 RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
1688
1689 #endif
1690
1691 return IA_NO_ERROR;
1692 }
1693
1694 } // namespace android
1695
1696 __attribute__((cfi_canonical_jump_table))
createSoftOMXComponent(const char * name,const OMX_CALLBACKTYPE * callbacks,OMX_PTR appData,OMX_COMPONENTTYPE ** component)1697 android::SoftOMXComponent* createSoftOMXComponent(const char* name,
1698 const OMX_CALLBACKTYPE* callbacks,
1699 OMX_PTR appData, OMX_COMPONENTTYPE** component) {
1700 ALOGI("createSoftOMXComponent for SoftXAACDEC");
1701 return new android::SoftXAAC(name, callbacks, appData, component);
1702 }
1703