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