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