Home | History | Annotate | Download | only in src
      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