1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 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 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 19 /*---------------------------------------------------------------------------- 20 ; INCLUDES 21 ----------------------------------------------------------------------------*/ 22 23 #include "amr_dec.h" 24 #include "frame.h" 25 #include "cnst.h" 26 #include "d_homing.h" 27 28 #define ETS_INPUT_FRAME_SIZE 500 29 30 //Compressed audio formats 31 #define PV_AMR_IETF 0 32 #define PV_AMR_IF2 1 33 #define PV_AMR_ETS 2 34 #define PV_AMR_IETF_COMBINED 3 35 36 //WB modes 37 #define PV_AMRWB_IETF_PAYLOAD 4 38 #define PV_AMRWB_IETF 5 39 40 41 // decoder returns -1 if there is an error in decoding a frame 42 #define PV_GSMAMR_DECODE_STATUS_ERR -1 43 44 // Currently, decoder returns a value >=0 if there is no error.(should be 0) 45 #define PV_GSMAMR_DECODE_STATUS_OK 0 46 47 // Find frame size for each frame type 48 static const OMX_S32 WBIETFFrameSize[16] = 49 { 50 18 // AMR-WB 6.60 Kbps 51 , 24 // AMR-WB 8.85 Kbps 52 , 33 // AMR-WB 12.65 Kbps 53 , 37 // AMR-WB 14.25 Kbps 54 , 41 // AMR-WB 15.85 Kbps 55 , 47 // AMR-WB 18.25 Kbps 56 , 51 // AMR-WB 19.85 Kbps 57 , 59 // AMR-WB 23.05 Kbps 58 , 61 // AMR-WB 23.85 Kbps 59 , 6 // AMR-WB SID 60 , 1 61 , 1 62 , 1 63 , 1 64 , 1 // WBAMR Frame No Data 65 , 1 // WBAMR Frame No Data 66 }; 67 68 ////////////////////////////////////////////////////////////////////////////////// 69 static const OMX_S32 IETFFrameSize[16] = 70 { 71 13 // AMR 4.75 Kbps 72 , 14 // AMR 5.15 Kbps 73 , 16 // AMR 5.90 Kbps 74 , 18 // AMR 6.70 Kbps 75 , 20 // AMR 7.40 Kbps 76 , 21 // AMR 7.95 Kbps 77 , 27 // AMR 10.2 Kbps 78 , 32 // AMR 12.2 Kbps 79 , 6 // GsmAmr comfort noise 80 , 7 // Gsm-Efr comfort noise 81 , 6 // IS-641 comfort noise 82 , 6 // Pdc-Efr comfort noise 83 , 1 // future use; 0 length but set to 1 to skip the frame type byte 84 , 1 // future use; 0 length but set to 1 to skip the frame type byte 85 , 1 // future use; 0 length but set to 1 to skip the frame type byte 86 , 1 // AMR Frame No Data 87 }; 88 89 static const OMX_S32 IF2FrameSize[16] = 90 { 91 13 // AMR 4.75 Kbps 92 , 14 // AMR 5.15 Kbps 93 , 16 // AMR 5.90 Kbps 94 , 18 // AMR 6.70 Kbps 95 , 19 // AMR 7.40 Kbps 96 , 21 // AMR 7.95 Kbps 97 , 26 // AMR 10.2 Kbps 98 , 31 // AMR 12.2 Kbps 99 , 6 // AMR Frame SID 100 , 6 // AMR Frame GSM EFR SID 101 , 6 // AMR Frame TDMA EFR SID 102 , 6 // AMR Frame PDC EFR SID 103 , 1 // future use; 0 length but set to 1 to skip the frame type byte 104 , 1 // future use; 0 length but set to 1 to skip the frame type byte 105 , 1 // future use; 0 length but set to 1 to skip the frame type byte 106 , 1 // AMR Frame No Data 107 }; 108 109 OmxAmrDecoder::OmxAmrDecoder() 110 { 111 iOmxInputFormat = PV_AMR_ETS; 112 iAMRFramesinTOC = 0; 113 iAmrInitFlag = 0; 114 iNarrowBandFlag = OMX_TRUE; 115 116 //Output frame size in NB would be double the L_FRAME, due to char* output buffer in case of openmax instead of short* in console app 117 iOutputFrameSize = L_FRAME * 2; 118 119 iCodecExternals = NULL; 120 iAudioAmrDecoder = NULL; 121 iTocTablePtr = NULL; 122 /* Initialize decoder homing flags */ 123 iDecHomingFlag = 0; 124 iDecHomingFlagOld = 1; 125 } 126 127 /* Decoder Initialization function */ 128 OMX_BOOL OmxAmrDecoder::AmrDecInit(OMX_AUDIO_AMRFRAMEFORMATTYPE aInFormat, OMX_AUDIO_AMRBANDMODETYPE aInMode) 129 { 130 OMX_S32 Status = 0; 131 132 iAmrInitFlag = 0; 133 134 if ((aInMode >= OMX_AUDIO_AMRBandModeNB0) && (aInMode <= OMX_AUDIO_AMRBandModeNB7)) 135 { 136 iAudioAmrDecoder = CDecoder_AMR_NB::NewL(); 137 138 if (!iAudioAmrDecoder) 139 { 140 return OMX_FALSE; 141 } 142 143 iNarrowBandFlag = OMX_TRUE; 144 iOutputFrameSize = L_FRAME * 2; 145 } 146 147 else if ((aInMode >= OMX_AUDIO_AMRBandModeWB0) && (aInMode <= OMX_AUDIO_AMRBandModeWB8)) 148 { 149 iAudioAmrDecoder = CDecoder_AMR_WB::NewL(); 150 151 if (!iAudioAmrDecoder) 152 { 153 return OMX_FALSE; 154 } 155 156 iNarrowBandFlag = OMX_FALSE; 157 iOutputFrameSize = L_FRAME * 4; 158 } 159 else 160 { 161 return OMX_FALSE; 162 } 163 164 165 if (!iCodecExternals) 166 { 167 iCodecExternals = OSCL_NEW(tPVAmrDecoderExternal, ()); 168 if (!iCodecExternals) 169 { 170 return OMX_FALSE; 171 } 172 } 173 174 //initialize all fields to 0 175 oscl_memset(iCodecExternals, 0, sizeof(tPVAmrDecoderExternal)); 176 iCodecExternals->quality = 1; // assume its always good data 177 178 //Extracting the input format information 179 if (OMX_AUDIO_AMRFrameFormatConformance == aInFormat) 180 { 181 iOmxInputFormat = PV_AMR_ETS; 182 iCodecExternals->input_format = ETS; 183 } 184 else if (OMX_AUDIO_AMRFrameFormatIF2 == aInFormat) 185 { 186 iOmxInputFormat = PV_AMR_IF2; 187 iCodecExternals->input_format = IF2; 188 } 189 else if (OMX_AUDIO_AMRFrameFormatRTPPayload == aInFormat) 190 { 191 if (OMX_TRUE == iNarrowBandFlag) 192 { 193 iOmxInputFormat = PV_AMR_IETF_COMBINED; 194 } 195 else 196 { 197 iOmxInputFormat = PV_AMRWB_IETF_PAYLOAD; 198 } 199 200 iCodecExternals->input_format = MIME_IETF; 201 } 202 else if (OMX_AUDIO_AMRFrameFormatFSF == aInFormat) 203 { 204 if (OMX_TRUE == iNarrowBandFlag) 205 { 206 iOmxInputFormat = PV_AMR_IETF; 207 } 208 else 209 { 210 iOmxInputFormat = PV_AMRWB_IETF; 211 } 212 213 iCodecExternals->input_format = MIME_IETF; 214 } 215 216 Status = iAudioAmrDecoder->StartL(iCodecExternals, false, false); 217 218 if (Status) 219 { 220 return OMX_FALSE; 221 } 222 223 return OMX_TRUE; 224 } 225 226 227 /* Decoder De-Initialization function */ 228 void OmxAmrDecoder::AmrDecDeinit() 229 { 230 /* This function call is platform-specific */ 231 if (iAudioAmrDecoder) 232 { 233 iAudioAmrDecoder->TerminateDecoderL(); 234 OSCL_DELETE(iAudioAmrDecoder); 235 iAudioAmrDecoder = NULL; 236 237 if (iCodecExternals) 238 { 239 OSCL_DELETE(iCodecExternals); 240 iCodecExternals = NULL; 241 } 242 } 243 } 244 245 246 void OmxAmrDecoder::ResetDecoder() 247 { 248 if (iAudioAmrDecoder) 249 { 250 iAudioAmrDecoder->ResetDecoderL(); 251 } 252 iAMRFramesinTOC = 0; 253 } 254 255 256 /* Find the start point & size of TOC table in case of IETF_Combined format */ 257 void OmxAmrDecoder::GetStartPointsForIETFCombinedMode 258 (OMX_U8* aPtrIn, OMX_U32 aLength, OMX_U8* &aTocPtr, OMX_S32* aNumOfBytes) 259 { 260 OMX_U8 Fbit = 0x80; 261 OMX_U32 FrameCnt = 0; 262 263 /* Count number of frames */ 264 aTocPtr = aPtrIn; 265 while ((*(aTocPtr + FrameCnt) & Fbit) && (FrameCnt < aLength)) 266 { 267 FrameCnt++; 268 } 269 270 FrameCnt++; 271 *aNumOfBytes = FrameCnt; 272 } 273 274 275 /* Decode function for all the input formats */ 276 OMX_BOOL OmxAmrDecoder::AmrDecodeFrame(OMX_S16* aOutputBuffer, 277 OMX_U32* aOutputLength, OMX_U8** aInBuffer, 278 OMX_U32* aInBufSize, OMX_S32* aIsFirstBuffer) 279 { 280 OMX_BOOL Status = OMX_TRUE; 281 OMX_S32 ByteOffset, ii; 282 TXFrameType TxFrame; 283 284 /* 3GPP Frame Type Buffer */ 285 Frame_Type_3GPP FrameType3gpp; 286 287 /* Takes care of extra bytes above the decoded ones 288 * e.g. toc length for ietf_combined, frame header length & 289 * one frame type byte for ietf format. 290 */ 291 OMX_S32 FrameBytesProcessed = 0, FrameLength; 292 293 /* Reset speech_bits buffer pointer */ 294 OMX_U8* pSpeechBits = *aInBuffer; 295 OMX_U8 *pTocPtr; 296 //ETS mode requires a 16-bit pointer 297 OMX_S16* pEtsSpeechBits = (OMX_S16*) * aInBuffer; 298 299 if ((PV_AMR_IETF_COMBINED == iOmxInputFormat) || (PV_AMR_IETF == iOmxInputFormat) 300 || (PV_AMRWB_IETF_PAYLOAD == iOmxInputFormat) || (PV_AMRWB_IETF == iOmxInputFormat)) 301 { 302 if ((PV_AMR_IETF_COMBINED == iOmxInputFormat) || (PV_AMRWB_IETF_PAYLOAD == iOmxInputFormat)) 303 { 304 if (0 == iAMRFramesinTOC) 305 { 306 pTocPtr = NULL; 307 GetStartPointsForIETFCombinedMode(pSpeechBits, *aInBufSize, 308 pTocPtr, &iAMRFramesinTOC); 309 pSpeechBits += iAMRFramesinTOC; 310 FrameBytesProcessed = iAMRFramesinTOC; 311 312 iTocTablePtr = pTocPtr; 313 iAMRFramesinTOC--; // ctr of amr frames 314 } 315 else 316 { 317 iAMRFramesinTOC--; 318 FrameBytesProcessed = 0; 319 } 320 321 FrameType3gpp = GetFrameTypeLength(iTocTablePtr, &FrameLength); 322 } 323 else //iOmxInputFormat == PV_AMR_IETF or (PV_AMRWB_IETF == iOmxInputFormat) 324 { 325 if (0 == iAmrInitFlag) 326 { 327 if ('#' == pSpeechBits[0]) 328 { 329 pSpeechBits += 6; 330 FrameBytesProcessed = 6; 331 } 332 iAmrInitFlag = 1; 333 } 334 335 FrameType3gpp = GetFrameTypeLength(pSpeechBits, &FrameLength); 336 } 337 338 // check if the frame size exceeds buffer boundaries 339 if ((FrameLength + FrameBytesProcessed) <= (OMX_S32) *aInBufSize) 340 { 341 /* Set up pointer to the start of frame to be decoded */ 342 iCodecExternals->mode = (uint32)FrameType3gpp; 343 iCodecExternals->pInputBuffer = (uint8*) pSpeechBits; 344 iCodecExternals->pOutputBuffer = (int16*) aOutputBuffer; 345 346 ByteOffset = iAudioAmrDecoder->ExecuteL(iCodecExternals); 347 348 if (PV_GSMAMR_DECODE_STATUS_ERR == ByteOffset) 349 { 350 *aInBufSize = 0; 351 *aOutputLength = 0; 352 iAMRFramesinTOC = 0; // make sure the TOC table (if necessary) gets initialized for the next time 353 Status = OMX_FALSE; 354 } 355 else 356 { 357 *aInBufSize -= (FrameLength + FrameBytesProcessed); 358 *aInBuffer += (FrameLength + FrameBytesProcessed); 359 *aOutputLength = iOutputFrameSize; 360 // in case of TOC, make sure that 361 // a) if no more data in the buffer and TOC indicates more data, reset TOC 362 // b) if TOC indicates no more data, and there is more data in the buffer, reset the buffer 363 if ((PV_AMR_IETF_COMBINED == iOmxInputFormat) || (PV_AMRWB_IETF_PAYLOAD == iOmxInputFormat)) 364 { 365 if ((0 == iAMRFramesinTOC) || (0 == *aInBufSize)) 366 { 367 *aInBufSize = 0; 368 iAMRFramesinTOC = 0; 369 } 370 } 371 372 } 373 } 374 else 375 { 376 *aInBufSize = 0; 377 *aOutputLength = 0; 378 iAMRFramesinTOC = 0; // make sure the TOC table (if necessary) gets initialized for the next time 379 Status = OMX_FALSE; // treat buffer overrun as an error 380 } 381 382 } 383 else if (PV_AMR_IF2 == iOmxInputFormat) 384 { 385 FrameType3gpp = (Frame_Type_3GPP)(pSpeechBits[0] & 0xF); 386 FrameLength = IF2FrameSize[FrameType3gpp]; 387 388 // check if the frame size exceeds buffer boundaries 389 if ((FrameLength + FrameBytesProcessed) <= (OMX_S32) *aInBufSize) 390 { 391 /* Set up pointer to the start of frame to be decoded */ 392 iCodecExternals->mode = (uint32)FrameType3gpp; 393 iCodecExternals->pInputBuffer = (uint8*) pSpeechBits; 394 iCodecExternals->pOutputBuffer = (int16*) aOutputBuffer; 395 396 ByteOffset = iAudioAmrDecoder->ExecuteL(iCodecExternals); 397 398 if (PV_GSMAMR_DECODE_STATUS_ERR == ByteOffset) 399 { 400 Status = OMX_FALSE; 401 } 402 403 if (ByteOffset <= (OMX_S32)*aInBufSize) 404 { 405 *aInBufSize -= ByteOffset; 406 *aInBuffer += ByteOffset; 407 *aOutputLength = iOutputFrameSize; 408 } 409 else 410 { 411 *aInBufSize = 0; 412 *aOutputLength = 0; 413 Status = OMX_FALSE; 414 } 415 } 416 else 417 { 418 *aInBufSize = 0; 419 *aOutputLength = 0; 420 Status = OMX_FALSE; // treat buffer overrun as an error 421 } 422 } 423 else if (PV_AMR_ETS == iOmxInputFormat) 424 { 425 FrameType3gpp = (enum Frame_Type_3GPP) pSpeechBits[(1 + MAX_SERIAL_SIZE) * 2]; 426 427 /* Get TX frame type */ 428 TxFrame = (TXFrameType)pEtsSpeechBits[0]; 429 430 /* Convert TX frame type to RX frame type */ 431 switch (TxFrame) 432 { 433 case TX_SPEECH_GOOD: 434 pEtsSpeechBits[0] = RX_SPEECH_GOOD; 435 break; 436 437 case TX_SPEECH_DEGRADED: 438 pEtsSpeechBits[0] = RX_SPEECH_DEGRADED; 439 break; 440 441 case TX_SPEECH_BAD: 442 pEtsSpeechBits[0] = RX_SPEECH_BAD; 443 break; 444 445 case TX_SID_FIRST: 446 pEtsSpeechBits[0] = RX_SID_FIRST; 447 break; 448 449 case TX_SID_UPDATE: 450 pEtsSpeechBits[0] = RX_SID_UPDATE; 451 break; 452 453 case TX_SID_BAD: 454 pEtsSpeechBits[0] = RX_SID_BAD; 455 break; 456 457 case TX_ONSET: 458 pEtsSpeechBits[0] = RX_ONSET; 459 break; 460 461 case TX_NO_DATA: 462 pEtsSpeechBits[0] = RX_NO_DATA; 463 FrameType3gpp = (enum Frame_Type_3GPP) iCodecExternals->mode; 464 break; 465 466 default: 467 break; 468 } 469 470 /* if homed: check if this frame is another homing frame */ 471 if (1 == iDecHomingFlagOld) 472 { 473 /* only check until end of first subframe */ 474 iDecHomingFlag = decoder_homing_frame_test_first( 475 (OMX_S16*) & pEtsSpeechBits[1], 476 (enum Mode) FrameType3gpp); 477 } 478 479 /* produce encoder homing frame if homed & input=decoder homing frame */ 480 if ((0 != iDecHomingFlag) && (0 != iDecHomingFlagOld)) 481 { 482 for (ii = 0; ii < L_FRAME; ii++) 483 { 484 aOutputBuffer[ii] = EHF_MASK; 485 } 486 } 487 else 488 { 489 /* Set up pointer to the start of frame to be decoded */ 490 iCodecExternals->mode = (uint32)FrameType3gpp; 491 iCodecExternals->pInputBuffer = (uint8*) pEtsSpeechBits; 492 iCodecExternals->pOutputBuffer = (int16*) aOutputBuffer; 493 494 ByteOffset = iAudioAmrDecoder->ExecuteL(iCodecExternals); 495 496 if (PV_GSMAMR_DECODE_STATUS_ERR == ByteOffset) 497 { 498 Status = OMX_FALSE; 499 } 500 501 } 502 503 /* if not homed: check whether current frame is a homing frame */ 504 if (0 == iDecHomingFlagOld) 505 { 506 /* check whole frame */ 507 iDecHomingFlag = decoder_homing_frame_test( 508 (OMX_S16*) & pEtsSpeechBits[1], 509 (enum Mode) FrameType3gpp); 510 } 511 /* reset decoder if current frame is a homing frame */ 512 if (0 != iDecHomingFlag) 513 { 514 iAudioAmrDecoder->ResetDecoderL(); 515 } 516 517 iDecHomingFlagOld = iDecHomingFlag; 518 519 //Input buffer requirement per frame is constant at ETS_INPUT_FRAME_SIZE 520 *aInBufSize -= ETS_INPUT_FRAME_SIZE; 521 *aInBuffer += ETS_INPUT_FRAME_SIZE; 522 *aOutputLength = iOutputFrameSize; 523 } 524 525 (*aIsFirstBuffer)++; 526 527 return Status; 528 } 529 530 /* Decode function for all the input formats */ 531 OMX_BOOL OmxAmrDecoder::AmrDecodeSilenceFrame(OMX_S16* aOutputBuffer, 532 OMX_U32* aOutputLength) 533 { 534 OMX_BOOL Status = OMX_TRUE; 535 OMX_S32 ByteOffset; 536 OMX_U8 FrameType = 15; // silence frame 537 538 iCodecExternals->mode = (uint32) FrameType; 539 iCodecExternals->pInputBuffer = (uint8*) & FrameType; 540 iCodecExternals->pOutputBuffer = (int16*) aOutputBuffer; 541 542 ByteOffset = iAudioAmrDecoder->ExecuteL(iCodecExternals); 543 544 if (PV_GSMAMR_DECODE_STATUS_ERR == ByteOffset) 545 { 546 Status = OMX_FALSE; 547 } 548 else 549 { 550 *aOutputLength = iOutputFrameSize; 551 } 552 553 return Status; 554 } 555 556 557 /* Get Frame type for format == PVMF_AMR_IETF or PVMF_AMR_IETF_COMBINED and the WB counterparts*/ 558 Frame_Type_3GPP OmxAmrDecoder::GetFrameTypeLength(OMX_U8* &aFrame, OMX_S32* aFrameLength) 559 { 560 Frame_Type_3GPP FrameType3gpp; 561 562 563 FrameType3gpp = (Frame_Type_3GPP)((aFrame[0] >> 3) & 0x0F); 564 565 //Narrow Band AMR 566 if (OMX_TRUE == iNarrowBandFlag) 567 { 568 *aFrameLength = IETFFrameSize[FrameType3gpp]; 569 } 570 else 571 { 572 *aFrameLength = WBIETFFrameSize[FrameType3gpp]; 573 } 574 575 576 577 if (PV_AMR_IETF_COMBINED == iOmxInputFormat || PV_AMRWB_IETF_PAYLOAD == iOmxInputFormat) 578 { 579 // move ptr for TOC 580 aFrame++; 581 (*aFrameLength)--; // account for the 1 byte of length being not in the frame, but in the TOC 582 } 583 else if ((PV_AMR_IETF == iOmxInputFormat) || (PV_AMRWB_IETF == iOmxInputFormat)) 584 { 585 aFrame++; // move ptr to data to skip the frame type/size field 586 } 587 588 589 return (FrameType3gpp); 590 } 591