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
51FILE *inFile;
52FILE *outFile;
53#endif
54
55OMX_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    }
148EXIT:
149    FunctionOut();
150
151    return ret;
152}
153
154OMX_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    }
256EXIT:
257    FunctionOut();
258
259    return ret;
260}
261
262OMX_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
299EXIT:
300    FunctionOut();
301
302    return ret;
303}
304
305OMX_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
342EXIT:
343    FunctionOut();
344
345    return ret;
346}
347
348OMX_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
386EXIT:
387    FunctionOut();
388
389    return ret;
390}
391
392OMX_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
430EXIT:
431    FunctionOut();
432
433    return ret;
434}
435
436OMX_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    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
452
453#ifdef SRP_DUMP_TO_FILE
454    inFile = fopen("/data/InFile.mp3", "w+");
455    outFile = fopen("/data/OutFile.pcm", "w+");
456#endif
457
458EXIT:
459    FunctionOut();
460
461    return ret;
462}
463
464OMX_ERRORTYPE Exynos_SRP_Mp3Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
465{
466    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
467    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
468
469    FunctionIn();
470
471#ifdef SRP_DUMP_TO_FILE
472    fclose(inFile);
473    fclose(outFile);
474#endif
475
476EXIT:
477    FunctionOut();
478
479    return ret;
480}
481
482OMX_ERRORTYPE Exynos_SRP_Mp3_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
483{
484    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
485    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
486    EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
487    EXYNOS_MP3_HANDLE             *pMp3Dec = (EXYNOS_MP3_HANDLE *)pAudioDec->hCodecHandle;
488    struct srp_dec_info            codecDecInfo;
489    OMX_S32                        returnCodec = 0;
490    unsigned long                  isSRPStopped = 0;
491    OMX_PTR                        dataBuffer = NULL;
492    unsigned int                   dataLen = 0;
493    OMX_BOOL                       isSRPIbufOverflow = OMX_FALSE;
494
495    FunctionIn();
496
497#ifdef SRP_DUMP_TO_FILE
498    if (pExynosComponent->reInputData == OMX_FALSE) {
499        fwrite(pInputData->buffer.singlePlaneBuffer.dataBuffer, pInputData->dataLen, 1, inFile);
500    }
501#endif
502
503    /* Save timestamp and flags of input data */
504    pOutputData->timeStamp = pInputData->timeStamp;
505    pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS);
506
507    /* Decoding mp3 frames by SRP */
508    if (pExynosComponent->getAllDelayBuffer == OMX_FALSE) {
509        returnCodec = SRP_Decode(pInputData->buffer.singlePlaneBuffer.dataBuffer, pInputData->dataLen);
510
511        if (returnCodec >= 0) {
512            if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
513                SRP_Send_EOS();
514                pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_TRUE;
515            }
516        } else if (returnCodec == SRP_ERROR_IBUF_OVERFLOW) {
517            isSRPIbufOverflow = OMX_TRUE;
518            ret = OMX_ErrorInputDataDecodeYet;
519        }
520    }
521
522    if (pMp3Dec->hSRPMp3Handle.bConfiguredSRP == OMX_FALSE) {
523        if ((pInputData->dataLen <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
524            pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
525            pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE;
526            ret = OMX_ErrorNone;
527            goto EXIT;
528        }
529
530        returnCodec = SRP_Get_Dec_Info(&codecDecInfo);
531        if (returnCodec < 0) {
532            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Dec_Info failed: %d", returnCodec);
533            ret = OMX_ErrorHardware;
534            goto EXIT;
535        }
536
537        if (!codecDecInfo.sample_rate || !codecDecInfo.channels) {
538            if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
539                pOutputData->dataLen = 0;
540                pExynosComponent->getAllDelayBuffer = OMX_TRUE;
541                ret = OMX_ErrorInputDataDecodeYet;
542            } else {
543                pExynosComponent->getAllDelayBuffer = OMX_FALSE;
544                if (isSRPIbufOverflow)
545                    ret = OMX_ErrorInputDataDecodeYet;
546                else
547                    ret = OMX_ErrorNone;
548            }
549            goto EXIT;
550        }
551
552        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "numChannels(%d), samplingRate(%d)",
553            codecDecInfo.channels, codecDecInfo.sample_rate);
554
555        if (pMp3Dec->pcmParam.nChannels != codecDecInfo.channels ||
556            pMp3Dec->pcmParam.nSamplingRate != codecDecInfo.sample_rate) {
557            /* Change channel count and sampling rate information */
558            pMp3Dec->pcmParam.nChannels = codecDecInfo.channels;
559            pMp3Dec->pcmParam.nSamplingRate = codecDecInfo.sample_rate;
560
561            /* Send Port Settings changed call back */
562            (*(pExynosComponent->pCallbacks->EventHandler))
563                  (pOMXComponent,
564                   pExynosComponent->callbackData,
565                   OMX_EventPortSettingsChanged, /* The command was completed */
566                   OMX_DirOutput, /* This is the port index */
567                   0,
568                   NULL);
569        }
570
571        pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_TRUE;
572
573        if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
574            pOutputData->dataLen = 0;
575            pExynosComponent->getAllDelayBuffer = OMX_TRUE;
576            ret = OMX_ErrorInputDataDecodeYet;
577        } else {
578            pExynosComponent->getAllDelayBuffer = OMX_FALSE;
579            if (isSRPIbufOverflow)
580                ret = OMX_ErrorInputDataDecodeYet;
581            else
582                ret = OMX_ErrorNone;
583        }
584        goto EXIT;
585    }
586
587    /* Get decoded data from SRP */
588    returnCodec = SRP_Get_PCM(&dataBuffer, &dataLen);
589    if (dataLen > 0) {
590        pOutputData->dataLen = dataLen;
591        Exynos_OSAL_Memcpy(pOutputData->buffer.singlePlaneBuffer.dataBuffer, dataBuffer, dataLen);
592    } else {
593        pOutputData->dataLen = 0;
594    }
595
596#ifdef SRP_DUMP_TO_FILE
597    if (pOutputData->dataLen > 0)
598        fwrite(pOutputData->buffer.singlePlaneBuffer.dataBuffer, pOutputData->dataLen, 1, outFile);
599#endif
600
601    /* Delay EOS signal until all the PCM is returned from the SRP driver. */
602    if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
603        if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
604            returnCodec = SRP_GetParams(SRP_STOP_EOS_STATE, &isSRPStopped);
605            if (returnCodec != 0)
606                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail SRP_STOP_EOS_STATE");
607            if (isSRPStopped == 1) {
608                pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
609                pExynosComponent->getAllDelayBuffer = OMX_FALSE;
610                pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; /* for repeating one song */
611                ret = OMX_ErrorNone;
612            } else {
613                pExynosComponent->getAllDelayBuffer = OMX_TRUE;
614                ret = OMX_ErrorInputDataDecodeYet;
615            }
616        } else { /* Flush after EOS */
617            pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE;
618        }
619    }
620EXIT:
621    FunctionOut();
622
623    return ret;
624}
625
626OMX_ERRORTYPE Exynos_SRP_Mp3Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
627{
628    OMX_ERRORTYPE             ret = OMX_ErrorNone;
629    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
630    EXYNOS_OMX_BASEPORT      *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
631    EXYNOS_OMX_BASEPORT      *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
632
633    FunctionIn();
634
635    if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) ||
636            (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) {
637        if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
638            ret = OMX_ErrorInputDataDecodeYet;
639        else
640            ret = OMX_ErrorNone;
641
642        goto EXIT;
643    }
644    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent)) {
645        if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
646            ret = OMX_ErrorInputDataDecodeYet;
647        else
648            ret = OMX_ErrorNone;
649
650        goto EXIT;
651    }
652
653    ret = Exynos_SRP_Mp3_Decode_Block(pOMXComponent, pInputData, pOutputData);
654
655    if (ret != OMX_ErrorNone) {
656        if (ret == OMX_ErrorInputDataDecodeYet) {
657            pOutputData->usedDataLen = 0;
658            pOutputData->remainDataLen = pOutputData->dataLen;
659        } else {
660            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
661                                                    pExynosComponent->callbackData,
662                                                    OMX_EventError, ret, 0, NULL);
663        }
664    } else {
665        pInputData->usedDataLen += pInputData->dataLen;
666        pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen;
667        pInputData->dataLen -= pInputData->usedDataLen;
668        pInputData->usedDataLen = 0;
669
670        pOutputData->usedDataLen = 0;
671        pOutputData->remainDataLen = pOutputData->dataLen;
672    }
673
674EXIT:
675    FunctionOut();
676
677    return ret;
678}
679
680OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
681{
682    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
683    OMX_COMPONENTTYPE             *pOMXComponent = NULL;
684    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
685    EXYNOS_OMX_BASEPORT           *pExynosPort = NULL;
686    EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL;
687    EXYNOS_MP3_HANDLE             *pMp3Dec = NULL;
688    OMX_PTR                        pInputBuffer = NULL;
689    OMX_PTR                        pOutputBuffer = NULL;
690    unsigned int                   inputBufferSize = 0;
691    unsigned int                   inputBufferNum = 0;
692    unsigned int                   outputBufferSize = 0;
693    unsigned int                   outputBufferNum = 0;
694    OMX_S32                        returnCodec;
695    int i = 0;
696
697    FunctionIn();
698
699    if ((hComponent == NULL) || (componentName == NULL)) {
700        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret);
701        ret = OMX_ErrorBadParameter;
702        goto EXIT;
703    }
704    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MP3_DEC, componentName) != 0) {
705        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret);
706        ret = OMX_ErrorBadParameter;
707        goto EXIT;
708    }
709
710    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
711    ret = Exynos_OMX_AudioDecodeComponentInit(pOMXComponent);
712    if (ret != OMX_ErrorNone) {
713        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret);
714        goto EXIT;
715    }
716    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
717    pExynosComponent->codecType = HW_AUDIO_DEC_CODEC;
718
719    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
720    if (pExynosComponent->componentName == NULL) {
721        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret);
722        ret = OMX_ErrorInsufficientResources;
723        goto EXIT_ERROR_1;
724    }
725    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
726    Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MP3_DEC);
727
728    pMp3Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MP3_HANDLE));
729    if (pMp3Dec == NULL) {
730        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_MP3_HANDLE alloc error, ret: %X", __FUNCTION__, ret);
731        ret = OMX_ErrorInsufficientResources;
732        goto EXIT_ERROR_2;
733    }
734    Exynos_OSAL_Memset(pMp3Dec, 0, sizeof(EXYNOS_MP3_HANDLE));
735    pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
736    pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pMp3Dec;
737
738    /* Create and Init SRP */
739    pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_FALSE;
740    returnCodec = SRP_Create(SRP_INIT_BLOCK_MODE);
741    if (returnCodec < 0) {
742        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Create failed: %d", returnCodec);
743        ret = OMX_ErrorHardware;
744        goto EXIT_ERROR_3;
745    }
746    pMp3Dec->hSRPMp3Handle.hSRPHandle = (OMX_HANDLETYPE)returnCodec; /* SRP's fd */
747    returnCodec = SRP_Init();
748    if (returnCodec < 0) {
749        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Init failed: %d", returnCodec);
750        ret = OMX_ErrorHardware;
751        goto EXIT_ERROR_4;
752    }
753    pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_TRUE;
754
755    /* Get input buffer info from SRP */
756    returnCodec = SRP_Get_Ibuf_Info(&pInputBuffer, &inputBufferSize, &inputBufferNum);
757    if (returnCodec < 0) {
758        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Ibuf_Info failed: %d", returnCodec);
759        ret = OMX_ErrorHardware;
760        goto EXIT_ERROR_5;
761    }
762
763    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
764    pExynosPort->processData.allocSize = inputBufferSize;
765    pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = Exynos_OSAL_Malloc(inputBufferSize);
766    if (pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer == NULL) {
767        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Input data buffer alloc failed");
768        ret = OMX_ErrorInsufficientResources;
769        goto EXIT_ERROR_5;
770    }
771
772    /* Get output buffer info from SRP */
773    returnCodec = SRP_Get_Obuf_Info(&pOutputBuffer, &outputBufferSize, &outputBufferNum);
774    if (returnCodec < 0) {
775        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Obuf_Info failed: %d", returnCodec);
776        ret = OMX_ErrorHardware;
777        goto EXIT_ERROR_6;
778    }
779
780    /* Set componentVersion */
781    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
782    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
783    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
784    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
785
786    /* Set specVersion */
787    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
788    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
789    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
790    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
791
792    /* Input port */
793    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
794    pExynosPort->portDefinition.nBufferCountActual = inputBufferNum;
795    pExynosPort->portDefinition.nBufferCountMin = inputBufferNum;
796    pExynosPort->portDefinition.nBufferSize = inputBufferSize;
797    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
798    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
799    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/mpeg");
800    pExynosPort->portDefinition.format.audio.pNativeRender = 0;
801    pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
802    pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
803    pExynosPort->portWayType = WAY1_PORT;
804
805    /* Output port */
806    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
807    pExynosPort->portDefinition.nBufferCountActual = outputBufferNum;
808    pExynosPort->portDefinition.nBufferCountMin = outputBufferNum;
809    pExynosPort->portDefinition.nBufferSize = outputBufferSize;
810    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
811    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
812    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
813    pExynosPort->portDefinition.format.audio.pNativeRender = 0;
814    pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
815    pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
816    pExynosPort->portWayType = WAY1_PORT;
817
818    /* Default values for Mp3 audio param */
819    INIT_SET_SIZE_VERSION(&pMp3Dec->mp3Param, OMX_AUDIO_PARAM_MP3TYPE);
820    pMp3Dec->mp3Param.nPortIndex      = INPUT_PORT_INDEX;
821    pMp3Dec->mp3Param.nChannels       = DEFAULT_AUDIO_CHANNELS_NUM;
822    pMp3Dec->mp3Param.nBitRate        = 0;
823    pMp3Dec->mp3Param.nSampleRate     = DEFAULT_AUDIO_SAMPLING_FREQ;
824    pMp3Dec->mp3Param.nAudioBandWidth = 0;
825    pMp3Dec->mp3Param.eChannelMode    = OMX_AUDIO_ChannelModeStereo;
826    pMp3Dec->mp3Param.eFormat         = OMX_AUDIO_MP3StreamFormatMP1Layer3;
827
828    /* Default values for PCM audio param */
829    INIT_SET_SIZE_VERSION(&pMp3Dec->pcmParam, OMX_AUDIO_PARAM_PCMMODETYPE);
830    pMp3Dec->pcmParam.nPortIndex         = OUTPUT_PORT_INDEX;
831    pMp3Dec->pcmParam.nChannels          = DEFAULT_AUDIO_CHANNELS_NUM;
832    pMp3Dec->pcmParam.eNumData           = OMX_NumericalDataSigned;
833    pMp3Dec->pcmParam.eEndian            = OMX_EndianLittle;
834    pMp3Dec->pcmParam.bInterleaved       = OMX_TRUE;
835    pMp3Dec->pcmParam.nBitPerSample      = DEFAULT_AUDIO_BIT_PER_SAMPLE;
836    pMp3Dec->pcmParam.nSamplingRate      = DEFAULT_AUDIO_SAMPLING_FREQ;
837    pMp3Dec->pcmParam.ePCMMode           = OMX_AUDIO_PCMModeLinear;
838    pMp3Dec->pcmParam.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
839    pMp3Dec->pcmParam.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
840
841    pOMXComponent->GetParameter      = &Exynos_SRP_Mp3Dec_GetParameter;
842    pOMXComponent->SetParameter      = &Exynos_SRP_Mp3Dec_SetParameter;
843    pOMXComponent->GetConfig         = &Exynos_SRP_Mp3Dec_GetConfig;
844    pOMXComponent->SetConfig         = &Exynos_SRP_Mp3Dec_SetConfig;
845    pOMXComponent->GetExtensionIndex = &Exynos_SRP_Mp3Dec_GetExtensionIndex;
846    pOMXComponent->ComponentRoleEnum = &Exynos_SRP_Mp3Dec_ComponentRoleEnum;
847    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
848
849    /* ToDo: Change the function name associated with a specific codec */
850    pExynosComponent->exynos_codec_componentInit      = &Exynos_SRP_Mp3Dec_Init;
851    pExynosComponent->exynos_codec_componentTerminate = &Exynos_SRP_Mp3Dec_Terminate;
852    pAudioDec->exynos_codec_bufferProcess = &Exynos_SRP_Mp3Dec_bufferProcess;
853    pAudioDec->exynos_checkInputFrame = NULL;
854
855    pExynosComponent->currentState = OMX_StateLoaded;
856
857    ret = OMX_ErrorNone;
858    goto EXIT; /* This function is performed successfully. */
859
860EXIT_ERROR_6:
861    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
862    Exynos_OSAL_Free(pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer);
863    pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = NULL;
864    pExynosPort->processData.allocSize = 0;
865EXIT_ERROR_5:
866    SRP_Deinit();
867EXIT_ERROR_4:
868    SRP_Terminate();
869EXIT_ERROR_3:
870    Exynos_OSAL_Free(pMp3Dec);
871    pAudioDec->hCodecHandle = NULL;
872EXIT_ERROR_2:
873    Exynos_OSAL_Free(pExynosComponent->componentName);
874    pExynosComponent->componentName = NULL;
875EXIT_ERROR_1:
876    Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
877EXIT:
878    FunctionOut();
879
880    return ret;
881}
882
883OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
884{
885    OMX_ERRORTYPE             ret = OMX_ErrorNone;
886    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
887    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
888    EXYNOS_MP3_HANDLE        *pMp3Dec = NULL;
889    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
890
891    FunctionIn();
892
893    if (hComponent == NULL) {
894        ret = OMX_ErrorBadParameter;
895        goto EXIT;
896    }
897    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
898    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
899
900    Exynos_OSAL_Free(pExynosComponent->componentName);
901    pExynosComponent->componentName = NULL;
902    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
903    if (pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer) {
904        Exynos_OSAL_Free(pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer);
905        pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = NULL;
906        pExynosPort->processData.allocSize = 0;
907    }
908
909    pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
910    if (pMp3Dec != NULL) {
911        if (pMp3Dec->hSRPMp3Handle.bSRPLoaded == OMX_TRUE) {
912            SRP_Deinit();
913            SRP_Terminate();
914        }
915        Exynos_OSAL_Free(pMp3Dec);
916        ((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
917    }
918
919    ret = Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
920    if (ret != OMX_ErrorNone) {
921        goto EXIT;
922    }
923
924    ret = OMX_ErrorNone;
925
926EXIT:
927    FunctionOut();
928
929    return ret;
930}
931