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 #ifndef OSCL_BASE_H_INCLUDED
19 #include "oscl_base.h"
20 #endif
21
22 #include "mp3_dec.h"
23 #include "pvmp3decoder_api.h"
24
Mp3Decoder()25 Mp3Decoder::Mp3Decoder()
26 {
27 iMP3DecExt = NULL;
28 iAudioMp3Decoder = NULL;
29 iInputUsedLength = 0;
30 iInitFlag = 0;
31 }
32
Mp3DecInit(OMX_AUDIO_CONFIG_EQUALIZERTYPE * aEqualizerType)33 OMX_BOOL Mp3Decoder::Mp3DecInit(OMX_AUDIO_CONFIG_EQUALIZERTYPE* aEqualizerType)
34 {
35 //Default equalization type
36 e_equalization EqualizType = (e_equalization) aEqualizerType->sBandIndex.nValue;
37
38 iAudioMp3Decoder = CPvMP3_Decoder::NewL();
39
40 if (!iAudioMp3Decoder)
41 {
42 return OMX_FALSE;
43 }
44
45 // create iMP3DecExt
46 if (!iMP3DecExt)
47 {
48 iMP3DecExt = OSCL_NEW(tPVMP3DecoderExternal, ());
49 if (!iMP3DecExt)
50 {
51 return OMX_FALSE;
52 }
53 iMP3DecExt->inputBufferCurrentLength = 0;
54 }
55
56 // Initialize the decoder
57 //Input/output buffer allocation and CrcEnabler has been kept as false
58 iAudioMp3Decoder->StartL(iMP3DecExt, false, false, false, EqualizType);
59 iMP3DecExt->inputBufferMaxLength = 512;
60
61 iInitFlag = 0;
62 iInputUsedLength = 0;
63
64 return OMX_TRUE;
65 }
66
ResetDecoder()67 void Mp3Decoder::ResetDecoder()
68 {
69 if (iAudioMp3Decoder)
70 {
71 iAudioMp3Decoder->ResetDecoderL();
72 }
73 }
74
Mp3DecDeinit()75 void Mp3Decoder::Mp3DecDeinit()
76 {
77 if (iAudioMp3Decoder)
78 {
79 iAudioMp3Decoder->TerminateDecoderL();
80 delete iAudioMp3Decoder;
81 iAudioMp3Decoder = NULL;
82
83 if (iMP3DecExt)
84 {
85 OSCL_DELETE(iMP3DecExt);
86 iMP3DecExt = NULL;
87 }
88 }
89 }
90
91
Mp3DecodeAudio(OMX_S16 * aOutBuff,OMX_U32 * aOutputLength,OMX_U8 ** aInputBuf,OMX_U32 * aInBufSize,OMX_S32 * aFrameCount,OMX_AUDIO_PARAM_PCMMODETYPE * aAudioPcmParam,OMX_AUDIO_PARAM_MP3TYPE * aAudioMp3Param,OMX_BOOL aMarkerFlag,OMX_BOOL * aResizeFlag)92 Int Mp3Decoder::Mp3DecodeAudio(OMX_S16* aOutBuff,
93 OMX_U32* aOutputLength, OMX_U8** aInputBuf,
94 OMX_U32* aInBufSize, OMX_S32* aFrameCount,
95 OMX_AUDIO_PARAM_PCMMODETYPE* aAudioPcmParam,
96 OMX_AUDIO_PARAM_MP3TYPE* aAudioMp3Param,
97 OMX_BOOL aMarkerFlag,
98 OMX_BOOL* aResizeFlag)
99 {
100
101 int32 Status = MP3DEC_SUCCESS;
102 *aResizeFlag = OMX_FALSE;
103
104
105 if (iInitFlag == 0)
106 {
107 //Initialization is required again when the client inbetween rewinds the input bitstream
108 //Added to pass khronous conformance tests
109 if (*aFrameCount != 0)
110 {
111 e_equalization EqualizType = iMP3DecExt->equalizerType;
112 iMP3DecExt->inputBufferCurrentLength = 0;
113 iInputUsedLength = 0;
114 iAudioMp3Decoder->StartL(iMP3DecExt, false, false, false, EqualizType);
115 }
116
117 iInitFlag = 1;
118 }
119
120 iMP3DecExt->pInputBuffer = *aInputBuf + iInputUsedLength;
121 iMP3DecExt->pOutputBuffer = &aOutBuff[0];
122
123 iMP3DecExt->inputBufferCurrentLength = *aInBufSize;
124 iMP3DecExt->inputBufferUsedLength = 0;
125
126 if (OMX_FALSE == aMarkerFlag)
127 {
128 //If the input buffer has finished off, do not check the frame boundaries just return from here
129 //This will detect the EOS for without marker test case.
130 if (0 == iMP3DecExt->inputBufferCurrentLength)
131 {
132 iInputUsedLength = 0;
133 return MP3DEC_INCOMPLETE_FRAME;
134 }
135 //If the marker flag is not set, find out the frame boundaries
136 else
137 {
138 Status = iAudioMp3Decoder->SeekMp3Synchronization(iMP3DecExt);
139
140 if (1 == Status)
141 {
142 if (0 == iMP3DecExt->inputBufferCurrentLength)
143 {
144 //This indicates the case of corrupt frame, discard input bytes equal to inputBufferMaxLength
145 *aInBufSize -= iMP3DecExt->inputBufferMaxLength;
146 iInputUsedLength += iMP3DecExt->inputBufferMaxLength;
147 iMP3DecExt->inputBufferUsedLength += iMP3DecExt->inputBufferMaxLength;;
148
149 //return sucess so that we can continue decoding with rest of the buffer,
150 //after discarding the corrupted bit-streams
151 return MP3DEC_SUCCESS;
152 }
153 else
154 {
155 *aInputBuf += iInputUsedLength;
156 iMP3DecExt->inputBufferUsedLength = 0;
157 iInputUsedLength = 0;
158 return MP3DEC_INCOMPLETE_FRAME;
159 }
160 }
161 }
162 }
163
164 /*
165 * inform decoder how much more room is available in the output buffer
166 */
167 iMP3DecExt->outputFrameSize = (*aOutputLength); /* in int16 samples */
168
169 Status = iAudioMp3Decoder->ExecuteL(iMP3DecExt);
170
171 if (MP3DEC_SUCCESS == Status)
172 {
173 *aInBufSize -= iMP3DecExt->inputBufferUsedLength;
174
175 if (0 == *aInBufSize)
176 {
177 iInputUsedLength = 0;
178 }
179 else
180 {
181 iInputUsedLength += iMP3DecExt->inputBufferUsedLength;
182 }
183
184 *aOutputLength = iMP3DecExt->outputFrameSize;
185
186 //After decoding the first frame, update all the input & output port settings
187 if (0 == *aFrameCount)
188 {
189
190 //Output Port Parameters
191 aAudioPcmParam->nSamplingRate = iMP3DecExt->samplingRate;
192 aAudioPcmParam->nChannels = iMP3DecExt->num_channels;
193
194 //Input Port Parameters
195 aAudioMp3Param->nSampleRate = iMP3DecExt->samplingRate;
196
197 //Set the Resize flag to send the port settings changed callback
198 *aResizeFlag = OMX_TRUE;
199
200 }
201
202 }
203 else if (Status == MP3DEC_INVALID_FRAME)
204 {
205 *aInBufSize = 0;
206 iInputUsedLength = 0;
207 *aOutputLength = 0;
208 }
209 else if (Status == MP3DEC_INCOMPLETE_FRAME)
210 {
211 *aInputBuf += iInputUsedLength;
212 iMP3DecExt->inputBufferUsedLength = 0;
213 iInputUsedLength = 0;
214 *aOutputLength = 0;
215 }
216 else if (Status == MP3DEC_OUTPUT_BUFFER_TOO_SMALL)
217 {
218 /*
219 * This condition is only reached when the mp3 version has changed
220 * (which is an abnormal condition)
221 */
222 *aInputBuf += iInputUsedLength;
223 iMP3DecExt->inputBufferUsedLength = 0;
224 iInputUsedLength = 0;
225 *aOutputLength = 0;
226 /*
227 * Reseting the counter will force to recalculate timing parameters
228 * ( this will eliminate any silence insertion gap, but may force changing
229 * audio device parameters ( sampling freq, etc) in the middle of decoding
230 * If this is allowed, reset the counter.
231 */
232 // (*aFrameCount) = -1;
233
234 }
235
236 else
237 {
238 *aInputBuf += iInputUsedLength;
239 iInputUsedLength = 0;
240 *aOutputLength = 0;
241 }
242
243
244 (*aFrameCount)++;
245
246 return Status;
247
248 }
249