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
OmxAmrEncoder()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 */
AmrEncInit(OMX_AUDIO_PARAM_PCMMODETYPE aPcmMode,OMX_AUDIO_PARAM_AMRTYPE aAmrParam,OMX_U32 * aInputFrameLength,OMX_U32 * aMaxNumberOutputFrames)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 */
AmrEncDeinit()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 */
AmrEncodeFrame(OMX_U8 * aOutputBuffer,OMX_U32 * aOutputLength,OMX_U8 * aInBuffer,OMX_U32 aInBufSize,OMX_TICKS aInTimeStamp,OMX_TICKS * aOutTimeStamp)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