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