• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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