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_Basecomponent.c 20 * @brief 21 * @author SeungBeom Kim (sbcrux.kim (at) samsung.com) 22 * Yunji Kim (yunji.kim (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 #include <unistd.h> 32 33 #include "Exynos_OSAL_Event.h" 34 #include "Exynos_OSAL_Thread.h" 35 #include "Exynos_OSAL_ETC.h" 36 #include "Exynos_OSAL_Semaphore.h" 37 #include "Exynos_OSAL_Mutex.h" 38 #include "Exynos_OMX_Baseport.h" 39 #include "Exynos_OMX_Basecomponent.h" 40 #include "Exynos_OMX_Resourcemanager.h" 41 #include "Exynos_OMX_Macros.h" 42 43 #undef EXYNOS_LOG_TAG 44 #define EXYNOS_LOG_TAG "EXYNOS_BASE_COMP" 45 #define EXYNOS_LOG_OFF 46 //#define EXYNOS_TRACE_ON 47 #include "Exynos_OSAL_Log.h" 48 49 50 /* Change CHECK_SIZE_VERSION Macro */ 51 OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size) 52 { 53 OMX_ERRORTYPE ret = OMX_ErrorNone; 54 55 OMX_VERSIONTYPE* version = NULL; 56 if (header == NULL) { 57 ret = OMX_ErrorBadParameter; 58 goto EXIT; 59 } 60 version = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32)); 61 if (*((OMX_U32*)header) != size) { 62 ret = OMX_ErrorBadParameter; 63 goto EXIT; 64 } 65 if (version->s.nVersionMajor != VERSIONMAJOR_NUMBER || 66 version->s.nVersionMinor != VERSIONMINOR_NUMBER) { 67 ret = OMX_ErrorVersionMismatch; 68 goto EXIT; 69 } 70 ret = OMX_ErrorNone; 71 EXIT: 72 return ret; 73 } 74 75 OMX_ERRORTYPE Exynos_OMX_GetComponentVersion( 76 OMX_IN OMX_HANDLETYPE hComponent, 77 OMX_OUT OMX_STRING pComponentName, 78 OMX_OUT OMX_VERSIONTYPE *pComponentVersion, 79 OMX_OUT OMX_VERSIONTYPE *pSpecVersion, 80 OMX_OUT OMX_UUIDTYPE *pComponentUUID) 81 { 82 OMX_ERRORTYPE ret = OMX_ErrorNone; 83 OMX_COMPONENTTYPE *pOMXComponent = NULL; 84 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 85 OMX_U32 compUUID[3]; 86 87 FunctionIn(); 88 89 /* check parameters */ 90 if (hComponent == NULL || 91 pComponentName == NULL || pComponentVersion == NULL || 92 pSpecVersion == NULL || pComponentUUID == NULL) { 93 ret = OMX_ErrorBadParameter; 94 goto EXIT; 95 } 96 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 97 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 98 if (ret != OMX_ErrorNone) { 99 goto EXIT; 100 } 101 102 if (pOMXComponent->pComponentPrivate == NULL) { 103 ret = OMX_ErrorBadParameter; 104 goto EXIT; 105 } 106 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 107 108 if (pExynosComponent->currentState == OMX_StateInvalid) { 109 ret = OMX_ErrorInvalidState; 110 goto EXIT; 111 } 112 113 Exynos_OSAL_Strcpy(pComponentName, pExynosComponent->componentName); 114 Exynos_OSAL_Memcpy(pComponentVersion, &(pExynosComponent->componentVersion), sizeof(OMX_VERSIONTYPE)); 115 Exynos_OSAL_Memcpy(pSpecVersion, &(pExynosComponent->specVersion), sizeof(OMX_VERSIONTYPE)); 116 117 /* Fill UUID with handle address, PID and UID. 118 * This should guarantee uiniqness */ 119 compUUID[0] = (OMX_U32)pOMXComponent; 120 compUUID[1] = getpid(); 121 compUUID[2] = getuid(); 122 Exynos_OSAL_Memcpy(*pComponentUUID, compUUID, 3 * sizeof(*compUUID)); 123 124 ret = OMX_ErrorNone; 125 126 EXIT: 127 FunctionOut(); 128 129 return ret; 130 } 131 132 OMX_ERRORTYPE Exynos_OMX_GetState ( 133 OMX_IN OMX_HANDLETYPE hComponent, 134 OMX_OUT OMX_STATETYPE *pState) 135 { 136 OMX_ERRORTYPE ret = OMX_ErrorNone; 137 OMX_COMPONENTTYPE *pOMXComponent = NULL; 138 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 139 140 FunctionIn(); 141 142 if (hComponent == NULL || pState == NULL) { 143 ret = OMX_ErrorBadParameter; 144 goto EXIT; 145 } 146 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 147 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 148 if (ret != OMX_ErrorNone) { 149 goto EXIT; 150 } 151 152 if (pOMXComponent->pComponentPrivate == NULL) { 153 ret = OMX_ErrorBadParameter; 154 goto EXIT; 155 } 156 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 157 158 *pState = pExynosComponent->currentState; 159 ret = OMX_ErrorNone; 160 161 EXIT: 162 FunctionOut(); 163 164 return ret; 165 } 166 167 OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 messageParam) 168 { 169 OMX_ERRORTYPE ret = OMX_ErrorNone; 170 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 171 EXYNOS_OMX_MESSAGE *message; 172 OMX_STATETYPE destState = messageParam; 173 OMX_STATETYPE currentState = pExynosComponent->currentState; 174 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 175 OMX_S32 countValue = 0; 176 unsigned int i = 0, j = 0; 177 int k = 0; 178 179 FunctionIn(); 180 181 /* check parameters */ 182 if (currentState == destState) { 183 ret = OMX_ErrorSameState; 184 goto EXIT; 185 } 186 if (currentState == OMX_StateInvalid) { 187 ret = OMX_ErrorInvalidState; 188 goto EXIT; 189 } 190 191 if ((currentState == OMX_StateLoaded) && (destState == OMX_StateIdle)) { 192 ret = Exynos_OMX_Get_Resource(pOMXComponent); 193 if (ret != OMX_ErrorNone) { 194 Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent); 195 goto EXIT; 196 } 197 } 198 if (((currentState == OMX_StateIdle) && (destState == OMX_StateLoaded)) || 199 ((currentState == OMX_StateIdle) && (destState == OMX_StateInvalid)) || 200 ((currentState == OMX_StateExecuting) && (destState == OMX_StateInvalid)) || 201 ((currentState == OMX_StatePause) && (destState == OMX_StateInvalid))) { 202 Exynos_OMX_Release_Resource(pOMXComponent); 203 } 204 205 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "destState: %d currentState: %d", destState, currentState); 206 switch (destState) { 207 case OMX_StateInvalid: 208 switch (currentState) { 209 case OMX_StateWaitForResources: 210 Exynos_OMX_Out_WaitForResource(pOMXComponent); 211 case OMX_StateIdle: 212 case OMX_StateExecuting: 213 case OMX_StatePause: 214 case OMX_StateLoaded: 215 pExynosComponent->currentState = OMX_StateInvalid; 216 ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent); 217 218 for (i = 0; i < ALL_PORT_NUM; i++) { 219 if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) { 220 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex); 221 pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL; 222 } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) { 223 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex); 224 pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL; 225 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex); 226 pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL; 227 } 228 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex); 229 pExynosComponent->pExynosPort[i].hPortMutex = NULL; 230 } 231 232 if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { 233 Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent); 234 pExynosComponent->pauseEvent = NULL; 235 } else { 236 for (i = 0; i < ALL_PORT_NUM; i++) { 237 Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); 238 pExynosComponent->pExynosPort[i].pauseEvent = NULL; 239 if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) { 240 Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); 241 pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; 242 } 243 } 244 } 245 for (i = 0; i < ALL_PORT_NUM; i++) { 246 Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID); 247 pExynosComponent->pExynosPort[i].bufferSemID = NULL; 248 } 249 if (pExynosComponent->exynos_codec_componentTerminate != NULL) 250 pExynosComponent->exynos_codec_componentTerminate(pOMXComponent); 251 252 ret = OMX_ErrorInvalidState; 253 break; 254 default: 255 ret = OMX_ErrorInvalidState; 256 break; 257 } 258 break; 259 case OMX_StateLoaded: 260 switch (currentState) { 261 case OMX_StateIdle: 262 ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent); 263 264 for (i = 0; i < ALL_PORT_NUM; i++) { 265 if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) { 266 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex); 267 pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL; 268 } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) { 269 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex); 270 pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL; 271 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex); 272 pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL; 273 } 274 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex); 275 pExynosComponent->pExynosPort[i].hPortMutex = NULL; 276 } 277 if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { 278 Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent); 279 pExynosComponent->pauseEvent = NULL; 280 } else { 281 for (i = 0; i < ALL_PORT_NUM; i++) { 282 Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); 283 pExynosComponent->pExynosPort[i].pauseEvent = NULL; 284 if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) { 285 Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); 286 pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; 287 } 288 } 289 } 290 for (i = 0; i < ALL_PORT_NUM; i++) { 291 Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID); 292 pExynosComponent->pExynosPort[i].bufferSemID = NULL; 293 } 294 295 pExynosComponent->exynos_codec_componentTerminate(pOMXComponent); 296 297 for (i = 0; i < (pExynosComponent->portParam.nPorts); i++) { 298 pExynosPort = (pExynosComponent->pExynosPort + i); 299 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 300 while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) { 301 message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); 302 if (message != NULL) 303 Exynos_OSAL_Free(message); 304 } 305 ret = pExynosComponent->exynos_FreeTunnelBuffer(pExynosPort, i); 306 if (OMX_ErrorNone != ret) { 307 goto EXIT; 308 } 309 } else { 310 if (CHECK_PORT_ENABLED(pExynosPort)) { 311 Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource); 312 pExynosPort->portDefinition.bPopulated = OMX_FALSE; 313 } 314 } 315 } 316 pExynosComponent->currentState = OMX_StateLoaded; 317 break; 318 case OMX_StateWaitForResources: 319 ret = Exynos_OMX_Out_WaitForResource(pOMXComponent); 320 pExynosComponent->currentState = OMX_StateLoaded; 321 break; 322 case OMX_StateExecuting: 323 case OMX_StatePause: 324 default: 325 ret = OMX_ErrorIncorrectStateTransition; 326 break; 327 } 328 break; 329 case OMX_StateIdle: 330 switch (currentState) { 331 case OMX_StateLoaded: 332 for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { 333 pExynosPort = (pExynosComponent->pExynosPort + i); 334 if (pExynosPort == NULL) { 335 ret = OMX_ErrorBadParameter; 336 goto EXIT; 337 } 338 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 339 if (CHECK_PORT_ENABLED(pExynosPort)) { 340 ret = pExynosComponent->exynos_AllocateTunnelBuffer(pExynosPort, i); 341 if (ret!=OMX_ErrorNone) 342 goto EXIT; 343 } 344 } else { 345 if (CHECK_PORT_ENABLED(pExynosPort)) { 346 Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[i].loadedResource); 347 if (pExynosComponent->abendState == OMX_TRUE) { 348 Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent); 349 ret = Exynos_OMX_Release_Resource(pOMXComponent); 350 goto EXIT; 351 } 352 pExynosPort->portDefinition.bPopulated = OMX_TRUE; 353 } 354 } 355 } 356 ret = pExynosComponent->exynos_codec_componentInit(pOMXComponent); 357 if (ret != OMX_ErrorNone) { 358 /* 359 * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free 360 */ 361 Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent); 362 Exynos_OMX_Release_Resource(pOMXComponent); 363 goto EXIT; 364 } 365 if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { 366 Exynos_OSAL_SignalCreate(&pExynosComponent->pauseEvent); 367 } else { 368 for (i = 0; i < ALL_PORT_NUM; i++) { 369 Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].pauseEvent); 370 if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) 371 Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); 372 } 373 } 374 for (i = 0; i < ALL_PORT_NUM; i++) { 375 ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->pExynosPort[i].bufferSemID); 376 if (ret != OMX_ErrorNone) { 377 ret = OMX_ErrorInsufficientResources; 378 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 379 goto EXIT; 380 } 381 } 382 for (i = 0; i < ALL_PORT_NUM; i++) { 383 if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) { 384 ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex); 385 if (ret != OMX_ErrorNone) { 386 ret = OMX_ErrorInsufficientResources; 387 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 388 goto EXIT; 389 } 390 } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) { 391 ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex); 392 if (ret != OMX_ErrorNone) { 393 ret = OMX_ErrorInsufficientResources; 394 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 395 goto EXIT; 396 } 397 ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex); 398 if (ret != OMX_ErrorNone) { 399 ret = OMX_ErrorInsufficientResources; 400 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 401 goto EXIT; 402 } 403 } 404 ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].hPortMutex); 405 if (ret != OMX_ErrorNone) { 406 ret = OMX_ErrorInsufficientResources; 407 goto EXIT; 408 } 409 } 410 411 ret = pExynosComponent->exynos_BufferProcessCreate(pOMXComponent); 412 if (ret != OMX_ErrorNone) { 413 /* 414 * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free 415 */ 416 if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { 417 Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent); 418 pExynosComponent->pauseEvent = NULL; 419 } else { 420 for (i = 0; i < ALL_PORT_NUM; i++) { 421 Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); 422 pExynosComponent->pExynosPort[i].pauseEvent = NULL; 423 if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) { 424 Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); 425 pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; 426 } 427 } 428 } 429 for (i = 0; i < ALL_PORT_NUM; i++) { 430 if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) { 431 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex); 432 pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL; 433 } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) { 434 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex); 435 pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL; 436 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex); 437 pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL; 438 } 439 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex); 440 pExynosComponent->pExynosPort[i].hPortMutex = NULL; 441 } 442 for (i = 0; i < ALL_PORT_NUM; i++) { 443 Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID); 444 pExynosComponent->pExynosPort[i].bufferSemID = NULL; 445 } 446 447 ret = OMX_ErrorInsufficientResources; 448 goto EXIT; 449 } 450 pExynosComponent->currentState = OMX_StateIdle; 451 break; 452 case OMX_StateExecuting: 453 case OMX_StatePause: 454 Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE); 455 pExynosComponent->currentState = OMX_StateIdle; 456 break; 457 case OMX_StateWaitForResources: 458 pExynosComponent->currentState = OMX_StateIdle; 459 break; 460 default: 461 ret = OMX_ErrorIncorrectStateTransition; 462 break; 463 } 464 break; 465 case OMX_StateExecuting: 466 switch (currentState) { 467 case OMX_StateLoaded: 468 ret = OMX_ErrorIncorrectStateTransition; 469 break; 470 case OMX_StateIdle: 471 for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { 472 pExynosPort = &pExynosComponent->pExynosPort[i]; 473 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) && CHECK_PORT_ENABLED(pExynosPort)) { 474 for (j = 0; j < pExynosPort->tunnelBufferNum; j++) { 475 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID); 476 } 477 } 478 } 479 480 pExynosComponent->transientState = EXYNOS_OMX_TransStateMax; 481 pExynosComponent->currentState = OMX_StateExecuting; 482 if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { 483 Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent); 484 } else { 485 for (i = 0; i < ALL_PORT_NUM; i++) { 486 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent); 487 } 488 } 489 break; 490 case OMX_StatePause: 491 for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { 492 pExynosPort = &pExynosComponent->pExynosPort[i]; 493 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) && CHECK_PORT_ENABLED(pExynosPort)) { 494 OMX_S32 semaValue = 0, cnt = 0; 495 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[i].bufferSemID, &semaValue); 496 if (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > semaValue) { 497 cnt = Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) - semaValue; 498 for (k = 0; k < cnt; k++) { 499 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID); 500 } 501 } 502 } 503 } 504 505 pExynosComponent->currentState = OMX_StateExecuting; 506 if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { 507 Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent); 508 } else { 509 for (i = 0; i < ALL_PORT_NUM; i++) { 510 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent); 511 } 512 } 513 break; 514 case OMX_StateWaitForResources: 515 ret = OMX_ErrorIncorrectStateTransition; 516 break; 517 default: 518 ret = OMX_ErrorIncorrectStateTransition; 519 break; 520 } 521 break; 522 case OMX_StatePause: 523 switch (currentState) { 524 case OMX_StateLoaded: 525 ret = OMX_ErrorIncorrectStateTransition; 526 break; 527 case OMX_StateIdle: 528 pExynosComponent->currentState = OMX_StatePause; 529 break; 530 case OMX_StateExecuting: 531 pExynosComponent->currentState = OMX_StatePause; 532 break; 533 case OMX_StateWaitForResources: 534 ret = OMX_ErrorIncorrectStateTransition; 535 break; 536 default: 537 ret = OMX_ErrorIncorrectStateTransition; 538 break; 539 } 540 break; 541 case OMX_StateWaitForResources: 542 switch (currentState) { 543 case OMX_StateLoaded: 544 ret = Exynos_OMX_In_WaitForResource(pOMXComponent); 545 pExynosComponent->currentState = OMX_StateWaitForResources; 546 break; 547 case OMX_StateIdle: 548 case OMX_StateExecuting: 549 case OMX_StatePause: 550 ret = OMX_ErrorIncorrectStateTransition; 551 break; 552 default: 553 ret = OMX_ErrorIncorrectStateTransition; 554 break; 555 } 556 break; 557 default: 558 ret = OMX_ErrorIncorrectStateTransition; 559 break; 560 } 561 562 EXIT: 563 if (ret == OMX_ErrorNone) { 564 if (pExynosComponent->pCallbacks != NULL) { 565 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 566 pExynosComponent->callbackData, 567 OMX_EventCmdComplete, OMX_CommandStateSet, 568 destState, NULL); 569 } 570 } else { 571 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d", __FUNCTION__, __LINE__); 572 if (pExynosComponent->pCallbacks != NULL) { 573 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 574 pExynosComponent->callbackData, 575 OMX_EventError, ret, 0, NULL); 576 } 577 } 578 FunctionOut(); 579 580 return ret; 581 } 582 583 static OMX_ERRORTYPE Exynos_OMX_MessageHandlerThread(OMX_PTR threadData) 584 { 585 OMX_ERRORTYPE ret = OMX_ErrorNone; 586 OMX_COMPONENTTYPE *pOMXComponent = NULL; 587 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 588 EXYNOS_OMX_MESSAGE *message = NULL; 589 OMX_U32 messageType = 0, portIndex = 0; 590 591 FunctionIn(); 592 593 if (threadData == NULL) { 594 ret = OMX_ErrorBadParameter; 595 goto EXIT; 596 } 597 598 pOMXComponent = (OMX_COMPONENTTYPE *)threadData; 599 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 600 if (ret != OMX_ErrorNone) { 601 goto EXIT; 602 } 603 604 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 605 606 while (pExynosComponent->bExitMessageHandlerThread == OMX_FALSE) { 607 Exynos_OSAL_SemaphoreWait(pExynosComponent->msgSemaphoreHandle); 608 message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosComponent->messageQ); 609 if (message != NULL) { 610 messageType = message->messageType; 611 switch (messageType) { 612 case OMX_CommandStateSet: 613 ret = Exynos_OMX_ComponentStateSet(pOMXComponent, message->messageParam); 614 break; 615 case OMX_CommandFlush: 616 ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, message->messageParam, OMX_TRUE); 617 break; 618 case OMX_CommandPortDisable: 619 ret = Exynos_OMX_PortDisableProcess(pOMXComponent, message->messageParam); 620 break; 621 case OMX_CommandPortEnable: 622 ret = Exynos_OMX_PortEnableProcess(pOMXComponent, message->messageParam); 623 break; 624 case OMX_CommandMarkBuffer: 625 portIndex = message->messageParam; 626 pExynosComponent->pExynosPort[portIndex].markType.hMarkTargetComponent = ((OMX_MARKTYPE *)message->pCmdData)->hMarkTargetComponent; 627 pExynosComponent->pExynosPort[portIndex].markType.pMarkData = ((OMX_MARKTYPE *)message->pCmdData)->pMarkData; 628 break; 629 case (OMX_COMMANDTYPE)EXYNOS_OMX_CommandComponentDeInit: 630 pExynosComponent->bExitMessageHandlerThread = OMX_TRUE; 631 break; 632 default: 633 break; 634 } 635 Exynos_OSAL_Free(message); 636 message = NULL; 637 } 638 } 639 640 Exynos_OSAL_ThreadExit(NULL); 641 642 EXIT: 643 FunctionOut(); 644 645 return ret; 646 } 647 648 static OMX_ERRORTYPE Exynos_StateSet(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) 649 { 650 OMX_U32 destState = nParam; 651 OMX_U32 i = 0; 652 653 if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateLoaded)) { 654 pExynosComponent->transientState = EXYNOS_OMX_TransStateLoadedToIdle; 655 for(i = 0; i < pExynosComponent->portParam.nPorts; i++) { 656 pExynosComponent->pExynosPort[i].portState = OMX_StateIdle; 657 } 658 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle"); 659 } else if ((destState == OMX_StateLoaded) && (pExynosComponent->currentState == OMX_StateIdle)) { 660 pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToLoaded; 661 for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { 662 pExynosComponent->pExynosPort[i].portState = OMX_StateLoaded; 663 } 664 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateLoaded"); 665 } else if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateExecuting)) { 666 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 667 668 pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]); 669 if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) && 670 (pExynosPort->portState == OMX_StateIdle)) { 671 pExynosPort->exceptionFlag = INVALID_STATE; 672 Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); 673 } 674 675 pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]); 676 if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) && 677 (pExynosPort->portState == OMX_StateIdle)) { 678 pExynosPort->exceptionFlag = INVALID_STATE; 679 Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); 680 } 681 682 pExynosComponent->transientState = EXYNOS_OMX_TransStateExecutingToIdle; 683 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle"); 684 } else if ((destState == OMX_StateExecuting) && (pExynosComponent->currentState == OMX_StateIdle)) { 685 pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToExecuting; 686 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateExecuting"); 687 } else if (destState == OMX_StateInvalid) { 688 for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { 689 pExynosComponent->pExynosPort[i].portState = OMX_StateInvalid; 690 } 691 } 692 693 return OMX_ErrorNone; 694 } 695 696 static OMX_ERRORTYPE Exynos_SetPortFlush(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) 697 { 698 OMX_ERRORTYPE ret = OMX_ErrorNone; 699 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 700 OMX_S32 portIndex = nParam; 701 OMX_U16 i = 0, cnt = 0, index = 0; 702 703 704 if ((pExynosComponent->currentState == OMX_StateExecuting) || 705 (pExynosComponent->currentState == OMX_StatePause)) { 706 if ((portIndex != ALL_PORT_INDEX) && 707 ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) { 708 ret = OMX_ErrorBadPortIndex; 709 goto EXIT; 710 } 711 712 /********************* 713 * need flush event set ????? 714 **********************/ 715 cnt = (portIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; 716 for (i = 0; i < cnt; i++) { 717 if (portIndex == ALL_PORT_INDEX) 718 index = i; 719 else 720 index = portIndex; 721 pExynosComponent->pExynosPort[index].bIsPortFlushed = OMX_TRUE; 722 } 723 } else { 724 ret = OMX_ErrorIncorrectStateOperation; 725 goto EXIT; 726 } 727 ret = OMX_ErrorNone; 728 729 EXIT: 730 return ret; 731 } 732 733 static OMX_ERRORTYPE Exynos_SetPortEnable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) 734 { 735 OMX_ERRORTYPE ret = OMX_ErrorNone; 736 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 737 OMX_S32 portIndex = nParam; 738 OMX_U16 i = 0, cnt = 0; 739 740 FunctionIn(); 741 742 if ((portIndex != ALL_PORT_INDEX) && 743 ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) { 744 ret = OMX_ErrorBadPortIndex; 745 goto EXIT; 746 } 747 748 if (portIndex == ALL_PORT_INDEX) { 749 for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { 750 pExynosPort = &pExynosComponent->pExynosPort[i]; 751 if (CHECK_PORT_ENABLED(pExynosPort)) { 752 ret = OMX_ErrorIncorrectStateOperation; 753 goto EXIT; 754 } else { 755 pExynosPort->portState = OMX_StateIdle; 756 } 757 } 758 } else { 759 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 760 if (CHECK_PORT_ENABLED(pExynosPort)) { 761 ret = OMX_ErrorIncorrectStateOperation; 762 goto EXIT; 763 } else { 764 pExynosPort->portState = OMX_StateIdle; 765 } 766 } 767 ret = OMX_ErrorNone; 768 769 EXIT: 770 FunctionOut(); 771 772 return ret; 773 774 } 775 776 static OMX_ERRORTYPE Exynos_SetPortDisable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) 777 { 778 OMX_ERRORTYPE ret = OMX_ErrorNone; 779 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 780 OMX_S32 portIndex = nParam; 781 OMX_U16 i = 0, cnt = 0; 782 783 FunctionIn(); 784 785 if ((portIndex != ALL_PORT_INDEX) && 786 ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) { 787 ret = OMX_ErrorBadPortIndex; 788 goto EXIT; 789 } 790 791 if (portIndex == ALL_PORT_INDEX) { 792 for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { 793 pExynosPort = &pExynosComponent->pExynosPort[i]; 794 if (!CHECK_PORT_ENABLED(pExynosPort)) { 795 ret = OMX_ErrorIncorrectStateOperation; 796 goto EXIT; 797 } 798 pExynosPort->portState = OMX_StateLoaded; 799 pExynosPort->bIsPortDisabled = OMX_TRUE; 800 } 801 } else { 802 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 803 pExynosPort->portState = OMX_StateLoaded; 804 pExynosPort->bIsPortDisabled = OMX_TRUE; 805 } 806 ret = OMX_ErrorNone; 807 808 EXIT: 809 FunctionOut(); 810 811 return ret; 812 } 813 814 static OMX_ERRORTYPE Exynos_SetMarkBuffer(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) 815 { 816 OMX_ERRORTYPE ret = OMX_ErrorNone; 817 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 818 OMX_U32 portIndex = nParam; 819 OMX_U16 i = 0, cnt = 0; 820 821 822 if (nParam >= pExynosComponent->portParam.nPorts) { 823 ret = OMX_ErrorBadPortIndex; 824 goto EXIT; 825 } 826 827 if ((pExynosComponent->currentState == OMX_StateExecuting) || 828 (pExynosComponent->currentState == OMX_StatePause)) { 829 ret = OMX_ErrorNone; 830 } else { 831 ret = OMX_ErrorIncorrectStateOperation; 832 } 833 834 EXIT: 835 return ret; 836 } 837 838 static OMX_ERRORTYPE Exynos_OMX_CommandQueue( 839 EXYNOS_OMX_BASECOMPONENT *pExynosComponent, 840 OMX_COMMANDTYPE Cmd, 841 OMX_U32 nParam, 842 OMX_PTR pCmdData) 843 { 844 OMX_ERRORTYPE ret = OMX_ErrorNone; 845 EXYNOS_OMX_MESSAGE *command = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE)); 846 847 if (command == NULL) { 848 ret = OMX_ErrorInsufficientResources; 849 goto EXIT; 850 } 851 command->messageType = (OMX_U32)Cmd; 852 command->messageParam = nParam; 853 command->pCmdData = pCmdData; 854 855 ret = Exynos_OSAL_Queue(&pExynosComponent->messageQ, (void *)command); 856 if (ret != 0) { 857 ret = OMX_ErrorUndefined; 858 goto EXIT; 859 } 860 ret = Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle); 861 862 EXIT: 863 return ret; 864 } 865 866 OMX_ERRORTYPE Exynos_OMX_SendCommand( 867 OMX_IN OMX_HANDLETYPE hComponent, 868 OMX_IN OMX_COMMANDTYPE Cmd, 869 OMX_IN OMX_U32 nParam, 870 OMX_IN OMX_PTR pCmdData) 871 { 872 OMX_ERRORTYPE ret = OMX_ErrorNone; 873 OMX_COMPONENTTYPE *pOMXComponent = NULL; 874 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 875 EXYNOS_OMX_MESSAGE *message = NULL; 876 877 FunctionIn(); 878 879 if (hComponent == NULL) { 880 ret = OMX_ErrorBadParameter; 881 goto EXIT; 882 } 883 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 884 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 885 if (ret != OMX_ErrorNone) { 886 goto EXIT; 887 } 888 889 if (pOMXComponent->pComponentPrivate == NULL) { 890 ret = OMX_ErrorBadParameter; 891 goto EXIT; 892 } 893 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 894 895 if (pExynosComponent->currentState == OMX_StateInvalid) { 896 ret = OMX_ErrorInvalidState; 897 goto EXIT; 898 } 899 900 switch (Cmd) { 901 case OMX_CommandStateSet : 902 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandStateSet"); 903 Exynos_StateSet(pExynosComponent, nParam); 904 break; 905 case OMX_CommandFlush : 906 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandFlush"); 907 ret = Exynos_SetPortFlush(pExynosComponent, nParam); 908 if (ret != OMX_ErrorNone) 909 goto EXIT; 910 break; 911 case OMX_CommandPortDisable : 912 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortDisable"); 913 ret = Exynos_SetPortDisable(pExynosComponent, nParam); 914 if (ret != OMX_ErrorNone) 915 goto EXIT; 916 break; 917 case OMX_CommandPortEnable : 918 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortEnable"); 919 ret = Exynos_SetPortEnable(pExynosComponent, nParam); 920 if (ret != OMX_ErrorNone) 921 goto EXIT; 922 break; 923 case OMX_CommandMarkBuffer : 924 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandMarkBuffer"); 925 ret = Exynos_SetMarkBuffer(pExynosComponent, nParam); 926 if (ret != OMX_ErrorNone) 927 goto EXIT; 928 break; 929 default: 930 break; 931 } 932 933 ret = Exynos_OMX_CommandQueue(pExynosComponent, Cmd, nParam, pCmdData); 934 935 EXIT: 936 FunctionOut(); 937 938 return ret; 939 } 940 941 OMX_ERRORTYPE Exynos_OMX_GetParameter( 942 OMX_IN OMX_HANDLETYPE hComponent, 943 OMX_IN OMX_INDEXTYPE nParamIndex, 944 OMX_INOUT OMX_PTR ComponentParameterStructure) 945 { 946 OMX_ERRORTYPE ret = OMX_ErrorNone; 947 OMX_COMPONENTTYPE *pOMXComponent = NULL; 948 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 949 950 FunctionIn(); 951 952 if (hComponent == NULL) { 953 ret = OMX_ErrorBadParameter; 954 goto EXIT; 955 } 956 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 957 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 958 if (ret != OMX_ErrorNone) { 959 goto EXIT; 960 } 961 962 if (pOMXComponent->pComponentPrivate == NULL) { 963 ret = OMX_ErrorBadParameter; 964 goto EXIT; 965 } 966 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 967 968 if (ComponentParameterStructure == NULL) { 969 ret = OMX_ErrorBadParameter; 970 goto EXIT; 971 } 972 if (pExynosComponent->currentState == OMX_StateInvalid) { 973 ret = OMX_ErrorInvalidState; 974 goto EXIT; 975 } 976 977 switch (nParamIndex) { 978 case OMX_IndexParamAudioInit: 979 case OMX_IndexParamVideoInit: 980 case OMX_IndexParamImageInit: 981 case OMX_IndexParamOtherInit: 982 { 983 OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; 984 ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); 985 if (ret != OMX_ErrorNone) { 986 goto EXIT; 987 } 988 portParam->nPorts = 0; 989 portParam->nStartPortNumber = 0; 990 } 991 break; 992 case OMX_IndexParamPortDefinition: 993 { 994 OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; 995 OMX_U32 portIndex = portDefinition->nPortIndex; 996 EXYNOS_OMX_BASEPORT *pExynosPort; 997 998 if (portIndex >= pExynosComponent->portParam.nPorts) { 999 ret = OMX_ErrorBadPortIndex; 1000 goto EXIT; 1001 } 1002 ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); 1003 if (ret != OMX_ErrorNone) { 1004 goto EXIT; 1005 } 1006 1007 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 1008 Exynos_OSAL_Memcpy(portDefinition, &pExynosPort->portDefinition, portDefinition->nSize); 1009 } 1010 break; 1011 case OMX_IndexParamPriorityMgmt: 1012 { 1013 OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; 1014 1015 ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); 1016 if (ret != OMX_ErrorNone) { 1017 goto EXIT; 1018 } 1019 1020 compPriority->nGroupID = pExynosComponent->compPriority.nGroupID; 1021 compPriority->nGroupPriority = pExynosComponent->compPriority.nGroupPriority; 1022 } 1023 break; 1024 1025 case OMX_IndexParamCompBufferSupplier: 1026 { 1027 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; 1028 OMX_U32 portIndex = bufferSupplier->nPortIndex; 1029 EXYNOS_OMX_BASEPORT *pExynosPort; 1030 1031 if ((pExynosComponent->currentState == OMX_StateLoaded) || 1032 (pExynosComponent->currentState == OMX_StateWaitForResources)) { 1033 if (portIndex >= pExynosComponent->portParam.nPorts) { 1034 ret = OMX_ErrorBadPortIndex; 1035 goto EXIT; 1036 } 1037 ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); 1038 if (ret != OMX_ErrorNone) { 1039 goto EXIT; 1040 } 1041 1042 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 1043 1044 1045 if (pExynosPort->portDefinition.eDir == OMX_DirInput) { 1046 if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 1047 bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput; 1048 } else if (CHECK_PORT_TUNNELED(pExynosPort)) { 1049 bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; 1050 } else { 1051 bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified; 1052 } 1053 } else { 1054 if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 1055 bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; 1056 } else if (CHECK_PORT_TUNNELED(pExynosPort)) { 1057 bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput; 1058 } else { 1059 bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified; 1060 } 1061 } 1062 } 1063 else 1064 { 1065 ret = OMX_ErrorIncorrectStateOperation; 1066 goto EXIT; 1067 } 1068 } 1069 break; 1070 default: 1071 { 1072 ret = OMX_ErrorUnsupportedIndex; 1073 goto EXIT; 1074 } 1075 break; 1076 } 1077 1078 ret = OMX_ErrorNone; 1079 1080 EXIT: 1081 1082 FunctionOut(); 1083 1084 return ret; 1085 } 1086 1087 OMX_ERRORTYPE Exynos_OMX_SetParameter( 1088 OMX_IN OMX_HANDLETYPE hComponent, 1089 OMX_IN OMX_INDEXTYPE nIndex, 1090 OMX_IN OMX_PTR ComponentParameterStructure) 1091 { 1092 OMX_ERRORTYPE ret = OMX_ErrorNone; 1093 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1094 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1095 1096 FunctionIn(); 1097 1098 if (hComponent == NULL) { 1099 ret = OMX_ErrorBadParameter; 1100 goto EXIT; 1101 } 1102 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1103 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1104 if (ret != OMX_ErrorNone) { 1105 goto EXIT; 1106 } 1107 1108 if (pOMXComponent->pComponentPrivate == NULL) { 1109 ret = OMX_ErrorBadParameter; 1110 goto EXIT; 1111 } 1112 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1113 1114 if (ComponentParameterStructure == NULL) { 1115 ret = OMX_ErrorBadParameter; 1116 goto EXIT; 1117 } 1118 if (pExynosComponent->currentState == OMX_StateInvalid) { 1119 ret = OMX_ErrorInvalidState; 1120 goto EXIT; 1121 } 1122 1123 switch (nIndex) { 1124 case OMX_IndexParamAudioInit: 1125 case OMX_IndexParamVideoInit: 1126 case OMX_IndexParamImageInit: 1127 case OMX_IndexParamOtherInit: 1128 { 1129 OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; 1130 ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); 1131 if (ret != OMX_ErrorNone) { 1132 goto EXIT; 1133 } 1134 1135 if ((pExynosComponent->currentState != OMX_StateLoaded) && 1136 (pExynosComponent->currentState != OMX_StateWaitForResources)) { 1137 ret = OMX_ErrorIncorrectStateOperation; 1138 goto EXIT; 1139 } 1140 ret = OMX_ErrorUndefined; 1141 /* Exynos_OSAL_Memcpy(&pExynosComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */ 1142 } 1143 break; 1144 case OMX_IndexParamPortDefinition: 1145 { 1146 OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; 1147 OMX_U32 portIndex = portDefinition->nPortIndex; 1148 EXYNOS_OMX_BASEPORT *pExynosPort; 1149 1150 if (portIndex >= pExynosComponent->portParam.nPorts) { 1151 ret = OMX_ErrorBadPortIndex; 1152 goto EXIT; 1153 } 1154 ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); 1155 if (ret != OMX_ErrorNone) { 1156 goto EXIT; 1157 } 1158 1159 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 1160 1161 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { 1162 if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { 1163 ret = OMX_ErrorIncorrectStateOperation; 1164 goto EXIT; 1165 } 1166 } 1167 if (portDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) { 1168 ret = OMX_ErrorBadParameter; 1169 goto EXIT; 1170 } 1171 1172 Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, portDefinition, portDefinition->nSize); 1173 } 1174 break; 1175 case OMX_IndexParamPriorityMgmt: 1176 { 1177 OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; 1178 1179 if ((pExynosComponent->currentState != OMX_StateLoaded) && 1180 (pExynosComponent->currentState != OMX_StateWaitForResources)) { 1181 ret = OMX_ErrorIncorrectStateOperation; 1182 goto EXIT; 1183 } 1184 1185 ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); 1186 if (ret != OMX_ErrorNone) { 1187 goto EXIT; 1188 } 1189 1190 pExynosComponent->compPriority.nGroupID = compPriority->nGroupID; 1191 pExynosComponent->compPriority.nGroupPriority = compPriority->nGroupPriority; 1192 } 1193 break; 1194 case OMX_IndexParamCompBufferSupplier: 1195 { 1196 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; 1197 OMX_U32 portIndex = bufferSupplier->nPortIndex; 1198 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 1199 1200 1201 if (portIndex >= pExynosComponent->portParam.nPorts) { 1202 ret = OMX_ErrorBadPortIndex; 1203 goto EXIT; 1204 } 1205 ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); 1206 if (ret != OMX_ErrorNone) { 1207 goto EXIT; 1208 } 1209 1210 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 1211 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { 1212 if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { 1213 ret = OMX_ErrorIncorrectStateOperation; 1214 goto EXIT; 1215 } 1216 } 1217 1218 if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) { 1219 ret = OMX_ErrorNone; 1220 goto EXIT; 1221 } 1222 if (CHECK_PORT_TUNNELED(pExynosPort) == 0) { 1223 ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/ 1224 goto EXIT; 1225 } 1226 1227 if (pExynosPort->portDefinition.eDir == OMX_DirInput) { 1228 if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { 1229 /* 1230 if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 1231 ret = OMX_ErrorNone; 1232 } 1233 */ 1234 pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER; 1235 bufferSupplier->nPortIndex = pExynosPort->tunneledPort; 1236 ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); 1237 goto EXIT; 1238 } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { 1239 ret = OMX_ErrorNone; 1240 if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 1241 pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER; 1242 bufferSupplier->nPortIndex = pExynosPort->tunneledPort; 1243 ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); 1244 } 1245 goto EXIT; 1246 } 1247 } else if (pExynosPort->portDefinition.eDir == OMX_DirOutput) { 1248 if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { 1249 ret = OMX_ErrorNone; 1250 if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 1251 pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER; 1252 ret = OMX_ErrorNone; 1253 } 1254 goto EXIT; 1255 } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { 1256 /* 1257 if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { 1258 ret = OMX_ErrorNone; 1259 } 1260 */ 1261 pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER; 1262 ret = OMX_ErrorNone; 1263 goto EXIT; 1264 } 1265 } 1266 } 1267 break; 1268 default: 1269 { 1270 ret = OMX_ErrorUnsupportedIndex; 1271 goto EXIT; 1272 } 1273 break; 1274 } 1275 1276 ret = OMX_ErrorNone; 1277 1278 EXIT: 1279 1280 FunctionOut(); 1281 1282 return ret; 1283 } 1284 1285 OMX_ERRORTYPE Exynos_OMX_GetConfig( 1286 OMX_IN OMX_HANDLETYPE hComponent, 1287 OMX_IN OMX_INDEXTYPE nIndex, 1288 OMX_INOUT OMX_PTR pComponentConfigStructure) 1289 { 1290 OMX_ERRORTYPE ret = OMX_ErrorNone; 1291 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1292 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1293 1294 FunctionIn(); 1295 1296 if (hComponent == NULL) { 1297 ret = OMX_ErrorBadParameter; 1298 goto EXIT; 1299 } 1300 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1301 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1302 if (ret != OMX_ErrorNone) { 1303 goto EXIT; 1304 } 1305 1306 if (pOMXComponent->pComponentPrivate == NULL) { 1307 ret = OMX_ErrorBadParameter; 1308 goto EXIT; 1309 } 1310 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1311 1312 if (pComponentConfigStructure == NULL) { 1313 ret = OMX_ErrorBadParameter; 1314 goto EXIT; 1315 } 1316 if (pExynosComponent->currentState == OMX_StateInvalid) { 1317 ret = OMX_ErrorInvalidState; 1318 goto EXIT; 1319 } 1320 1321 switch (nIndex) { 1322 default: 1323 ret = OMX_ErrorUnsupportedIndex; 1324 break; 1325 } 1326 1327 EXIT: 1328 FunctionOut(); 1329 1330 return ret; 1331 } 1332 1333 OMX_ERRORTYPE Exynos_OMX_SetConfig( 1334 OMX_IN OMX_HANDLETYPE hComponent, 1335 OMX_IN OMX_INDEXTYPE nIndex, 1336 OMX_IN OMX_PTR pComponentConfigStructure) 1337 { 1338 OMX_ERRORTYPE ret = OMX_ErrorNone; 1339 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1340 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1341 1342 FunctionIn(); 1343 1344 if (hComponent == NULL) { 1345 ret = OMX_ErrorBadParameter; 1346 goto EXIT; 1347 } 1348 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1349 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1350 if (ret != OMX_ErrorNone) { 1351 goto EXIT; 1352 } 1353 1354 if (pOMXComponent->pComponentPrivate == NULL) { 1355 ret = OMX_ErrorBadParameter; 1356 goto EXIT; 1357 } 1358 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1359 1360 if (pComponentConfigStructure == NULL) { 1361 ret = OMX_ErrorBadParameter; 1362 goto EXIT; 1363 } 1364 if (pExynosComponent->currentState == OMX_StateInvalid) { 1365 ret = OMX_ErrorInvalidState; 1366 goto EXIT; 1367 } 1368 1369 switch (nIndex) { 1370 default: 1371 ret = OMX_ErrorUnsupportedIndex; 1372 break; 1373 } 1374 1375 EXIT: 1376 FunctionOut(); 1377 1378 return ret; 1379 } 1380 1381 OMX_ERRORTYPE Exynos_OMX_GetExtensionIndex( 1382 OMX_IN OMX_HANDLETYPE hComponent, 1383 OMX_IN OMX_STRING cParameterName, 1384 OMX_OUT OMX_INDEXTYPE *pIndexType) 1385 { 1386 OMX_ERRORTYPE ret = OMX_ErrorNone; 1387 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1388 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1389 1390 FunctionIn(); 1391 1392 if (hComponent == NULL) { 1393 ret = OMX_ErrorBadParameter; 1394 goto EXIT; 1395 } 1396 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1397 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1398 if (ret != OMX_ErrorNone) { 1399 goto EXIT; 1400 } 1401 1402 if (pOMXComponent->pComponentPrivate == NULL) { 1403 ret = OMX_ErrorBadParameter; 1404 goto EXIT; 1405 } 1406 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1407 1408 if ((cParameterName == NULL) || (pIndexType == NULL)) { 1409 ret = OMX_ErrorBadParameter; 1410 goto EXIT; 1411 } 1412 if (pExynosComponent->currentState == OMX_StateInvalid) { 1413 ret = OMX_ErrorInvalidState; 1414 goto EXIT; 1415 } 1416 1417 ret = OMX_ErrorBadParameter; 1418 1419 EXIT: 1420 FunctionOut(); 1421 1422 return ret; 1423 } 1424 1425 OMX_ERRORTYPE Exynos_OMX_SetCallbacks ( 1426 OMX_IN OMX_HANDLETYPE hComponent, 1427 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 1428 OMX_IN OMX_PTR pAppData) 1429 { 1430 OMX_ERRORTYPE ret = OMX_ErrorNone; 1431 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1432 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1433 1434 FunctionIn(); 1435 1436 if (hComponent == NULL) { 1437 ret = OMX_ErrorBadParameter; 1438 goto EXIT; 1439 } 1440 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1441 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1442 if (ret != OMX_ErrorNone) { 1443 goto EXIT; 1444 } 1445 1446 if (pOMXComponent->pComponentPrivate == NULL) { 1447 ret = OMX_ErrorBadParameter; 1448 goto EXIT; 1449 } 1450 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1451 1452 if (pCallbacks == NULL) { 1453 ret = OMX_ErrorBadParameter; 1454 goto EXIT; 1455 } 1456 if (pExynosComponent->currentState == OMX_StateInvalid) { 1457 ret = OMX_ErrorInvalidState; 1458 goto EXIT; 1459 } 1460 if (pExynosComponent->currentState != OMX_StateLoaded) { 1461 ret = OMX_ErrorIncorrectStateOperation; 1462 goto EXIT; 1463 } 1464 1465 pExynosComponent->pCallbacks = pCallbacks; 1466 pExynosComponent->callbackData = pAppData; 1467 1468 ret = OMX_ErrorNone; 1469 1470 EXIT: 1471 FunctionOut(); 1472 1473 return ret; 1474 } 1475 1476 OMX_ERRORTYPE Exynos_OMX_UseEGLImage( 1477 OMX_IN OMX_HANDLETYPE hComponent, 1478 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 1479 OMX_IN OMX_U32 nPortIndex, 1480 OMX_IN OMX_PTR pAppPrivate, 1481 OMX_IN void *eglImage) 1482 { 1483 return OMX_ErrorNotImplemented; 1484 } 1485 1486 OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor( 1487 OMX_IN OMX_HANDLETYPE hComponent) 1488 { 1489 OMX_ERRORTYPE ret = OMX_ErrorNone; 1490 OMX_COMPONENTTYPE *pOMXComponent; 1491 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1492 1493 FunctionIn(); 1494 1495 if (hComponent == NULL) { 1496 ret = OMX_ErrorBadParameter; 1497 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); 1498 goto EXIT; 1499 } 1500 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1501 pExynosComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASECOMPONENT)); 1502 if (pExynosComponent == NULL) { 1503 ret = OMX_ErrorInsufficientResources; 1504 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1505 goto EXIT; 1506 } 1507 Exynos_OSAL_Memset(pExynosComponent, 0, sizeof(EXYNOS_OMX_BASECOMPONENT)); 1508 pOMXComponent->pComponentPrivate = (OMX_PTR)pExynosComponent; 1509 1510 ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->msgSemaphoreHandle); 1511 if (ret != OMX_ErrorNone) { 1512 ret = OMX_ErrorInsufficientResources; 1513 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1514 goto EXIT; 1515 } 1516 ret = Exynos_OSAL_MutexCreate(&pExynosComponent->compMutex); 1517 if (ret != OMX_ErrorNone) { 1518 ret = OMX_ErrorInsufficientResources; 1519 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1520 goto EXIT; 1521 } 1522 ret = Exynos_OSAL_SignalCreate(&pExynosComponent->abendStateEvent); 1523 if (ret != OMX_ErrorNone) { 1524 ret = OMX_ErrorInsufficientResources; 1525 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1526 goto EXIT; 1527 } 1528 1529 pExynosComponent->bExitMessageHandlerThread = OMX_FALSE; 1530 Exynos_OSAL_QueueCreate(&pExynosComponent->messageQ, MAX_QUEUE_ELEMENTS); 1531 ret = Exynos_OSAL_ThreadCreate(&pExynosComponent->hMessageHandler, Exynos_OMX_MessageHandlerThread, pOMXComponent); 1532 if (ret != OMX_ErrorNone) { 1533 ret = OMX_ErrorInsufficientResources; 1534 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1535 goto EXIT; 1536 } 1537 1538 pExynosComponent->bMultiThreadProcess = OMX_FALSE; 1539 1540 pOMXComponent->GetComponentVersion = &Exynos_OMX_GetComponentVersion; 1541 pOMXComponent->SendCommand = &Exynos_OMX_SendCommand; 1542 pOMXComponent->GetState = &Exynos_OMX_GetState; 1543 pOMXComponent->SetCallbacks = &Exynos_OMX_SetCallbacks; 1544 pOMXComponent->UseEGLImage = &Exynos_OMX_UseEGLImage; 1545 1546 EXIT: 1547 FunctionOut(); 1548 1549 return ret; 1550 } 1551 1552 OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor( 1553 OMX_IN OMX_HANDLETYPE hComponent) 1554 { 1555 OMX_ERRORTYPE ret = OMX_ErrorNone; 1556 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1557 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1558 OMX_S32 semaValue = 0; 1559 1560 FunctionIn(); 1561 1562 if (hComponent == NULL) { 1563 ret = OMX_ErrorBadParameter; 1564 goto EXIT; 1565 } 1566 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1567 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1568 if (ret != OMX_ErrorNone) { 1569 goto EXIT; 1570 } 1571 1572 if (pOMXComponent->pComponentPrivate == NULL) { 1573 ret = OMX_ErrorBadParameter; 1574 goto EXIT; 1575 } 1576 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1577 1578 Exynos_OMX_CommandQueue(pExynosComponent, EXYNOS_OMX_CommandComponentDeInit, 0, NULL); 1579 Exynos_OSAL_SleepMillisec(0); 1580 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->msgSemaphoreHandle, &semaValue); 1581 if (semaValue == 0) 1582 Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle); 1583 Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle); 1584 1585 Exynos_OSAL_ThreadTerminate(pExynosComponent->hMessageHandler); 1586 pExynosComponent->hMessageHandler = NULL; 1587 1588 Exynos_OSAL_SignalTerminate(pExynosComponent->abendStateEvent); 1589 pExynosComponent->abendStateEvent = NULL; 1590 Exynos_OSAL_MutexTerminate(pExynosComponent->compMutex); 1591 pExynosComponent->compMutex = NULL; 1592 Exynos_OSAL_SemaphoreTerminate(pExynosComponent->msgSemaphoreHandle); 1593 pExynosComponent->msgSemaphoreHandle = NULL; 1594 Exynos_OSAL_QueueTerminate(&pExynosComponent->messageQ); 1595 1596 Exynos_OSAL_Free(pExynosComponent); 1597 pExynosComponent = NULL; 1598 1599 ret = OMX_ErrorNone; 1600 EXIT: 1601 FunctionOut(); 1602 1603 return ret; 1604 } 1605 1606 1607