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