xref: /aosp_15_r20/frameworks/av/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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