SoftAACEncoder2.cpp revision 67ef30185837950144d30e5a73d852eb9a7a0a89
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 "SoftAACEncoder2" 19#include <utils/Log.h> 20 21#include "SoftAACEncoder2.h" 22#include <OMX_AudioExt.h> 23 24#include <media/stagefright/foundation/ADebug.h> 25#include <media/stagefright/foundation/hexdump.h> 26 27namespace android { 28 29template<class T> 30static void InitOMXParams(T *params) { 31 params->nSize = sizeof(T); 32 params->nVersion.s.nVersionMajor = 1; 33 params->nVersion.s.nVersionMinor = 0; 34 params->nVersion.s.nRevision = 0; 35 params->nVersion.s.nStep = 0; 36} 37 38SoftAACEncoder2::SoftAACEncoder2( 39 const char *name, 40 const OMX_CALLBACKTYPE *callbacks, 41 OMX_PTR appData, 42 OMX_COMPONENTTYPE **component) 43 : SimpleSoftOMXComponent(name, callbacks, appData, component), 44 mAACEncoder(NULL), 45 mNumChannels(1), 46 mSampleRate(44100), 47 mBitRate(0), 48 mSBRMode(-1), 49 mSBRRatio(0), 50 mAACProfile(OMX_AUDIO_AACObjectLC), 51 mSentCodecSpecificData(false), 52 mInputSize(0), 53 mInputFrame(NULL), 54 mInputTimeUs(-1ll), 55 mSawInputEOS(false), 56 mSignalledError(false) { 57 initPorts(); 58 CHECK_EQ(initEncoder(), (status_t)OK); 59 setAudioParams(); 60} 61 62SoftAACEncoder2::~SoftAACEncoder2() { 63 aacEncClose(&mAACEncoder); 64 65 delete[] mInputFrame; 66 mInputFrame = NULL; 67} 68 69void SoftAACEncoder2::initPorts() { 70 OMX_PARAM_PORTDEFINITIONTYPE def; 71 InitOMXParams(&def); 72 73 def.nPortIndex = 0; 74 def.eDir = OMX_DirInput; 75 def.nBufferCountMin = kNumBuffers; 76 def.nBufferCountActual = def.nBufferCountMin; 77 def.nBufferSize = kNumSamplesPerFrame * sizeof(int16_t) * 2; 78 def.bEnabled = OMX_TRUE; 79 def.bPopulated = OMX_FALSE; 80 def.eDomain = OMX_PortDomainAudio; 81 def.bBuffersContiguous = OMX_FALSE; 82 def.nBufferAlignment = 1; 83 84 def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 85 def.format.audio.pNativeRender = NULL; 86 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 87 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 88 89 addPort(def); 90 91 def.nPortIndex = 1; 92 def.eDir = OMX_DirOutput; 93 def.nBufferCountMin = kNumBuffers; 94 def.nBufferCountActual = def.nBufferCountMin; 95 def.nBufferSize = 8192; 96 def.bEnabled = OMX_TRUE; 97 def.bPopulated = OMX_FALSE; 98 def.eDomain = OMX_PortDomainAudio; 99 def.bBuffersContiguous = OMX_FALSE; 100 def.nBufferAlignment = 2; 101 102 def.format.audio.cMIMEType = const_cast<char *>("audio/aac"); 103 def.format.audio.pNativeRender = NULL; 104 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 105 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 106 107 addPort(def); 108} 109 110status_t SoftAACEncoder2::initEncoder() { 111 if (AACENC_OK != aacEncOpen(&mAACEncoder, 0, 0)) { 112 ALOGE("Failed to init AAC encoder"); 113 return UNKNOWN_ERROR; 114 } 115 return OK; 116} 117 118OMX_ERRORTYPE SoftAACEncoder2::internalGetParameter( 119 OMX_INDEXTYPE index, OMX_PTR params) { 120 switch (index) { 121 case OMX_IndexParamAudioPortFormat: 122 { 123 OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = 124 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; 125 126 if (!isValidOMXParam(formatParams)) { 127 return OMX_ErrorBadParameter; 128 } 129 130 if (formatParams->nPortIndex > 1) { 131 return OMX_ErrorUndefined; 132 } 133 134 if (formatParams->nIndex > 0) { 135 return OMX_ErrorNoMore; 136 } 137 138 formatParams->eEncoding = 139 (formatParams->nPortIndex == 0) 140 ? OMX_AUDIO_CodingPCM : OMX_AUDIO_CodingAAC; 141 142 return OMX_ErrorNone; 143 } 144 145 case OMX_IndexParamAudioAac: 146 { 147 OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = 148 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; 149 150 if (!isValidOMXParam(aacParams)) { 151 return OMX_ErrorBadParameter; 152 } 153 154 if (aacParams->nPortIndex != 1) { 155 return OMX_ErrorUndefined; 156 } 157 158 aacParams->nBitRate = mBitRate; 159 aacParams->nAudioBandWidth = 0; 160 aacParams->nAACtools = 0; 161 aacParams->nAACERtools = 0; 162 aacParams->eAACProfile = (OMX_AUDIO_AACPROFILETYPE) mAACProfile; 163 aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 164 aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo; 165 166 aacParams->nChannels = mNumChannels; 167 aacParams->nSampleRate = mSampleRate; 168 aacParams->nFrameLength = 0; 169 170 switch (mSBRMode) { 171 case 1: // sbr on 172 switch (mSBRRatio) { 173 case 0: 174 // set both OMX AAC tool flags 175 aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 176 aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 177 break; 178 case 1: 179 // set single-rate SBR active 180 aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 181 aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 182 break; 183 case 2: 184 // set dual-rate SBR active 185 aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 186 aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 187 break; 188 default: 189 ALOGE("invalid SBR ratio %d", mSBRRatio); 190 TRESPASS(); 191 } 192 break; 193 case 0: // sbr off 194 case -1: // sbr undefined 195 aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 196 aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 197 break; 198 default: 199 ALOGE("invalid SBR mode %d", mSBRMode); 200 TRESPASS(); 201 } 202 203 204 205 return OMX_ErrorNone; 206 } 207 208 case OMX_IndexParamAudioPcm: 209 { 210 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 211 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 212 213 if (!isValidOMXParam(pcmParams)) { 214 return OMX_ErrorBadParameter; 215 } 216 217 if (pcmParams->nPortIndex != 0) { 218 return OMX_ErrorUndefined; 219 } 220 221 pcmParams->eNumData = OMX_NumericalDataSigned; 222 pcmParams->eEndian = OMX_EndianBig; 223 pcmParams->bInterleaved = OMX_TRUE; 224 pcmParams->nBitPerSample = 16; 225 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 226 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 227 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 228 229 pcmParams->nChannels = mNumChannels; 230 pcmParams->nSamplingRate = mSampleRate; 231 232 return OMX_ErrorNone; 233 } 234 235 default: 236 return SimpleSoftOMXComponent::internalGetParameter(index, params); 237 } 238} 239 240OMX_ERRORTYPE SoftAACEncoder2::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_encoder.aac", 254 OMX_MAX_STRINGNAME_SIZE - 1)) { 255 return OMX_ErrorUndefined; 256 } 257 258 return OMX_ErrorNone; 259 } 260 261 case OMX_IndexParamAudioPortFormat: 262 { 263 const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = 264 (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; 265 266 if (!isValidOMXParam(formatParams)) { 267 return OMX_ErrorBadParameter; 268 } 269 270 if (formatParams->nPortIndex > 1) { 271 return OMX_ErrorUndefined; 272 } 273 274 if (formatParams->nIndex > 0) { 275 return OMX_ErrorNoMore; 276 } 277 278 if ((formatParams->nPortIndex == 0 279 && formatParams->eEncoding != OMX_AUDIO_CodingPCM) 280 || (formatParams->nPortIndex == 1 281 && formatParams->eEncoding != OMX_AUDIO_CodingAAC)) { 282 return OMX_ErrorUndefined; 283 } 284 285 return OMX_ErrorNone; 286 } 287 288 case OMX_IndexParamAudioAac: 289 { 290 OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = 291 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; 292 293 if (!isValidOMXParam(aacParams)) { 294 return OMX_ErrorBadParameter; 295 } 296 297 if (aacParams->nPortIndex != 1) { 298 return OMX_ErrorUndefined; 299 } 300 301 mBitRate = aacParams->nBitRate; 302 mNumChannels = aacParams->nChannels; 303 mSampleRate = aacParams->nSampleRate; 304 if (aacParams->eAACProfile != OMX_AUDIO_AACObjectNull) { 305 mAACProfile = aacParams->eAACProfile; 306 } 307 308 if (!(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR) 309 && !(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) { 310 mSBRMode = 0; 311 mSBRRatio = 0; 312 } else if ((aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR) 313 && !(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) { 314 mSBRMode = 1; 315 mSBRRatio = 1; 316 } else if (!(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR) 317 && (aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) { 318 mSBRMode = 1; 319 mSBRRatio = 2; 320 } else { 321 mSBRMode = -1; // codec default sbr mode 322 mSBRRatio = 0; 323 } 324 325 if (setAudioParams() != OK) { 326 return OMX_ErrorUndefined; 327 } 328 329 return OMX_ErrorNone; 330 } 331 332 case OMX_IndexParamAudioPcm: 333 { 334 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 335 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 336 337 if (!isValidOMXParam(pcmParams)) { 338 return OMX_ErrorBadParameter; 339 } 340 341 if (pcmParams->nPortIndex != 0) { 342 return OMX_ErrorUndefined; 343 } 344 345 mNumChannels = pcmParams->nChannels; 346 mSampleRate = pcmParams->nSamplingRate; 347 if (setAudioParams() != OK) { 348 return OMX_ErrorUndefined; 349 } 350 351 return OMX_ErrorNone; 352 } 353 354 default: 355 return SimpleSoftOMXComponent::internalSetParameter(index, params); 356 } 357} 358 359static CHANNEL_MODE getChannelMode(OMX_U32 nChannels) { 360 CHANNEL_MODE chMode = MODE_INVALID; 361 switch (nChannels) { 362 case 1: chMode = MODE_1; break; 363 case 2: chMode = MODE_2; break; 364 case 3: chMode = MODE_1_2; break; 365 case 4: chMode = MODE_1_2_1; break; 366 case 5: chMode = MODE_1_2_2; break; 367 case 6: chMode = MODE_1_2_2_1; break; 368 default: chMode = MODE_INVALID; 369 } 370 return chMode; 371} 372 373static AUDIO_OBJECT_TYPE getAOTFromProfile(OMX_U32 profile) { 374 if (profile == OMX_AUDIO_AACObjectLC) { 375 return AOT_AAC_LC; 376 } else if (profile == OMX_AUDIO_AACObjectHE) { 377 return AOT_SBR; 378 } else if (profile == OMX_AUDIO_AACObjectHE_PS) { 379 return AOT_PS; 380 } else if (profile == OMX_AUDIO_AACObjectLD) { 381 return AOT_ER_AAC_LD; 382 } else if (profile == OMX_AUDIO_AACObjectELD) { 383 return AOT_ER_AAC_ELD; 384 } else { 385 ALOGW("Unsupported AAC profile - defaulting to AAC-LC"); 386 return AOT_AAC_LC; 387 } 388} 389 390status_t SoftAACEncoder2::setAudioParams() { 391 // We call this whenever sample rate, number of channels, bitrate or SBR mode change 392 // in reponse to setParameter calls. 393 394 ALOGV("setAudioParams: %u Hz, %u channels, %u bps, %i sbr mode, %i sbr ratio", 395 mSampleRate, mNumChannels, mBitRate, mSBRMode, mSBRRatio); 396 397 if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_AOT, 398 getAOTFromProfile(mAACProfile))) { 399 ALOGE("Failed to set AAC encoder parameters"); 400 return UNKNOWN_ERROR; 401 } 402 403 if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SAMPLERATE, mSampleRate)) { 404 ALOGE("Failed to set AAC encoder parameters"); 405 return UNKNOWN_ERROR; 406 } 407 if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_BITRATE, mBitRate)) { 408 ALOGE("Failed to set AAC encoder parameters"); 409 return UNKNOWN_ERROR; 410 } 411 if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CHANNELMODE, 412 getChannelMode(mNumChannels))) { 413 ALOGE("Failed to set AAC encoder parameters"); 414 return UNKNOWN_ERROR; 415 } 416 if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_TRANSMUX, TT_MP4_RAW)) { 417 ALOGE("Failed to set AAC encoder parameters"); 418 return UNKNOWN_ERROR; 419 } 420 421 if (mSBRMode != -1 && mAACProfile == OMX_AUDIO_AACObjectELD) { 422 if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_MODE, mSBRMode)) { 423 ALOGE("Failed to set AAC encoder parameters"); 424 return UNKNOWN_ERROR; 425 } 426 } 427 428 /* SBR ratio parameter configurations: 429 0: Default configuration wherein SBR ratio is configured depending on audio object type by 430 the FDK. 431 1: Downsampled SBR (default for ELD) 432 2: Dualrate SBR (default for HE-AAC) 433 */ 434 if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_RATIO, mSBRRatio)) { 435 ALOGE("Failed to set AAC encoder parameters"); 436 return UNKNOWN_ERROR; 437 } 438 439 return OK; 440} 441 442void SoftAACEncoder2::onQueueFilled(OMX_U32 /* portIndex */) { 443 if (mSignalledError) { 444 return; 445 } 446 447 List<BufferInfo *> &inQueue = getPortQueue(0); 448 List<BufferInfo *> &outQueue = getPortQueue(1); 449 450 if (!mSentCodecSpecificData) { 451 // The very first thing we want to output is the codec specific 452 // data. It does not require any input data but we will need an 453 // output buffer to store it in. 454 455 if (outQueue.empty()) { 456 return; 457 } 458 459 if (AACENC_OK != aacEncEncode(mAACEncoder, NULL, NULL, NULL, NULL)) { 460 ALOGE("Unable to initialize encoder for profile / sample-rate / bit-rate / channels"); 461 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 462 mSignalledError = true; 463 return; 464 } 465 466 OMX_U32 actualBitRate = aacEncoder_GetParam(mAACEncoder, AACENC_BITRATE); 467 if (mBitRate != actualBitRate) { 468 ALOGW("Requested bitrate %u unsupported, using %u", mBitRate, actualBitRate); 469 } 470 471 AACENC_InfoStruct encInfo; 472 if (AACENC_OK != aacEncInfo(mAACEncoder, &encInfo)) { 473 ALOGE("Failed to get AAC encoder info"); 474 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 475 mSignalledError = true; 476 return; 477 } 478 479 BufferInfo *outInfo = *outQueue.begin(); 480 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 481 outHeader->nFilledLen = encInfo.confSize; 482 outHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG; 483 484 uint8_t *out = outHeader->pBuffer + outHeader->nOffset; 485 memcpy(out, encInfo.confBuf, encInfo.confSize); 486 487 outQueue.erase(outQueue.begin()); 488 outInfo->mOwnedByUs = false; 489 notifyFillBufferDone(outHeader); 490 491 mSentCodecSpecificData = true; 492 } 493 494 size_t numBytesPerInputFrame = 495 mNumChannels * kNumSamplesPerFrame * sizeof(int16_t); 496 497 // Limit input size so we only get one ELD frame 498 if (mAACProfile == OMX_AUDIO_AACObjectELD && numBytesPerInputFrame > 512) { 499 numBytesPerInputFrame = 512; 500 } 501 502 for (;;) { 503 // We do the following until we run out of buffers. 504 505 while (mInputSize < numBytesPerInputFrame) { 506 // As long as there's still input data to be read we 507 // will drain "kNumSamplesPerFrame * mNumChannels" samples 508 // into the "mInputFrame" buffer and then encode those 509 // as a unit into an output buffer. 510 511 if (mSawInputEOS || inQueue.empty()) { 512 return; 513 } 514 515 BufferInfo *inInfo = *inQueue.begin(); 516 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 517 518 const void *inData = inHeader->pBuffer + inHeader->nOffset; 519 520 size_t copy = numBytesPerInputFrame - mInputSize; 521 if (copy > inHeader->nFilledLen) { 522 copy = inHeader->nFilledLen; 523 } 524 525 if (mInputFrame == NULL) { 526 mInputFrame = new int16_t[numBytesPerInputFrame / sizeof(int16_t)]; 527 } 528 529 if (mInputSize == 0) { 530 mInputTimeUs = inHeader->nTimeStamp; 531 } 532 533 memcpy((uint8_t *)mInputFrame + mInputSize, inData, copy); 534 mInputSize += copy; 535 536 inHeader->nOffset += copy; 537 inHeader->nFilledLen -= copy; 538 539 // "Time" on the input buffer has in effect advanced by the 540 // number of audio frames we just advanced nOffset by. 541 inHeader->nTimeStamp += 542 (copy * 1000000ll / mSampleRate) 543 / (mNumChannels * sizeof(int16_t)); 544 545 if (inHeader->nFilledLen == 0) { 546 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 547 mSawInputEOS = true; 548 549 // Pad any remaining data with zeroes. 550 memset((uint8_t *)mInputFrame + mInputSize, 551 0, 552 numBytesPerInputFrame - mInputSize); 553 554 mInputSize = numBytesPerInputFrame; 555 } 556 557 inQueue.erase(inQueue.begin()); 558 inInfo->mOwnedByUs = false; 559 notifyEmptyBufferDone(inHeader); 560 561 inData = NULL; 562 inHeader = NULL; 563 inInfo = NULL; 564 } 565 } 566 567 // At this point we have all the input data necessary to encode 568 // a single frame, all we need is an output buffer to store the result 569 // in. 570 571 if (outQueue.empty()) { 572 return; 573 } 574 575 BufferInfo *outInfo = *outQueue.begin(); 576 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 577 578 uint8_t *outPtr = (uint8_t *)outHeader->pBuffer + outHeader->nOffset; 579 size_t outAvailable = outHeader->nAllocLen - outHeader->nOffset; 580 581 AACENC_InArgs inargs; 582 AACENC_OutArgs outargs; 583 memset(&inargs, 0, sizeof(inargs)); 584 memset(&outargs, 0, sizeof(outargs)); 585 inargs.numInSamples = numBytesPerInputFrame / sizeof(int16_t); 586 587 void* inBuffer[] = { (unsigned char *)mInputFrame }; 588 INT inBufferIds[] = { IN_AUDIO_DATA }; 589 INT inBufferSize[] = { (INT)numBytesPerInputFrame }; 590 INT inBufferElSize[] = { sizeof(int16_t) }; 591 592 AACENC_BufDesc inBufDesc; 593 inBufDesc.numBufs = sizeof(inBuffer) / sizeof(void*); 594 inBufDesc.bufs = (void**)&inBuffer; 595 inBufDesc.bufferIdentifiers = inBufferIds; 596 inBufDesc.bufSizes = inBufferSize; 597 inBufDesc.bufElSizes = inBufferElSize; 598 599 void* outBuffer[] = { outPtr }; 600 INT outBufferIds[] = { OUT_BITSTREAM_DATA }; 601 INT outBufferSize[] = { 0 }; 602 INT outBufferElSize[] = { sizeof(UCHAR) }; 603 604 AACENC_BufDesc outBufDesc; 605 outBufDesc.numBufs = sizeof(outBuffer) / sizeof(void*); 606 outBufDesc.bufs = (void**)&outBuffer; 607 outBufDesc.bufferIdentifiers = outBufferIds; 608 outBufDesc.bufSizes = outBufferSize; 609 outBufDesc.bufElSizes = outBufferElSize; 610 611 // Encode the mInputFrame, which is treated as a modulo buffer 612 AACENC_ERROR encoderErr = AACENC_OK; 613 size_t nOutputBytes = 0; 614 615 do { 616 memset(&outargs, 0, sizeof(outargs)); 617 618 outBuffer[0] = outPtr; 619 outBufferSize[0] = outAvailable - nOutputBytes; 620 621 encoderErr = aacEncEncode(mAACEncoder, 622 &inBufDesc, 623 &outBufDesc, 624 &inargs, 625 &outargs); 626 627 if (encoderErr == AACENC_OK) { 628 outPtr += outargs.numOutBytes; 629 nOutputBytes += outargs.numOutBytes; 630 631 if (outargs.numInSamples > 0) { 632 int numRemainingSamples = inargs.numInSamples - outargs.numInSamples; 633 if (numRemainingSamples > 0) { 634 memmove(mInputFrame, 635 &mInputFrame[outargs.numInSamples], 636 sizeof(int16_t) * numRemainingSamples); 637 } 638 inargs.numInSamples -= outargs.numInSamples; 639 } 640 } 641 } while (encoderErr == AACENC_OK && inargs.numInSamples > 0); 642 643 outHeader->nFilledLen = nOutputBytes; 644 645 outHeader->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; 646 647 if (mSawInputEOS) { 648 // We also tag this output buffer with EOS if it corresponds 649 // to the final input buffer. 650 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 651 } 652 653 outHeader->nTimeStamp = mInputTimeUs; 654 655#if 0 656 ALOGI("sending %d bytes of data (time = %lld us, flags = 0x%08lx)", 657 nOutputBytes, mInputTimeUs, outHeader->nFlags); 658 659 hexdump(outHeader->pBuffer + outHeader->nOffset, outHeader->nFilledLen); 660#endif 661 662 outQueue.erase(outQueue.begin()); 663 outInfo->mOwnedByUs = false; 664 notifyFillBufferDone(outHeader); 665 666 outHeader = NULL; 667 outInfo = NULL; 668 669 mInputSize = 0; 670 } 671} 672 673} // namespace android 674 675android::SoftOMXComponent *createSoftOMXComponent( 676 const char *name, const OMX_CALLBACKTYPE *callbacks, 677 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 678 return new android::SoftAACEncoder2(name, callbacks, appData, component); 679} 680