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_Baseport.c 20 * @brief 21 * @author SeungBeom Kim (sbcrux.kim (at) samsung.com) 22 * HyeYeon Chung (hyeon.chung (at) samsung.com) 23 * @version 2.0.0 24 * @history 25 * 2012.02.20 : Create 26 */ 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #include "Exynos_OMX_Macros.h" 33 #include "Exynos_OSAL_Event.h" 34 #include "Exynos_OSAL_Semaphore.h" 35 #include "Exynos_OSAL_Mutex.h" 36 37 #include "Exynos_OMX_Baseport.h" 38 #include "Exynos_OMX_Basecomponent.h" 39 40 #undef EXYNOS_LOG_TAG 41 #define EXYNOS_LOG_TAG "EXYNOS_BASE_PORT" 42 #define EXYNOS_LOG_OFF 43 //#define EXYNOS_TRACE_ON 44 #include "Exynos_OSAL_Log.h" 45 46 47 OMX_ERRORTYPE Exynos_OMX_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader) 48 { 49 OMX_ERRORTYPE ret = OMX_ErrorNone; 50 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 51 EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 52 OMX_U32 i = 0; 53 54 Exynos_OSAL_MutexLock(pExynosPort->hPortMutex); 55 for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { 56 if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) { 57 pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE; 58 break; 59 } 60 } 61 62 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 63 pExynosComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader); 64 65 return ret; 66 } 67 68 OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader) 69 { 70 OMX_ERRORTYPE ret = OMX_ErrorNone; 71 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 72 EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 73 OMX_U32 i = 0; 74 75 Exynos_OSAL_MutexLock(pExynosPort->hPortMutex); 76 for (i = 0; i < MAX_BUFFER_NUM; i++) { 77 if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) { 78 pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE; 79 break; 80 } 81 } 82 83 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 84 pExynosComponent->pCallbacks->FillBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader); 85 86 EXIT: 87 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d, bufferHeader:0x%x", __FUNCTION__, __LINE__, bufferHeader); 88 return ret; 89 } 90 91 OMX_ERRORTYPE Exynos_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent) 92 { 93 OMX_ERRORTYPE ret = OMX_ErrorNone; 94 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 95 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 96 OMX_S32 portIndex = 0; 97 EXYNOS_OMX_DATABUFFER *flushPortBuffer[2] = {NULL, NULL}; 98 OMX_U32 i = 0, cnt = 0; 99 100 FunctionIn(); 101 102 if (pOMXComponent == NULL) { 103 ret = OMX_ErrorBadParameter; 104 goto EXIT; 105 } 106 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 107 if (ret != OMX_ErrorNone) { 108 goto EXIT; 109 } 110 111 if (pOMXComponent->pComponentPrivate == NULL) { 112 ret = OMX_ErrorBadParameter; 113 goto EXIT; 114 } 115 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 116 117 cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; 118 119 for (i = 0; i < cnt; i++) { 120 if (nPortIndex == ALL_PORT_INDEX) 121 portIndex = i; 122 else 123 portIndex = nPortIndex; 124 125 pExynosComponent->exynos_BufferFlush(pOMXComponent, portIndex, bEvent); 126 } 127 128 EXIT: 129 if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) { 130 Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__); 131 pExynosComponent->pCallbacks->EventHandler(pOMXComponent, 132 pExynosComponent->callbackData, 133 OMX_EventError, 134 ret, 0, NULL); 135 } 136 137 FunctionOut(); 138 139 return ret; 140 } 141 142 OMX_ERRORTYPE Exynos_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) 143 { 144 OMX_ERRORTYPE ret = OMX_ErrorNone; 145 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 146 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 147 OMX_U32 i = 0, cnt = 0; 148 149 FunctionIn(); 150 151 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 152 153 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { 154 Exynos_OSAL_SemaphoreWait(pExynosPort->loadedResource); 155 156 if (pExynosPort->exceptionFlag == INVALID_STATE) { 157 pExynosPort->exceptionFlag = NEED_PORT_DISABLE; 158 goto EXIT; 159 } 160 pExynosPort->portDefinition.bPopulated = OMX_TRUE; 161 } 162 pExynosPort->exceptionFlag = GENERAL_STATE; 163 pExynosPort->portDefinition.bEnabled = OMX_TRUE; 164 165 ret = OMX_ErrorNone; 166 167 EXIT: 168 FunctionOut(); 169 170 return ret; 171 } 172 173 OMX_ERRORTYPE Exynos_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) 174 { 175 OMX_ERRORTYPE ret = OMX_ErrorNone; 176 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 177 OMX_S32 portIndex = 0; 178 OMX_U32 i = 0, cnt = 0; 179 180 FunctionIn(); 181 182 if (pOMXComponent == NULL) { 183 ret = OMX_ErrorBadParameter; 184 goto EXIT; 185 } 186 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 187 if (ret != OMX_ErrorNone) { 188 goto EXIT; 189 } 190 191 if (pOMXComponent->pComponentPrivate == NULL) { 192 ret = OMX_ErrorBadParameter; 193 goto EXIT; 194 } 195 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 196 197 cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1; 198 199 for (i = 0; i < cnt; i++) { 200 if (nPortIndex == ALL_PORT_INDEX) 201 portIndex = i; 202 else 203 portIndex = nPortIndex; 204 205 ret = Exynos_OMX_EnablePort(pOMXComponent, portIndex); 206 if (ret == OMX_ErrorNone) { 207 pExynosComponent->pCallbacks->EventHandler(pOMXComponent, 208 pExynosComponent->callbackData, 209 OMX_EventCmdComplete, 210 OMX_CommandPortEnable, portIndex, NULL); 211 } 212 } 213 214 EXIT: 215 if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) { 216 pExynosComponent->pCallbacks->EventHandler(pOMXComponent, 217 pExynosComponent->callbackData, 218 OMX_EventError, 219 ret, 0, NULL); 220 } 221 222 FunctionOut(); 223 224 return ret; 225 } 226 227 OMX_ERRORTYPE Exynos_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) 228 { 229 OMX_ERRORTYPE ret = OMX_ErrorNone; 230 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 231 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 232 OMX_U32 i = 0, elemNum = 0; 233 EXYNOS_OMX_MESSAGE *message; 234 235 FunctionIn(); 236 237 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 238 239 if (!CHECK_PORT_ENABLED(pExynosPort)) { 240 ret = OMX_ErrorNone; 241 goto EXIT; 242 } 243 244 if (pExynosComponent->currentState != OMX_StateLoaded) { 245 if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 246 while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) { 247 message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); 248 Exynos_OSAL_Free(message); 249 } 250 } 251 pExynosPort->portDefinition.bPopulated = OMX_FALSE; 252 Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource); 253 } 254 pExynosPort->portDefinition.bEnabled = OMX_FALSE; 255 ret = OMX_ErrorNone; 256 257 EXIT: 258 FunctionOut(); 259 260 return ret; 261 } 262 263 OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) 264 { 265 OMX_ERRORTYPE ret = OMX_ErrorNone; 266 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 267 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 268 OMX_S32 portIndex = 0; 269 OMX_U32 i = 0, cnt = 0; 270 EXYNOS_OMX_DATABUFFER *flushPortBuffer[2] = {NULL, NULL}; 271 272 FunctionIn(); 273 274 if (pOMXComponent == NULL) { 275 ret = OMX_ErrorBadParameter; 276 goto EXIT; 277 } 278 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 279 if (ret != OMX_ErrorNone) { 280 goto EXIT; 281 } 282 283 if (pOMXComponent->pComponentPrivate == NULL) { 284 ret = OMX_ErrorBadParameter; 285 goto EXIT; 286 } 287 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 288 289 cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; 290 291 /* port flush*/ 292 for(i = 0; i < cnt; i++) { 293 if (nPortIndex == ALL_PORT_INDEX) 294 portIndex = i; 295 else 296 portIndex = nPortIndex; 297 298 Exynos_OMX_BufferFlushProcess(pOMXComponent, portIndex, OMX_FALSE); 299 } 300 301 for(i = 0; i < cnt; i++) { 302 if (nPortIndex == ALL_PORT_INDEX) 303 portIndex = i; 304 else 305 portIndex = nPortIndex; 306 307 ret = Exynos_OMX_DisablePort(pOMXComponent, portIndex); 308 pExynosComponent->pExynosPort[portIndex].bIsPortDisabled = OMX_FALSE; 309 if (ret == OMX_ErrorNone) { 310 pExynosComponent->pCallbacks->EventHandler(pOMXComponent, 311 pExynosComponent->callbackData, 312 OMX_EventCmdComplete, 313 OMX_CommandPortDisable, portIndex, NULL); 314 } 315 } 316 317 EXIT: 318 if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) { 319 pExynosComponent->pCallbacks->EventHandler(pOMXComponent, 320 pExynosComponent->callbackData, 321 OMX_EventError, 322 ret, 0, NULL); 323 } 324 325 FunctionOut(); 326 327 return ret; 328 } 329 330 OMX_ERRORTYPE Exynos_OMX_EmptyThisBuffer( 331 OMX_IN OMX_HANDLETYPE hComponent, 332 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 333 { 334 OMX_ERRORTYPE ret = OMX_ErrorNone; 335 OMX_COMPONENTTYPE *pOMXComponent = NULL; 336 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 337 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 338 OMX_BOOL findBuffer = OMX_FALSE; 339 EXYNOS_OMX_MESSAGE *message; 340 OMX_U32 i = 0; 341 342 FunctionIn(); 343 344 if (hComponent == NULL) { 345 ret = OMX_ErrorBadParameter; 346 goto EXIT; 347 } 348 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 349 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 350 if (ret != OMX_ErrorNone) { 351 goto EXIT; 352 } 353 354 if (pOMXComponent->pComponentPrivate == NULL) { 355 ret = OMX_ErrorBadParameter; 356 goto EXIT; 357 } 358 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 359 if (pExynosComponent->currentState == OMX_StateInvalid) { 360 ret = OMX_ErrorInvalidState; 361 goto EXIT; 362 } 363 364 if (pBuffer == NULL) { 365 ret = OMX_ErrorBadParameter; 366 goto EXIT; 367 } 368 if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) { 369 ret = OMX_ErrorBadPortIndex; 370 goto EXIT; 371 } 372 373 ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 374 if (ret != OMX_ErrorNone) { 375 goto EXIT; 376 } 377 378 if ((pExynosComponent->currentState != OMX_StateIdle) && 379 (pExynosComponent->currentState != OMX_StateExecuting) && 380 (pExynosComponent->currentState != OMX_StatePause)) { 381 ret = OMX_ErrorIncorrectStateOperation; 382 goto EXIT; 383 } 384 385 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 386 if ((!CHECK_PORT_ENABLED(pExynosPort)) || 387 (CHECK_PORT_BEING_FLUSHED(pExynosPort) && 388 (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) || 389 ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) && 390 (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) { 391 ret = OMX_ErrorIncorrectStateOperation; 392 goto EXIT; 393 } 394 395 Exynos_OSAL_MutexLock(pExynosPort->hPortMutex); 396 for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { 397 if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) { 398 pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE; 399 findBuffer = OMX_TRUE; 400 break; 401 } 402 } 403 404 if (findBuffer == OMX_FALSE) { 405 ret = OMX_ErrorBadParameter; 406 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 407 goto EXIT; 408 } 409 410 message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE)); 411 if (message == NULL) { 412 ret = OMX_ErrorInsufficientResources; 413 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 414 goto EXIT; 415 } 416 message->messageType = EXYNOS_OMX_CommandEmptyBuffer; 417 message->messageParam = (OMX_U32) i; 418 message->pCmdData = (OMX_PTR)pBuffer; 419 420 ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message); 421 if (ret != 0) { 422 ret = OMX_ErrorUndefined; 423 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 424 goto EXIT; 425 } 426 ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); 427 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 428 429 EXIT: 430 FunctionOut(); 431 432 return ret; 433 } 434 435 OMX_ERRORTYPE Exynos_OMX_FillThisBuffer( 436 OMX_IN OMX_HANDLETYPE hComponent, 437 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 438 { 439 OMX_ERRORTYPE ret = OMX_ErrorNone; 440 OMX_COMPONENTTYPE *pOMXComponent = NULL; 441 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 442 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 443 OMX_BOOL findBuffer = OMX_FALSE; 444 EXYNOS_OMX_MESSAGE *message; 445 OMX_U32 i = 0; 446 447 FunctionIn(); 448 449 if (hComponent == NULL) { 450 ret = OMX_ErrorBadParameter; 451 goto EXIT; 452 } 453 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 454 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 455 if (ret != OMX_ErrorNone) { 456 goto EXIT; 457 } 458 459 if (pOMXComponent->pComponentPrivate == NULL) { 460 ret = OMX_ErrorBadParameter; 461 goto EXIT; 462 } 463 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 464 if (pExynosComponent->currentState == OMX_StateInvalid) { 465 ret = OMX_ErrorInvalidState; 466 goto EXIT; 467 } 468 469 if (pBuffer == NULL) { 470 ret = OMX_ErrorBadParameter; 471 goto EXIT; 472 } 473 if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) { 474 ret = OMX_ErrorBadPortIndex; 475 goto EXIT; 476 } 477 478 ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 479 if (ret != OMX_ErrorNone) { 480 goto EXIT; 481 } 482 483 if ((pExynosComponent->currentState != OMX_StateIdle) && 484 (pExynosComponent->currentState != OMX_StateExecuting) && 485 (pExynosComponent->currentState != OMX_StatePause)) { 486 ret = OMX_ErrorIncorrectStateOperation; 487 goto EXIT; 488 } 489 490 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 491 if ((!CHECK_PORT_ENABLED(pExynosPort)) || 492 (CHECK_PORT_BEING_FLUSHED(pExynosPort) && 493 (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) || 494 ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) && 495 (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) { 496 ret = OMX_ErrorIncorrectStateOperation; 497 goto EXIT; 498 } 499 500 Exynos_OSAL_MutexLock(pExynosPort->hPortMutex); 501 for (i = 0; i < MAX_BUFFER_NUM; i++) { 502 if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) { 503 pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE; 504 findBuffer = OMX_TRUE; 505 break; 506 } 507 } 508 509 if (findBuffer == OMX_FALSE) { 510 ret = OMX_ErrorBadParameter; 511 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 512 goto EXIT; 513 } 514 515 message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE)); 516 if (message == NULL) { 517 ret = OMX_ErrorInsufficientResources; 518 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 519 goto EXIT; 520 } 521 message->messageType = EXYNOS_OMX_CommandFillBuffer; 522 message->messageParam = (OMX_U32) i; 523 message->pCmdData = (OMX_PTR)pBuffer; 524 525 ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message); 526 if (ret != 0) { 527 ret = OMX_ErrorUndefined; 528 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 529 goto EXIT; 530 } 531 532 ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); 533 Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); 534 535 EXIT: 536 FunctionOut(); 537 538 return ret; 539 } 540 541 OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent) 542 { 543 OMX_ERRORTYPE ret = OMX_ErrorNone; 544 OMX_COMPONENTTYPE *pOMXComponent = NULL; 545 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 546 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 547 EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL; 548 EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; 549 int i = 0; 550 551 FunctionIn(); 552 553 if (hComponent == NULL) { 554 ret = OMX_ErrorBadParameter; 555 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); 556 goto EXIT; 557 } 558 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 559 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 560 if (ret != OMX_ErrorNone) { 561 goto EXIT; 562 } 563 564 if (pOMXComponent->pComponentPrivate == NULL) { 565 ret = OMX_ErrorBadParameter; 566 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); 567 goto EXIT; 568 } 569 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 570 571 INIT_SET_SIZE_VERSION(&pExynosComponent->portParam, OMX_PORT_PARAM_TYPE); 572 pExynosComponent->portParam.nPorts = ALL_PORT_NUM; 573 pExynosComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX; 574 575 pExynosPort = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM); 576 if (pExynosPort == NULL) { 577 ret = OMX_ErrorInsufficientResources; 578 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 579 goto EXIT; 580 } 581 Exynos_OSAL_Memset(pExynosPort, 0, sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM); 582 pExynosComponent->pExynosPort = pExynosPort; 583 584 /* Input Port */ 585 pExynosInputPort = &pExynosPort[INPUT_PORT_INDEX]; 586 587 Exynos_OSAL_QueueCreate(&pExynosInputPort->bufferQ, MAX_QUEUE_ELEMENTS); 588 589 pExynosInputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM); 590 if (pExynosInputPort->extendBufferHeader == NULL) { 591 Exynos_OSAL_Free(pExynosPort); 592 pExynosPort = NULL; 593 ret = OMX_ErrorInsufficientResources; 594 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 595 goto EXIT; 596 } 597 Exynos_OSAL_Memset(pExynosInputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM); 598 599 pExynosInputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); 600 if (pExynosInputPort->bufferStateAllocate == NULL) { 601 Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); 602 pExynosInputPort->extendBufferHeader = NULL; 603 Exynos_OSAL_Free(pExynosPort); 604 pExynosPort = NULL; 605 ret = OMX_ErrorInsufficientResources; 606 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 607 goto EXIT; 608 } 609 Exynos_OSAL_Memset(pExynosInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); 610 611 pExynosInputPort->bufferSemID = NULL; 612 pExynosInputPort->assignedBufferNum = 0; 613 pExynosInputPort->portState = OMX_StateMax; 614 pExynosInputPort->bIsPortFlushed = OMX_FALSE; 615 pExynosInputPort->bIsPortDisabled = OMX_FALSE; 616 pExynosInputPort->tunneledComponent = NULL; 617 pExynosInputPort->tunneledPort = 0; 618 pExynosInputPort->tunnelBufferNum = 0; 619 pExynosInputPort->bufferSupplier = OMX_BufferSupplyUnspecified; 620 pExynosInputPort->tunnelFlags = 0; 621 ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->loadedResource); 622 if (ret != OMX_ErrorNone) { 623 Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); 624 pExynosInputPort->bufferStateAllocate = NULL; 625 Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); 626 pExynosInputPort->extendBufferHeader = NULL; 627 Exynos_OSAL_Free(pExynosPort); 628 pExynosPort = NULL; 629 goto EXIT; 630 } 631 ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->unloadedResource); 632 if (ret != OMX_ErrorNone) { 633 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); 634 pExynosInputPort->loadedResource = NULL; 635 Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); 636 pExynosInputPort->bufferStateAllocate = NULL; 637 Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); 638 pExynosInputPort->extendBufferHeader = NULL; 639 Exynos_OSAL_Free(pExynosPort); 640 pExynosPort = NULL; 641 goto EXIT; 642 } 643 644 INIT_SET_SIZE_VERSION(&pExynosInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); 645 pExynosInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX; 646 pExynosInputPort->portDefinition.eDir = OMX_DirInput; 647 pExynosInputPort->portDefinition.nBufferCountActual = 0; 648 pExynosInputPort->portDefinition.nBufferCountMin = 0; 649 pExynosInputPort->portDefinition.nBufferSize = 0; 650 pExynosInputPort->portDefinition.bEnabled = OMX_FALSE; 651 pExynosInputPort->portDefinition.bPopulated = OMX_FALSE; 652 pExynosInputPort->portDefinition.eDomain = OMX_PortDomainMax; 653 pExynosInputPort->portDefinition.bBuffersContiguous = OMX_FALSE; 654 pExynosInputPort->portDefinition.nBufferAlignment = 0; 655 pExynosInputPort->markType.hMarkTargetComponent = NULL; 656 pExynosInputPort->markType.pMarkData = NULL; 657 pExynosInputPort->exceptionFlag = GENERAL_STATE; 658 659 /* Output Port */ 660 pExynosOutputPort = &pExynosPort[OUTPUT_PORT_INDEX]; 661 662 Exynos_OSAL_QueueCreate(&pExynosOutputPort->bufferQ, MAX_QUEUE_ELEMENTS); /* For in case of "Output Buffer Share", MAX ELEMENTS(DPB + EDPB) */ 663 664 pExynosOutputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM); 665 if (pExynosOutputPort->extendBufferHeader == NULL) { 666 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource); 667 pExynosInputPort->unloadedResource = NULL; 668 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); 669 pExynosInputPort->loadedResource = NULL; 670 Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); 671 pExynosInputPort->bufferStateAllocate = NULL; 672 Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); 673 pExynosInputPort->extendBufferHeader = NULL; 674 Exynos_OSAL_Free(pExynosPort); 675 pExynosPort = NULL; 676 ret = OMX_ErrorInsufficientResources; 677 goto EXIT; 678 } 679 Exynos_OSAL_Memset(pExynosOutputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM); 680 681 pExynosOutputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); 682 if (pExynosOutputPort->bufferStateAllocate == NULL) { 683 Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader); 684 pExynosOutputPort->extendBufferHeader = NULL; 685 686 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource); 687 pExynosInputPort->unloadedResource = NULL; 688 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); 689 pExynosInputPort->loadedResource = NULL; 690 Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); 691 pExynosInputPort->bufferStateAllocate = NULL; 692 Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); 693 pExynosInputPort->extendBufferHeader = NULL; 694 Exynos_OSAL_Free(pExynosPort); 695 pExynosPort = NULL; 696 ret = OMX_ErrorInsufficientResources; 697 goto EXIT; 698 } 699 Exynos_OSAL_Memset(pExynosOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); 700 701 pExynosOutputPort->bufferSemID = NULL; 702 pExynosOutputPort->assignedBufferNum = 0; 703 pExynosOutputPort->portState = OMX_StateMax; 704 pExynosOutputPort->bIsPortFlushed = OMX_FALSE; 705 pExynosOutputPort->bIsPortDisabled = OMX_FALSE; 706 pExynosOutputPort->tunneledComponent = NULL; 707 pExynosOutputPort->tunneledPort = 0; 708 pExynosOutputPort->tunnelBufferNum = 0; 709 pExynosOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified; 710 pExynosOutputPort->tunnelFlags = 0; 711 ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->loadedResource); 712 if (ret != OMX_ErrorNone) { 713 Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate); 714 pExynosOutputPort->bufferStateAllocate = NULL; 715 Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader); 716 pExynosOutputPort->extendBufferHeader = NULL; 717 718 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource); 719 pExynosInputPort->unloadedResource = NULL; 720 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); 721 pExynosInputPort->loadedResource = NULL; 722 Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); 723 pExynosInputPort->bufferStateAllocate = NULL; 724 Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); 725 pExynosInputPort->extendBufferHeader = NULL; 726 Exynos_OSAL_Free(pExynosPort); 727 pExynosPort = NULL; 728 goto EXIT; 729 } 730 ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->unloadedResource); 731 if (ret != OMX_ErrorNone) { 732 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->loadedResource); 733 pExynosOutputPort->loadedResource = NULL; 734 Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate); 735 pExynosOutputPort->bufferStateAllocate = NULL; 736 Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader); 737 pExynosOutputPort->extendBufferHeader = NULL; 738 739 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource); 740 pExynosInputPort->unloadedResource = NULL; 741 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); 742 pExynosInputPort->loadedResource = NULL; 743 Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); 744 pExynosInputPort->bufferStateAllocate = NULL; 745 Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); 746 pExynosInputPort->extendBufferHeader = NULL; 747 Exynos_OSAL_Free(pExynosPort); 748 pExynosPort = NULL; 749 goto EXIT; 750 } 751 752 INIT_SET_SIZE_VERSION(&pExynosOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); 753 pExynosOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX; 754 pExynosOutputPort->portDefinition.eDir = OMX_DirOutput; 755 pExynosOutputPort->portDefinition.nBufferCountActual = 0; 756 pExynosOutputPort->portDefinition.nBufferCountMin = 0; 757 pExynosOutputPort->portDefinition.nBufferSize = 0; 758 pExynosOutputPort->portDefinition.bEnabled = OMX_FALSE; 759 pExynosOutputPort->portDefinition.bPopulated = OMX_FALSE; 760 pExynosOutputPort->portDefinition.eDomain = OMX_PortDomainMax; 761 pExynosOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE; 762 pExynosOutputPort->portDefinition.nBufferAlignment = 0; 763 pExynosOutputPort->markType.hMarkTargetComponent = NULL; 764 pExynosOutputPort->markType.pMarkData = NULL; 765 pExynosOutputPort->exceptionFlag = GENERAL_STATE; 766 767 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; 768 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; 769 pExynosComponent->checkTimeStamp.startTimeStamp = 0; 770 pExynosComponent->checkTimeStamp.nStartFlags = 0x0; 771 772 pOMXComponent->EmptyThisBuffer = &Exynos_OMX_EmptyThisBuffer; 773 pOMXComponent->FillThisBuffer = &Exynos_OMX_FillThisBuffer; 774 775 ret = OMX_ErrorNone; 776 EXIT: 777 FunctionOut(); 778 779 return ret; 780 } 781 782 OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent) 783 { 784 OMX_ERRORTYPE ret = OMX_ErrorNone; 785 OMX_COMPONENTTYPE *pOMXComponent = NULL; 786 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 787 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 788 789 OMX_S32 countValue = 0; 790 int i = 0; 791 792 FunctionIn(); 793 794 if (hComponent == NULL) { 795 ret = OMX_ErrorBadParameter; 796 goto EXIT; 797 } 798 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 799 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 800 if (ret != OMX_ErrorNone) { 801 goto EXIT; 802 } 803 if (pOMXComponent->pComponentPrivate == NULL) { 804 ret = OMX_ErrorBadParameter; 805 goto EXIT; 806 } 807 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 808 809 if (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) { 810 pExynosComponent->abendState = OMX_TRUE; 811 for (i = 0; i < ALL_PORT_NUM; i++) { 812 pExynosPort = &pExynosComponent->pExynosPort[i]; 813 Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); 814 } 815 Exynos_OSAL_SignalWait(pExynosComponent->abendStateEvent, DEF_MAX_WAIT_TIME); 816 Exynos_OSAL_SignalReset(pExynosComponent->abendStateEvent); 817 } 818 819 for (i = 0; i < ALL_PORT_NUM; i++) { 820 pExynosPort = &pExynosComponent->pExynosPort[i]; 821 822 Exynos_OSAL_SemaphoreTerminate(pExynosPort->loadedResource); 823 pExynosPort->loadedResource = NULL; 824 Exynos_OSAL_SemaphoreTerminate(pExynosPort->unloadedResource); 825 pExynosPort->unloadedResource = NULL; 826 Exynos_OSAL_Free(pExynosPort->bufferStateAllocate); 827 pExynosPort->bufferStateAllocate = NULL; 828 Exynos_OSAL_Free(pExynosPort->extendBufferHeader); 829 pExynosPort->extendBufferHeader = NULL; 830 831 Exynos_OSAL_QueueTerminate(&pExynosPort->bufferQ); 832 } 833 Exynos_OSAL_Free(pExynosComponent->pExynosPort); 834 pExynosComponent->pExynosPort = NULL; 835 ret = OMX_ErrorNone; 836 EXIT: 837 FunctionOut(); 838 839 return ret; 840 } 841 842 OMX_ERRORTYPE Exynos_ResetDataBuffer(EXYNOS_OMX_DATABUFFER *pDataBuffer) 843 { 844 OMX_ERRORTYPE ret = OMX_ErrorNone; 845 846 if (pDataBuffer == NULL) { 847 ret = OMX_ErrorBadParameter; 848 goto EXIT; 849 } 850 851 pDataBuffer->dataValid = OMX_FALSE; 852 pDataBuffer->dataLen = 0; 853 pDataBuffer->remainDataLen = 0; 854 pDataBuffer->usedDataLen = 0; 855 pDataBuffer->bufferHeader = NULL; 856 pDataBuffer->nFlags = 0; 857 pDataBuffer->timeStamp = 0; 858 pDataBuffer->pPrivate = NULL; 859 860 EXIT: 861 return ret; 862 } 863 864 OMX_ERRORTYPE Exynos_ResetCodecData(EXYNOS_OMX_DATA *pData) 865 { 866 OMX_ERRORTYPE ret = OMX_ErrorNone; 867 868 if (pData == NULL) { 869 ret = OMX_ErrorBadParameter; 870 goto EXIT; 871 } 872 873 pData->dataLen = 0; 874 pData->usedDataLen = 0; 875 pData->remainDataLen = 0; 876 pData->nFlags = 0; 877 pData->timeStamp = 0; 878 pData->pPrivate = NULL; 879 pData->bufferHeader = NULL; 880 pData->allocSize = 0; 881 882 EXIT: 883 return ret; 884 } 885 886 OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_PLANE nPlane) 887 { 888 OMX_ERRORTYPE ret = OMX_ErrorNone; 889 890 if (nPlane == ONE_PLANE) { 891 /* Case of Shared Buffer, Only support singlePlaneBuffer */ 892 pData->buffer.singlePlaneBuffer.dataBuffer = pUseBuffer->bufferHeader->pBuffer; 893 } else { 894 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not support plane"); 895 ret = OMX_ErrorNotImplemented; 896 goto EXIT; 897 } 898 899 pData->allocSize = pUseBuffer->allocSize; 900 pData->dataLen = pUseBuffer->dataLen; 901 pData->usedDataLen = pUseBuffer->usedDataLen; 902 pData->remainDataLen = pUseBuffer->remainDataLen; 903 pData->timeStamp = pUseBuffer->timeStamp; 904 pData->nFlags = pUseBuffer->nFlags; 905 pData->pPrivate = pUseBuffer->pPrivate; 906 pData->bufferHeader = pUseBuffer->bufferHeader; 907 908 EXIT: 909 return ret; 910 } 911 912 OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer) 913 { 914 OMX_ERRORTYPE ret = OMX_ErrorNone; 915 916 pUseBuffer->bufferHeader = pData->bufferHeader; 917 pUseBuffer->allocSize = pData->allocSize; 918 pUseBuffer->dataLen = pData->dataLen; 919 pUseBuffer->usedDataLen = pData->usedDataLen; 920 pUseBuffer->remainDataLen = pData->remainDataLen; 921 pUseBuffer->timeStamp = pData->timeStamp; 922 pUseBuffer->nFlags = pData->nFlags; 923 pUseBuffer->pPrivate = pData->pPrivate; 924 925 return ret; 926 } 927