3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file Exynos_OMX_Mp3dec.c
21 * @author Yunji Kim (yunji.kim@samsung.com)
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"
43 #define EXYNOS_LOG_TAG "EXYNOS_MP3_DEC"
44 #define EXYNOS_LOG_OFF
45 #include "Exynos_OSAL_Log.h"
47 //#define SRP_DUMP_TO_FILE
48 #ifdef SRP_DUMP_TO_FILE
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)
60 OMX_ERRORTYPE ret = OMX_ErrorNone;
61 OMX_COMPONENTTYPE *pOMXComponent = NULL;
62 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
66 if (hComponent == NULL || pComponentParameterStructure == NULL) {
67 ret = OMX_ErrorBadParameter;
70 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
71 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
72 if (ret != OMX_ErrorNone) {
75 if (pOMXComponent->pComponentPrivate == NULL) {
76 ret = OMX_ErrorBadParameter;
80 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
81 if (pExynosComponent->currentState == OMX_StateInvalid ) {
82 ret = OMX_ErrorInvalidState;
86 switch (nParamIndex) {
87 case OMX_IndexParamAudioMp3:
89 OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
90 OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = NULL;
91 EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
93 ret = Exynos_OMX_Check_SizeVersion(pDstMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
94 if (ret != OMX_ErrorNone) {
98 if (pDstMp3Param->nPortIndex >= ALL_PORT_NUM) {
99 ret = OMX_ErrorBadPortIndex;
103 pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
104 pSrcMp3Param = &pMp3Dec->mp3Param;
106 Exynos_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
109 case OMX_IndexParamAudioPcm:
111 OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
112 OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = NULL;
113 EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
115 ret = Exynos_OMX_Check_SizeVersion(pDstPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
116 if (ret != OMX_ErrorNone) {
120 if (pDstPcmParam->nPortIndex >= ALL_PORT_NUM) {
121 ret = OMX_ErrorBadPortIndex;
125 pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
126 pSrcPcmParam = &pMp3Dec->pcmParam;
128 Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
131 case OMX_IndexParamStandardComponentRole:
134 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
136 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
137 if (ret != OMX_ErrorNone) {
141 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
145 ret = Exynos_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
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)
159 OMX_ERRORTYPE ret = OMX_ErrorNone;
160 OMX_COMPONENTTYPE *pOMXComponent = NULL;
161 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
165 if (hComponent == NULL || pComponentParameterStructure == NULL) {
166 ret = OMX_ErrorBadParameter;
169 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
170 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
171 if (ret != OMX_ErrorNone) {
174 if (pOMXComponent->pComponentPrivate == NULL) {
175 ret = OMX_ErrorBadParameter;
179 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
180 if (pExynosComponent->currentState == OMX_StateInvalid ) {
181 ret = OMX_ErrorInvalidState;
186 case OMX_IndexParamAudioMp3:
188 OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = NULL;
189 OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
190 EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
192 ret = Exynos_OMX_Check_SizeVersion(pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
193 if (ret != OMX_ErrorNone) {
197 if (pSrcMp3Param->nPortIndex >= ALL_PORT_NUM) {
198 ret = OMX_ErrorBadPortIndex;
202 pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
203 pDstMp3Param = &pMp3Dec->mp3Param;
205 Exynos_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
208 case OMX_IndexParamAudioPcm:
210 OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = NULL;
211 OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
212 EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
214 ret = Exynos_OMX_Check_SizeVersion(pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
215 if (ret != OMX_ErrorNone) {
219 if (pSrcPcmParam->nPortIndex >= ALL_PORT_NUM) {
220 ret = OMX_ErrorBadPortIndex;
224 pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
225 pDstPcmParam = &pMp3Dec->pcmParam;
227 Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
230 case OMX_IndexParamStandardComponentRole:
232 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
234 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
235 if (ret != OMX_ErrorNone) {
239 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
240 ret = OMX_ErrorIncorrectStateOperation;
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;
247 ret = OMX_ErrorBadParameter;
253 ret = Exynos_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
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)
267 OMX_ERRORTYPE ret = OMX_ErrorNone;
268 OMX_COMPONENTTYPE *pOMXComponent = NULL;
269 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
273 if (hComponent == NULL || pComponentConfigStructure == NULL) {
274 ret = OMX_ErrorBadParameter;
277 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
278 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
279 if (ret != OMX_ErrorNone) {
282 if (pOMXComponent->pComponentPrivate == NULL) {
283 ret = OMX_ErrorBadParameter;
287 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
288 if (pExynosComponent->currentState == OMX_StateInvalid) {
289 ret = OMX_ErrorInvalidState;
295 ret = Exynos_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
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)
310 OMX_ERRORTYPE ret = OMX_ErrorNone;
311 OMX_COMPONENTTYPE *pOMXComponent = NULL;
312 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
316 if (hComponent == NULL || pComponentConfigStructure == NULL) {
317 ret = OMX_ErrorBadParameter;
320 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
321 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
322 if (ret != OMX_ErrorNone) {
325 if (pOMXComponent->pComponentPrivate == NULL) {
326 ret = OMX_ErrorBadParameter;
330 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
331 if (pExynosComponent->currentState == OMX_StateInvalid) {
332 ret = OMX_ErrorInvalidState;
338 ret = Exynos_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
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)
353 OMX_ERRORTYPE ret = OMX_ErrorNone;
354 OMX_COMPONENTTYPE *pOMXComponent = NULL;
355 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
359 if (hComponent == NULL) {
360 ret = OMX_ErrorBadParameter;
363 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
364 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
365 if (ret != OMX_ErrorNone) {
369 if (pOMXComponent->pComponentPrivate == NULL) {
370 ret = OMX_ErrorBadParameter;
373 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
375 if ((cParameterName == NULL) || (pIndexType == NULL)) {
376 ret = OMX_ErrorBadParameter;
379 if (pExynosComponent->currentState == OMX_StateInvalid) {
380 ret = OMX_ErrorInvalidState;
384 ret = Exynos_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
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)
397 OMX_ERRORTYPE ret = OMX_ErrorNone;
398 OMX_COMPONENTTYPE *pOMXComponent = NULL;
399 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
404 if ((hComponent == NULL) || (cRole == NULL)) {
405 ret = OMX_ErrorBadParameter;
408 if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) {
409 ret = OMX_ErrorNoMore;
412 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
413 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
414 if (ret != OMX_ErrorNone) {
417 if (pOMXComponent->pComponentPrivate == NULL) {
418 ret = OMX_ErrorBadParameter;
422 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
423 if (pExynosComponent->currentState == OMX_StateInvalid ) {
424 ret = OMX_ErrorInvalidState;
428 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
436 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
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;
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;
452 pMp3Dec->nPendingflags = 0;
454 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
456 #ifdef SRP_DUMP_TO_FILE
457 inFile = fopen("/data/InFile.mp3", "w+");
458 outFile = fopen("/data/OutFile.pcm", "w+");
467 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
469 OMX_ERRORTYPE ret = OMX_ErrorNone;
470 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
474 #ifdef SRP_DUMP_TO_FILE
485 OMX_ERRORTYPE Exynos_SRP_Mp3_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
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};
501 #ifdef SRP_DUMP_TO_FILE
502 if (pExynosComponent->reInputData == OMX_FALSE) {
503 fwrite(pInputData->buffer.singlePlaneBuffer.dataBuffer, pInputData->dataLen, 1, inFile);
507 /* Save timestamp and flags of input data */
509 pOutputData->timeStamp = pInputData->timeStamp;
511 if (pExynosComponent->checkTimeStamp.startTimeStamp == pInputData->timeStamp) {
512 pMp3Dec->timeStamp = pInputData->timeStamp;
515 pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS);
517 /* Decoding mp3 frames by SRP */
518 if (pExynosComponent->getAllDelayBuffer == OMX_FALSE) {
519 if (pInputData->dataLen == 0)
520 returnCodec = SRP_Decode(dummy, sizeof(dummy));
522 returnCodec = SRP_Decode(pInputData->buffer.singlePlaneBuffer.dataBuffer, pInputData->dataLen);
524 if (returnCodec >= 0) {
525 if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
527 pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_TRUE;
529 } else if (returnCodec == SRP_ERROR_IBUF_OVERFLOW) {
530 isSRPIbufOverflow = OMX_TRUE;
531 ret = OMX_ErrorInputDataDecodeYet;
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;
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;
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;
556 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
557 if (isSRPIbufOverflow)
558 ret = OMX_ErrorInputDataDecodeYet;
565 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "numChannels(%d), samplingRate(%d)",
566 codecDecInfo.channels, codecDecInfo.sample_rate);
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;
574 /* Send Port Settings changed call back */
575 (*(pExynosComponent->pCallbacks->EventHandler))
577 pExynosComponent->callbackData,
578 OMX_EventPortSettingsChanged, /* The command was completed */
579 OMX_DirOutput, /* This is the port index */
584 pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_TRUE;
586 if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
587 pOutputData->dataLen = 0;
588 pExynosComponent->getAllDelayBuffer = OMX_TRUE;
589 ret = OMX_ErrorInputDataDecodeYet;
591 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
592 if (isSRPIbufOverflow)
593 ret = OMX_ErrorInputDataDecodeYet;
600 /* Get decoded data from SRP */
601 returnCodec = SRP_Get_PCM(&dataBuffer, &dataLen);
603 pOutputData->dataLen = dataLen;
604 Exynos_OSAL_Memcpy(pOutputData->buffer.singlePlaneBuffer.dataBuffer, dataBuffer, dataLen);
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;
612 pOutputData->dataLen = 0;
614 pMp3Dec->nPendingflags = pOutputData->nFlags;
618 #ifdef SRP_DUMP_TO_FILE
619 if (pOutputData->dataLen > 0)
620 fwrite(pOutputData->buffer.singlePlaneBuffer.dataBuffer, pOutputData->dataLen, 1, outFile);
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;
633 pOutputData->timeStamp = pInputData->timeStamp; /*For ALP EOS Timestamp*/
635 pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; /* for repeating one song */
638 pExynosComponent->getAllDelayBuffer = OMX_TRUE;
639 ret = OMX_ErrorInputDataDecodeYet;
641 } else { /* Flush after EOS */
642 pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE;
651 OMX_ERRORTYPE Exynos_SRP_Mp3Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
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];
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;
669 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent)) {
670 if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
671 ret = OMX_ErrorInputDataDecodeYet;
678 ret = Exynos_SRP_Mp3_Decode_Block(pOMXComponent, pInputData, pOutputData);
680 if (ret != OMX_ErrorNone) {
681 if (ret == OMX_ErrorInputDataDecodeYet) {
682 pOutputData->usedDataLen = 0;
683 pOutputData->remainDataLen = pOutputData->dataLen;
685 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
686 pExynosComponent->callbackData,
687 OMX_EventError, ret, 0, NULL);
690 pInputData->usedDataLen += pInputData->dataLen;
691 pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen;
692 pInputData->dataLen -= pInputData->usedDataLen;
693 pInputData->usedDataLen = 0;
695 pOutputData->usedDataLen = 0;
696 pOutputData->remainDataLen = pOutputData->dataLen;
705 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
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;
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;
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;
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);
741 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
742 pExynosComponent->codecType = HW_AUDIO_DEC_CODEC;
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;
750 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
751 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MP3_DEC);
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;
759 Exynos_OSAL_Memset(pMp3Dec, 0, sizeof(EXYNOS_MP3_HANDLE));
760 pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
761 pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pMp3Dec;
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;
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;
778 pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_TRUE;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
880 pExynosComponent->currentState = OMX_StateLoaded;
883 goto EXIT; /* This function is performed successfully. */
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;
895 Exynos_OSAL_Free(pMp3Dec);
896 pAudioDec->hCodecHandle = NULL;
898 Exynos_OSAL_Free(pExynosComponent->componentName);
899 pExynosComponent->componentName = NULL;
901 Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
908 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
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;
918 if (hComponent == NULL) {
919 ret = OMX_ErrorBadParameter;
922 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
923 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
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;
934 pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
935 if (pMp3Dec != NULL) {
936 if (pMp3Dec->hSRPMp3Handle.bSRPLoaded == OMX_TRUE) {
940 Exynos_OSAL_Free(pMp3Dec);
941 ((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
944 ret = Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
945 if (ret != OMX_ErrorNone) {