Files
hardware_samsung_slsi-linar…/openmax/component/common/Exynos_OMX_Basecomponent.c
Sam Protsenko d70d919c01 Add original Samsung hardware projects
Change-Id: I79380bc91acf57ca5f3e56fb64af76f4c45f6566
Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>
2023-09-09 08:33:16 +02:00

2558 lines
88 KiB
C

/*
*
* Copyright 2012 Samsung Electronics S.LSI Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @file Exynos_OMX_Basecomponent.c
* @brief
* @author SeungBeom Kim (sbcrux.kim@samsung.com)
* Taehwan Kim (t_h.kim@samsung.com)
* @version 2.5.0
* @history
* 2012.02.20 : Create
* 2017.08.03 : Change event handling
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "Exynos_OSAL_Event.h"
#include "Exynos_OSAL_Thread.h"
#include "Exynos_OSAL_ETC.h"
#include "Exynos_OSAL_Semaphore.h"
#include "Exynos_OSAL_Mutex.h"
#include "Exynos_OMX_Baseport.h"
#include "Exynos_OMX_Basecomponent.h"
#include "Exynos_OMX_Resourcemanager.h"
#include "Exynos_OMX_Macros.h"
#undef EXYNOS_LOG_TAG
#define EXYNOS_LOG_TAG "EXYNOS_BASE_COMP"
//#define EXYNOS_LOG_OFF
#include "Exynos_OSAL_Log.h"
static OMX_ERRORTYPE Exynos_CheckStateSet(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
static OMX_ERRORTYPE Exynos_CheckPortFlush(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
static OMX_ERRORTYPE Exynos_CheckPortDisable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
static OMX_ERRORTYPE Exynos_CheckPortEnable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
static OMX_ERRORTYPE Exynos_CheckMarkBuffer(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
static OMX_ERRORTYPE Exynos_OMX_CommandQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_COMMANDTYPE Cmd, OMX_U32 nParam, OMX_PTR pCmdData);
/* Change CHECK_SIZE_VERSION Macro */
OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_VERSIONTYPE *version = NULL;
if (header == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
version = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32));
if (*((OMX_U32*)header) != size) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
Exynos_OSAL_Log(EXYNOS_LOG_FUNC_TRACE, "[%s] nVersionMajor:%d, nVersionMinor:%d", __FUNCTION__, version->s.nVersionMajor, version->s.nVersionMinor);
if ((version->s.nVersionMajor != VERSIONMAJOR_NUMBER) ||
(version->s.nVersionMinor > VERSIONMINOR_NUMBER)) {
ret = OMX_ErrorVersionMismatch;
goto EXIT;
}
ret = OMX_ErrorNone;
EXIT:
return ret;
}
/* OMX Interface */
OMX_ERRORTYPE Exynos_OMX_GetComponentVersion(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STRING pComponentName,
OMX_OUT OMX_VERSIONTYPE *pComponentVersion,
OMX_OUT OMX_VERSIONTYPE *pSpecVersion,
OMX_OUT OMX_UUIDTYPE *pComponentUUID)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
unsigned long compUUID[3];
FunctionIn();
/* check parameters */
if (hComponent == NULL ||
pComponentName == NULL || pComponentVersion == NULL ||
pSpecVersion == NULL || pComponentUUID == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
Exynos_OSAL_Strcpy(pComponentName, pExynosComponent->componentName);
Exynos_OSAL_Memcpy(pComponentVersion, &(pExynosComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
Exynos_OSAL_Memcpy(pSpecVersion, &(pExynosComponent->specVersion), sizeof(OMX_VERSIONTYPE));
/* Fill UUID with handle address, PID and UID.
* This should guarantee uiniqness */
compUUID[0] = (unsigned long)pOMXComponent;
compUUID[1] = (unsigned long)getpid();
compUUID[2] = (unsigned long)getuid();
Exynos_OSAL_Memcpy(*pComponentUUID, compUUID, 3 * sizeof(*compUUID));
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OMX_SendCommand(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_COMMANDTYPE Cmd,
OMX_IN OMX_U32 nParam,
OMX_IN OMX_PTR pCmdData)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if (hComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
switch (Cmd) {
case OMX_CommandStateSet :
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandStateSet(%s)",
pExynosComponent, __FUNCTION__, stateString(nParam));
ret = Exynos_CheckStateSet(pExynosComponent, nParam);
break;
case OMX_CommandFlush :
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandFlush(port:0x%x)",
pExynosComponent, __FUNCTION__, nParam);
ret = Exynos_CheckPortFlush(pExynosComponent, nParam);
break;
case OMX_CommandPortDisable :
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandPortDisable(port:0x%x)",
pExynosComponent, __FUNCTION__, nParam);
ret = Exynos_CheckPortDisable(pExynosComponent, nParam);
break;
case OMX_CommandPortEnable :
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandPortEnable(port:0x%x)",
pExynosComponent, __FUNCTION__, nParam);
ret = Exynos_CheckPortEnable(pExynosComponent, nParam);
break;
case OMX_CommandMarkBuffer :
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandMarkBuffer(0x%x)",
pExynosComponent, __FUNCTION__, nParam);
ret = Exynos_CheckMarkBuffer(pExynosComponent, nParam);
break;
default:
ret = OMX_ErrorBadParameter;
break;
}
if (ret == OMX_ErrorNone) {
ret = Exynos_OMX_CommandQueue(pExynosComponent, Cmd, nParam, pCmdData);
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OMX_CommandQueue()", pExynosComponent, __FUNCTION__);
goto EXIT;
}
/* wait for msg handler's ack except for MarkBuffer */
if (Cmd != OMX_CommandMarkBuffer)
Exynos_OSAL_SemaphoreWait(pExynosComponent->hSemaMsgProgress);
}
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OMX_GetState(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STATETYPE *pState)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if (hComponent == NULL || pState == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
*pState = pExynosComponent->currentState;
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OMX_SetCallbacks(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
OMX_IN OMX_PTR pAppData)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if ((hComponent == NULL) ||
(pCallbacks == NULL)) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
if (pExynosComponent->currentState != OMX_StateLoaded) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
pExynosComponent->pCallbacks = pCallbacks;
pExynosComponent->callbackData = pAppData;
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}
#ifdef EGL_IMAGE_SUPPORT
OMX_ERRORTYPE Exynos_OMX_UseEGLImage(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
OMX_IN OMX_U32 nPortIndex,
OMX_IN OMX_PTR pAppPrivate,
OMX_IN void *eglImage)
{
return OMX_ErrorNotImplemented;
}
#endif
static OMX_ERRORTYPE Exynos_CheckStateSet(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorUndefined;
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if (pExynosComponent->currentState == (OMX_STATETYPE)nParam) {
ret = OMX_ErrorSameState;
goto EXIT;
}
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
switch ((OMX_STATETYPE)nParam) {
case OMX_StateInvalid:
{
ret = OMX_ErrorNone;
}
break;
case OMX_StateLoaded:
{
if ((pExynosComponent->currentState != OMX_StateIdle) &&
(pExynosComponent->currentState != OMX_StateWaitForResources)) {
ret = OMX_ErrorIncorrectStateTransition;
goto EXIT;
}
ret = OMX_ErrorNone;
}
break;
case OMX_StateWaitForResources:
{
if (pExynosComponent->currentState != OMX_StateLoaded) {
ret = OMX_ErrorIncorrectStateTransition;
goto EXIT;
}
ret = OMX_ErrorNone;
}
break;
case OMX_StateIdle:
{
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorIncorrectStateTransition;
goto EXIT;
}
ret = OMX_ErrorNone;
}
break;
case OMX_StateExecuting:
{
if ((pExynosComponent->currentState != OMX_StateIdle) &&
(pExynosComponent->currentState != OMX_StatePause)) {
ret = OMX_ErrorIncorrectStateTransition;
goto EXIT;
}
ret = OMX_ErrorNone;
}
break;
case OMX_StatePause:
{
if ((pExynosComponent->currentState != OMX_StateIdle) &&
(pExynosComponent->currentState != OMX_StateExecuting)) {
ret = OMX_ErrorIncorrectStateTransition;
goto EXIT;
}
ret = OMX_ErrorNone;
}
break;
default:
ret = OMX_ErrorBadParameter;
break;
}
EXIT:
return ret;
}
static OMX_ERRORTYPE Exynos_CheckPortFlush(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorUndefined;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
OMX_U32 nPortIndex = nParam;
OMX_U32 i = 0;
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
(nPortIndex >= pExynosComponent->portParam.nPorts)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if ((pExynosComponent->currentState == OMX_StateExecuting) ||
(pExynosComponent->currentState == OMX_StatePause)) {
if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
(nPortIndex >= pExynosComponent->portParam.nPorts)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &pExynosComponent->pExynosPort[i];
if (!CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
}
} else {
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
if (!CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
}
ret = OMX_ErrorNone;
} else {
ret = OMX_ErrorIncorrectStateOperation;
}
EXIT:
return ret;
}
static OMX_ERRORTYPE Exynos_CheckPortDisable(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorUndefined;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
OMX_U32 nPortIndex = nParam;
OMX_U32 i = 0;
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
(nPortIndex >= pExynosComponent->portParam.nPorts)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &pExynosComponent->pExynosPort[i];
if (!CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
}
ret = OMX_ErrorNone;
} else {
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
if (!CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
ret = OMX_ErrorNone;
}
EXIT:
return ret;
}
static OMX_ERRORTYPE Exynos_CheckPortEnable(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorUndefined;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
OMX_U32 nPortIndex = nParam;
OMX_U32 i = 0;
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
(nPortIndex >= pExynosComponent->portParam.nPorts)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &pExynosComponent->pExynosPort[i];
if (CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
}
ret = OMX_ErrorNone;
} else {
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
if (CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
ret = OMX_ErrorNone;
}
EXIT:
return ret;
}
static OMX_ERRORTYPE Exynos_CheckMarkBuffer(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorUndefined;
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if (nParam >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if ((pExynosComponent->currentState == OMX_StateExecuting) ||
(pExynosComponent->currentState == OMX_StatePause)) {
ret = OMX_ErrorNone;
} else {
ret = OMX_ErrorIncorrectStateOperation;
}
EXIT:
return ret;
}
static OMX_ERRORTYPE Exynos_SetStateSet(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_U32 i = 0;
FunctionIn();
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
switch ((OMX_STATETYPE)nParam) {
case OMX_StateIdle:
{
/* Loaded to Idle */
if (pExynosComponent->currentState == OMX_StateLoaded) {
pExynosComponent->transientState = EXYNOS_OMX_TransStateLoadedToIdle;
for(i = 0; i < pExynosComponent->portParam.nPorts; i++)
pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateEnabling;
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateLoaded to OMX_StateIdle", pExynosComponent, __FUNCTION__);
ret = OMX_ErrorNone;
goto EXIT;
}
/* Executing to Idle */
if (pExynosComponent->currentState == OMX_StateExecuting) {
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
pExynosComponent->transientState = EXYNOS_OMX_TransStateExecutingToIdle;
pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) &&
(pExynosPort->portState == EXYNOS_OMX_PortStateEnabling)) {
pExynosPort->exceptionFlag = INVALID_STATE;
}
pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) &&
(pExynosPort->portState == EXYNOS_OMX_PortStateEnabling)) {
pExynosPort->exceptionFlag = INVALID_STATE;
}
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateExecuting to OMX_StateIdle", pExynosComponent, __FUNCTION__);
ret = OMX_ErrorNone;
goto EXIT;
}
/* Pause to Idle */
if (pExynosComponent->currentState == OMX_StatePause) {
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StatePause to OMX_StateIdle", pExynosComponent, __FUNCTION__);
ret = OMX_ErrorNone;
goto EXIT;
}
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
ret = OMX_ErrorNone;
}
break;
case OMX_StateExecuting:
{
/* Idle to Executing */
if (pExynosComponent->currentState == OMX_StateIdle) {
pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToExecuting;
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateIdle to OMX_StateExecuting", pExynosComponent, __FUNCTION__);
ret = OMX_ErrorNone;
goto EXIT;
}
/* Pause to Executing */
if (pExynosComponent->currentState == OMX_StatePause) {
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StatePause to OMX_StateIdle", pExynosComponent, __FUNCTION__);
ret = OMX_ErrorNone;
goto EXIT;
}
ret = OMX_ErrorBadParameter;
}
break;
case OMX_StateLoaded:
{
/* Idle to Loaded */
if (pExynosComponent->currentState == OMX_StateIdle) {
pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToLoaded;
for (i = 0; i < pExynosComponent->portParam.nPorts; i++)
pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateDisabling;
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateIdle to OMX_StateLoaded", pExynosComponent, __FUNCTION__);
}
}
break;
case OMX_StateInvalid:
{
for (i = 0; i < pExynosComponent->portParam.nPorts; i++)
pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateInvalid;
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s to OMX_StateInvalid",
pExynosComponent, __FUNCTION__, stateString(pExynosComponent->currentState));
}
break;
default:
Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s to %s", pExynosComponent, __FUNCTION__,
stateString(pExynosComponent->currentState), stateString(nParam));
break;
}
EXIT:
FunctionOut();
return ret;
}
static OMX_ERRORTYPE Exynos_SetPortFlush(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
OMX_U32 nPortIndex = nParam;
OMX_U32 i;
FunctionIn();
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if ((pExynosComponent->currentState == OMX_StateExecuting) ||
(pExynosComponent->currentState == OMX_StatePause)) {
if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
(nPortIndex >= pExynosComponent->portParam.nPorts)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &pExynosComponent->pExynosPort[i];
if (!CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
pExynosPort->portState = EXYNOS_OMX_PortStateFlushing;
}
} else {
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
if (!CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
pExynosPort->portState = EXYNOS_OMX_PortStateFlushing;
}
} else {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}
static OMX_ERRORTYPE Exynos_SetPortDisable(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
OMX_U32 nPortIndex = nParam;
OMX_U32 i = 0;
FunctionIn();
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
(nPortIndex >= pExynosComponent->portParam.nPorts)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &pExynosComponent->pExynosPort[i];
if (!CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
pExynosPort->portState = EXYNOS_OMX_PortStateDisabling;
}
} else {
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
if (!CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
pExynosPort->portState = EXYNOS_OMX_PortStateDisabling;
}
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}
static OMX_ERRORTYPE Exynos_SetPortEnable(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
OMX_U32 nPortIndex = nParam;
OMX_U32 i;
FunctionIn();
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
(nPortIndex >= pExynosComponent->portParam.nPorts)) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &pExynosComponent->pExynosPort[i];
if (CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
pExynosPort->portState = EXYNOS_OMX_PortStateEnabling;
}
} else {
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
if (CHECK_PORT_ENABLED(pExynosPort)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
pExynosPort->portState = EXYNOS_OMX_PortStateEnabling;
}
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}
static OMX_ERRORTYPE Exynos_SetMarkBuffer(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_U32 nParam)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
FunctionIn();
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if (nParam >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
if ((pExynosComponent->currentState == OMX_StateExecuting) ||
(pExynosComponent->currentState == OMX_StatePause)) {
ret = OMX_ErrorNone;
} else {
ret = OMX_ErrorIncorrectStateOperation;
}
EXIT:
FunctionOut();
return ret;
}
static OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(
OMX_COMPONENTTYPE *pOMXComponent,
OMX_U32 destState)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
OMX_STATETYPE currentState = OMX_StateLoaded;
int i;
FunctionIn();
if (pOMXComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorUndefined;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
currentState = pExynosComponent->currentState;
if (pExynosComponent->currentState == (OMX_STATETYPE)destState) {
ret = OMX_ErrorSameState;
goto EXIT;
}
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] current:(%s) dest:(%s)", pExynosComponent, __FUNCTION__,
stateString(currentState), stateString(destState));
switch ((OMX_STATETYPE)destState) {
case OMX_StateInvalid:
{
switch (currentState) {
case OMX_StateWaitForResources:
Exynos_OMX_Out_WaitForResource(pOMXComponent);
case OMX_StateIdle:
case OMX_StateExecuting:
case OMX_StatePause:
case OMX_StateLoaded:
pExynosComponent->currentState = OMX_StateInvalid;
ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent);
for (i = 0; i < ALL_PORT_NUM; i++) {
/* terminate mutex in way */
if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
} else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
}
/* terminate mutex for port */
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
pExynosComponent->pExynosPort[i].hPortMutex = NULL;
}
/* terminate signal about pause */
for (i = 0; i < ALL_PORT_NUM; i++) {
Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
pExynosComponent->pExynosPort[i].pauseEvent = NULL;
}
/* terminate sema for buffer handling on port */
for (i = 0; i < ALL_PORT_NUM; i++) {
Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
pExynosComponent->pExynosPort[i].bufferSemID = NULL;
}
//if (currentState != OMX_StateLoaded)
pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
ret = OMX_ErrorInvalidState;
if (pExynosComponent->abendState == OMX_TRUE)
goto NO_EVENT_EXIT;
break;
default:
ret = OMX_ErrorInvalidState;
break;
}
}
break;
case OMX_StateLoaded:
{
switch (currentState) {
case OMX_StateIdle:
for(i = 0; i < (int)pExynosComponent->portParam.nPorts; i++)
pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateDisabling;
ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent);
for (i = 0; i < ALL_PORT_NUM; i++) {
/* terminate mutex in way */
if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
} else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
}
/* terminate mutex for port */
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
pExynosComponent->pExynosPort[i].hPortMutex = NULL;
}
/* terminate signal about pause */
for (i = 0; i < ALL_PORT_NUM; i++) {
Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
pExynosComponent->pExynosPort[i].pauseEvent = NULL;
}
/* terminate sema for buffer handling on port */
for (i = 0; i < ALL_PORT_NUM; i++) {
Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
pExynosComponent->pExynosPort[i].bufferSemID = NULL;
}
pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
#ifdef TUNNELING_SUPPORT
for (i = 0; i < (pExynosComponent->portParam.nPorts); i++) {
pExynosPort = &(pExynosComponent->pExynosPort[i]);
if (CHECK_PORT_TUNNELED(pExynosPort) &&
CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
while (Exynos_OSAL_GetElemNum(&(pExynosPort->bufferQ)) > 0) {
EXYNOS_OMX_MESSAGE *pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
if (pMessage != NULL)
Exynos_OSAL_Free(pMessage);
}
ret = pExynosComponent->exynos_FreeTunnelBuffer(pExynosPort, i);
if (OMX_ErrorNone != ret)
goto EXIT;
}
}
#endif
/* if all buffers are freed, send an event */
if ((pExynosComponent->pExynosPort[INPUT_PORT_INDEX].assignedBufferNum <= 0) &&
(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].assignedBufferNum <= 0)) {
Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_LOAD_STATE, NULL);
}
goto NO_EVENT_EXIT;
case OMX_StateWaitForResources:
ret = Exynos_OMX_Out_WaitForResource(pOMXComponent);
pExynosComponent->currentState = OMX_StateLoaded;
break;
case OMX_StateExecuting:
case OMX_StatePause:
default:
ret = OMX_ErrorIncorrectStateTransition;
break;
}
}
break;
case OMX_StateIdle:
{
switch (currentState) {
case OMX_StateLoaded:
for (i = 0; i < (int)pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &(pExynosComponent->pExynosPort[i]);
pExynosPort->portState = EXYNOS_OMX_PortStateEnabling;
#ifdef TUNNELING_SUPPORT
if (CHECK_PORT_TUNNELED(pExynosPort) &&
CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) &&
CHECK_PORT_ENABLED(pExynosPort)) {
ret = pExynosComponent->exynos_AllocateTunnelBuffer(pExynosPort, i);
if (ret!=OMX_ErrorNone)
goto EXIT;
}
#endif
}
Exynos_OSAL_Get_Log_Property(); // For debuging, Function called when GetHandle function is success
ret = pExynosComponent->exynos_codec_componentInit(pOMXComponent);
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to exynos_codec_componentInit() (0x%x)", pExynosComponent, __FUNCTION__, ret);
#ifdef TUNNELING_SUPPORT
/*
* if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
*/
#endif
goto EXIT;
}
/* create sema for buffer handling on port */
for (i = 0; i < ALL_PORT_NUM; i++) {
ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->pExynosPort[i].bufferSemID);
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SemaphoreCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
ret = OMX_ErrorInsufficientResources;
goto FAIL_TO_IDLE;
}
}
/* create signal about pause */
for (i = 0; i < ALL_PORT_NUM; i++) {
ret = Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].pauseEvent);
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_SignalCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
ret = OMX_ErrorInsufficientResources;
goto FAIL_TO_IDLE;
}
}
for (i = 0; i < ALL_PORT_NUM; i++) {
/* create mutex in way */
if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
ret = OMX_ErrorInsufficientResources;
goto FAIL_TO_IDLE;
}
} else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
ret = OMX_ErrorInsufficientResources;
goto FAIL_TO_IDLE;
}
ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
ret = OMX_ErrorInsufficientResources;
goto FAIL_TO_IDLE;
}
}
/* create mutex for port */
ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].hPortMutex);
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
ret = OMX_ErrorInsufficientResources;
goto FAIL_TO_IDLE;
}
}
ret = pExynosComponent->exynos_BufferProcessCreate(pOMXComponent);
if (ret != OMX_ErrorNone) {
FAIL_TO_IDLE:
#ifdef TUNNELING_SUPPORT
/*
* if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
*/
#endif
for (i = 0; i < ALL_PORT_NUM; i++) {
/* terminate mutex in way */
if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
} else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
}
/* terminate mutex for port */
Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
pExynosComponent->pExynosPort[i].hPortMutex = NULL;
}
/* terminate signal about pause */
for (i = 0; i < ALL_PORT_NUM; i++) {
Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
pExynosComponent->pExynosPort[i].pauseEvent = NULL;
}
/* terminate sema for buffer handling on port */
for (i = 0; i < ALL_PORT_NUM; i++) {
Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
pExynosComponent->pExynosPort[i].bufferSemID = NULL;
}
ret = OMX_ErrorInsufficientResources;
goto EXIT;
}
/* if all buffers are allocated, send an event */
if (CHECK_PORT_POPULATED(&(pExynosComponent->pExynosPort[INPUT_PORT_INDEX])) &&
CHECK_PORT_POPULATED(&(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]))) {
Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_IDLE_STATE, NULL);
}
goto NO_EVENT_EXIT;
break;
case OMX_StateExecuting:
Exynos_SetPortFlush(pExynosComponent, ALL_PORT_INDEX);
ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE);
pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
pExynosComponent->currentState = OMX_StateIdle;
break;
case OMX_StatePause:
Exynos_SetPortFlush(pExynosComponent, ALL_PORT_INDEX);
ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE);
pExynosComponent->currentState = OMX_StateIdle;
break;
case OMX_StateWaitForResources:
pExynosComponent->currentState = OMX_StateIdle;
break;
default:
ret = OMX_ErrorIncorrectStateTransition;
break;
}
}
break;
case OMX_StateExecuting:
{
int j;
switch (currentState) {
case OMX_StateLoaded:
ret = OMX_ErrorIncorrectStateTransition;
break;
case OMX_StateIdle:
#ifdef TUNNELING_SUPPORT
for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &pExynosComponent->pExynosPort[i];
if (CHECK_PORT_TUNNELED(pExynosPort) &&
CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) &&
CHECK_PORT_ENABLED(pExynosPort)) {
for (j = 0; j < pExynosPort->tunnelBufferNum; j++)
Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
}
}
#endif
pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
pExynosComponent->currentState = OMX_StateExecuting;
/* set signal about pause */
for (i = 0; i < ALL_PORT_NUM; i++)
Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent);
break;
case OMX_StatePause:
#ifdef TUNNELING_SUPPORT
for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &pExynosComponent->pExynosPort[i];
if (CHECK_PORT_TUNNELED(pExynosPort) &&
CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) &&
CHECK_PORT_ENABLED(pExynosPort)) {
OMX_S32 semaValue = 0, cnt = 0;
Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[i].bufferSemID, &semaValue);
if (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > semaValue) {
cnt = Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) - semaValue;
for (j = 0; j < cnt; j++)
Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
}
}
}
#endif
pExynosComponent->currentState = OMX_StateExecuting;
/* set signal about pause */
for (i = 0; i < ALL_PORT_NUM; i++)
Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent);
break;
case OMX_StateWaitForResources:
ret = OMX_ErrorIncorrectStateTransition;
break;
default:
ret = OMX_ErrorIncorrectStateTransition;
break;
}
}
break;
case OMX_StatePause:
{
switch (currentState) {
case OMX_StateLoaded:
ret = OMX_ErrorIncorrectStateTransition;
break;
case OMX_StateIdle:
pExynosComponent->currentState = OMX_StatePause;
break;
case OMX_StateExecuting:
pExynosComponent->currentState = OMX_StatePause;
break;
case OMX_StateWaitForResources:
ret = OMX_ErrorIncorrectStateTransition;
break;
default:
ret = OMX_ErrorIncorrectStateTransition;
break;
}
}
break;
case OMX_StateWaitForResources:
{
switch (currentState) {
case OMX_StateLoaded:
ret = Exynos_OMX_In_WaitForResource(pOMXComponent);
pExynosComponent->currentState = OMX_StateWaitForResources;
break;
case OMX_StateIdle:
case OMX_StateExecuting:
case OMX_StatePause:
ret = OMX_ErrorIncorrectStateTransition;
break;
default:
ret = OMX_ErrorIncorrectStateTransition;
break;
}
}
break;
default:
ret = OMX_ErrorIncorrectStateTransition;
break;
}
EXIT:
if (ret == OMX_ErrorNone) {
if (pExynosComponent->pCallbacks != NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(%s)",
pExynosComponent, __FUNCTION__, stateString(destState));
pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
pExynosComponent->callbackData,
OMX_EventCmdComplete, OMX_CommandStateSet,
destState, NULL);
}
} else {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OMX_ComponentStateSet(%s) (0x%x)",
pExynosComponent, __FUNCTION__, stateString(destState), ret);
if ((pExynosComponent != NULL) &&
(pExynosComponent->pCallbacks != NULL)) {
pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
pExynosComponent->callbackData,
OMX_EventError, ret, 0, NULL);
}
}
NO_EVENT_EXIT: /* postpone to send event */
FunctionOut();
return ret;
}
static OMX_ERRORTYPE Exynos_OMX_EventHandler(
OMX_COMPONENTTYPE *pOMXComponent,
EVENT_COMMAD_TYPE cmd)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
int i = 0;
if ((pOMXComponent == NULL) ||
(pOMXComponent->pComponentPrivate == NULL)) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
switch (cmd) {
case EVENT_CMD_STATE_TO_LOAD_STATE: /* Idle to Loaded */
{
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
if (pExynosComponent->currentState == OMX_StateLoaded) {
/* event was already handled */
break;
}
if ((pExynosComponent->currentState != OMX_StateIdle) ||
(pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded)) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid state(state:0x%x, transient:0x%x)",
pExynosComponent, __FUNCTION__,
pExynosComponent->currentState, pExynosComponent->transientState);
break;
}
for (i = 0; i < (int)pExynosComponent->portParam.nPorts; i++) {
pExynosPort = &(pExynosComponent->pExynosPort[i]);
if (CHECK_PORT_ENABLED(pExynosPort)) {
while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
EXYNOS_OMX_MESSAGE *pMsg = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
if (pMsg != NULL)
Exynos_OSAL_Free(pMsg);
}
}
pExynosPort->portState = EXYNOS_OMX_PortStateLoaded;
}
pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
pExynosComponent->currentState = OMX_StateLoaded;
if (pExynosComponent->pCallbacks != NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(OMX_StateLoaded)", pExynosComponent, __FUNCTION__);
pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
pExynosComponent->callbackData,
OMX_EventCmdComplete,
OMX_CommandStateSet,
OMX_StateLoaded,
NULL);
}
}
break;
case EVENT_CMD_STATE_TO_IDLE_STATE: /* Loaded to Idle */
{
if (pExynosComponent->currentState == OMX_StateIdle) {
/* event was already handled */
break;
}
if ((pExynosComponent->currentState != OMX_StateLoaded) ||
(pExynosComponent->transientState != EXYNOS_OMX_TransStateLoadedToIdle)) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid state(state:0x%x, transient:0x%x)",
pExynosComponent, __FUNCTION__,
pExynosComponent->currentState, pExynosComponent->transientState);
break;
}
for (i = 0; i < (int)pExynosComponent->portParam.nPorts; i++)
pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateIdle;
pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
pExynosComponent->currentState = OMX_StateIdle;
if (pExynosComponent->pCallbacks != NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(OMX_StateIdle)", pExynosComponent, __FUNCTION__);
pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
pExynosComponent->callbackData,
OMX_EventCmdComplete,
OMX_CommandStateSet,
OMX_StateIdle,
NULL);
}
}
break;
case EVENT_CMD_DISABLE_INPUT_PORT: /* PortDisable(INPUT_PORT) */
{
if (!CHECK_PORT_ENABLED((&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]))) {
/* event was already handled */
break;
}
Exynos_OMX_DisablePort(pOMXComponent, INPUT_PORT_INDEX);
pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portState = EXYNOS_OMX_PortStateLoaded;
if (pExynosComponent->pCallbacks != NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(Disable/input port)", pExynosComponent, __FUNCTION__);
pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
pExynosComponent->callbackData,
OMX_EventCmdComplete,
OMX_CommandPortDisable, INPUT_PORT_INDEX, NULL);
}
}
break;
case EVENT_CMD_DISABLE_OUTPUT_PORT:
{
if (!CHECK_PORT_ENABLED((&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]))) {
/* event was already handled */
break;
}
Exynos_OMX_DisablePort(pOMXComponent, OUTPUT_PORT_INDEX);
pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portState = EXYNOS_OMX_PortStateLoaded;
if (pExynosComponent->pCallbacks != NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(Disable/output port)", pExynosComponent, __FUNCTION__);
pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
pExynosComponent->callbackData,
OMX_EventCmdComplete,
OMX_CommandPortDisable, OUTPUT_PORT_INDEX, NULL);
}
}
break;
case EVENT_CMD_ENABLE_INPUT_PORT: /* PortEnable(INPUT_PORT) */
{
if (CHECK_PORT_ENABLED((&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]))) {
/* event was already handled */
break;
}
Exynos_OMX_EnablePort(pOMXComponent, INPUT_PORT_INDEX);
pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portState = EXYNOS_OMX_PortStateIdle;
if (pExynosComponent->pCallbacks != NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(Enable/input port)", pExynosComponent, __FUNCTION__);
pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
pExynosComponent->callbackData,
OMX_EventCmdComplete,
OMX_CommandPortEnable, INPUT_PORT_INDEX, NULL);
}
}
break;
case EVENT_CMD_ENABLE_OUTPUT_PORT: /* PortEnable(OUTPUT_PORT) */
{
if (CHECK_PORT_ENABLED((&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]))) {
/* event was already handled */
break;
}
Exynos_OMX_EnablePort(pOMXComponent, OUTPUT_PORT_INDEX);
pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portState = EXYNOS_OMX_PortStateIdle;
if (pExynosComponent->pCallbacks != NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(Enable/output port)", pExynosComponent, __FUNCTION__);
pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
pExynosComponent->callbackData,
OMX_EventCmdComplete,
OMX_CommandPortEnable, OUTPUT_PORT_INDEX, NULL);
}
}
break;
default:
ret = OMX_ErrorBadParameter;
break;
}
EXIT:
return ret;
}
static OMX_ERRORTYPE Exynos_OMX_MessageHandlerThread(OMX_PTR threadData)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if (threadData == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
while (pExynosComponent->bExitMessageHandlerThread == OMX_FALSE) {
EXYNOS_OMX_MESSAGE *pMessage = NULL;
Exynos_OSAL_SemaphoreWait(pExynosComponent->hSemaMsgWait);
pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosComponent->messageQ);
if (pMessage != NULL) {
switch ((int)pMessage->type) {
case OMX_CommandStateSet:
{
Exynos_SetStateSet(pExynosComponent, pMessage->param);
if (pMessage->param != OMX_StateInvalid)
Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
ret = Exynos_OMX_ComponentStateSet(pOMXComponent, pMessage->param);
if (pMessage->param == OMX_StateInvalid)
Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
}
break;
case OMX_CommandFlush:
{
Exynos_SetPortFlush(pExynosComponent, pMessage->param);
Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, pMessage->param, OMX_TRUE);
}
break;
case OMX_CommandPortDisable:
{
Exynos_SetPortDisable(pExynosComponent, pMessage->param);
Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
ret = Exynos_OMX_PortDisableProcess(pOMXComponent, pMessage->param);
}
break;
case OMX_CommandPortEnable:
{
Exynos_SetPortEnable(pExynosComponent, pMessage->param);
Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
ret = Exynos_OMX_PortEnableProcess(pOMXComponent, pMessage->param);
}
break;
case OMX_CommandMarkBuffer:
{
OMX_U32 nPortIndex = pMessage->param;
if ((pMessage->pCmdData != NULL) &&
((nPortIndex == INPUT_PORT_INDEX) ||
(nPortIndex == OUTPUT_PORT_INDEX))) {
OMX_MARKTYPE *pMarkType = (OMX_MARKTYPE *)(pMessage->pCmdData);
pExynosComponent->pExynosPort[nPortIndex].markType.hMarkTargetComponent = pMarkType->hMarkTargetComponent;
pExynosComponent->pExynosPort[nPortIndex].markType.pMarkData = pMarkType->pMarkData;
}
}
break;
case Exynos_OMX_CommandSendEvent:
{
Exynos_OMX_EventHandler(pOMXComponent, (EVENT_COMMAD_TYPE)pMessage->param);
}
break;
case EXYNOS_OMX_CommandComponentDeInit:
{
pExynosComponent->bExitMessageHandlerThread = OMX_TRUE;
}
break;
default:
break;
}
Exynos_OSAL_Free(pMessage);
pMessage = NULL;
}
}
Exynos_OSAL_ThreadExit(NULL);
EXIT:
FunctionOut();
return ret;
}
static OMX_ERRORTYPE Exynos_OMX_CommandQueue(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
OMX_COMMANDTYPE Cmd,
OMX_U32 nParam,
OMX_PTR pCmdData)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
EXYNOS_OMX_MESSAGE *command = NULL;
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorUndefined;
goto EXIT;
}
command = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
if (command == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_Malloc()", pExynosComponent, __FUNCTION__);
ret = OMX_ErrorInsufficientResources;
goto EXIT;
}
command->type = (OMX_U32)Cmd;
command->param = nParam;
command->pCmdData = pCmdData;
ret = Exynos_OSAL_Queue(&pExynosComponent->messageQ, (void *)command);
if (ret != 0) {
Exynos_OSAL_Free(command);
ret = OMX_ErrorUndefined;
goto EXIT;
}
ret = Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgWait);
EXIT:
return ret;
}
OMX_ERRORTYPE Exynos_OMX_GetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR pParams)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if ((hComponent == NULL) ||
(pParams == NULL)) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
switch ((int)nParamIndex) {
case OMX_IndexParamAudioInit:
case OMX_IndexParamVideoInit:
case OMX_IndexParamImageInit:
case OMX_IndexParamOtherInit:
{
OMX_PORT_PARAM_TYPE *pPortParam = (OMX_PORT_PARAM_TYPE *)pParams;
ret = Exynos_OMX_Check_SizeVersion(pPortParam, sizeof(OMX_PORT_PARAM_TYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
pPortParam->nPorts = 0;
pPortParam->nStartPortNumber = 0;
}
break;
case OMX_IndexParamPortDefinition:
{
OMX_PARAM_PORTDEFINITIONTYPE *pDstPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParams;
OMX_U32 nPortIndex = pDstPortDef->nPortIndex;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
/* except nSize, nVersion and nPortIndex */
int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
if (nPortIndex >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
ret = Exynos_OMX_Check_SizeVersion(pDstPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
Exynos_OSAL_Memcpy(((char *)pDstPortDef) + nOffset,
((char *)&pExynosPort->portDefinition) + nOffset,
pDstPortDef->nSize - nOffset);
}
break;
case OMX_IndexParamPriorityMgmt:
{
OMX_PRIORITYMGMTTYPE *pPriority = (OMX_PRIORITYMGMTTYPE *)pParams;
ret = Exynos_OMX_Check_SizeVersion(pPriority, sizeof(OMX_PRIORITYMGMTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
pPriority->nGroupID = pExynosComponent->compPriority.nGroupID;
pPriority->nGroupPriority = pExynosComponent->compPriority.nGroupPriority;
}
break;
case OMX_IndexParamCompBufferSupplier:
{
OMX_PARAM_BUFFERSUPPLIERTYPE *pSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE *)pParams;
OMX_U32 nPortIndex = pSupplierType->nPortIndex;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
if ((pExynosComponent->currentState == OMX_StateLoaded) ||
(pExynosComponent->currentState == OMX_StateWaitForResources)) {
if (nPortIndex >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
ret = Exynos_OMX_Check_SizeVersion(pSupplierType, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
pSupplierType->eBufferSupplier = OMX_BufferSupplyInput;
} else if (CHECK_PORT_TUNNELED(pExynosPort)) {
pSupplierType->eBufferSupplier = OMX_BufferSupplyOutput;
} else {
pSupplierType->eBufferSupplier = OMX_BufferSupplyUnspecified;
}
} else {
if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
pSupplierType->eBufferSupplier = OMX_BufferSupplyOutput;
} else if (CHECK_PORT_TUNNELED(pExynosPort)) {
pSupplierType->eBufferSupplier = OMX_BufferSupplyInput;
} else {
pSupplierType->eBufferSupplier = OMX_BufferSupplyUnspecified;
}
}
}
else
{
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
}
break;
case OMX_IndexExynosParamImageCrop:
{
EXYNOS_OMX_VIDEO_PARAM_IMAGE_CROP *pImageCrop = (EXYNOS_OMX_VIDEO_PARAM_IMAGE_CROP *)pParams;
ret = Exynos_OMX_Check_SizeVersion(pImageCrop, sizeof(EXYNOS_OMX_VIDEO_PARAM_IMAGE_CROP));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
pImageCrop->bEnabled = pExynosComponent->bUseImgCrop;
ret = OMX_ErrorNone;
}
break;
default:
{
ret = OMX_ErrorUnsupportedIndex;
goto EXIT;
}
break;
}
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OMX_SetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_IN OMX_PTR pParams)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if ((hComponent == NULL) ||
(pParams == NULL)) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
switch ((int)nParamIndex) {
case OMX_IndexParamAudioInit:
case OMX_IndexParamVideoInit:
case OMX_IndexParamImageInit:
case OMX_IndexParamOtherInit:
{
OMX_PORT_PARAM_TYPE *pPortParam = (OMX_PORT_PARAM_TYPE *)pParams;
ret = Exynos_OMX_Check_SizeVersion(pPortParam, sizeof(OMX_PORT_PARAM_TYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
if ((pExynosComponent->currentState != OMX_StateLoaded) &&
(pExynosComponent->currentState != OMX_StateWaitForResources)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
/* ret = OMX_ErrorUndefined; */
/* Exynos_OSAL_Memcpy(&pExynosComponent->portParam, pPortParam, sizeof(OMX_PORT_PARAM_TYPE)); */
}
break;
case OMX_IndexParamPortDefinition:
{
OMX_PARAM_PORTDEFINITIONTYPE *pSrcPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParams;
OMX_U32 nPortIndex = pSrcPortDef->nPortIndex;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
/* except nSize, nVersion and nPortIndex */
int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
if (nPortIndex >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
ret = Exynos_OMX_Check_SizeVersion(pSrcPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
if ((pExynosComponent->currentState != OMX_StateLoaded) &&
(pExynosComponent->currentState != OMX_StateWaitForResources)) {
if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
}
if (pSrcPortDef->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
Exynos_OSAL_Memcpy(((char *)&pExynosPort->portDefinition) + nOffset,
((char *)pSrcPortDef) + nOffset,
pSrcPortDef->nSize - nOffset);
}
break;
case OMX_IndexParamPriorityMgmt:
{
OMX_PRIORITYMGMTTYPE *pPriority = (OMX_PRIORITYMGMTTYPE *)pParams;
if ((pExynosComponent->currentState != OMX_StateLoaded) &&
(pExynosComponent->currentState != OMX_StateWaitForResources)) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
ret = Exynos_OMX_Check_SizeVersion(pPriority, sizeof(OMX_PRIORITYMGMTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
pExynosComponent->compPriority.nGroupID = pPriority->nGroupID;
pExynosComponent->compPriority.nGroupPriority = pPriority->nGroupPriority;
}
break;
case OMX_IndexParamCompBufferSupplier:
{
OMX_PARAM_BUFFERSUPPLIERTYPE *pSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE *)pParams;
OMX_U32 nPortIndex = pSupplierType->nPortIndex;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
if (nPortIndex >= pExynosComponent->portParam.nPorts) {
ret = OMX_ErrorBadPortIndex;
goto EXIT;
}
ret = Exynos_OMX_Check_SizeVersion(pSupplierType, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
if ((pExynosComponent->currentState != OMX_StateLoaded) &&
(pExynosComponent->currentState != OMX_StateWaitForResources)) {
if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
ret = OMX_ErrorIncorrectStateOperation;
goto EXIT;
}
}
if (pSupplierType->eBufferSupplier == OMX_BufferSupplyUnspecified) {
ret = OMX_ErrorNone;
goto EXIT;
}
if (CHECK_PORT_TUNNELED(pExynosPort) == 0) {
ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/
goto EXIT;
}
if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
if (pSupplierType->eBufferSupplier == OMX_BufferSupplyInput) {
/*
if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
ret = OMX_ErrorNone;
}
*/
pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
pSupplierType->nPortIndex = pExynosPort->tunneledPort;
ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, pSupplierType);
goto EXIT;
} else if (pSupplierType->eBufferSupplier == OMX_BufferSupplyOutput) {
ret = OMX_ErrorNone;
if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
pSupplierType->nPortIndex = pExynosPort->tunneledPort;
ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, pSupplierType);
}
goto EXIT;
}
} else if (pExynosPort->portDefinition.eDir == OMX_DirOutput) {
if (pSupplierType->eBufferSupplier == OMX_BufferSupplyInput) {
ret = OMX_ErrorNone;
if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
ret = OMX_ErrorNone;
}
goto EXIT;
} else if (pSupplierType->eBufferSupplier == OMX_BufferSupplyOutput) {
/*
if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
ret = OMX_ErrorNone;
}
*/
pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
ret = OMX_ErrorNone;
goto EXIT;
}
}
}
break;
default:
{
ret = OMX_ErrorUnsupportedIndex;
goto EXIT;
}
break;
}
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OMX_GetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nConfigIndex,
OMX_INOUT OMX_PTR pConfigs)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if (hComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pConfigs == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
switch (nConfigIndex) {
default:
ret = OMX_ErrorUnsupportedIndex;
break;
}
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OMX_SetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nConfigIndex,
OMX_IN OMX_PTR pConfigs)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if (hComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pConfigs == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
switch (nConfigIndex) {
default:
ret = OMX_ErrorUnsupportedIndex;
break;
}
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OMX_GetExtensionIndex(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_STRING cParameterName,
OMX_OUT OMX_INDEXTYPE *pIndexType)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
if ((hComponent == NULL) ||
(cParameterName == NULL) ||
(pIndexType == NULL)) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
if (pExynosComponent->currentState == OMX_StateInvalid) {
ret = OMX_ErrorInvalidState;
goto EXIT;
}
if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_IMAGE_CROP) == 0) {
*pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamImageCrop;
ret = OMX_ErrorNone;
goto EXIT;
}
ret = OMX_ErrorBadParameter;
EXIT:
FunctionOut();
return ret;
}
OMX_PTR Exynos_OMX_MakeDynamicConfig(
OMX_INDEXTYPE nConfigIndex,
OMX_PTR pConfigs)
{
OMX_PTR ret = NULL;
OMX_S32 nConfigSize = 0;
switch ((int)nConfigIndex) {
case OMX_IndexConfigVideoIntraPeriod:
{
nConfigSize = sizeof(OMX_U32);
ret = Exynos_OSAL_Malloc(sizeof(OMX_U32) + nConfigSize);
}
break;
case OMX_IndexConfigVideoRoiInfo:
{
EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *pRoiInfo = (EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *)pConfigs;
OMX_S32 nRoiMBInfoSize = 0;
nConfigSize = *(OMX_U32 *)pConfigs;
if (pRoiInfo->bUseRoiInfo == OMX_TRUE)
nRoiMBInfoSize = pRoiInfo->nRoiMBInfoSize;
ret = Exynos_OSAL_Malloc(sizeof(OMX_U32) + nConfigSize + nRoiMBInfoSize);
if (ret != NULL)
Exynos_OSAL_Memcpy((OMX_PTR)((OMX_U8 *)ret + sizeof(OMX_U32) + nConfigSize), pRoiInfo->pRoiMBInfo, nRoiMBInfoSize);
}
break;
default:
nConfigSize = *(OMX_U32 *)pConfigs;
ret = Exynos_OSAL_Malloc(sizeof(OMX_U32) + nConfigSize);
break;
}
if (ret != NULL) {
*((OMX_S32 *)ret) = (OMX_S32)nConfigIndex;
Exynos_OSAL_Memcpy((OMX_PTR)((OMX_U8 *)ret + sizeof(OMX_U32)), pConfigs, nConfigSize);
}
return ret;
}
OMX_ERRORTYPE Exynos_OMX_SendEventCommand(
EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
EVENT_COMMAD_TYPE Cmd,
OMX_PTR pCmdData)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
FunctionIn();
if (pExynosComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
ret = OMX_ErrorBadParameter;
goto EXIT;
}
if (pExynosComponent->currentState == OMX_StateInvalid) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] current state is OMX_StateInvalid", pExynosComponent, __FUNCTION__);
ret = OMX_ErrorInvalidState;
goto EXIT;
}
ret = Exynos_OMX_CommandQueue(pExynosComponent, (OMX_COMMANDTYPE)Exynos_OMX_CommandSendEvent, Cmd, pCmdData);
EXIT:
FunctionOut();
return ret;
}
void Exynos_OMX_Component_AbnormalTermination(OMX_HANDLETYPE hComponent)
{
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
int i = 0;
FunctionIn();
if (hComponent == NULL) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
if (pOMXComponent->pComponentPrivate == NULL)
goto EXIT;
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
/* clear a msg command piled on queue */
while(Exynos_OSAL_GetElemNum(&pExynosComponent->messageQ) > 0)
Exynos_OSAL_Free(Exynos_OSAL_Dequeue(&pExynosComponent->messageQ));
pExynosComponent->abendState = OMX_TRUE;
/* change to invalid state */
Exynos_OMX_SendCommand(hComponent, OMX_CommandStateSet, OMX_StateInvalid, NULL);
EXIT:
FunctionOut();
return;
}
OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor(
OMX_IN OMX_HANDLETYPE hComponent)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
FunctionIn();
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] lib version is %s", __FUNCTION__, IS_64BIT_OS? "64bit":"32bit");
if (hComponent == NULL) {
ret = OMX_ErrorBadParameter;
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] OMX_ErrorBadParameter (0x%x)", __FUNCTION__, ret);
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
pExynosComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASECOMPONENT));
if (pExynosComponent == NULL) {
ret = OMX_ErrorInsufficientResources;
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Malloc (0x%x)", __FUNCTION__, ret);
goto EXIT;
}
Exynos_OSAL_Memset(pExynosComponent, 0, sizeof(EXYNOS_OMX_BASECOMPONENT));
pOMXComponent->pComponentPrivate = (OMX_PTR)pExynosComponent;
ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->hSemaMsgWait);
if (ret != OMX_ErrorNone) {
ret = OMX_ErrorInsufficientResources;
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SemaphoreCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
goto EXIT;
}
ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->hSemaMsgProgress);
if (ret != OMX_ErrorNone) {
ret = OMX_ErrorInsufficientResources;
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SemaphoreCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
goto EXIT;
}
ret = Exynos_OSAL_MutexCreate(&pExynosComponent->compMutex);
if (ret != OMX_ErrorNone) {
ret = OMX_ErrorInsufficientResources;
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
goto EXIT;
}
ret = Exynos_OSAL_MutexCreate(&pExynosComponent->compEventMutex);
if (ret != OMX_ErrorNone) {
ret = OMX_ErrorInsufficientResources;
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
goto EXIT;
}
pExynosComponent->bExitMessageHandlerThread = OMX_FALSE;
Exynos_OSAL_QueueCreate(&pExynosComponent->messageQ, MAX_QUEUE_ELEMENTS);
ret = Exynos_OSAL_ThreadCreate(&pExynosComponent->hMessageHandler, Exynos_OMX_MessageHandlerThread, pOMXComponent);
if (ret != OMX_ErrorNone) {
ret = OMX_ErrorInsufficientResources;
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ThreadCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
goto EXIT;
}
Exynos_OSAL_QueueCreate(&pExynosComponent->dynamicConfigQ, MAX_QUEUE_ELEMENTS);
Exynos_OSAL_QueueCreate(&pExynosComponent->HDR10plusConfigQ, MAX_QUEUE_ELEMENTS);
pOMXComponent->GetComponentVersion = &Exynos_OMX_GetComponentVersion;
pOMXComponent->SendCommand = &Exynos_OMX_SendCommand;
pOMXComponent->GetState = &Exynos_OMX_GetState;
pOMXComponent->SetCallbacks = &Exynos_OMX_SetCallbacks;
#ifdef EGL_IMAGE_SUPPORT
pOMXComponent->UseEGLImage = &Exynos_OMX_UseEGLImage;
#endif
EXIT:
FunctionOut();
return ret;
}
OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(
OMX_IN OMX_HANDLETYPE hComponent)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
OMX_COMPONENTTYPE *pOMXComponent = NULL;
EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
OMX_S32 semaValue = 0;
FunctionIn();
if (hComponent == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
if (ret != OMX_ErrorNone) {
goto EXIT;
}
if (pOMXComponent->pComponentPrivate == NULL) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
while(Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
Exynos_OSAL_Free(Exynos_OSAL_Dequeue(&pExynosComponent->dynamicConfigQ));
}
Exynos_OSAL_QueueTerminate(&pExynosComponent->dynamicConfigQ);
while(Exynos_OSAL_GetElemNum(&pExynosComponent->HDR10plusConfigQ) > 0) {
Exynos_OSAL_Free(Exynos_OSAL_Dequeue(&pExynosComponent->HDR10plusConfigQ));
}
Exynos_OSAL_QueueTerminate(&pExynosComponent->HDR10plusConfigQ);
Exynos_OMX_CommandQueue(pExynosComponent, (OMX_COMMANDTYPE)EXYNOS_OMX_CommandComponentDeInit, 0, NULL);
Exynos_OSAL_SleepMillisec(0);
Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->hSemaMsgWait, &semaValue);
if (semaValue == 0)
Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgWait);
Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgWait);
Exynos_OSAL_ThreadTerminate(pExynosComponent->hMessageHandler);
pExynosComponent->hMessageHandler = NULL;
Exynos_OSAL_MutexTerminate(pExynosComponent->compEventMutex);
pExynosComponent->compMutex = NULL;
Exynos_OSAL_MutexTerminate(pExynosComponent->compMutex);
pExynosComponent->compMutex = NULL;
Exynos_OSAL_SemaphoreTerminate(pExynosComponent->hSemaMsgProgress);
pExynosComponent->hSemaMsgProgress = NULL;
Exynos_OSAL_SemaphoreTerminate(pExynosComponent->hSemaMsgWait);
pExynosComponent->hSemaMsgWait = NULL;
Exynos_OSAL_QueueTerminate(&pExynosComponent->messageQ);
Exynos_OSAL_Free(pExynosComponent);
pExynosComponent = NULL;
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}