• 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 #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