1 /* 2 * Copyright (C) 2011 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 "SoftAMR" 19 #include <utils/Log.h> 20 21 #include "SoftAMR.h" 22 23 #include "gsmamr_dec.h" 24 #include "pvamrwbdecoder.h" 25 26 #include <media/stagefright/foundation/ADebug.h> 27 28 namespace android { 29 30 template<class T> 31 static void InitOMXParams(T *params) { 32 params->nSize = sizeof(T); 33 params->nVersion.s.nVersionMajor = 1; 34 params->nVersion.s.nVersionMinor = 0; 35 params->nVersion.s.nRevision = 0; 36 params->nVersion.s.nStep = 0; 37 } 38 39 SoftAMR::SoftAMR( 40 const char *name, 41 const OMX_CALLBACKTYPE *callbacks, 42 OMX_PTR appData, 43 OMX_COMPONENTTYPE **component) 44 : SimpleSoftOMXComponent(name, callbacks, appData, component), 45 mMode(MODE_NARROW), 46 mState(NULL), 47 mDecoderBuf(NULL), 48 mDecoderCookie(NULL), 49 mInputBufferCount(0), 50 mAnchorTimeUs(0), 51 mNumSamplesOutput(0), 52 mSignalledError(false), 53 mOutputPortSettingsChange(NONE) { 54 if (!strcmp(name, "OMX.google.amrwb.decoder")) { 55 mMode = MODE_WIDE; 56 } else { 57 CHECK(!strcmp(name, "OMX.google.amrnb.decoder")); 58 } 59 60 initPorts(); 61 CHECK_EQ(initDecoder(), (status_t)OK); 62 } 63 64 SoftAMR::~SoftAMR() { 65 if (mMode == MODE_NARROW) { 66 GSMDecodeFrameExit(&mState); 67 mState = NULL; 68 } else { 69 free(mDecoderBuf); 70 mDecoderBuf = NULL; 71 72 mState = NULL; 73 mDecoderCookie = NULL; 74 } 75 } 76 77 void SoftAMR::initPorts() { 78 OMX_PARAM_PORTDEFINITIONTYPE def; 79 InitOMXParams(&def); 80 81 def.nPortIndex = 0; 82 def.eDir = OMX_DirInput; 83 def.nBufferCountMin = kNumBuffers; 84 def.nBufferCountActual = def.nBufferCountMin; 85 def.nBufferSize = 8192; 86 def.bEnabled = OMX_TRUE; 87 def.bPopulated = OMX_FALSE; 88 def.eDomain = OMX_PortDomainAudio; 89 def.bBuffersContiguous = OMX_FALSE; 90 def.nBufferAlignment = 1; 91 92 def.format.audio.cMIMEType = 93 mMode == MODE_NARROW 94 ? const_cast<char *>("audio/amr") 95 : const_cast<char *>("audio/amrwb"); 96 97 def.format.audio.pNativeRender = NULL; 98 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 99 def.format.audio.eEncoding = OMX_AUDIO_CodingAMR; 100 101 addPort(def); 102 103 def.nPortIndex = 1; 104 def.eDir = OMX_DirOutput; 105 def.nBufferCountMin = kNumBuffers; 106 def.nBufferCountActual = def.nBufferCountMin; 107 108 def.nBufferSize = 109 (mMode == MODE_NARROW ? kNumSamplesPerFrameNB : kNumSamplesPerFrameWB) 110 * sizeof(int16_t); 111 112 def.bEnabled = OMX_TRUE; 113 def.bPopulated = OMX_FALSE; 114 def.eDomain = OMX_PortDomainAudio; 115 def.bBuffersContiguous = OMX_FALSE; 116 def.nBufferAlignment = 2; 117 118 def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 119 def.format.audio.pNativeRender = NULL; 120 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 121 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 122 123 addPort(def); 124 } 125 126 status_t SoftAMR::initDecoder() { 127 if (mMode == MODE_NARROW) { 128 Word16 err = GSMInitDecode(&mState, (Word8 *)"AMRNBDecoder"); 129 130 if (err != 0) { 131 return UNKNOWN_ERROR; 132 } 133 } else { 134 int32_t memReq = pvDecoder_AmrWbMemRequirements(); 135 mDecoderBuf = malloc(memReq); 136 137 pvDecoder_AmrWb_Init(&mState, mDecoderBuf, &mDecoderCookie); 138 } 139 140 return OK; 141 } 142 143 OMX_ERRORTYPE SoftAMR::internalGetParameter( 144 OMX_INDEXTYPE index, OMX_PTR params) { 145 switch (index) { 146 case OMX_IndexParamAudioPortFormat: 147 { 148 OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = 149 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; 150 151 if (!isValidOMXParam(formatParams)) { 152 return OMX_ErrorBadParameter; 153 } 154 155 if (formatParams->nPortIndex > 1) { 156 return OMX_ErrorUndefined; 157 } 158 159 if (formatParams->nIndex > 0) { 160 return OMX_ErrorNoMore; 161 } 162 163 formatParams->eEncoding = 164 (formatParams->nPortIndex == 0) 165 ? OMX_AUDIO_CodingAMR : OMX_AUDIO_CodingPCM; 166 167 return OMX_ErrorNone; 168 } 169 170 case OMX_IndexParamAudioAmr: 171 { 172 OMX_AUDIO_PARAM_AMRTYPE *amrParams = 173 (OMX_AUDIO_PARAM_AMRTYPE *)params; 174 175 if (!isValidOMXParam(amrParams)) { 176 return OMX_ErrorBadParameter; 177 } 178 179 if (amrParams->nPortIndex != 0) { 180 return OMX_ErrorUndefined; 181 } 182 183 amrParams->nChannels = 1; 184 amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff; 185 amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 186 187 if (!isConfigured()) { 188 amrParams->nBitRate = 0; 189 amrParams->eAMRBandMode = OMX_AUDIO_AMRBandModeUnused; 190 } else { 191 amrParams->nBitRate = 0; 192 amrParams->eAMRBandMode = 193 mMode == MODE_NARROW 194 ? OMX_AUDIO_AMRBandModeNB0 : OMX_AUDIO_AMRBandModeWB0; 195 } 196 197 return OMX_ErrorNone; 198 } 199 200 case OMX_IndexParamAudioPcm: 201 { 202 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 203 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 204 205 if (!isValidOMXParam(pcmParams)) { 206 return OMX_ErrorBadParameter; 207 } 208 209 if (pcmParams->nPortIndex != 1) { 210 return OMX_ErrorUndefined; 211 } 212 213 pcmParams->nChannels = 1; 214 pcmParams->eNumData = OMX_NumericalDataSigned; 215 pcmParams->eEndian = OMX_EndianBig; 216 pcmParams->bInterleaved = OMX_TRUE; 217 pcmParams->nBitPerSample = 16; 218 219 pcmParams->nSamplingRate = 220 (mMode == MODE_NARROW) ? kSampleRateNB : kSampleRateWB; 221 222 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 223 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 224 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 225 226 return OMX_ErrorNone; 227 } 228 229 default: 230 return SimpleSoftOMXComponent::internalGetParameter(index, params); 231 } 232 } 233 234 OMX_ERRORTYPE SoftAMR::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 (!isValidOMXParam(roleParams)) { 243 return OMX_ErrorBadParameter; 244 } 245 246 if (mMode == MODE_NARROW) { 247 if (strncmp((const char *)roleParams->cRole, 248 "audio_decoder.amrnb", 249 OMX_MAX_STRINGNAME_SIZE - 1)) { 250 return OMX_ErrorUndefined; 251 } 252 } else { 253 if (strncmp((const char *)roleParams->cRole, 254 "audio_decoder.amrwb", 255 OMX_MAX_STRINGNAME_SIZE - 1)) { 256 return OMX_ErrorUndefined; 257 } 258 } 259 260 return OMX_ErrorNone; 261 } 262 263 case OMX_IndexParamAudioPortFormat: 264 { 265 const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = 266 (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; 267 268 if (!isValidOMXParam(formatParams)) { 269 return OMX_ErrorBadParameter; 270 } 271 272 if (formatParams->nPortIndex > 1) { 273 return OMX_ErrorUndefined; 274 } 275 276 if ((formatParams->nPortIndex == 0 277 && formatParams->eEncoding != OMX_AUDIO_CodingAMR) 278 || (formatParams->nPortIndex == 1 279 && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) { 280 return OMX_ErrorUndefined; 281 } 282 283 return OMX_ErrorNone; 284 } 285 286 case OMX_IndexParamAudioAmr: 287 { 288 const OMX_AUDIO_PARAM_AMRTYPE *aacParams = 289 (const OMX_AUDIO_PARAM_AMRTYPE *)params; 290 291 if (!isValidOMXParam(aacParams)) { 292 return OMX_ErrorBadParameter; 293 } 294 295 if (aacParams->nPortIndex != 0) { 296 return OMX_ErrorUndefined; 297 } 298 299 return OMX_ErrorNone; 300 } 301 302 case OMX_IndexParamAudioPcm: 303 { 304 const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 305 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 306 307 if (!isValidOMXParam(pcmParams)) { 308 return OMX_ErrorBadParameter; 309 } 310 311 if (pcmParams->nPortIndex != 1) { 312 return OMX_ErrorUndefined; 313 } 314 315 return OMX_ErrorNone; 316 } 317 318 default: 319 return SimpleSoftOMXComponent::internalSetParameter(index, params); 320 } 321 } 322 323 bool SoftAMR::isConfigured() const { 324 return mInputBufferCount > 0; 325 } 326 327 static size_t getFrameSize(unsigned FT) { 328 static const size_t kFrameSizeWB[10] = { 329 132, 177, 253, 285, 317, 365, 397, 461, 477, 40 330 }; 331 332 if (FT >= 10) { 333 return 1; 334 } 335 336 size_t frameSize = kFrameSizeWB[FT]; 337 338 // Round up bits to bytes and add 1 for the header byte. 339 frameSize = (frameSize + 7) / 8 + 1; 340 341 return frameSize; 342 } 343 344 void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { 345 List<BufferInfo *> &inQueue = getPortQueue(0); 346 List<BufferInfo *> &outQueue = getPortQueue(1); 347 348 if (mSignalledError || mOutputPortSettingsChange != NONE) { 349 return; 350 } 351 352 while (!inQueue.empty() && !outQueue.empty()) { 353 BufferInfo *inInfo = *inQueue.begin(); 354 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 355 356 BufferInfo *outInfo = *outQueue.begin(); 357 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 358 359 if ((inHeader->nFlags & OMX_BUFFERFLAG_EOS) && inHeader->nFilledLen == 0) { 360 inQueue.erase(inQueue.begin()); 361 inInfo->mOwnedByUs = false; 362 notifyEmptyBufferDone(inHeader); 363 364 outHeader->nFilledLen = 0; 365 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 366 367 outQueue.erase(outQueue.begin()); 368 outInfo->mOwnedByUs = false; 369 notifyFillBufferDone(outHeader); 370 return; 371 } 372 373 if (inHeader->nFilledLen == 0) { 374 inInfo->mOwnedByUs = false; 375 inQueue.erase(inQueue.begin()); 376 notifyEmptyBufferDone(inHeader); 377 continue; 378 } 379 380 if (inHeader->nOffset == 0) { 381 mAnchorTimeUs = inHeader->nTimeStamp; 382 mNumSamplesOutput = 0; 383 } 384 385 const uint8_t *inputPtr = inHeader->pBuffer + inHeader->nOffset; 386 int32_t numBytesRead; 387 388 if (mMode == MODE_NARROW) { 389 if (outHeader->nAllocLen < kNumSamplesPerFrameNB * sizeof(int16_t)) { 390 ALOGE("b/27662364: NB expected output buffer %zu bytes vs %u", 391 kNumSamplesPerFrameNB * sizeof(int16_t), outHeader->nAllocLen); 392 android_errorWriteLog(0x534e4554, "27662364"); 393 notify(OMX_EventError, OMX_ErrorOverflow, 0, NULL); 394 mSignalledError = true; 395 return; 396 } 397 398 int16 mode = ((inputPtr[0] >> 3) & 0x0f); 399 // for WMF since MIME_IETF is used when calling AMRDecode. 400 size_t frameSize = WmfDecBytesPerFrame[mode] + 1; 401 402 if (inHeader->nFilledLen < frameSize) { 403 ALOGE("b/27662364: expected %zu bytes vs %u", frameSize, inHeader->nFilledLen); 404 notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL); 405 mSignalledError = true; 406 return; 407 } 408 409 numBytesRead = 410 AMRDecode(mState, 411 (Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f), 412 (UWord8 *)&inputPtr[1], 413 reinterpret_cast<int16_t *>(outHeader->pBuffer), 414 MIME_IETF); 415 416 if (numBytesRead == -1) { 417 ALOGE("PV AMR decoder AMRDecode() call failed"); 418 419 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 420 mSignalledError = true; 421 422 return; 423 } 424 425 ++numBytesRead; // Include the frame type header byte. 426 427 if (static_cast<size_t>(numBytesRead) > inHeader->nFilledLen) { 428 // This is bad, should never have happened, but did. Abort now. 429 430 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 431 mSignalledError = true; 432 433 return; 434 } 435 } else { 436 if (outHeader->nAllocLen < kNumSamplesPerFrameWB * sizeof(int16_t)) { 437 ALOGE("b/27662364: WB expected output buffer %zu bytes vs %u", 438 kNumSamplesPerFrameWB * sizeof(int16_t), outHeader->nAllocLen); 439 android_errorWriteLog(0x534e4554, "27662364"); 440 notify(OMX_EventError, OMX_ErrorOverflow, 0, NULL); 441 mSignalledError = true; 442 return; 443 } 444 445 int16 mode = ((inputPtr[0] >> 3) & 0x0f); 446 447 if (mode >= 10 && mode <= 13) { 448 ALOGE("encountered illegal frame type %d in AMR WB content.", 449 mode); 450 451 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 452 mSignalledError = true; 453 454 return; 455 } 456 457 size_t frameSize = getFrameSize(mode); 458 if (inHeader->nFilledLen < frameSize) { 459 ALOGE("b/27662364: expected %zu bytes vs %u", frameSize, inHeader->nFilledLen); 460 notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL); 461 mSignalledError = true; 462 return; 463 } 464 465 int16_t *outPtr = (int16_t *)outHeader->pBuffer; 466 467 if (mode >= 9) { 468 // Produce silence instead of comfort noise and for 469 // speech lost/no data. 470 memset(outPtr, 0, kNumSamplesPerFrameWB * sizeof(int16_t)); 471 } else if (mode < 9) { 472 int16 frameType; 473 RX_State_wb rx_state; 474 mime_unsorting( 475 const_cast<uint8_t *>(&inputPtr[1]), 476 mInputSampleBuffer, 477 &frameType, &mode, 1, &rx_state); 478 479 int16_t numSamplesOutput; 480 pvDecoder_AmrWb( 481 mode, mInputSampleBuffer, 482 outPtr, 483 &numSamplesOutput, 484 mDecoderBuf, frameType, mDecoderCookie); 485 486 CHECK_EQ((int)numSamplesOutput, (int)kNumSamplesPerFrameWB); 487 488 for (int i = 0; i < kNumSamplesPerFrameWB; ++i) { 489 /* Delete the 2 LSBs (14-bit output) */ 490 outPtr[i] &= 0xfffC; 491 } 492 } 493 494 numBytesRead = frameSize; 495 } 496 497 inHeader->nOffset += numBytesRead; 498 inHeader->nFilledLen -= numBytesRead; 499 500 outHeader->nFlags = 0; 501 outHeader->nOffset = 0; 502 503 if (mMode == MODE_NARROW) { 504 outHeader->nFilledLen = kNumSamplesPerFrameNB * sizeof(int16_t); 505 506 outHeader->nTimeStamp = 507 mAnchorTimeUs 508 + (mNumSamplesOutput * 1000000ll) / kSampleRateNB; 509 510 mNumSamplesOutput += kNumSamplesPerFrameNB; 511 } else { 512 outHeader->nFilledLen = kNumSamplesPerFrameWB * sizeof(int16_t); 513 514 outHeader->nTimeStamp = 515 mAnchorTimeUs 516 + (mNumSamplesOutput * 1000000ll) / kSampleRateWB; 517 518 mNumSamplesOutput += kNumSamplesPerFrameWB; 519 } 520 521 if (inHeader->nFilledLen == 0 && (inHeader->nFlags & OMX_BUFFERFLAG_EOS) == 0) { 522 inInfo->mOwnedByUs = false; 523 inQueue.erase(inQueue.begin()); 524 inInfo = NULL; 525 notifyEmptyBufferDone(inHeader); 526 inHeader = NULL; 527 } 528 529 outInfo->mOwnedByUs = false; 530 outQueue.erase(outQueue.begin()); 531 outInfo = NULL; 532 notifyFillBufferDone(outHeader); 533 outHeader = NULL; 534 535 ++mInputBufferCount; 536 } 537 } 538 539 void SoftAMR::onPortFlushCompleted(OMX_U32 portIndex) { 540 ALOGV("onPortFlushCompleted portindex %d, resetting frame ", portIndex); 541 if (portIndex == 0) { 542 if (mMode == MODE_NARROW) { 543 Speech_Decode_Frame_reset(mState); 544 } else { 545 pvDecoder_AmrWb_Reset(mState, 0 /* reset_all */); 546 } 547 } 548 } 549 550 void SoftAMR::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 551 if (portIndex != 1) { 552 return; 553 } 554 555 switch (mOutputPortSettingsChange) { 556 case NONE: 557 break; 558 559 case AWAITING_DISABLED: 560 { 561 CHECK(!enabled); 562 mOutputPortSettingsChange = AWAITING_ENABLED; 563 break; 564 } 565 566 default: 567 { 568 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 569 CHECK(enabled); 570 mOutputPortSettingsChange = NONE; 571 break; 572 } 573 } 574 } 575 576 void SoftAMR::onReset() { 577 mSignalledError = false; 578 mOutputPortSettingsChange = NONE; 579 } 580 581 } // namespace android 582 583 android::SoftOMXComponent *createSoftOMXComponent( 584 const char *name, const OMX_CALLBACKTYPE *callbacks, 585 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 586 return new android::SoftAMR(name, callbacks, appData, component); 587 } 588 589