SoftAAC2.cpp revision 51f59b41eae9c4f493ebfd0972cee951895bdf19
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_TAG "SoftAAC2" 18//#define LOG_NDEBUG 0 19#include <utils/Log.h> 20 21#include "SoftAAC2.h" 22 23#include <cutils/properties.h> 24#include <media/stagefright/foundation/ADebug.h> 25#include <media/stagefright/foundation/hexdump.h> 26#include <media/stagefright/MediaErrors.h> 27 28#define FILEREAD_MAX_LAYERS 2 29 30#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */ 31#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */ 32#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */ 33#define MAX_CHANNEL_COUNT 6 /* maximum number of audio channels that can be decoded */ 34// names of properties that can be used to override the default DRC settings 35#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level" 36#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut" 37#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost" 38 39namespace android { 40 41template<class T> 42static void InitOMXParams(T *params) { 43 params->nSize = sizeof(T); 44 params->nVersion.s.nVersionMajor = 1; 45 params->nVersion.s.nVersionMinor = 0; 46 params->nVersion.s.nRevision = 0; 47 params->nVersion.s.nStep = 0; 48} 49 50SoftAAC2::SoftAAC2( 51 const char *name, 52 const OMX_CALLBACKTYPE *callbacks, 53 OMX_PTR appData, 54 OMX_COMPONENTTYPE **component) 55 : SimpleSoftOMXComponent(name, callbacks, appData, component), 56 mAACDecoder(NULL), 57 mStreamInfo(NULL), 58 mIsADTS(false), 59 mInputBufferCount(0), 60 mSignalledError(false), 61 mAnchorTimeUs(0), 62 mNumSamplesOutput(0), 63 mOutputPortSettingsChange(NONE) { 64 initPorts(); 65 CHECK_EQ(initDecoder(), (status_t)OK); 66} 67 68SoftAAC2::~SoftAAC2() { 69 aacDecoder_Close(mAACDecoder); 70} 71 72void SoftAAC2::initPorts() { 73 OMX_PARAM_PORTDEFINITIONTYPE def; 74 InitOMXParams(&def); 75 76 def.nPortIndex = 0; 77 def.eDir = OMX_DirInput; 78 def.nBufferCountMin = kNumInputBuffers; 79 def.nBufferCountActual = def.nBufferCountMin; 80 def.nBufferSize = 8192; 81 def.bEnabled = OMX_TRUE; 82 def.bPopulated = OMX_FALSE; 83 def.eDomain = OMX_PortDomainAudio; 84 def.bBuffersContiguous = OMX_FALSE; 85 def.nBufferAlignment = 1; 86 87 def.format.audio.cMIMEType = const_cast<char *>("audio/aac"); 88 def.format.audio.pNativeRender = NULL; 89 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 90 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 91 92 addPort(def); 93 94 def.nPortIndex = 1; 95 def.eDir = OMX_DirOutput; 96 def.nBufferCountMin = kNumOutputBuffers; 97 def.nBufferCountActual = def.nBufferCountMin; 98 def.nBufferSize = 4096 * MAX_CHANNEL_COUNT; 99 def.bEnabled = OMX_TRUE; 100 def.bPopulated = OMX_FALSE; 101 def.eDomain = OMX_PortDomainAudio; 102 def.bBuffersContiguous = OMX_FALSE; 103 def.nBufferAlignment = 2; 104 105 def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 106 def.format.audio.pNativeRender = NULL; 107 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 108 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 109 110 addPort(def); 111} 112 113status_t SoftAAC2::initDecoder() { 114 status_t status = UNKNOWN_ERROR; 115 mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1); 116 if (mAACDecoder != NULL) { 117 mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder); 118 if (mStreamInfo != NULL) { 119 status = OK; 120 } 121 } 122 mDecoderHasData = false; 123 124 // for streams that contain metadata, use the mobile profile DRC settings unless overridden 125 // by platform properties: 126 char value[PROPERTY_VALUE_MAX]; 127 // * AAC_DRC_REFERENCE_LEVEL 128 if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) { 129 unsigned refLevel = atoi(value); 130 ALOGV("AAC decoder using AAC_DRC_REFERENCE_LEVEL of %d instead of %d", 131 refLevel, DRC_DEFAULT_MOBILE_REF_LEVEL); 132 aacDecoder_SetParam(mAACDecoder, AAC_DRC_REFERENCE_LEVEL, refLevel); 133 } else { 134 aacDecoder_SetParam(mAACDecoder, AAC_DRC_REFERENCE_LEVEL, DRC_DEFAULT_MOBILE_REF_LEVEL); 135 } 136 // * AAC_DRC_ATTENUATION_FACTOR 137 if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) { 138 unsigned cut = atoi(value); 139 ALOGV("AAC decoder using AAC_DRC_ATTENUATION_FACTOR of %d instead of %d", 140 cut, DRC_DEFAULT_MOBILE_DRC_CUT); 141 aacDecoder_SetParam(mAACDecoder, AAC_DRC_ATTENUATION_FACTOR, cut); 142 } else { 143 aacDecoder_SetParam(mAACDecoder, AAC_DRC_ATTENUATION_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT); 144 } 145 // * AAC_DRC_BOOST_FACTOR (note: no default, using cut) 146 if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) { 147 unsigned boost = atoi(value); 148 ALOGV("AAC decoder using AAC_DRC_BOOST_FACTOR of %d", boost); 149 aacDecoder_SetParam(mAACDecoder, AAC_DRC_BOOST_FACTOR, boost); 150 } else { 151 aacDecoder_SetParam(mAACDecoder, AAC_DRC_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST); 152 } 153 154 return status; 155} 156 157OMX_ERRORTYPE SoftAAC2::internalGetParameter( 158 OMX_INDEXTYPE index, OMX_PTR params) { 159 switch (index) { 160 case OMX_IndexParamAudioAac: 161 { 162 OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = 163 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; 164 165 if (!isValidOMXParam(aacParams)) { 166 return OMX_ErrorBadParameter; 167 } 168 169 if (aacParams->nPortIndex != 0) { 170 return OMX_ErrorUndefined; 171 } 172 173 aacParams->nBitRate = 0; 174 aacParams->nAudioBandWidth = 0; 175 aacParams->nAACtools = 0; 176 aacParams->nAACERtools = 0; 177 aacParams->eAACProfile = OMX_AUDIO_AACObjectMain; 178 179 aacParams->eAACStreamFormat = 180 mIsADTS 181 ? OMX_AUDIO_AACStreamFormatMP4ADTS 182 : OMX_AUDIO_AACStreamFormatMP4FF; 183 184 aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo; 185 186 if (!isConfigured()) { 187 aacParams->nChannels = 1; 188 aacParams->nSampleRate = 44100; 189 aacParams->nFrameLength = 0; 190 } else { 191 aacParams->nChannels = mStreamInfo->numChannels; 192 aacParams->nSampleRate = mStreamInfo->sampleRate; 193 aacParams->nFrameLength = mStreamInfo->frameSize; 194 } 195 196 return OMX_ErrorNone; 197 } 198 199 case OMX_IndexParamAudioPcm: 200 { 201 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 202 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 203 204 if (!isValidOMXParam(pcmParams)) { 205 return OMX_ErrorBadParameter; 206 } 207 208 if (pcmParams->nPortIndex != 1) { 209 return OMX_ErrorUndefined; 210 } 211 212 pcmParams->eNumData = OMX_NumericalDataSigned; 213 pcmParams->eEndian = OMX_EndianBig; 214 pcmParams->bInterleaved = OMX_TRUE; 215 pcmParams->nBitPerSample = 16; 216 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 217 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 218 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 219 pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF; 220 pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE; 221 pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS; 222 pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS; 223 224 if (!isConfigured()) { 225 pcmParams->nChannels = 1; 226 pcmParams->nSamplingRate = 44100; 227 } else { 228 pcmParams->nChannels = mStreamInfo->numChannels; 229 pcmParams->nSamplingRate = mStreamInfo->sampleRate; 230 } 231 232 return OMX_ErrorNone; 233 } 234 235 default: 236 return SimpleSoftOMXComponent::internalGetParameter(index, params); 237 } 238} 239 240OMX_ERRORTYPE SoftAAC2::internalSetParameter( 241 OMX_INDEXTYPE index, const OMX_PTR params) { 242 switch (index) { 243 case OMX_IndexParamStandardComponentRole: 244 { 245 const OMX_PARAM_COMPONENTROLETYPE *roleParams = 246 (const OMX_PARAM_COMPONENTROLETYPE *)params; 247 248 if (!isValidOMXParam(roleParams)) { 249 return OMX_ErrorBadParameter; 250 } 251 252 if (strncmp((const char *)roleParams->cRole, 253 "audio_decoder.aac", 254 OMX_MAX_STRINGNAME_SIZE - 1)) { 255 return OMX_ErrorUndefined; 256 } 257 258 return OMX_ErrorNone; 259 } 260 261 case OMX_IndexParamAudioAac: 262 { 263 const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = 264 (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params; 265 266 if (!isValidOMXParam(aacParams)) { 267 return OMX_ErrorBadParameter; 268 } 269 270 if (aacParams->nPortIndex != 0) { 271 return OMX_ErrorUndefined; 272 } 273 274 if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) { 275 mIsADTS = false; 276 } else if (aacParams->eAACStreamFormat 277 == OMX_AUDIO_AACStreamFormatMP4ADTS) { 278 mIsADTS = true; 279 } else { 280 return OMX_ErrorUndefined; 281 } 282 283 return OMX_ErrorNone; 284 } 285 286 case OMX_IndexParamAudioPcm: 287 { 288 const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 289 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 290 291 if (!isValidOMXParam(pcmParams)) { 292 return OMX_ErrorBadParameter; 293 } 294 295 if (pcmParams->nPortIndex != 1) { 296 return OMX_ErrorUndefined; 297 } 298 299 return OMX_ErrorNone; 300 } 301 302 default: 303 return SimpleSoftOMXComponent::internalSetParameter(index, params); 304 } 305} 306 307bool SoftAAC2::isConfigured() const { 308 return mInputBufferCount > 0; 309} 310 311void SoftAAC2::maybeConfigureDownmix() const { 312 if (mStreamInfo->numChannels > 2) { 313 char value[PROPERTY_VALUE_MAX]; 314 if (!(property_get("media.aac_51_output_enabled", value, NULL) && 315 (!strcmp(value, "1") || !strcasecmp(value, "true")))) { 316 ALOGI("Downmixing multichannel AAC to stereo"); 317 aacDecoder_SetParam(mAACDecoder, AAC_PCM_OUTPUT_CHANNELS, 2); 318 mStreamInfo->numChannels = 2; 319 } 320 } 321} 322 323void SoftAAC2::onQueueFilled(OMX_U32 portIndex) { 324 if (mSignalledError || mOutputPortSettingsChange != NONE) { 325 return; 326 } 327 328 UCHAR* inBuffer[FILEREAD_MAX_LAYERS]; 329 UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0}; 330 UINT bytesValid[FILEREAD_MAX_LAYERS] = {0}; 331 332 List<BufferInfo *> &inQueue = getPortQueue(0); 333 List<BufferInfo *> &outQueue = getPortQueue(1); 334 335 if (portIndex == 0 && mInputBufferCount == 0) { 336 ++mInputBufferCount; 337 BufferInfo *info = *inQueue.begin(); 338 OMX_BUFFERHEADERTYPE *header = info->mHeader; 339 340 inBuffer[0] = header->pBuffer + header->nOffset; 341 inBufferLength[0] = header->nFilledLen; 342 343 AAC_DECODER_ERROR decoderErr = 344 aacDecoder_ConfigRaw(mAACDecoder, 345 inBuffer, 346 inBufferLength); 347 348 if (decoderErr != AAC_DEC_OK) { 349 mSignalledError = true; 350 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 351 return; 352 } 353 354 inQueue.erase(inQueue.begin()); 355 info->mOwnedByUs = false; 356 notifyEmptyBufferDone(header); 357 358 // Only send out port settings changed event if both sample rate 359 // and numChannels are valid. 360 if (mStreamInfo->sampleRate && mStreamInfo->numChannels) { 361 maybeConfigureDownmix(); 362 ALOGI("Initially configuring decoder: %d Hz, %d channels", 363 mStreamInfo->sampleRate, 364 mStreamInfo->numChannels); 365 366 notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 367 mOutputPortSettingsChange = AWAITING_DISABLED; 368 } 369 370 return; 371 } 372 373 while (!inQueue.empty() && !outQueue.empty()) { 374 BufferInfo *inInfo = *inQueue.begin(); 375 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 376 377 BufferInfo *outInfo = *outQueue.begin(); 378 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 379 380 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 381 inQueue.erase(inQueue.begin()); 382 inInfo->mOwnedByUs = false; 383 notifyEmptyBufferDone(inHeader); 384 385 if (mDecoderHasData) { 386 // flush out the decoder's delayed data by calling DecodeFrame 387 // one more time, with the AACDEC_FLUSH flag set 388 INT_PCM *outBuffer = 389 reinterpret_cast<INT_PCM *>( 390 outHeader->pBuffer + outHeader->nOffset); 391 392 AAC_DECODER_ERROR decoderErr = 393 aacDecoder_DecodeFrame(mAACDecoder, 394 outBuffer, 395 outHeader->nAllocLen, 396 AACDEC_FLUSH); 397 mDecoderHasData = false; 398 399 if (decoderErr != AAC_DEC_OK) { 400 mSignalledError = true; 401 402 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, 403 NULL); 404 405 return; 406 } 407 408 outHeader->nFilledLen = 409 mStreamInfo->frameSize 410 * sizeof(int16_t) 411 * mStreamInfo->numChannels; 412 } else { 413 // we never submitted any data to the decoder, so there's nothing to flush out 414 outHeader->nFilledLen = 0; 415 } 416 417 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 418 419 outQueue.erase(outQueue.begin()); 420 outInfo->mOwnedByUs = false; 421 notifyFillBufferDone(outHeader); 422 return; 423 } 424 425 if (inHeader->nOffset == 0) { 426 mAnchorTimeUs = inHeader->nTimeStamp; 427 mNumSamplesOutput = 0; 428 } 429 430 size_t adtsHeaderSize = 0; 431 if (mIsADTS) { 432 // skip 30 bits, aac_frame_length follows. 433 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll????? 434 435 const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset; 436 437 bool signalError = false; 438 if (inHeader->nFilledLen < 7) { 439 ALOGE("Audio data too short to contain even the ADTS header. " 440 "Got %ld bytes.", inHeader->nFilledLen); 441 hexdump(adtsHeader, inHeader->nFilledLen); 442 signalError = true; 443 } else { 444 bool protectionAbsent = (adtsHeader[1] & 1); 445 446 unsigned aac_frame_length = 447 ((adtsHeader[3] & 3) << 11) 448 | (adtsHeader[4] << 3) 449 | (adtsHeader[5] >> 5); 450 451 if (inHeader->nFilledLen < aac_frame_length) { 452 ALOGE("Not enough audio data for the complete frame. " 453 "Got %ld bytes, frame size according to the ADTS " 454 "header is %u bytes.", 455 inHeader->nFilledLen, aac_frame_length); 456 hexdump(adtsHeader, inHeader->nFilledLen); 457 signalError = true; 458 } else { 459 adtsHeaderSize = (protectionAbsent ? 7 : 9); 460 461 inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize; 462 inBufferLength[0] = aac_frame_length - adtsHeaderSize; 463 464 inHeader->nOffset += adtsHeaderSize; 465 inHeader->nFilledLen -= adtsHeaderSize; 466 } 467 } 468 469 if (signalError) { 470 mSignalledError = true; 471 472 notify(OMX_EventError, 473 OMX_ErrorStreamCorrupt, 474 ERROR_MALFORMED, 475 NULL); 476 477 return; 478 } 479 } else { 480 inBuffer[0] = inHeader->pBuffer + inHeader->nOffset; 481 inBufferLength[0] = inHeader->nFilledLen; 482 } 483 484 // Fill and decode 485 INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>( 486 outHeader->pBuffer + outHeader->nOffset); 487 488 bytesValid[0] = inBufferLength[0]; 489 490 int prevSampleRate = mStreamInfo->sampleRate; 491 int prevNumChannels = mStreamInfo->numChannels; 492 493 AAC_DECODER_ERROR decoderErr = AAC_DEC_NOT_ENOUGH_BITS; 494 while (bytesValid[0] > 0 && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) { 495 aacDecoder_Fill(mAACDecoder, 496 inBuffer, 497 inBufferLength, 498 bytesValid); 499 mDecoderHasData = true; 500 501 decoderErr = aacDecoder_DecodeFrame(mAACDecoder, 502 outBuffer, 503 outHeader->nAllocLen, 504 0 /* flags */); 505 506 if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) { 507 ALOGW("Not enough bits, bytesValid %d", bytesValid[0]); 508 } 509 } 510 511 size_t numOutBytes = 512 mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels; 513 514 if (decoderErr == AAC_DEC_OK) { 515 UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0]; 516 inHeader->nFilledLen -= inBufferUsedLength; 517 inHeader->nOffset += inBufferUsedLength; 518 } else { 519 ALOGW("AAC decoder returned error %d, substituting silence", 520 decoderErr); 521 522 memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes); 523 524 // Discard input buffer. 525 inHeader->nFilledLen = 0; 526 527 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1); 528 529 // fall through 530 } 531 532 if (inHeader->nFilledLen == 0) { 533 inInfo->mOwnedByUs = false; 534 inQueue.erase(inQueue.begin()); 535 inInfo = NULL; 536 notifyEmptyBufferDone(inHeader); 537 inHeader = NULL; 538 } 539 540 /* 541 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly 542 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual 543 * rate system and the sampling rate in the final output is actually 544 * doubled compared with the core AAC decoder sampling rate. 545 * 546 * Explicit signalling is done by explicitly defining SBR audio object 547 * type in the bitstream. Implicit signalling is done by embedding 548 * SBR content in AAC extension payload specific to SBR, and hence 549 * requires an AAC decoder to perform pre-checks on actual audio frames. 550 * 551 * Thus, we could not say for sure whether a stream is 552 * AAC+/eAAC+ until the first data frame is decoded. 553 */ 554 if (mInputBufferCount <= 2) { 555 if (mStreamInfo->sampleRate != prevSampleRate || 556 mStreamInfo->numChannels != prevNumChannels) { 557 maybeConfigureDownmix(); 558 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels", 559 prevSampleRate, mStreamInfo->sampleRate, 560 prevNumChannels, mStreamInfo->numChannels); 561 562 notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 563 mOutputPortSettingsChange = AWAITING_DISABLED; 564 return; 565 } 566 } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) { 567 ALOGW("Invalid AAC stream"); 568 mSignalledError = true; 569 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 570 return; 571 } 572 573 if (decoderErr == AAC_DEC_OK || mNumSamplesOutput > 0) { 574 // We'll only output data if we successfully decoded it or 575 // we've previously decoded valid data, in the latter case 576 // (decode failed) we'll output a silent frame. 577 outHeader->nFilledLen = numOutBytes; 578 outHeader->nFlags = 0; 579 580 outHeader->nTimeStamp = 581 mAnchorTimeUs 582 + (mNumSamplesOutput * 1000000ll) / mStreamInfo->sampleRate; 583 584 mNumSamplesOutput += mStreamInfo->frameSize; 585 586 outInfo->mOwnedByUs = false; 587 outQueue.erase(outQueue.begin()); 588 outInfo = NULL; 589 notifyFillBufferDone(outHeader); 590 outHeader = NULL; 591 } 592 593 if (decoderErr == AAC_DEC_OK) { 594 ++mInputBufferCount; 595 } 596 } 597} 598 599void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) { 600 if (portIndex == 0) { 601 // Make sure that the next buffer output does not still 602 // depend on fragments from the last one decoded. 603 // drain all existing data 604 drainDecoder(); 605 } 606} 607 608void SoftAAC2::drainDecoder() { 609 // a buffer big enough for 6 channels of decoded HE-AAC 610 short buf [2048*6]; 611 aacDecoder_DecodeFrame(mAACDecoder, 612 buf, sizeof(buf), AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR); 613 aacDecoder_DecodeFrame(mAACDecoder, 614 buf, sizeof(buf), AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR); 615 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1); 616 mDecoderHasData = false; 617} 618 619void SoftAAC2::onReset() { 620 drainDecoder(); 621 // reset the "configured" state 622 mInputBufferCount = 0; 623 mNumSamplesOutput = 0; 624 // To make the codec behave the same before and after a reset, we need to invalidate the 625 // streaminfo struct. This does that: 626 mStreamInfo->sampleRate = 0; 627 628 mSignalledError = false; 629 mOutputPortSettingsChange = NONE; 630} 631 632void SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 633 if (portIndex != 1) { 634 return; 635 } 636 637 switch (mOutputPortSettingsChange) { 638 case NONE: 639 break; 640 641 case AWAITING_DISABLED: 642 { 643 CHECK(!enabled); 644 mOutputPortSettingsChange = AWAITING_ENABLED; 645 break; 646 } 647 648 default: 649 { 650 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 651 CHECK(enabled); 652 mOutputPortSettingsChange = NONE; 653 break; 654 } 655 } 656} 657 658} // namespace android 659 660android::SoftOMXComponent *createSoftOMXComponent( 661 const char *name, const OMX_CALLBACKTYPE *callbacks, 662 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 663 return new android::SoftAAC2(name, callbacks, appData, component); 664} 665