SoftAAC2.cpp revision b7ddcc9460f488f0b032aeb27b52a423318a97ea
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#include <utils/Log.h> 19 20#include "SoftAAC2.h" 21 22#include <media/stagefright/foundation/ADebug.h> 23#include <media/stagefright/foundation/hexdump.h> 24 25#define FILEREAD_MAX_LAYERS 2 26 27namespace android { 28 29static Mutex gAACLibraryLock; 30static int gAACLibraryCount = 0; 31 32void initializeAACLibrary() { 33 Mutex::Autolock autoLock(gAACLibraryLock); 34 if (gAACLibraryCount++ == 0) { 35 CDKprolog(); 36 } 37} 38 39void cleanupAACLibrary() { 40 Mutex::Autolock autoLock(gAACLibraryLock); 41 if (--gAACLibraryCount == 0) { 42 CDKepilog(); 43 } 44} 45 46template<class T> 47static void InitOMXParams(T *params) { 48 params->nSize = sizeof(T); 49 params->nVersion.s.nVersionMajor = 1; 50 params->nVersion.s.nVersionMinor = 0; 51 params->nVersion.s.nRevision = 0; 52 params->nVersion.s.nStep = 0; 53} 54 55SoftAAC2::SoftAAC2( 56 const char *name, 57 const OMX_CALLBACKTYPE *callbacks, 58 OMX_PTR appData, 59 OMX_COMPONENTTYPE **component) 60 : SimpleSoftOMXComponent(name, callbacks, appData, component), 61 mAACDecoder(NULL), 62 mStreamInfo(NULL), 63 mIsADTS(false), 64 mInputBufferCount(0), 65 mSignalledError(false), 66 mAnchorTimeUs(0), 67 mNumSamplesOutput(0), 68 mOutputPortSettingsChange(NONE) { 69 initializeAACLibrary(); 70 initPorts(); 71 CHECK_EQ(initDecoder(), (status_t)OK); 72} 73 74SoftAAC2::~SoftAAC2() { 75 aacDecoder_Close(mAACDecoder); 76 cleanupAACLibrary(); 77} 78 79void SoftAAC2::initPorts() { 80 OMX_PARAM_PORTDEFINITIONTYPE def; 81 InitOMXParams(&def); 82 83 def.nPortIndex = 0; 84 def.eDir = OMX_DirInput; 85 def.nBufferCountMin = kNumBuffers; 86 def.nBufferCountActual = def.nBufferCountMin; 87 def.nBufferSize = 8192; 88 def.bEnabled = OMX_TRUE; 89 def.bPopulated = OMX_FALSE; 90 def.eDomain = OMX_PortDomainAudio; 91 def.bBuffersContiguous = OMX_FALSE; 92 def.nBufferAlignment = 1; 93 94 def.format.audio.cMIMEType = const_cast<char *>("audio/aac"); 95 def.format.audio.pNativeRender = NULL; 96 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 97 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 98 99 addPort(def); 100 101 def.nPortIndex = 1; 102 def.eDir = OMX_DirOutput; 103 def.nBufferCountMin = kNumBuffers; 104 def.nBufferCountActual = def.nBufferCountMin; 105 def.nBufferSize = 8192; 106 def.bEnabled = OMX_TRUE; 107 def.bPopulated = OMX_FALSE; 108 def.eDomain = OMX_PortDomainAudio; 109 def.bBuffersContiguous = OMX_FALSE; 110 def.nBufferAlignment = 2; 111 112 def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 113 def.format.audio.pNativeRender = NULL; 114 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 115 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 116 117 addPort(def); 118} 119 120status_t SoftAAC2::initDecoder() { 121 status_t status = UNKNOWN_ERROR; 122 mAACDecoder = aacDecoder_Open(TT_MP4_RAW, /* num layers */ 1); 123 if (mAACDecoder != NULL) { 124 mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder); 125 if (mStreamInfo != NULL) { 126 status = OK; 127 } 128 } 129 return status; 130} 131 132OMX_ERRORTYPE SoftAAC2::internalGetParameter( 133 OMX_INDEXTYPE index, OMX_PTR params) { 134 switch (index) { 135 case OMX_IndexParamAudioAac: 136 { 137 OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = 138 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; 139 140 if (aacParams->nPortIndex != 0) { 141 return OMX_ErrorUndefined; 142 } 143 144 aacParams->nBitRate = 0; 145 aacParams->nAudioBandWidth = 0; 146 aacParams->nAACtools = 0; 147 aacParams->nAACERtools = 0; 148 aacParams->eAACProfile = OMX_AUDIO_AACObjectMain; 149 150 aacParams->eAACStreamFormat = 151 mIsADTS 152 ? OMX_AUDIO_AACStreamFormatMP4ADTS 153 : OMX_AUDIO_AACStreamFormatMP4FF; 154 155 aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo; 156 157 if (!isConfigured()) { 158 aacParams->nChannels = 1; 159 aacParams->nSampleRate = 44100; 160 aacParams->nFrameLength = 0; 161 } else { 162 aacParams->nChannels = mStreamInfo->channelConfig; 163 aacParams->nSampleRate = mStreamInfo->aacSampleRate; 164 aacParams->nFrameLength = mStreamInfo->aacSamplesPerFrame; 165 } 166 167 return OMX_ErrorNone; 168 } 169 170 case OMX_IndexParamAudioPcm: 171 { 172 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 173 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 174 175 if (pcmParams->nPortIndex != 1) { 176 return OMX_ErrorUndefined; 177 } 178 179 pcmParams->eNumData = OMX_NumericalDataSigned; 180 pcmParams->eEndian = OMX_EndianBig; 181 pcmParams->bInterleaved = OMX_TRUE; 182 pcmParams->nBitPerSample = 16; 183 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 184 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 185 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 186 187 if (!isConfigured()) { 188 pcmParams->nChannels = 1; 189 pcmParams->nSamplingRate = 44100; 190 } else { 191 pcmParams->nChannels = mStreamInfo->channelConfig; 192 pcmParams->nSamplingRate = mStreamInfo->sampleRate; 193 } 194 195 return OMX_ErrorNone; 196 } 197 198 default: 199 return SimpleSoftOMXComponent::internalGetParameter(index, params); 200 } 201} 202 203OMX_ERRORTYPE SoftAAC2::internalSetParameter( 204 OMX_INDEXTYPE index, const OMX_PTR params) { 205 switch (index) { 206 case OMX_IndexParamStandardComponentRole: 207 { 208 const OMX_PARAM_COMPONENTROLETYPE *roleParams = 209 (const OMX_PARAM_COMPONENTROLETYPE *)params; 210 211 if (strncmp((const char *)roleParams->cRole, 212 "audio_decoder.aac", 213 OMX_MAX_STRINGNAME_SIZE - 1)) { 214 return OMX_ErrorUndefined; 215 } 216 217 return OMX_ErrorNone; 218 } 219 220 case OMX_IndexParamAudioAac: 221 { 222 const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = 223 (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params; 224 225 if (aacParams->nPortIndex != 0) { 226 return OMX_ErrorUndefined; 227 } 228 229 if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) { 230 mIsADTS = false; 231 } else if (aacParams->eAACStreamFormat 232 == OMX_AUDIO_AACStreamFormatMP4ADTS) { 233 mIsADTS = true; 234 } else { 235 return OMX_ErrorUndefined; 236 } 237 238 return OMX_ErrorNone; 239 } 240 241 case OMX_IndexParamAudioPcm: 242 { 243 const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 244 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 245 246 if (pcmParams->nPortIndex != 1) { 247 return OMX_ErrorUndefined; 248 } 249 250 return OMX_ErrorNone; 251 } 252 253 default: 254 return SimpleSoftOMXComponent::internalSetParameter(index, params); 255 } 256} 257 258bool SoftAAC2::isConfigured() const { 259 return mInputBufferCount > 0; 260} 261 262void SoftAAC2::onQueueFilled(OMX_U32 portIndex) { 263 if (mSignalledError || mOutputPortSettingsChange != NONE) { 264 return; 265 } 266 267 UCHAR* inBuffer[FILEREAD_MAX_LAYERS]; 268 UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0}; 269 UINT bytesValid[FILEREAD_MAX_LAYERS] = {0}; 270 AAC_DECODER_ERROR decoderErr; 271 272 List<BufferInfo *> &inQueue = getPortQueue(0); 273 List<BufferInfo *> &outQueue = getPortQueue(1); 274 275 if (portIndex == 0 && mInputBufferCount == 0) { 276 ++mInputBufferCount; 277 BufferInfo *info = *inQueue.begin(); 278 OMX_BUFFERHEADERTYPE *header = info->mHeader; 279 280 inBuffer[0] = header->pBuffer + header->nOffset; 281 inBufferLength[0] = header->nFilledLen; 282 283 AAC_DECODER_ERROR decoderErr = 284 aacDecoder_ConfigRaw(mAACDecoder, 285 inBuffer, 286 inBufferLength); 287 288 if (decoderErr != AAC_DEC_OK) { 289 mSignalledError = true; 290 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 291 return; 292 } 293 294 inQueue.erase(inQueue.begin()); 295 info->mOwnedByUs = false; 296 notifyEmptyBufferDone(header); 297 298 notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 299 mOutputPortSettingsChange = AWAITING_DISABLED; 300 return; 301 } 302 303 while (!inQueue.empty() && !outQueue.empty()) { 304 BufferInfo *inInfo = *inQueue.begin(); 305 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 306 307 BufferInfo *outInfo = *outQueue.begin(); 308 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 309 310 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 311 inQueue.erase(inQueue.begin()); 312 inInfo->mOwnedByUs = false; 313 notifyEmptyBufferDone(inHeader); 314 315 outHeader->nFilledLen = 0; 316 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 317 318 outQueue.erase(outQueue.begin()); 319 outInfo->mOwnedByUs = false; 320 notifyFillBufferDone(outHeader); 321 return; 322 } 323 324 if (inHeader->nOffset == 0) { 325 mAnchorTimeUs = inHeader->nTimeStamp; 326 mNumSamplesOutput = 0; 327 } 328 329 if (mIsADTS) { 330 // skip 30 bits, aac_frame_length follows. 331 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll????? 332 333 const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset; 334 335 CHECK_GE(inHeader->nFilledLen, 7); 336 337 bool protectionAbsent = (adtsHeader[1] & 1); 338 339 unsigned aac_frame_length = 340 ((adtsHeader[3] & 3) << 11) 341 | (adtsHeader[4] << 3) 342 | (adtsHeader[5] >> 5); 343 344 CHECK_GE(inHeader->nFilledLen, aac_frame_length); 345 346 size_t headerSize = (protectionAbsent ? 7 : 9); 347 348 inBuffer[0] = (UCHAR *)adtsHeader + headerSize; 349 inBufferLength[0] = aac_frame_length - headerSize; 350 351 inHeader->nOffset += headerSize; 352 inHeader->nFilledLen -= headerSize; 353 } else { 354 inBuffer[0] = inHeader->pBuffer + inHeader->nOffset; 355 inBufferLength[0] = inHeader->nFilledLen; 356 } 357 358 359 // Fill and decode 360 INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(outHeader->pBuffer + outHeader->nOffset); 361 bytesValid[0] = inBufferLength[0]; 362 363 int prevSampleRate = mStreamInfo->sampleRate; 364 decoderErr = aacDecoder_Fill(mAACDecoder, 365 inBuffer, 366 inBufferLength, 367 bytesValid); 368 decoderErr = aacDecoder_DecodeFrame(mAACDecoder, 369 outBuffer, 370 outHeader->nAllocLen, 371 /* flags */ 0); 372 373 /* 374 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly 375 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual 376 * rate system and the sampling rate in the final output is actually 377 * doubled compared with the core AAC decoder sampling rate. 378 * 379 * Explicit signalling is done by explicitly defining SBR audio object 380 * type in the bitstream. Implicit signalling is done by embedding 381 * SBR content in AAC extension payload specific to SBR, and hence 382 * requires an AAC decoder to perform pre-checks on actual audio frames. 383 * 384 * Thus, we could not say for sure whether a stream is 385 * AAC+/eAAC+ until the first data frame is decoded. 386 */ 387 if (decoderErr == AAC_DEC_OK && mInputBufferCount <= 2) { 388 if (mStreamInfo->sampleRate != prevSampleRate) { 389 notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 390 mOutputPortSettingsChange = AWAITING_DISABLED; 391 return; 392 } 393 } 394 395 size_t numOutBytes = 396 mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels; 397 398 if (decoderErr == AAC_DEC_OK) { 399 UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0]; 400 inHeader->nFilledLen -= inBufferUsedLength; 401 inHeader->nOffset += inBufferUsedLength; 402 } else { 403 ALOGW("AAC decoder returned error %d, substituting silence", 404 decoderErr); 405 406 memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes); 407 408 // Discard input buffer. 409 inHeader->nFilledLen = 0; 410 411 // fall through 412 } 413 414 if (decoderErr == AAC_DEC_OK || mNumSamplesOutput > 0) { 415 // We'll only output data if we successfully decoded it or 416 // we've previously decoded valid data, in the latter case 417 // (decode failed) we'll output a silent frame. 418 outHeader->nFilledLen = numOutBytes; 419 outHeader->nFlags = 0; 420 421 outHeader->nTimeStamp = 422 mAnchorTimeUs 423 + (mNumSamplesOutput * 1000000ll) / mStreamInfo->sampleRate; 424 425 mNumSamplesOutput += mStreamInfo->frameSize; 426 427 outInfo->mOwnedByUs = false; 428 outQueue.erase(outQueue.begin()); 429 outInfo = NULL; 430 notifyFillBufferDone(outHeader); 431 outHeader = NULL; 432 } 433 434 if (inHeader->nFilledLen == 0) { 435 inInfo->mOwnedByUs = false; 436 inQueue.erase(inQueue.begin()); 437 inInfo = NULL; 438 notifyEmptyBufferDone(inHeader); 439 inHeader = NULL; 440 } 441 442 if (decoderErr == AAC_DEC_OK) { 443 ++mInputBufferCount; 444 } 445 } 446} 447 448void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) { 449 if (portIndex == 0) { 450 451 // Make sure that the next buffer output does not still 452 // depend on fragments from the last one decoded. 453 aacDecoder_DecodeFrame(mAACDecoder, 454 NULL, 455 0, 456 AACDEC_FLUSH); 457 } 458} 459 460void SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 461 if (portIndex != 1) { 462 return; 463 } 464 465 switch (mOutputPortSettingsChange) { 466 case NONE: 467 break; 468 469 case AWAITING_DISABLED: 470 { 471 CHECK(!enabled); 472 mOutputPortSettingsChange = AWAITING_ENABLED; 473 break; 474 } 475 476 default: 477 { 478 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 479 CHECK(enabled); 480 mOutputPortSettingsChange = NONE; 481 break; 482 } 483 } 484} 485 486} // namespace android 487 488android::SoftOMXComponent *createSoftOMXComponent( 489 const char *name, const OMX_CALLBACKTYPE *callbacks, 490 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 491 return new android::SoftAAC2(name, callbacks, appData, component); 492} 493