Initial version of libomxil-e3250-v4l2
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / audio / dec / mp3 / Exynos_OMX_Mp3dec.c
1 /*
2  *
3  * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /*
19  * @file      Exynos_OMX_Mp3dec.c
20  * @brief
21  * @author    Yunji Kim (yunji.kim@samsung.com)
22  * @version   1.1.0
23  * @history
24  *   2012.02.28 : Create
25  */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "Exynos_OMX_Macros.h"
32 #include "Exynos_OMX_Basecomponent.h"
33 #include "Exynos_OMX_Baseport.h"
34 #include "Exynos_OMX_Adec.h"
35 #include "Exynos_OSAL_ETC.h"
36 #include "Exynos_OSAL_Semaphore.h"
37 #include "Exynos_OSAL_Thread.h"
38 #include "library_register.h"
39 #include "Exynos_OMX_Mp3dec.h"
40 #include "srp_api.h"
41
42 #undef  EXYNOS_LOG_TAG
43 #define EXYNOS_LOG_TAG    "EXYNOS_MP3_DEC"
44 #define EXYNOS_LOG_OFF
45 #include "Exynos_OSAL_Log.h"
46
47 //#define SRP_DUMP_TO_FILE
48 #ifdef SRP_DUMP_TO_FILE
49 #include "stdio.h"
50
51 FILE *inFile;
52 FILE *outFile;
53 #endif
54
55 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_GetParameter(
56     OMX_IN    OMX_HANDLETYPE hComponent,
57     OMX_IN    OMX_INDEXTYPE  nParamIndex,
58     OMX_INOUT OMX_PTR        pComponentParameterStructure)
59 {
60     OMX_ERRORTYPE             ret = OMX_ErrorNone;
61     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
62     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
63
64     FunctionIn();
65
66     if (hComponent == NULL || pComponentParameterStructure == NULL) {
67         ret = OMX_ErrorBadParameter;
68         goto EXIT;
69     }
70     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
71     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
72     if (ret != OMX_ErrorNone) {
73         goto EXIT;
74     }
75     if (pOMXComponent->pComponentPrivate == NULL) {
76         ret = OMX_ErrorBadParameter;
77         goto EXIT;
78     }
79
80     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
81     if (pExynosComponent->currentState == OMX_StateInvalid ) {
82         ret = OMX_ErrorInvalidState;
83         goto EXIT;
84     }
85
86     switch (nParamIndex) {
87     case OMX_IndexParamAudioMp3:
88     {
89         OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
90         OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = NULL;
91         EXYNOS_MP3_HANDLE       *pMp3Dec = NULL;
92
93         ret = Exynos_OMX_Check_SizeVersion(pDstMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
94         if (ret != OMX_ErrorNone) {
95             goto EXIT;
96         }
97
98         if (pDstMp3Param->nPortIndex >= ALL_PORT_NUM) {
99             ret = OMX_ErrorBadPortIndex;
100             goto EXIT;
101         }
102
103         pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
104         pSrcMp3Param = &pMp3Dec->mp3Param;
105
106         Exynos_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
107     }
108         break;
109     case OMX_IndexParamAudioPcm:
110     {
111         OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
112         OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = NULL;
113         EXYNOS_MP3_HANDLE           *pMp3Dec = NULL;
114
115         ret = Exynos_OMX_Check_SizeVersion(pDstPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
116         if (ret != OMX_ErrorNone) {
117             goto EXIT;
118         }
119
120         if (pDstPcmParam->nPortIndex >= ALL_PORT_NUM) {
121             ret = OMX_ErrorBadPortIndex;
122             goto EXIT;
123         }
124
125         pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
126         pSrcPcmParam = &pMp3Dec->pcmParam;
127
128         Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
129     }
130         break;
131     case OMX_IndexParamStandardComponentRole:
132     {
133         OMX_S32 codecType;
134         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
135
136         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
137         if (ret != OMX_ErrorNone) {
138             goto EXIT;
139         }
140
141         Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
142     }
143         break;
144     default:
145         ret = Exynos_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
146         break;
147     }
148 EXIT:
149     FunctionOut();
150
151     return ret;
152 }
153
154 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_SetParameter(
155     OMX_IN OMX_HANDLETYPE hComponent,
156     OMX_IN OMX_INDEXTYPE  nIndex,
157     OMX_IN OMX_PTR        pComponentParameterStructure)
158 {
159     OMX_ERRORTYPE             ret = OMX_ErrorNone;
160     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
161     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
162
163     FunctionIn();
164
165     if (hComponent == NULL || pComponentParameterStructure == NULL) {
166         ret = OMX_ErrorBadParameter;
167         goto EXIT;
168     }
169     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
170     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
171     if (ret != OMX_ErrorNone) {
172         goto EXIT;
173     }
174     if (pOMXComponent->pComponentPrivate == NULL) {
175         ret = OMX_ErrorBadParameter;
176         goto EXIT;
177     }
178
179     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
180     if (pExynosComponent->currentState == OMX_StateInvalid ) {
181         ret = OMX_ErrorInvalidState;
182         goto EXIT;
183     }
184
185     switch (nIndex) {
186     case OMX_IndexParamAudioMp3:
187     {
188         OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = NULL;
189         OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
190         EXYNOS_MP3_HANDLE       *pMp3Dec = NULL;
191
192         ret = Exynos_OMX_Check_SizeVersion(pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
193         if (ret != OMX_ErrorNone) {
194             goto EXIT;
195         }
196
197         if (pSrcMp3Param->nPortIndex >= ALL_PORT_NUM) {
198             ret = OMX_ErrorBadPortIndex;
199             goto EXIT;
200         }
201
202         pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
203         pDstMp3Param = &pMp3Dec->mp3Param;
204
205         Exynos_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
206     }
207         break;
208     case OMX_IndexParamAudioPcm:
209     {
210         OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = NULL;
211         OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
212         EXYNOS_MP3_HANDLE           *pMp3Dec = NULL;
213
214         ret = Exynos_OMX_Check_SizeVersion(pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
215         if (ret != OMX_ErrorNone) {
216             goto EXIT;
217         }
218
219         if (pSrcPcmParam->nPortIndex >= ALL_PORT_NUM) {
220             ret = OMX_ErrorBadPortIndex;
221             goto EXIT;
222         }
223
224         pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
225         pDstPcmParam = &pMp3Dec->pcmParam;
226
227         Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
228     }
229         break;
230     case OMX_IndexParamStandardComponentRole:
231     {
232         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
233
234         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
235         if (ret != OMX_ErrorNone) {
236             goto EXIT;
237         }
238
239         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
240             ret = OMX_ErrorIncorrectStateOperation;
241             goto EXIT;
242         }
243
244         if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE)) {
245             pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
246         } else {
247             ret = OMX_ErrorBadParameter;
248             goto EXIT;
249         }
250     }
251         break;
252     default:
253         ret = Exynos_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
254         break;
255     }
256 EXIT:
257     FunctionOut();
258
259     return ret;
260 }
261
262 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_GetConfig(
263     OMX_IN OMX_HANDLETYPE hComponent,
264     OMX_IN OMX_INDEXTYPE  nIndex,
265     OMX_IN OMX_PTR        pComponentConfigStructure)
266 {
267     OMX_ERRORTYPE             ret = OMX_ErrorNone;
268     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
269     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
270
271     FunctionIn();
272
273     if (hComponent == NULL || pComponentConfigStructure == NULL) {
274         ret = OMX_ErrorBadParameter;
275         goto EXIT;
276     }
277     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
278     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
279     if (ret != OMX_ErrorNone) {
280         goto EXIT;
281     }
282     if (pOMXComponent->pComponentPrivate == NULL) {
283         ret = OMX_ErrorBadParameter;
284         goto EXIT;
285     }
286
287     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
288     if (pExynosComponent->currentState == OMX_StateInvalid) {
289         ret = OMX_ErrorInvalidState;
290         goto EXIT;
291     }
292
293     switch (nIndex) {
294     default:
295         ret = Exynos_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
296         break;
297     }
298
299 EXIT:
300     FunctionOut();
301
302     return ret;
303 }
304
305 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_SetConfig(
306     OMX_IN OMX_HANDLETYPE hComponent,
307     OMX_IN OMX_INDEXTYPE  nIndex,
308     OMX_IN OMX_PTR        pComponentConfigStructure)
309 {
310     OMX_ERRORTYPE             ret = OMX_ErrorNone;
311     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
312     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
313
314     FunctionIn();
315
316     if (hComponent == NULL || pComponentConfigStructure == NULL) {
317         ret = OMX_ErrorBadParameter;
318         goto EXIT;
319     }
320     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
321     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
322     if (ret != OMX_ErrorNone) {
323         goto EXIT;
324     }
325     if (pOMXComponent->pComponentPrivate == NULL) {
326         ret = OMX_ErrorBadParameter;
327         goto EXIT;
328     }
329
330     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
331     if (pExynosComponent->currentState == OMX_StateInvalid) {
332         ret = OMX_ErrorInvalidState;
333         goto EXIT;
334     }
335
336     switch (nIndex) {
337     default:
338         ret = Exynos_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
339         break;
340     }
341
342 EXIT:
343     FunctionOut();
344
345     return ret;
346 }
347
348 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_GetExtensionIndex(
349     OMX_IN OMX_HANDLETYPE  hComponent,
350     OMX_IN OMX_STRING      cParameterName,
351     OMX_OUT OMX_INDEXTYPE *pIndexType)
352 {
353     OMX_ERRORTYPE             ret = OMX_ErrorNone;
354     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
355     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
356
357     FunctionIn();
358
359     if (hComponent == NULL) {
360         ret = OMX_ErrorBadParameter;
361         goto EXIT;
362     }
363     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
364     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
365     if (ret != OMX_ErrorNone) {
366         goto EXIT;
367     }
368
369     if (pOMXComponent->pComponentPrivate == NULL) {
370         ret = OMX_ErrorBadParameter;
371         goto EXIT;
372     }
373     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
374
375     if ((cParameterName == NULL) || (pIndexType == NULL)) {
376         ret = OMX_ErrorBadParameter;
377         goto EXIT;
378     }
379     if (pExynosComponent->currentState == OMX_StateInvalid) {
380         ret = OMX_ErrorInvalidState;
381         goto EXIT;
382     }
383
384     ret = Exynos_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
385
386 EXIT:
387     FunctionOut();
388
389     return ret;
390 }
391
392 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_ComponentRoleEnum(
393     OMX_IN  OMX_HANDLETYPE hComponent,
394     OMX_OUT OMX_U8        *cRole,
395     OMX_IN  OMX_U32        nIndex)
396 {
397     OMX_ERRORTYPE               ret = OMX_ErrorNone;
398     OMX_COMPONENTTYPE          *pOMXComponent = NULL;
399     EXYNOS_OMX_BASECOMPONENT   *pExynosComponent = NULL;
400     OMX_S32                     codecType;
401
402     FunctionIn();
403
404     if ((hComponent == NULL) || (cRole == NULL)) {
405         ret = OMX_ErrorBadParameter;
406         goto EXIT;
407     }
408     if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) {
409         ret = OMX_ErrorNoMore;
410         goto EXIT;
411     }
412     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
413     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
414     if (ret != OMX_ErrorNone) {
415         goto EXIT;
416     }
417     if (pOMXComponent->pComponentPrivate == NULL) {
418         ret = OMX_ErrorBadParameter;
419         goto EXIT;
420     }
421
422     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
423     if (pExynosComponent->currentState == OMX_StateInvalid ) {
424         ret = OMX_ErrorInvalidState;
425         goto EXIT;
426     }
427
428     Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
429
430 EXIT:
431     FunctionOut();
432
433     return ret;
434 }
435
436 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
437 {
438     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
439     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
440     EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
441     EXYNOS_MP3_HANDLE             *pMp3Dec = (EXYNOS_MP3_HANDLE *)pAudioDec->hCodecHandle;
442
443     FunctionIn();
444
445     Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
446     Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
447     pExynosComponent->bUseFlagEOF = OMX_TRUE; /* Mp3 extractor should parse into frame unit. */
448     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
449     pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_FALSE;
450     pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE;
451 #ifdef SLP_PLATFORM
452     pMp3Dec->nPendingflags = 0;
453 #endif
454     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
455
456 #ifdef SRP_DUMP_TO_FILE
457     inFile = fopen("/data/InFile.mp3", "w+");
458     outFile = fopen("/data/OutFile.pcm", "w+");
459 #endif
460
461 EXIT:
462     FunctionOut();
463
464     return ret;
465 }
466
467 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
468 {
469     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
470     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
471
472     FunctionIn();
473
474 #ifdef SRP_DUMP_TO_FILE
475     fclose(inFile);
476     fclose(outFile);
477 #endif
478
479 EXIT:
480     FunctionOut();
481
482     return ret;
483 }
484
485 OMX_ERRORTYPE Exynos_SRP_Mp3_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
486 {
487     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
488     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
489     EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
490     EXYNOS_MP3_HANDLE             *pMp3Dec = (EXYNOS_MP3_HANDLE *)pAudioDec->hCodecHandle;
491     struct srp_dec_info            codecDecInfo;
492     OMX_S32                        returnCodec = 0;
493     unsigned long                  isSRPStopped = 0;
494     OMX_PTR                        dataBuffer = NULL;
495     unsigned int                   dataLen = 0;
496     OMX_BOOL                       isSRPIbufOverflow = OMX_FALSE;
497     char        dummy[2]={0xFF, 0xFF};
498
499     FunctionIn();
500
501 #ifdef SRP_DUMP_TO_FILE
502     if (pExynosComponent->reInputData == OMX_FALSE) {
503         fwrite(pInputData->buffer.singlePlaneBuffer.dataBuffer, pInputData->dataLen, 1, inFile);
504     }
505 #endif
506
507     /* Save timestamp and flags of input data */
508 #ifndef SLP_PLATFORM
509     pOutputData->timeStamp = pInputData->timeStamp;
510 #else
511     if (pExynosComponent->checkTimeStamp.startTimeStamp == pInputData->timeStamp) {
512         pMp3Dec->timeStamp = pInputData->timeStamp;
513     }
514 #endif
515     pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS);
516
517     /* Decoding mp3 frames by SRP */
518     if (pExynosComponent->getAllDelayBuffer == OMX_FALSE) {
519        if (pInputData->dataLen == 0)
520             returnCodec = SRP_Decode(dummy, sizeof(dummy));
521        else
522             returnCodec = SRP_Decode(pInputData->buffer.singlePlaneBuffer.dataBuffer, pInputData->dataLen);
523
524         if (returnCodec >= 0) {
525             if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
526                 SRP_Send_EOS();
527                 pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_TRUE;
528             }
529         } else if (returnCodec == SRP_ERROR_IBUF_OVERFLOW) {
530             isSRPIbufOverflow = OMX_TRUE;
531             ret = OMX_ErrorInputDataDecodeYet;
532         }
533     }
534
535     if (pMp3Dec->hSRPMp3Handle.bConfiguredSRP == OMX_FALSE) {
536         if ((pInputData->dataLen <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
537             pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
538             pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE;
539             ret = OMX_ErrorNone;
540             goto EXIT;
541         }
542
543         returnCodec = SRP_Get_Dec_Info(&codecDecInfo);
544         if (returnCodec < 0) {
545             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Dec_Info failed: %d", returnCodec);
546             ret = OMX_ErrorHardware;
547             goto EXIT;
548         }
549
550         if (!codecDecInfo.sample_rate || !codecDecInfo.channels) {
551             if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
552                 pOutputData->dataLen = 0;
553                 pExynosComponent->getAllDelayBuffer = OMX_TRUE;
554                 ret = OMX_ErrorInputDataDecodeYet;
555             } else {
556                 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
557                 if (isSRPIbufOverflow)
558                     ret = OMX_ErrorInputDataDecodeYet;
559                 else
560                     ret = OMX_ErrorNone;
561             }
562             goto EXIT;
563         }
564
565         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "numChannels(%d), samplingRate(%d)",
566             codecDecInfo.channels, codecDecInfo.sample_rate);
567
568         if (pMp3Dec->pcmParam.nChannels != codecDecInfo.channels ||
569             pMp3Dec->pcmParam.nSamplingRate != codecDecInfo.sample_rate) {
570             /* Change channel count and sampling rate information */
571             pMp3Dec->pcmParam.nChannels = codecDecInfo.channels;
572             pMp3Dec->pcmParam.nSamplingRate = codecDecInfo.sample_rate;
573
574             /* Send Port Settings changed call back */
575             (*(pExynosComponent->pCallbacks->EventHandler))
576                   (pOMXComponent,
577                    pExynosComponent->callbackData,
578                    OMX_EventPortSettingsChanged, /* The command was completed */
579                    OMX_DirOutput, /* This is the port index */
580                    0,
581                    NULL);
582         }
583
584         pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_TRUE;
585
586         if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
587             pOutputData->dataLen = 0;
588             pExynosComponent->getAllDelayBuffer = OMX_TRUE;
589             ret = OMX_ErrorInputDataDecodeYet;
590         } else {
591             pExynosComponent->getAllDelayBuffer = OMX_FALSE;
592             if (isSRPIbufOverflow)
593                 ret = OMX_ErrorInputDataDecodeYet;
594             else
595                 ret = OMX_ErrorNone;
596         }
597         goto EXIT;
598     }
599
600     /* Get decoded data from SRP */
601     returnCodec = SRP_Get_PCM(&dataBuffer, &dataLen);
602     if (dataLen > 0) {
603         pOutputData->dataLen = dataLen;
604         Exynos_OSAL_Memcpy(pOutputData->buffer.singlePlaneBuffer.dataBuffer, dataBuffer, dataLen);
605 #ifdef SLP_PLATFORM
606         pOutputData->timeStamp = pMp3Dec->timeStamp;
607         pMp3Dec->timeStamp += 1000000 * (OMX_TICKS)dataLen / (pMp3Dec->pcmParam.nSamplingRate * pMp3Dec->pcmParam.nChannels * pMp3Dec->pcmParam.nBitPerSample / 8);
608         pOutputData->nFlags |= pMp3Dec->nPendingflags;
609         pMp3Dec->nPendingflags = 0;
610 #endif
611     } else {
612         pOutputData->dataLen = 0;
613 #ifdef SLP_PLATFORM
614         pMp3Dec->nPendingflags = pOutputData->nFlags;
615 #endif
616     }
617
618 #ifdef SRP_DUMP_TO_FILE
619     if (pOutputData->dataLen > 0)
620         fwrite(pOutputData->buffer.singlePlaneBuffer.dataBuffer, pOutputData->dataLen, 1, outFile);
621 #endif
622
623     /* Delay EOS signal until all the PCM is returned from the SRP driver. */
624     if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
625         if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
626             returnCodec = SRP_GetParams(SRP_STOP_EOS_STATE, &isSRPStopped);
627             if (returnCodec != 0)
628                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail SRP_STOP_EOS_STATE");
629             if (isSRPStopped == 1) {
630                 pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
631                 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
632 #ifdef SLP_PLATFORM
633                 pOutputData->timeStamp = pInputData->timeStamp; /*For ALP EOS Timestamp*/
634 #endif
635                 pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; /* for repeating one song */
636                 ret = OMX_ErrorNone;
637             } else {
638                 pExynosComponent->getAllDelayBuffer = OMX_TRUE;
639                 ret = OMX_ErrorInputDataDecodeYet;
640             }
641         } else { /* Flush after EOS */
642             pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE;
643         }
644     }
645 EXIT:
646     FunctionOut();
647
648     return ret;
649 }
650
651 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
652 {
653     OMX_ERRORTYPE             ret = OMX_ErrorNone;
654     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
655     EXYNOS_OMX_BASEPORT      *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
656     EXYNOS_OMX_BASEPORT      *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
657
658     FunctionIn();
659
660     if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) ||
661             (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) {
662         if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
663             ret = OMX_ErrorInputDataDecodeYet;
664         else
665             ret = OMX_ErrorNone;
666
667         goto EXIT;
668     }
669     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent)) {
670         if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
671             ret = OMX_ErrorInputDataDecodeYet;
672         else
673             ret = OMX_ErrorNone;
674
675         goto EXIT;
676     }
677
678     ret = Exynos_SRP_Mp3_Decode_Block(pOMXComponent, pInputData, pOutputData);
679
680     if (ret != OMX_ErrorNone) {
681         if (ret == OMX_ErrorInputDataDecodeYet) {
682             pOutputData->usedDataLen = 0;
683             pOutputData->remainDataLen = pOutputData->dataLen;
684         } else {
685             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
686                                                     pExynosComponent->callbackData,
687                                                     OMX_EventError, ret, 0, NULL);
688         }
689     } else {
690         pInputData->usedDataLen += pInputData->dataLen;
691         pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen;
692         pInputData->dataLen -= pInputData->usedDataLen;
693         pInputData->usedDataLen = 0;
694
695         pOutputData->usedDataLen = 0;
696         pOutputData->remainDataLen = pOutputData->dataLen;
697     }
698
699 EXIT:
700     FunctionOut();
701
702     return ret;
703 }
704
705 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
706 {
707     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
708     OMX_COMPONENTTYPE             *pOMXComponent = NULL;
709     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
710     EXYNOS_OMX_BASEPORT           *pExynosPort = NULL;
711     EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL;
712     EXYNOS_MP3_HANDLE             *pMp3Dec = NULL;
713     OMX_PTR                        pInputBuffer = NULL;
714     OMX_PTR                        pOutputBuffer = NULL;
715     unsigned int                   inputBufferSize = 0;
716     unsigned int                   inputBufferNum = 0;
717     unsigned int                   outputBufferSize = 0;
718     unsigned int                   outputBufferNum = 0;
719     OMX_S32                        returnCodec;
720     int i = 0;
721
722     FunctionIn();
723
724     if ((hComponent == NULL) || (componentName == NULL)) {
725         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret);
726         ret = OMX_ErrorBadParameter;
727         goto EXIT;
728     }
729     if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MP3_DEC, componentName) != 0) {
730         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret);
731         ret = OMX_ErrorBadParameter;
732         goto EXIT;
733     }
734
735     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
736     ret = Exynos_OMX_AudioDecodeComponentInit(pOMXComponent);
737     if (ret != OMX_ErrorNone) {
738         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret);
739         goto EXIT;
740     }
741     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
742     pExynosComponent->codecType = HW_AUDIO_DEC_CODEC;
743
744     pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
745     if (pExynosComponent->componentName == NULL) {
746         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret);
747         ret = OMX_ErrorInsufficientResources;
748         goto EXIT_ERROR_1;
749     }
750     Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
751     Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MP3_DEC);
752
753     pMp3Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MP3_HANDLE));
754     if (pMp3Dec == NULL) {
755         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_MP3_HANDLE alloc error, ret: %X", __FUNCTION__, ret);
756         ret = OMX_ErrorInsufficientResources;
757         goto EXIT_ERROR_2;
758     }
759     Exynos_OSAL_Memset(pMp3Dec, 0, sizeof(EXYNOS_MP3_HANDLE));
760     pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
761     pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pMp3Dec;
762
763     /* Create and Init SRP */
764     pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_FALSE;
765     returnCodec = SRP_Create(SRP_INIT_BLOCK_MODE);
766     if (returnCodec < 0) {
767         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Create failed: %d", returnCodec);
768         ret = OMX_ErrorHardware;
769         goto EXIT_ERROR_3;
770     }
771     pMp3Dec->hSRPMp3Handle.hSRPHandle = (OMX_HANDLETYPE)returnCodec; /* SRP's fd */
772     returnCodec = SRP_Init();
773     if (returnCodec < 0) {
774         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Init failed: %d", returnCodec);
775         ret = OMX_ErrorHardware;
776         goto EXIT_ERROR_4;
777     }
778     pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_TRUE;
779
780     /* Get input buffer info from SRP */
781     returnCodec = SRP_Get_Ibuf_Info(&pInputBuffer, &inputBufferSize, &inputBufferNum);
782     if (returnCodec < 0) {
783         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Ibuf_Info failed: %d", returnCodec);
784         ret = OMX_ErrorHardware;
785         goto EXIT_ERROR_5;
786     }
787
788     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
789     pExynosPort->processData.allocSize = inputBufferSize;
790     pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = Exynos_OSAL_Malloc(inputBufferSize);
791     if (pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer == NULL) {
792         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Input data buffer alloc failed");
793         ret = OMX_ErrorInsufficientResources;
794         goto EXIT_ERROR_5;
795     }
796
797     /* Get output buffer info from SRP */
798     returnCodec = SRP_Get_Obuf_Info(&pOutputBuffer, &outputBufferSize, &outputBufferNum);
799     if (returnCodec < 0) {
800         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Obuf_Info failed: %d", returnCodec);
801         ret = OMX_ErrorHardware;
802         goto EXIT_ERROR_6;
803     }
804
805     /* Set componentVersion */
806     pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
807     pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
808     pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
809     pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
810
811     /* Set specVersion */
812     pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
813     pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
814     pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
815     pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
816
817     /* Input port */
818     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
819     pExynosPort->portDefinition.nBufferCountActual = inputBufferNum;
820     pExynosPort->portDefinition.nBufferCountMin = inputBufferNum;
821     pExynosPort->portDefinition.nBufferSize = inputBufferSize;
822     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
823     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
824     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/mpeg");
825     pExynosPort->portDefinition.format.audio.pNativeRender = 0;
826     pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
827     pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
828     pExynosPort->portWayType = WAY1_PORT;
829
830     /* Output port */
831     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
832     pExynosPort->portDefinition.nBufferCountActual = outputBufferNum;
833     pExynosPort->portDefinition.nBufferCountMin = outputBufferNum;
834     pExynosPort->portDefinition.nBufferSize = outputBufferSize;
835     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
836     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
837     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
838     pExynosPort->portDefinition.format.audio.pNativeRender = 0;
839     pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
840     pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
841     pExynosPort->portWayType = WAY1_PORT;
842
843     /* Default values for Mp3 audio param */
844     INIT_SET_SIZE_VERSION(&pMp3Dec->mp3Param, OMX_AUDIO_PARAM_MP3TYPE);
845     pMp3Dec->mp3Param.nPortIndex      = INPUT_PORT_INDEX;
846     pMp3Dec->mp3Param.nChannels       = DEFAULT_AUDIO_CHANNELS_NUM;
847     pMp3Dec->mp3Param.nBitRate        = 0;
848     pMp3Dec->mp3Param.nSampleRate     = DEFAULT_AUDIO_SAMPLING_FREQ;
849     pMp3Dec->mp3Param.nAudioBandWidth = 0;
850     pMp3Dec->mp3Param.eChannelMode    = OMX_AUDIO_ChannelModeStereo;
851     pMp3Dec->mp3Param.eFormat         = OMX_AUDIO_MP3StreamFormatMP1Layer3;
852
853     /* Default values for PCM audio param */
854     INIT_SET_SIZE_VERSION(&pMp3Dec->pcmParam, OMX_AUDIO_PARAM_PCMMODETYPE);
855     pMp3Dec->pcmParam.nPortIndex         = OUTPUT_PORT_INDEX;
856     pMp3Dec->pcmParam.nChannels          = DEFAULT_AUDIO_CHANNELS_NUM;
857     pMp3Dec->pcmParam.eNumData           = OMX_NumericalDataSigned;
858     pMp3Dec->pcmParam.eEndian            = OMX_EndianLittle;
859     pMp3Dec->pcmParam.bInterleaved       = OMX_TRUE;
860     pMp3Dec->pcmParam.nBitPerSample      = DEFAULT_AUDIO_BIT_PER_SAMPLE;
861     pMp3Dec->pcmParam.nSamplingRate      = DEFAULT_AUDIO_SAMPLING_FREQ;
862     pMp3Dec->pcmParam.ePCMMode           = OMX_AUDIO_PCMModeLinear;
863     pMp3Dec->pcmParam.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
864     pMp3Dec->pcmParam.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
865
866     pOMXComponent->GetParameter      = &Exynos_SRP_Mp3Dec_GetParameter;
867     pOMXComponent->SetParameter      = &Exynos_SRP_Mp3Dec_SetParameter;
868     pOMXComponent->GetConfig         = &Exynos_SRP_Mp3Dec_GetConfig;
869     pOMXComponent->SetConfig         = &Exynos_SRP_Mp3Dec_SetConfig;
870     pOMXComponent->GetExtensionIndex = &Exynos_SRP_Mp3Dec_GetExtensionIndex;
871     pOMXComponent->ComponentRoleEnum = &Exynos_SRP_Mp3Dec_ComponentRoleEnum;
872     pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
873
874     /* ToDo: Change the function name associated with a specific codec */
875     pExynosComponent->exynos_codec_componentInit      = &Exynos_SRP_Mp3Dec_Init;
876     pExynosComponent->exynos_codec_componentTerminate = &Exynos_SRP_Mp3Dec_Terminate;
877     pAudioDec->exynos_codec_bufferProcess = &Exynos_SRP_Mp3Dec_bufferProcess;
878     pAudioDec->exynos_checkInputFrame = NULL;
879
880     pExynosComponent->currentState = OMX_StateLoaded;
881
882     ret = OMX_ErrorNone;
883     goto EXIT; /* This function is performed successfully. */
884
885 EXIT_ERROR_6:
886     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
887     Exynos_OSAL_Free(pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer);
888     pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = NULL;
889     pExynosPort->processData.allocSize = 0;
890 EXIT_ERROR_5:
891     SRP_Deinit();
892 EXIT_ERROR_4:
893     SRP_Terminate();
894 EXIT_ERROR_3:
895     Exynos_OSAL_Free(pMp3Dec);
896     pAudioDec->hCodecHandle = NULL;
897 EXIT_ERROR_2:
898     Exynos_OSAL_Free(pExynosComponent->componentName);
899     pExynosComponent->componentName = NULL;
900 EXIT_ERROR_1:
901     Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
902 EXIT:
903     FunctionOut();
904
905     return ret;
906 }
907
908 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
909 {
910     OMX_ERRORTYPE             ret = OMX_ErrorNone;
911     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
912     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
913     EXYNOS_MP3_HANDLE        *pMp3Dec = NULL;
914     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
915
916     FunctionIn();
917
918     if (hComponent == NULL) {
919         ret = OMX_ErrorBadParameter;
920         goto EXIT;
921     }
922     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
923     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
924
925     Exynos_OSAL_Free(pExynosComponent->componentName);
926     pExynosComponent->componentName = NULL;
927     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
928     if (pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer) {
929         Exynos_OSAL_Free(pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer);
930         pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = NULL;
931         pExynosPort->processData.allocSize = 0;
932     }
933
934     pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
935     if (pMp3Dec != NULL) {
936         if (pMp3Dec->hSRPMp3Handle.bSRPLoaded == OMX_TRUE) {
937             SRP_Deinit();
938             SRP_Terminate();
939         }
940         Exynos_OSAL_Free(pMp3Dec);
941         ((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
942     }
943
944     ret = Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
945     if (ret != OMX_ErrorNone) {
946         goto EXIT;
947     }
948
949     ret = OMX_ErrorNone;
950
951 EXIT:
952     FunctionOut();
953
954     return ret;
955 }