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