SoftAAC2.cpp revision 423766ca07beb7e3e9cd301385708ca13fcce3e1
1/* 2 * Copyright (C) 2012 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 "SoftAAC2" 19#include <utils/Log.h> 20 21#include "SoftAAC2.h" 22#include <OMX_AudioExt.h> 23#include <OMX_IndexExt.h> 24 25#include <cutils/properties.h> 26#include <media/stagefright/foundation/ADebug.h> 27#include <media/stagefright/foundation/hexdump.h> 28#include <media/stagefright/MediaErrors.h> 29 30#include <math.h> 31 32#define FILEREAD_MAX_LAYERS 2 33 34#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */ 35#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */ 36#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */ 37#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1 /* switch for heavy compression for mobile conf */ 38#define DRC_DEFAULT_MOBILE_ENC_LEVEL -1 /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */ 39#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */ 40// names of properties that can be used to override the default DRC settings 41#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level" 42#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut" 43#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost" 44#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy" 45#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level" 46 47namespace android { 48 49template<class T> 50static void InitOMXParams(T *params) { 51 params->nSize = sizeof(T); 52 params->nVersion.s.nVersionMajor = 1; 53 params->nVersion.s.nVersionMinor = 0; 54 params->nVersion.s.nRevision = 0; 55 params->nVersion.s.nStep = 0; 56} 57 58SoftAAC2::SoftAAC2( 59 const char *name, 60 const OMX_CALLBACKTYPE *callbacks, 61 OMX_PTR appData, 62 OMX_COMPONENTTYPE **component) 63 : SimpleSoftOMXComponent(name, callbacks, appData, component), 64 mAACDecoder(NULL), 65 mStreamInfo(NULL), 66 mIsADTS(false), 67 mInputBufferCount(0), 68 mOutputBufferCount(0), 69 mSignalledError(false), 70 mLastInHeader(NULL), 71 mOutputPortSettingsChange(NONE) { 72 initPorts(); 73 CHECK_EQ(initDecoder(), (status_t)OK); 74} 75 76SoftAAC2::~SoftAAC2() { 77 aacDecoder_Close(mAACDecoder); 78 delete mOutputDelayRingBuffer; 79} 80 81void SoftAAC2::initPorts() { 82 OMX_PARAM_PORTDEFINITIONTYPE def; 83 InitOMXParams(&def); 84 85 def.nPortIndex = 0; 86 def.eDir = OMX_DirInput; 87 def.nBufferCountMin = kNumInputBuffers; 88 def.nBufferCountActual = def.nBufferCountMin; 89 def.nBufferSize = 8192; 90 def.bEnabled = OMX_TRUE; 91 def.bPopulated = OMX_FALSE; 92 def.eDomain = OMX_PortDomainAudio; 93 def.bBuffersContiguous = OMX_FALSE; 94 def.nBufferAlignment = 1; 95 96 def.format.audio.cMIMEType = const_cast<char *>("audio/aac"); 97 def.format.audio.pNativeRender = NULL; 98 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 99 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 100 101 addPort(def); 102 103 def.nPortIndex = 1; 104 def.eDir = OMX_DirOutput; 105 def.nBufferCountMin = kNumOutputBuffers; 106 def.nBufferCountActual = def.nBufferCountMin; 107 def.nBufferSize = 4096 * MAX_CHANNEL_COUNT; 108 def.bEnabled = OMX_TRUE; 109 def.bPopulated = OMX_FALSE; 110 def.eDomain = OMX_PortDomainAudio; 111 def.bBuffersContiguous = OMX_FALSE; 112 def.nBufferAlignment = 2; 113 114 def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 115 def.format.audio.pNativeRender = NULL; 116 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 117 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 118 119 addPort(def); 120} 121 122status_t SoftAAC2::initDecoder() { 123 ALOGV("initDecoder()"); 124 status_t status = UNKNOWN_ERROR; 125 mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1); 126 if (mAACDecoder != NULL) { 127 mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder); 128 if (mStreamInfo != NULL) { 129 status = OK; 130 } 131 } 132 133 mEndOfInput = false; 134 mEndOfOutput = false; 135 mOutputDelayCompensated = 0; 136 mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax; 137 mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize]; 138 mOutputDelayRingBufferWritePos = 0; 139 mOutputDelayRingBufferReadPos = 0; 140 mOutputDelayRingBufferFilled = 0; 141 142 if (mAACDecoder == NULL) { 143 ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code"); 144 } 145 146 //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0); 147 148 //init DRC wrapper 149 mDrcWrap.setDecoderHandle(mAACDecoder); 150 mDrcWrap.submitStreamData(mStreamInfo); 151 152 // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties 153 // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone) 154 char value[PROPERTY_VALUE_MAX]; 155 // DRC_PRES_MODE_WRAP_DESIRED_TARGET 156 if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) { 157 unsigned refLevel = atoi(value); 158 ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d", refLevel, 159 DRC_DEFAULT_MOBILE_REF_LEVEL); 160 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, refLevel); 161 } else { 162 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, DRC_DEFAULT_MOBILE_REF_LEVEL); 163 } 164 // DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR 165 if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) { 166 unsigned cut = atoi(value); 167 ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", cut, 168 DRC_DEFAULT_MOBILE_DRC_CUT); 169 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, cut); 170 } else { 171 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT); 172 } 173 // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR 174 if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) { 175 unsigned boost = atoi(value); 176 ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", boost, 177 DRC_DEFAULT_MOBILE_DRC_BOOST); 178 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, boost); 179 } else { 180 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST); 181 } 182 // DRC_PRES_MODE_WRAP_DESIRED_HEAVY 183 if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) { 184 unsigned heavy = atoi(value); 185 ALOGV("AAC decoder using desried DRC heavy compression switch of %d instead of %d", heavy, 186 DRC_DEFAULT_MOBILE_DRC_HEAVY); 187 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, heavy); 188 } else { 189 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY); 190 } 191 // DRC_PRES_MODE_WRAP_ENCODER_TARGET 192 if (property_get(PROP_DRC_OVERRIDE_ENC_LEVEL, value, NULL)) { 193 unsigned encoderRefLevel = atoi(value); 194 ALOGV("AAC decoder using encoder-side DRC reference level of %d instead of %d", 195 encoderRefLevel, DRC_DEFAULT_MOBILE_ENC_LEVEL); 196 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, encoderRefLevel); 197 } else { 198 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, DRC_DEFAULT_MOBILE_ENC_LEVEL); 199 } 200 201 return status; 202} 203 204OMX_ERRORTYPE SoftAAC2::internalGetParameter( 205 OMX_INDEXTYPE index, OMX_PTR params) { 206 switch (index) { 207 case OMX_IndexParamAudioAac: 208 { 209 OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = 210 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; 211 212 if (!isValidOMXParam(aacParams)) { 213 return OMX_ErrorBadParameter; 214 } 215 216 if (aacParams->nPortIndex != 0) { 217 return OMX_ErrorUndefined; 218 } 219 220 aacParams->nBitRate = 0; 221 aacParams->nAudioBandWidth = 0; 222 aacParams->nAACtools = 0; 223 aacParams->nAACERtools = 0; 224 aacParams->eAACProfile = OMX_AUDIO_AACObjectMain; 225 226 aacParams->eAACStreamFormat = 227 mIsADTS 228 ? OMX_AUDIO_AACStreamFormatMP4ADTS 229 : OMX_AUDIO_AACStreamFormatMP4FF; 230 231 aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo; 232 233 if (!isConfigured()) { 234 aacParams->nChannels = 1; 235 aacParams->nSampleRate = 44100; 236 aacParams->nFrameLength = 0; 237 } else { 238 aacParams->nChannels = mStreamInfo->numChannels; 239 aacParams->nSampleRate = mStreamInfo->sampleRate; 240 aacParams->nFrameLength = mStreamInfo->frameSize; 241 } 242 243 return OMX_ErrorNone; 244 } 245 246 case OMX_IndexParamAudioPcm: 247 { 248 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 249 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 250 251 if (!isValidOMXParam(pcmParams)) { 252 return OMX_ErrorBadParameter; 253 } 254 255 if (pcmParams->nPortIndex != 1) { 256 return OMX_ErrorUndefined; 257 } 258 259 pcmParams->eNumData = OMX_NumericalDataSigned; 260 pcmParams->eEndian = OMX_EndianBig; 261 pcmParams->bInterleaved = OMX_TRUE; 262 pcmParams->nBitPerSample = 16; 263 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 264 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 265 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 266 pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF; 267 pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE; 268 pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS; 269 pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS; 270 271 if (!isConfigured()) { 272 pcmParams->nChannels = 1; 273 pcmParams->nSamplingRate = 44100; 274 } else { 275 pcmParams->nChannels = mStreamInfo->numChannels; 276 pcmParams->nSamplingRate = mStreamInfo->sampleRate; 277 } 278 279 return OMX_ErrorNone; 280 } 281 282 default: 283 return SimpleSoftOMXComponent::internalGetParameter(index, params); 284 } 285} 286 287OMX_ERRORTYPE SoftAAC2::internalSetParameter( 288 OMX_INDEXTYPE index, const OMX_PTR params) { 289 switch ((int)index) { 290 case OMX_IndexParamStandardComponentRole: 291 { 292 const OMX_PARAM_COMPONENTROLETYPE *roleParams = 293 (const OMX_PARAM_COMPONENTROLETYPE *)params; 294 295 if (!isValidOMXParam(roleParams)) { 296 return OMX_ErrorBadParameter; 297 } 298 299 if (strncmp((const char *)roleParams->cRole, 300 "audio_decoder.aac", 301 OMX_MAX_STRINGNAME_SIZE - 1)) { 302 return OMX_ErrorUndefined; 303 } 304 305 return OMX_ErrorNone; 306 } 307 308 case OMX_IndexParamAudioAac: 309 { 310 const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = 311 (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params; 312 313 if (!isValidOMXParam(aacParams)) { 314 return OMX_ErrorBadParameter; 315 } 316 317 if (aacParams->nPortIndex != 0) { 318 return OMX_ErrorUndefined; 319 } 320 321 if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) { 322 mIsADTS = false; 323 } else if (aacParams->eAACStreamFormat 324 == OMX_AUDIO_AACStreamFormatMP4ADTS) { 325 mIsADTS = true; 326 } else { 327 return OMX_ErrorUndefined; 328 } 329 330 return OMX_ErrorNone; 331 } 332 333 case OMX_IndexParamAudioAndroidAacPresentation: 334 { 335 const OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE *aacPresParams = 336 (const OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE *)params; 337 // for the following parameters of the OMX_AUDIO_PARAM_AACPROFILETYPE structure, 338 // a value of -1 implies the parameter is not set by the application: 339 // nMaxOutputChannels uses default platform properties, see configureDownmix() 340 // nDrcCut uses default platform properties, see initDecoder() 341 // nDrcBoost idem 342 // nHeavyCompression idem 343 // nTargetReferenceLevel idem 344 // nEncodedTargetLevel idem 345 if (aacPresParams->nMaxOutputChannels >= 0) { 346 int max; 347 if (aacPresParams->nMaxOutputChannels >= 8) { max = 8; } 348 else if (aacPresParams->nMaxOutputChannels >= 6) { max = 6; } 349 else if (aacPresParams->nMaxOutputChannels >= 2) { max = 2; } 350 else { 351 // -1 or 0: disable downmix, 1: mono 352 max = aacPresParams->nMaxOutputChannels; 353 } 354 ALOGV("set nMaxOutputChannels=%d", max); 355 aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, max); 356 } 357 bool updateDrcWrapper = false; 358 if (aacPresParams->nDrcBoost >= 0) { 359 ALOGV("set nDrcBoost=%d", aacPresParams->nDrcBoost); 360 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, 361 aacPresParams->nDrcBoost); 362 updateDrcWrapper = true; 363 } 364 if (aacPresParams->nDrcCut >= 0) { 365 ALOGV("set nDrcCut=%d", aacPresParams->nDrcCut); 366 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, aacPresParams->nDrcCut); 367 updateDrcWrapper = true; 368 } 369 if (aacPresParams->nHeavyCompression >= 0) { 370 ALOGV("set nHeavyCompression=%d", aacPresParams->nHeavyCompression); 371 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, 372 aacPresParams->nHeavyCompression); 373 updateDrcWrapper = true; 374 } 375 if (aacPresParams->nTargetReferenceLevel >= 0) { 376 ALOGV("set nTargetReferenceLevel=%d", aacPresParams->nTargetReferenceLevel); 377 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, 378 aacPresParams->nTargetReferenceLevel); 379 updateDrcWrapper = true; 380 } 381 if (aacPresParams->nEncodedTargetLevel >= 0) { 382 ALOGV("set nEncodedTargetLevel=%d", aacPresParams->nEncodedTargetLevel); 383 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, 384 aacPresParams->nEncodedTargetLevel); 385 updateDrcWrapper = true; 386 } 387 if (aacPresParams->nPCMLimiterEnable >= 0) { 388 aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 389 (aacPresParams->nPCMLimiterEnable != 0)); 390 } 391 if (updateDrcWrapper) { 392 mDrcWrap.update(); 393 } 394 395 return OMX_ErrorNone; 396 } 397 398 case OMX_IndexParamAudioPcm: 399 { 400 const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 401 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 402 403 if (!isValidOMXParam(pcmParams)) { 404 return OMX_ErrorBadParameter; 405 } 406 407 if (pcmParams->nPortIndex != 1) { 408 return OMX_ErrorUndefined; 409 } 410 411 return OMX_ErrorNone; 412 } 413 414 default: 415 return SimpleSoftOMXComponent::internalSetParameter(index, params); 416 } 417} 418 419bool SoftAAC2::isConfigured() const { 420 return mInputBufferCount > 0; 421} 422 423void SoftAAC2::configureDownmix() const { 424 char value[PROPERTY_VALUE_MAX]; 425 if (!(property_get("media.aac_51_output_enabled", value, NULL) 426 && (!strcmp(value, "1") || !strcasecmp(value, "true")))) { 427 ALOGI("limiting to stereo output"); 428 aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, 2); 429 // By default, the decoder creates a 5.1 channel downmix signal 430 // for seven and eight channel input streams. To enable 6.1 and 7.1 channel output 431 // use aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1) 432 } 433} 434 435bool SoftAAC2::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) { 436 if (numSamples == 0) { 437 return true; 438 } 439 if (outputDelayRingBufferSpaceLeft() < numSamples) { 440 ALOGE("RING BUFFER WOULD OVERFLOW"); 441 return false; 442 } 443 if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize 444 && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos 445 || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) { 446 // faster memcopy loop without checks, if the preconditions allow this 447 for (int32_t i = 0; i < numSamples; i++) { 448 mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i]; 449 } 450 451 if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) { 452 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize; 453 } 454 } else { 455 ALOGV("slow SoftAAC2::outputDelayRingBufferPutSamples()"); 456 457 for (int32_t i = 0; i < numSamples; i++) { 458 mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i]; 459 mOutputDelayRingBufferWritePos++; 460 if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) { 461 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize; 462 } 463 } 464 } 465 mOutputDelayRingBufferFilled += numSamples; 466 return true; 467} 468 469int32_t SoftAAC2::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) { 470 471 if (numSamples > mOutputDelayRingBufferFilled) { 472 ALOGE("RING BUFFER WOULD UNDERRUN"); 473 return -1; 474 } 475 476 if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize 477 && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos 478 || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) { 479 // faster memcopy loop without checks, if the preconditions allow this 480 if (samples != 0) { 481 for (int32_t i = 0; i < numSamples; i++) { 482 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++]; 483 } 484 } else { 485 mOutputDelayRingBufferReadPos += numSamples; 486 } 487 if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) { 488 mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize; 489 } 490 } else { 491 ALOGV("slow SoftAAC2::outputDelayRingBufferGetSamples()"); 492 493 for (int32_t i = 0; i < numSamples; i++) { 494 if (samples != 0) { 495 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos]; 496 } 497 mOutputDelayRingBufferReadPos++; 498 if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) { 499 mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize; 500 } 501 } 502 } 503 mOutputDelayRingBufferFilled -= numSamples; 504 return numSamples; 505} 506 507int32_t SoftAAC2::outputDelayRingBufferSamplesAvailable() { 508 return mOutputDelayRingBufferFilled; 509} 510 511int32_t SoftAAC2::outputDelayRingBufferSpaceLeft() { 512 return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable(); 513} 514 515 516void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) { 517 if (mSignalledError || mOutputPortSettingsChange != NONE) { 518 return; 519 } 520 521 UCHAR* inBuffer[FILEREAD_MAX_LAYERS]; 522 UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0}; 523 UINT bytesValid[FILEREAD_MAX_LAYERS] = {0}; 524 525 List<BufferInfo *> &inQueue = getPortQueue(0); 526 List<BufferInfo *> &outQueue = getPortQueue(1); 527 528 while ((!inQueue.empty() || mEndOfInput) && !outQueue.empty()) { 529 if (!inQueue.empty()) { 530 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT]; 531 BufferInfo *inInfo = *inQueue.begin(); 532 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 533 534 mEndOfInput = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0; 535 536 if (mInputBufferCount == 0 && !(inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 537 ALOGE("first buffer should have OMX_BUFFERFLAG_CODECCONFIG set"); 538 inHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; 539 } 540 if ((inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != 0) { 541 BufferInfo *inInfo = *inQueue.begin(); 542 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 543 544 inBuffer[0] = inHeader->pBuffer + inHeader->nOffset; 545 inBufferLength[0] = inHeader->nFilledLen; 546 547 AAC_DECODER_ERROR decoderErr = 548 aacDecoder_ConfigRaw(mAACDecoder, 549 inBuffer, 550 inBufferLength); 551 552 if (decoderErr != AAC_DEC_OK) { 553 ALOGW("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr); 554 mSignalledError = true; 555 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 556 return; 557 } 558 559 mInputBufferCount++; 560 mOutputBufferCount++; // fake increase of outputBufferCount to keep the counters aligned 561 562 inInfo->mOwnedByUs = false; 563 inQueue.erase(inQueue.begin()); 564 mLastInHeader = NULL; 565 inInfo = NULL; 566 notifyEmptyBufferDone(inHeader); 567 inHeader = NULL; 568 569 configureDownmix(); 570 // Only send out port settings changed event if both sample rate 571 // and numChannels are valid. 572 if (mStreamInfo->sampleRate && mStreamInfo->numChannels) { 573 ALOGI("Initially configuring decoder: %d Hz, %d channels", 574 mStreamInfo->sampleRate, 575 mStreamInfo->numChannels); 576 577 notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 578 mOutputPortSettingsChange = AWAITING_DISABLED; 579 } 580 return; 581 } 582 583 if (inHeader->nFilledLen == 0) { 584 inInfo->mOwnedByUs = false; 585 inQueue.erase(inQueue.begin()); 586 mLastInHeader = NULL; 587 inInfo = NULL; 588 notifyEmptyBufferDone(inHeader); 589 inHeader = NULL; 590 continue; 591 } 592 593 if (mIsADTS) { 594 size_t adtsHeaderSize = 0; 595 // skip 30 bits, aac_frame_length follows. 596 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll????? 597 598 const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset; 599 600 bool signalError = false; 601 if (inHeader->nFilledLen < 7) { 602 ALOGE("Audio data too short to contain even the ADTS header. " 603 "Got %d bytes.", inHeader->nFilledLen); 604 hexdump(adtsHeader, inHeader->nFilledLen); 605 signalError = true; 606 } else { 607 bool protectionAbsent = (adtsHeader[1] & 1); 608 609 unsigned aac_frame_length = 610 ((adtsHeader[3] & 3) << 11) 611 | (adtsHeader[4] << 3) 612 | (adtsHeader[5] >> 5); 613 614 if (inHeader->nFilledLen < aac_frame_length) { 615 ALOGE("Not enough audio data for the complete frame. " 616 "Got %d bytes, frame size according to the ADTS " 617 "header is %u bytes.", 618 inHeader->nFilledLen, aac_frame_length); 619 hexdump(adtsHeader, inHeader->nFilledLen); 620 signalError = true; 621 } else { 622 adtsHeaderSize = (protectionAbsent ? 7 : 9); 623 624 inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize; 625 inBufferLength[0] = aac_frame_length - adtsHeaderSize; 626 627 inHeader->nOffset += adtsHeaderSize; 628 inHeader->nFilledLen -= adtsHeaderSize; 629 } 630 } 631 632 if (signalError) { 633 mSignalledError = true; 634 notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL); 635 return; 636 } 637 638 // insert buffer size and time stamp 639 mBufferSizes.add(inBufferLength[0]); 640 if (mLastInHeader != inHeader) { 641 mBufferTimestamps.add(inHeader->nTimeStamp); 642 mLastInHeader = inHeader; 643 } else { 644 int64_t currentTime = mBufferTimestamps.top(); 645 currentTime += mStreamInfo->aacSamplesPerFrame * 646 1000000ll / mStreamInfo->sampleRate; 647 mBufferTimestamps.add(currentTime); 648 } 649 } else { 650 inBuffer[0] = inHeader->pBuffer + inHeader->nOffset; 651 inBufferLength[0] = inHeader->nFilledLen; 652 mLastInHeader = inHeader; 653 mBufferTimestamps.add(inHeader->nTimeStamp); 654 mBufferSizes.add(inHeader->nFilledLen); 655 } 656 657 // Fill and decode 658 bytesValid[0] = inBufferLength[0]; 659 660 INT prevSampleRate = mStreamInfo->sampleRate; 661 INT prevNumChannels = mStreamInfo->numChannels; 662 663 aacDecoder_Fill(mAACDecoder, 664 inBuffer, 665 inBufferLength, 666 bytesValid); 667 668 // run DRC check 669 mDrcWrap.submitStreamData(mStreamInfo); 670 mDrcWrap.update(); 671 672 UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0]; 673 inHeader->nFilledLen -= inBufferUsedLength; 674 inHeader->nOffset += inBufferUsedLength; 675 676 AAC_DECODER_ERROR decoderErr; 677 int numLoops = 0; 678 do { 679 if (outputDelayRingBufferSpaceLeft() < 680 (mStreamInfo->frameSize * mStreamInfo->numChannels)) { 681 ALOGV("skipping decode: not enough space left in ringbuffer"); 682 break; 683 } 684 685 int numConsumed = mStreamInfo->numTotalBytes; 686 decoderErr = aacDecoder_DecodeFrame(mAACDecoder, 687 tmpOutBuffer, 688 2048 * MAX_CHANNEL_COUNT, 689 0 /* flags */); 690 691 numConsumed = mStreamInfo->numTotalBytes - numConsumed; 692 numLoops++; 693 694 if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) { 695 break; 696 } 697 mDecodedSizes.add(numConsumed); 698 699 if (decoderErr != AAC_DEC_OK) { 700 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr); 701 } 702 703 if (bytesValid[0] != 0) { 704 ALOGE("bytesValid[0] != 0 should never happen"); 705 mSignalledError = true; 706 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 707 return; 708 } 709 710 size_t numOutBytes = 711 mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels; 712 713 if (decoderErr == AAC_DEC_OK) { 714 if (!outputDelayRingBufferPutSamples(tmpOutBuffer, 715 mStreamInfo->frameSize * mStreamInfo->numChannels)) { 716 mSignalledError = true; 717 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 718 return; 719 } 720 } else { 721 ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr); 722 723 memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow 724 725 if (!outputDelayRingBufferPutSamples(tmpOutBuffer, 726 mStreamInfo->frameSize * mStreamInfo->numChannels)) { 727 mSignalledError = true; 728 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 729 return; 730 } 731 732 // Discard input buffer. 733 if (inHeader) { 734 inHeader->nFilledLen = 0; 735 } 736 737 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1); 738 739 // After an error, replace the last entry in mBufferSizes with the sum of the 740 // last <numLoops> entries from mDecodedSizes to resynchronize the in/out lists. 741 mBufferSizes.pop(); 742 int n = 0; 743 for (int i = 0; i < numLoops; i++) { 744 n += mDecodedSizes.itemAt(mDecodedSizes.size() - numLoops + i); 745 } 746 mBufferSizes.add(n); 747 748 // fall through 749 } 750 751 /* 752 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly 753 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual 754 * rate system and the sampling rate in the final output is actually 755 * doubled compared with the core AAC decoder sampling rate. 756 * 757 * Explicit signalling is done by explicitly defining SBR audio object 758 * type in the bitstream. Implicit signalling is done by embedding 759 * SBR content in AAC extension payload specific to SBR, and hence 760 * requires an AAC decoder to perform pre-checks on actual audio frames. 761 * 762 * Thus, we could not say for sure whether a stream is 763 * AAC+/eAAC+ until the first data frame is decoded. 764 */ 765 if (mInputBufferCount <= 2 || mOutputBufferCount > 1) { // TODO: <= 1 766 if (mStreamInfo->sampleRate != prevSampleRate || 767 mStreamInfo->numChannels != prevNumChannels) { 768 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels", 769 prevSampleRate, mStreamInfo->sampleRate, 770 prevNumChannels, mStreamInfo->numChannels); 771 772 notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 773 mOutputPortSettingsChange = AWAITING_DISABLED; 774 775 if (inHeader && inHeader->nFilledLen == 0) { 776 inInfo->mOwnedByUs = false; 777 mInputBufferCount++; 778 inQueue.erase(inQueue.begin()); 779 mLastInHeader = NULL; 780 inInfo = NULL; 781 notifyEmptyBufferDone(inHeader); 782 inHeader = NULL; 783 } 784 return; 785 } 786 } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) { 787 ALOGW("Invalid AAC stream"); 788 mSignalledError = true; 789 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 790 return; 791 } 792 if (inHeader && inHeader->nFilledLen == 0) { 793 inInfo->mOwnedByUs = false; 794 mInputBufferCount++; 795 inQueue.erase(inQueue.begin()); 796 mLastInHeader = NULL; 797 inInfo = NULL; 798 notifyEmptyBufferDone(inHeader); 799 inHeader = NULL; 800 } else { 801 ALOGV("inHeader->nFilledLen = %d", inHeader ? inHeader->nFilledLen : 0); 802 } 803 } while (decoderErr == AAC_DEC_OK); 804 } 805 806 int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels; 807 808 if (!mEndOfInput && mOutputDelayCompensated < outputDelay) { 809 // discard outputDelay at the beginning 810 int32_t toCompensate = outputDelay - mOutputDelayCompensated; 811 int32_t discard = outputDelayRingBufferSamplesAvailable(); 812 if (discard > toCompensate) { 813 discard = toCompensate; 814 } 815 int32_t discarded = outputDelayRingBufferGetSamples(0, discard); 816 mOutputDelayCompensated += discarded; 817 continue; 818 } 819 820 if (mEndOfInput) { 821 while (mOutputDelayCompensated > 0) { 822 // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC 823 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT]; 824 825 // run DRC check 826 mDrcWrap.submitStreamData(mStreamInfo); 827 mDrcWrap.update(); 828 829 AAC_DECODER_ERROR decoderErr = 830 aacDecoder_DecodeFrame(mAACDecoder, 831 tmpOutBuffer, 832 2048 * MAX_CHANNEL_COUNT, 833 AACDEC_FLUSH); 834 if (decoderErr != AAC_DEC_OK) { 835 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr); 836 } 837 838 int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels; 839 if (tmpOutBufferSamples > mOutputDelayCompensated) { 840 tmpOutBufferSamples = mOutputDelayCompensated; 841 } 842 outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples); 843 mOutputDelayCompensated -= tmpOutBufferSamples; 844 } 845 } 846 847 while (!outQueue.empty() 848 && outputDelayRingBufferSamplesAvailable() 849 >= mStreamInfo->frameSize * mStreamInfo->numChannels) { 850 BufferInfo *outInfo = *outQueue.begin(); 851 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 852 853 if (outHeader->nOffset != 0) { 854 ALOGE("outHeader->nOffset != 0 is not handled"); 855 mSignalledError = true; 856 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 857 return; 858 } 859 860 INT_PCM *outBuffer = 861 reinterpret_cast<INT_PCM *>(outHeader->pBuffer + outHeader->nOffset); 862 int samplesize = mStreamInfo->numChannels * sizeof(int16_t); 863 if (outHeader->nOffset 864 + mStreamInfo->frameSize * samplesize 865 > outHeader->nAllocLen) { 866 ALOGE("buffer overflow"); 867 mSignalledError = true; 868 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 869 return; 870 871 } 872 873 int available = outputDelayRingBufferSamplesAvailable(); 874 int numSamples = outHeader->nAllocLen / sizeof(int16_t); 875 if (numSamples > available) { 876 numSamples = available; 877 } 878 int64_t currentTime = 0; 879 if (available) { 880 881 int numFrames = numSamples / (mStreamInfo->frameSize * mStreamInfo->numChannels); 882 numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels); 883 884 ALOGV("%d samples available (%d), or %d frames", 885 numSamples, available, numFrames); 886 int64_t *nextTimeStamp = &mBufferTimestamps.editItemAt(0); 887 currentTime = *nextTimeStamp; 888 int32_t *currentBufLeft = &mBufferSizes.editItemAt(0); 889 for (int i = 0; i < numFrames; i++) { 890 int32_t decodedSize = mDecodedSizes.itemAt(0); 891 mDecodedSizes.removeAt(0); 892 ALOGV("decoded %d of %d", decodedSize, *currentBufLeft); 893 if (*currentBufLeft > decodedSize) { 894 // adjust/interpolate next time stamp 895 *currentBufLeft -= decodedSize; 896 *nextTimeStamp += mStreamInfo->aacSamplesPerFrame * 897 1000000ll / mStreamInfo->sampleRate; 898 ALOGV("adjusted nextTimeStamp/size to %lld/%d", 899 *nextTimeStamp, *currentBufLeft); 900 } else { 901 // move to next timestamp in list 902 if (mBufferTimestamps.size() > 0) { 903 mBufferTimestamps.removeAt(0); 904 nextTimeStamp = &mBufferTimestamps.editItemAt(0); 905 mBufferSizes.removeAt(0); 906 currentBufLeft = &mBufferSizes.editItemAt(0); 907 ALOGV("moved to next time/size: %lld/%d", 908 *nextTimeStamp, *currentBufLeft); 909 } 910 // try to limit output buffer size to match input buffers 911 // (e.g when an input buffer contained 4 "sub" frames, output 912 // at most 4 decoded units in the corresponding output buffer) 913 // This is optional. Remove the next three lines to fill the output 914 // buffer with as many units as available. 915 numFrames = i + 1; 916 numSamples = numFrames * mStreamInfo->frameSize * mStreamInfo->numChannels; 917 break; 918 } 919 } 920 921 ALOGV("getting %d from ringbuffer", numSamples); 922 int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples); 923 if (ns != numSamples) { 924 ALOGE("not a complete frame of samples available"); 925 mSignalledError = true; 926 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 927 return; 928 } 929 } 930 931 outHeader->nFilledLen = numSamples * sizeof(int16_t); 932 933 if (mEndOfInput && !outQueue.empty() && outputDelayRingBufferSamplesAvailable() == 0) { 934 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 935 mEndOfOutput = true; 936 } else { 937 outHeader->nFlags = 0; 938 } 939 940 outHeader->nTimeStamp = currentTime; 941 942 mOutputBufferCount++; 943 outInfo->mOwnedByUs = false; 944 outQueue.erase(outQueue.begin()); 945 outInfo = NULL; 946 ALOGV("out timestamp %lld / %d", outHeader->nTimeStamp, outHeader->nFilledLen); 947 notifyFillBufferDone(outHeader); 948 outHeader = NULL; 949 } 950 951 if (mEndOfInput) { 952 if (outputDelayRingBufferSamplesAvailable() > 0 953 && outputDelayRingBufferSamplesAvailable() 954 < mStreamInfo->frameSize * mStreamInfo->numChannels) { 955 ALOGE("not a complete frame of samples available"); 956 mSignalledError = true; 957 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 958 return; 959 } 960 961 if (mEndOfInput && !outQueue.empty() && outputDelayRingBufferSamplesAvailable() == 0) { 962 if (!mEndOfOutput) { 963 // send empty block signaling EOS 964 mEndOfOutput = true; 965 BufferInfo *outInfo = *outQueue.begin(); 966 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 967 968 if (outHeader->nOffset != 0) { 969 ALOGE("outHeader->nOffset != 0 is not handled"); 970 mSignalledError = true; 971 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 972 return; 973 } 974 975 INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(outHeader->pBuffer 976 + outHeader->nOffset); 977 int32_t ns = 0; 978 outHeader->nFilledLen = 0; 979 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 980 981 outHeader->nTimeStamp = mBufferTimestamps.itemAt(0); 982 mBufferTimestamps.clear(); 983 mBufferSizes.clear(); 984 mDecodedSizes.clear(); 985 986 mOutputBufferCount++; 987 outInfo->mOwnedByUs = false; 988 outQueue.erase(outQueue.begin()); 989 outInfo = NULL; 990 notifyFillBufferDone(outHeader); 991 outHeader = NULL; 992 } 993 break; // if outQueue not empty but no more output 994 } 995 } 996 } 997} 998 999void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) { 1000 if (portIndex == 0) { 1001 // Make sure that the next buffer output does not still 1002 // depend on fragments from the last one decoded. 1003 // drain all existing data 1004 drainDecoder(); 1005 mBufferTimestamps.clear(); 1006 mBufferSizes.clear(); 1007 mDecodedSizes.clear(); 1008 mLastInHeader = NULL; 1009 } else { 1010 int avail; 1011 while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) { 1012 if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) { 1013 avail = mStreamInfo->frameSize * mStreamInfo->numChannels; 1014 } 1015 int32_t ns = outputDelayRingBufferGetSamples(0, avail); 1016 if (ns != avail) { 1017 ALOGE("not a complete frame of samples available"); 1018 break; 1019 } 1020 mOutputBufferCount++; 1021 } 1022 mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos; 1023 } 1024} 1025 1026void SoftAAC2::drainDecoder() { 1027 int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels; 1028 1029 // flush decoder until outputDelay is compensated 1030 while (mOutputDelayCompensated > 0) { 1031 // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC 1032 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT]; 1033 1034 // run DRC check 1035 mDrcWrap.submitStreamData(mStreamInfo); 1036 mDrcWrap.update(); 1037 1038 AAC_DECODER_ERROR decoderErr = 1039 aacDecoder_DecodeFrame(mAACDecoder, 1040 tmpOutBuffer, 1041 2048 * MAX_CHANNEL_COUNT, 1042 AACDEC_FLUSH); 1043 if (decoderErr != AAC_DEC_OK) { 1044 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr); 1045 } 1046 1047 int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels; 1048 if (tmpOutBufferSamples > mOutputDelayCompensated) { 1049 tmpOutBufferSamples = mOutputDelayCompensated; 1050 } 1051 outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples); 1052 1053 mOutputDelayCompensated -= tmpOutBufferSamples; 1054 } 1055} 1056 1057void SoftAAC2::onReset() { 1058 drainDecoder(); 1059 // reset the "configured" state 1060 mInputBufferCount = 0; 1061 mOutputBufferCount = 0; 1062 mOutputDelayCompensated = 0; 1063 mOutputDelayRingBufferWritePos = 0; 1064 mOutputDelayRingBufferReadPos = 0; 1065 mOutputDelayRingBufferFilled = 0; 1066 mEndOfInput = false; 1067 mEndOfOutput = false; 1068 mBufferTimestamps.clear(); 1069 mBufferSizes.clear(); 1070 mDecodedSizes.clear(); 1071 mLastInHeader = NULL; 1072 1073 // To make the codec behave the same before and after a reset, we need to invalidate the 1074 // streaminfo struct. This does that: 1075 mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only 1076 1077 mSignalledError = false; 1078 mOutputPortSettingsChange = NONE; 1079} 1080 1081void SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 1082 if (portIndex != 1) { 1083 return; 1084 } 1085 1086 switch (mOutputPortSettingsChange) { 1087 case NONE: 1088 break; 1089 1090 case AWAITING_DISABLED: 1091 { 1092 CHECK(!enabled); 1093 mOutputPortSettingsChange = AWAITING_ENABLED; 1094 break; 1095 } 1096 1097 default: 1098 { 1099 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 1100 CHECK(enabled); 1101 mOutputPortSettingsChange = NONE; 1102 break; 1103 } 1104 } 1105} 1106 1107} // namespace android 1108 1109android::SoftOMXComponent *createSoftOMXComponent( 1110 const char *name, const OMX_CALLBACKTYPE *callbacks, 1111 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 1112 return new android::SoftAAC2(name, callbacks, appData, component); 1113} 1114