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_IndexParamAudioAmr: 147 { 148 OMX_AUDIO_PARAM_AMRTYPE *amrParams = 149 (OMX_AUDIO_PARAM_AMRTYPE *)params; 150 151 if (amrParams->nPortIndex != 0) { 152 return OMX_ErrorUndefined; 153 } 154 155 amrParams->nChannels = 1; 156 amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff; 157 amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 158 159 if (!isConfigured()) { 160 amrParams->nBitRate = 0; 161 amrParams->eAMRBandMode = OMX_AUDIO_AMRBandModeUnused; 162 } else { 163 amrParams->nBitRate = 0; 164 amrParams->eAMRBandMode = 165 mMode == MODE_NARROW 166 ? OMX_AUDIO_AMRBandModeNB0 : OMX_AUDIO_AMRBandModeWB0; 167 } 168 169 return OMX_ErrorNone; 170 } 171 172 case OMX_IndexParamAudioPcm: 173 { 174 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 175 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 176 177 if (pcmParams->nPortIndex != 1) { 178 return OMX_ErrorUndefined; 179 } 180 181 pcmParams->nChannels = 1; 182 pcmParams->eNumData = OMX_NumericalDataSigned; 183 pcmParams->eEndian = OMX_EndianBig; 184 pcmParams->bInterleaved = OMX_TRUE; 185 pcmParams->nBitPerSample = 16; 186 187 pcmParams->nSamplingRate = 188 (mMode == MODE_NARROW) ? kSampleRateNB : kSampleRateWB; 189 190 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 191 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 192 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 193 194 return OMX_ErrorNone; 195 } 196 197 default: 198 return SimpleSoftOMXComponent::internalGetParameter(index, params); 199 } 200 } 201 202 OMX_ERRORTYPE SoftAMR::internalSetParameter( 203 OMX_INDEXTYPE index, const OMX_PTR params) { 204 switch (index) { 205 case OMX_IndexParamStandardComponentRole: 206 { 207 const OMX_PARAM_COMPONENTROLETYPE *roleParams = 208 (const OMX_PARAM_COMPONENTROLETYPE *)params; 209 210 if (mMode == MODE_NARROW) { 211 if (strncmp((const char *)roleParams->cRole, 212 "audio_decoder.amrnb", 213 OMX_MAX_STRINGNAME_SIZE - 1)) { 214 return OMX_ErrorUndefined; 215 } 216 } else { 217 if (strncmp((const char *)roleParams->cRole, 218 "audio_decoder.amrwb", 219 OMX_MAX_STRINGNAME_SIZE - 1)) { 220 return OMX_ErrorUndefined; 221 } 222 } 223 224 return OMX_ErrorNone; 225 } 226 227 case OMX_IndexParamAudioAmr: 228 { 229 const OMX_AUDIO_PARAM_AMRTYPE *aacParams = 230 (const OMX_AUDIO_PARAM_AMRTYPE *)params; 231 232 if (aacParams->nPortIndex != 0) { 233 return OMX_ErrorUndefined; 234 } 235 236 return OMX_ErrorNone; 237 } 238 239 case OMX_IndexParamAudioPcm: 240 { 241 const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 242 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 243 244 if (pcmParams->nPortIndex != 1) { 245 return OMX_ErrorUndefined; 246 } 247 248 return OMX_ErrorNone; 249 } 250 251 default: 252 return SimpleSoftOMXComponent::internalSetParameter(index, params); 253 } 254 } 255 256 bool SoftAMR::isConfigured() const { 257 return mInputBufferCount > 0; 258 } 259 260 static size_t getFrameSize(unsigned FT) { 261 static const size_t kFrameSizeWB[10] = { 262 132, 177, 253, 285, 317, 365, 397, 461, 477, 40 263 }; 264 265 if (FT >= 10) { 266 return 1; 267 } 268 269 size_t frameSize = kFrameSizeWB[FT]; 270 271 // Round up bits to bytes and add 1 for the header byte. 272 frameSize = (frameSize + 7) / 8 + 1; 273 274 return frameSize; 275 } 276 277 void SoftAMR::onQueueFilled(OMX_U32 portIndex) { 278 List<BufferInfo *> &inQueue = getPortQueue(0); 279 List<BufferInfo *> &outQueue = getPortQueue(1); 280 281 if (mSignalledError || mOutputPortSettingsChange != NONE) { 282 return; 283 } 284 285 while (!inQueue.empty() && !outQueue.empty()) { 286 BufferInfo *inInfo = *inQueue.begin(); 287 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 288 289 BufferInfo *outInfo = *outQueue.begin(); 290 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 291 292 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 293 inQueue.erase(inQueue.begin()); 294 inInfo->mOwnedByUs = false; 295 notifyEmptyBufferDone(inHeader); 296 297 outHeader->nFilledLen = 0; 298 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 299 300 outQueue.erase(outQueue.begin()); 301 outInfo->mOwnedByUs = false; 302 notifyFillBufferDone(outHeader); 303 return; 304 } 305 306 if (inHeader->nOffset == 0) { 307 mAnchorTimeUs = inHeader->nTimeStamp; 308 mNumSamplesOutput = 0; 309 } 310 311 const uint8_t *inputPtr = inHeader->pBuffer + inHeader->nOffset; 312 int32_t numBytesRead; 313 314 if (mMode == MODE_NARROW) { 315 numBytesRead = 316 AMRDecode(mState, 317 (Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f), 318 (UWord8 *)&inputPtr[1], 319 reinterpret_cast<int16_t *>(outHeader->pBuffer), 320 MIME_IETF); 321 322 if (numBytesRead == -1) { 323 ALOGE("PV AMR decoder AMRDecode() call failed"); 324 325 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 326 mSignalledError = true; 327 328 return; 329 } 330 331 ++numBytesRead; // Include the frame type header byte. 332 333 if (static_cast<size_t>(numBytesRead) > inHeader->nFilledLen) { 334 // This is bad, should never have happened, but did. Abort now. 335 336 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 337 mSignalledError = true; 338 339 return; 340 } 341 } else { 342 int16 mode = ((inputPtr[0] >> 3) & 0x0f); 343 344 if (mode >= 10 && mode <= 13) { 345 ALOGE("encountered illegal frame type %d in AMR WB content.", 346 mode); 347 348 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 349 mSignalledError = true; 350 351 return; 352 } 353 354 size_t frameSize = getFrameSize(mode); 355 CHECK_GE(inHeader->nFilledLen, frameSize); 356 357 int16_t *outPtr = (int16_t *)outHeader->pBuffer; 358 359 if (mode >= 9) { 360 // Produce silence instead of comfort noise and for 361 // speech lost/no data. 362 memset(outPtr, 0, kNumSamplesPerFrameWB * sizeof(int16_t)); 363 } else if (mode < 9) { 364 int16 frameType; 365 RX_State_wb rx_state; 366 mime_unsorting( 367 const_cast<uint8_t *>(&inputPtr[1]), 368 mInputSampleBuffer, 369 &frameType, &mode, 1, &rx_state); 370 371 int16_t numSamplesOutput; 372 pvDecoder_AmrWb( 373 mode, mInputSampleBuffer, 374 outPtr, 375 &numSamplesOutput, 376 mDecoderBuf, frameType, mDecoderCookie); 377 378 CHECK_EQ((int)numSamplesOutput, (int)kNumSamplesPerFrameWB); 379 380 for (int i = 0; i < kNumSamplesPerFrameWB; ++i) { 381 /* Delete the 2 LSBs (14-bit output) */ 382 outPtr[i] &= 0xfffC; 383 } 384 } 385 386 numBytesRead = frameSize; 387 } 388 389 inHeader->nOffset += numBytesRead; 390 inHeader->nFilledLen -= numBytesRead; 391 392 outHeader->nFlags = 0; 393 outHeader->nOffset = 0; 394 395 if (mMode == MODE_NARROW) { 396 outHeader->nFilledLen = kNumSamplesPerFrameNB * sizeof(int16_t); 397 398 outHeader->nTimeStamp = 399 mAnchorTimeUs 400 + (mNumSamplesOutput * 1000000ll) / kSampleRateNB; 401 402 mNumSamplesOutput += kNumSamplesPerFrameNB; 403 } else { 404 outHeader->nFilledLen = kNumSamplesPerFrameWB * sizeof(int16_t); 405 406 outHeader->nTimeStamp = 407 mAnchorTimeUs 408 + (mNumSamplesOutput * 1000000ll) / kSampleRateWB; 409 410 mNumSamplesOutput += kNumSamplesPerFrameWB; 411 } 412 413 if (inHeader->nFilledLen == 0) { 414 inInfo->mOwnedByUs = false; 415 inQueue.erase(inQueue.begin()); 416 inInfo = NULL; 417 notifyEmptyBufferDone(inHeader); 418 inHeader = NULL; 419 } 420 421 outInfo->mOwnedByUs = false; 422 outQueue.erase(outQueue.begin()); 423 outInfo = NULL; 424 notifyFillBufferDone(outHeader); 425 outHeader = NULL; 426 427 ++mInputBufferCount; 428 } 429 } 430 431 void SoftAMR::onPortFlushCompleted(OMX_U32 portIndex) { 432 } 433 434 void SoftAMR::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 435 if (portIndex != 1) { 436 return; 437 } 438 439 switch (mOutputPortSettingsChange) { 440 case NONE: 441 break; 442 443 case AWAITING_DISABLED: 444 { 445 CHECK(!enabled); 446 mOutputPortSettingsChange = AWAITING_ENABLED; 447 break; 448 } 449 450 default: 451 { 452 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 453 CHECK(enabled); 454 mOutputPortSettingsChange = NONE; 455 break; 456 } 457 } 458 } 459 460 } // namespace android 461 462 android::SoftOMXComponent *createSoftOMXComponent( 463 const char *name, const OMX_CALLBACKTYPE *callbacks, 464 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 465 return new android::SoftAMR(name, callbacks, appData, component); 466 } 467 468