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_enc.h"
     24 
     25 
     26 OmxAmrEncoder::OmxAmrEncoder()
     27 {
     28     // Codec and encoder setting structure
     29     ipGsmEncoder = NULL;
     30     ipEncProps   = NULL;
     31     iNextStartTime = 0;
     32 
     33     iOutputFormat             = PVMF_MIME_AMR_IETF;
     34     ipSizeArrayForOutputFrames = NULL;
     35     iNextStartTime            = 0;
     36 
     37     iMaxNumOutputFramesPerBuffer = MAX_NUM_OUTPUT_FRAMES_PER_BUFFER;
     38     iOneInputFrameLength         = 320;
     39     iMaxInputSize                = 0;
     40 
     41     iAmrInitFlag = 0;
     42 }
     43 
     44 
     45 /* Decoder Initialization function */
     46 OMX_BOOL OmxAmrEncoder::AmrEncInit(OMX_AUDIO_PARAM_PCMMODETYPE aPcmMode,
     47                                    OMX_AUDIO_PARAM_AMRTYPE aAmrParam,
     48                                    OMX_U32* aInputFrameLength,
     49                                    OMX_U32* aMaxNumberOutputFrames)
     50 {
     51     OMX_U32 MaxOutputBufferSize;
     52 
     53 
     54     iAmrInitFlag = 0;
     55 
     56     ipGsmEncoder = OSCL_NEW(CPvGsmAmrEncoder, ());
     57     if (!ipGsmEncoder)
     58     {
     59         return OMX_FALSE;
     60     }
     61 
     62     // for encoder properties
     63     ipEncProps = OSCL_NEW(TEncodeProperties, ());
     64     if (!ipEncProps)
     65     {
     66         return OMX_FALSE;
     67     }
     68 
     69     //Extracting the output format information
     70     if (OMX_AUDIO_AMRFrameFormatFSF == aAmrParam.eAMRFrameFormat)
     71     {
     72         iOutputFormat = PVMF_MIME_AMR_IETF;
     73     }
     74     else if (OMX_AUDIO_AMRFrameFormatIF2 == aAmrParam.eAMRFrameFormat)
     75     {
     76         iOutputFormat = PVMF_MIME_AMR_IF2;
     77     }
     78     else
     79     {
     80         //unsupported format
     81         return OMX_FALSE;
     82     }
     83 
     84 
     85     if (OMX_AUDIO_AMRBandModeNB0 == aAmrParam.eAMRBandMode)
     86     {
     87         ipEncProps->iMode = ipGsmEncoder->GSM_AMR_4_75;
     88     }
     89     else if (OMX_AUDIO_AMRBandModeNB1 == aAmrParam.eAMRBandMode)
     90     {
     91         ipEncProps->iMode = ipGsmEncoder->GSM_AMR_5_15;
     92     }
     93     else if (OMX_AUDIO_AMRBandModeNB2 == aAmrParam.eAMRBandMode)
     94     {
     95         ipEncProps->iMode = ipGsmEncoder->GSM_AMR_5_90;
     96     }
     97     else if (OMX_AUDIO_AMRBandModeNB3 == aAmrParam.eAMRBandMode)
     98     {
     99         ipEncProps->iMode = ipGsmEncoder->GSM_AMR_6_70;
    100     }
    101     else if (OMX_AUDIO_AMRBandModeNB4 == aAmrParam.eAMRBandMode)
    102     {
    103         ipEncProps->iMode = ipGsmEncoder->GSM_AMR_7_40;
    104     }
    105     else if (OMX_AUDIO_AMRBandModeNB5 == aAmrParam.eAMRBandMode)
    106     {
    107         ipEncProps->iMode = ipGsmEncoder->GSM_AMR_7_95;
    108     }
    109     else if (OMX_AUDIO_AMRBandModeNB6 == aAmrParam.eAMRBandMode)
    110     {
    111         ipEncProps->iMode = ipGsmEncoder->GSM_AMR_10_2;
    112     }
    113     else if (OMX_AUDIO_AMRBandModeNB7 == aAmrParam.eAMRBandMode)
    114     {
    115         ipEncProps->iMode = ipGsmEncoder->GSM_AMR_12_2;
    116     }
    117     else
    118     {
    119         //unsupported mode
    120         return OMX_FALSE;
    121     }
    122 
    123     //Adding all the param verification here before allocating them into ipEncProps
    124     if ((16 != aPcmMode.nBitPerSample) ||
    125             (8000 != aPcmMode.nSamplingRate) ||
    126             (1 != aPcmMode.nChannels))
    127     {
    128         return OMX_FALSE;
    129     }
    130 
    131 
    132     ipEncProps->iInBitsPerSample  = aPcmMode.nBitPerSample;
    133     ipEncProps->iInSamplingRate   = aPcmMode.nSamplingRate;
    134     ipEncProps->iInClockRate      = 1000;
    135     ipEncProps->iInNumChannels    = (uint8)aPcmMode.nChannels;
    136     ipEncProps->iInInterleaveMode = TEncodeProperties::EINTERLEAVE_LR;
    137 
    138     ipEncProps->iBitStreamFormat = (iOutputFormat == PVMF_MIME_AMR_IF2);
    139     ipEncProps->iAudioObjectType    = 0; // only for AAC encoder
    140     ipEncProps->iOutSamplingRate    = aPcmMode.nSamplingRate;
    141     ipEncProps->iOutNumChannels     = (uint8)aPcmMode.nChannels;
    142     ipEncProps->iOutClockRate       = ipEncProps->iInClockRate;
    143 
    144     // initialize the amr encoder
    145     MaxOutputBufferSize = iMaxNumOutputFramesPerBuffer * MAX_AMR_FRAME_SIZE;
    146     if (ipGsmEncoder->InitializeEncoder(MaxOutputBufferSize, ipEncProps) < 0)
    147     {
    148         return OMX_FALSE;
    149     }
    150 
    151     ipSizeArrayForOutputFrames = (int32*) oscl_malloc(iMaxNumOutputFramesPerBuffer * sizeof(int32));
    152     oscl_memset(ipSizeArrayForOutputFrames, 0, iMaxNumOutputFramesPerBuffer * sizeof(int32));
    153 
    154     iOneInputFrameLength = AMR_FRAME_LENGTH_IN_TIMESTAMP * ipEncProps->iInSamplingRate * ipEncProps->iInBitsPerSample / 8000000;
    155     iMaxInputSize = iMaxNumOutputFramesPerBuffer * iOneInputFrameLength;
    156 
    157     *aInputFrameLength = iOneInputFrameLength;
    158 
    159     *aMaxNumberOutputFrames = iMaxNumOutputFramesPerBuffer;
    160 
    161     return OMX_TRUE;
    162 }
    163 
    164 
    165 /* Decoder De-Initialization function */
    166 void OmxAmrEncoder::AmrEncDeinit()
    167 {
    168     if (ipGsmEncoder)
    169     {
    170         ipGsmEncoder->CleanupEncoder();
    171         OSCL_DELETE(ipGsmEncoder);
    172         ipGsmEncoder = NULL;
    173     }
    174 
    175     if (ipEncProps)
    176     {
    177         OSCL_DELETE(ipEncProps);
    178         ipEncProps = NULL;
    179     }
    180 
    181     if (ipSizeArrayForOutputFrames)
    182     {
    183         oscl_free(ipSizeArrayForOutputFrames);
    184         ipSizeArrayForOutputFrames = NULL;
    185     }
    186 }
    187 
    188 
    189 /* Decode function for all the input formats */
    190 OMX_BOOL OmxAmrEncoder::AmrEncodeFrame(OMX_U8*    aOutputBuffer,
    191                                        OMX_U32*   aOutputLength,
    192                                        OMX_U8*    aInBuffer,
    193                                        OMX_U32    aInBufSize,
    194                                        OMX_TICKS  aInTimeStamp,
    195                                        OMX_TICKS* aOutTimeStamp)
    196 {
    197 
    198     TInputAudioStream StreamInput;
    199     TOutputAudioStream StreamOutput;
    200     int32 InputFrameNum;
    201 
    202 
    203     StreamOutput.iBitStreamBuffer = (uint8*) aOutputBuffer;
    204     StreamOutput.iNumSampleFrames = 0;
    205     StreamOutput.iSampleFrameSize = ipSizeArrayForOutputFrames;
    206 
    207     //Calculate the number of input frames to be encoded
    208     InputFrameNum = aInBufSize / iOneInputFrameLength;
    209 
    210 
    211     StreamInput.iSampleBuffer = (uint8*) aInBuffer;
    212     StreamInput.iSampleLength = (int32) aInBufSize;
    213     StreamInput.iMode         = ipEncProps->iMode;
    214     StreamInput.iStartTime    = (iNextStartTime >= aInTimeStamp  ? iNextStartTime : aInTimeStamp);
    215     StreamInput.iStopTime     = StreamInput.iStartTime + AMR_FRAME_LENGTH_IN_TIMESTAMP * InputFrameNum;
    216     iNextStartTime            = StreamInput.iStopTime; // for the next encoding
    217 
    218     // Do encoding at one time for multiple frame input
    219     if (ipGsmEncoder->Encode(StreamInput, StreamOutput) < 0 || StreamOutput.iNumSampleFrames != InputFrameNum)
    220     {
    221         return OMX_FALSE;
    222     }
    223 
    224     // For IETF, make a conversion from WMF
    225     uint8* TmpBuffer = StreamOutput.iBitStreamBuffer;
    226     uint32 ii;
    227 
    228     for (ii = 0; ii < (uint32)StreamOutput.iNumSampleFrames; ii++)
    229     {
    230         // for IETF format, we need to make change
    231         if (!ipEncProps->iBitStreamFormat)
    232         {
    233             // non-IF2 => IETF format, not WMF format
    234             TmpBuffer[0] = (uint8)(((TmpBuffer[0] << 3) | 0x4) & 0x7C); // IETF frame header: P(1) + FT(4) + Q(1) + P(2) , Q=1 for good frame, P=padding bit, 0
    235             TmpBuffer += StreamOutput.iSampleFrameSize[ii];
    236         }
    237 
    238         // Set fragment length
    239         *aOutputLength += StreamOutput.iSampleFrameSize[ii];
    240     }
    241 
    242 
    243     *aOutTimeStamp = StreamInput.iStartTime;
    244 
    245     return OMX_TRUE;
    246 }
    247 
    248 
    249 
    250