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