/* * * Copyright 2010 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 SEC_OMX_Baseport.c * @brief * @author SeungBeom Kim (sbcrux.kim@samsung.com) * HyeYeon Chung (hyeon.chung@samsung.com) * @version 1.0 * @history * 2010.7.15 : Create */ #include #include #include #include "SEC_OMX_Macros.h" #include "SEC_OSAL_Event.h" #include "SEC_OSAL_Semaphore.h" #include "SEC_OSAL_Mutex.h" #include "SEC_OMX_Baseport.h" #include "SEC_OMX_Basecomponent.h" #undef SEC_LOG_TAG #define SEC_LOG_TAG "SEC_BASE_PORT" #define SEC_LOG_OFF #include "SEC_OSAL_Log.h" OMX_ERRORTYPE SEC_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; SEC_OMX_BASEPORT *pSECPort = NULL; OMX_BUFFERHEADERTYPE *bufferHeader = NULL; SEC_OMX_MESSAGE *message = NULL; OMX_U32 flushNum = 0; OMX_S32 semValue = 0; FunctionIn(); pSECPort = &pSECComponent->pSECPort[portIndex]; while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > 0) { SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &semValue); if (semValue == 0) SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID); SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); if (message != NULL) { bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData; bufferHeader->nFilledLen = 0; if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { if (portIndex) { OMX_EmptyThisBuffer(pSECPort->tunneledComponent, bufferHeader); } else { OMX_FillThisBuffer(pSECPort->tunneledComponent, bufferHeader); } SEC_OSAL_Free(message); message = NULL; } else if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { SEC_OSAL_Log(SEC_LOG_ERROR, "Tunneled mode is not working, Line:%d", __LINE__); ret = OMX_ErrorNotImplemented; SEC_OSAL_Queue(&pSECPort->bufferQ, pSECPort); goto EXIT; } else { if (portIndex == OUTPUT_PORT_INDEX) { pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); } else { pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); } SEC_OSAL_Free(message); message = NULL; } } } if (pSECComponent->secDataBuffer[portIndex].dataValid == OMX_TRUE) { if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); message->pCmdData = pSECComponent->secDataBuffer[portIndex].bufferHeader; message->messageType = 0; message->messageParam = -1; SEC_OSAL_Queue(&pSECPort->bufferQ, message); pSECComponent->sec_BufferReset(pOMXComponent, portIndex); } else { if (portIndex == INPUT_PORT_INDEX) pSECComponent->sec_InputBufferReturn(pOMXComponent); else if (portIndex == OUTPUT_PORT_INDEX) pSECComponent->sec_OutputBufferReturn(pOMXComponent); } } if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) < pSECPort->assignedBufferNum) { SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); } if (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) != pSECPort->assignedBufferNum) SEC_OSAL_SetElemNum(&pSECPort->bufferQ, pSECPort->assignedBufferNum); } else { while(1) { int cnt; SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &cnt); if (cnt == 0) break; SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); } SEC_OSAL_SetElemNum(&pSECPort->bufferQ, 0); } pSECComponent->processData[portIndex].dataLen = 0; pSECComponent->processData[portIndex].nFlags = 0; pSECComponent->processData[portIndex].remainDataLen = 0; pSECComponent->processData[portIndex].timeStamp = 0; pSECComponent->processData[portIndex].usedDataLen = 0; EXIT: FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; SEC_OMX_BASECOMPONENT *pSECComponent = NULL; SEC_OMX_BASEPORT *pSECPort = NULL; OMX_S32 portIndex = 0; OMX_U32 i = 0, cnt = 0; SEC_OMX_DATABUFFER *flushBuffer = NULL; FunctionIn(); if (pOMXComponent == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if (pOMXComponent->pComponentPrivate == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; for (i = 0; i < cnt; i++) { if (nPortIndex == ALL_PORT_INDEX) portIndex = i; else portIndex = nPortIndex; SEC_OSAL_SignalSet(pSECComponent->pauseEvent); flushBuffer = &pSECComponent->secDataBuffer[portIndex]; SEC_OSAL_MutexLock(flushBuffer->bufferMutex); ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; if (ret == OMX_ErrorNone) { SEC_OSAL_Log(SEC_LOG_TRACE,"OMX_CommandFlush EventCmdComplete"); pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, pSECComponent->callbackData, OMX_EventCmdComplete, OMX_CommandFlush, portIndex, NULL); } if (portIndex == INPUT_PORT_INDEX) { pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); pSECComponent->getAllDelayBuffer = OMX_FALSE; pSECComponent->bSaveFlagEOS = OMX_FALSE; pSECComponent->reInputData = OMX_FALSE; } else if (portIndex == OUTPUT_PORT_INDEX) { pSECComponent->remainOutputData = OMX_FALSE; } } EXIT: if (ret != OMX_ErrorNone) { pSECComponent->pCallbacks->EventHandler(pOMXComponent, pSECComponent->callbackData, OMX_EventError, ret, 0, NULL); } FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_BufferFlushProcessNoEvent(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; SEC_OMX_BASECOMPONENT *pSECComponent = NULL; SEC_OMX_BASEPORT *pSECPort = NULL; OMX_S32 portIndex = 0; OMX_U32 i = 0, cnt = 0; SEC_OMX_DATABUFFER *flushBuffer = NULL; FunctionIn(); if (pOMXComponent == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if (pOMXComponent->pComponentPrivate == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; for (i = 0; i < cnt; i++) { if (nPortIndex == ALL_PORT_INDEX) portIndex = i; else portIndex = nPortIndex; pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_TRUE; SEC_OSAL_SignalSet(pSECComponent->pauseEvent); flushBuffer = &pSECComponent->secDataBuffer[portIndex]; SEC_OSAL_MutexLock(flushBuffer->bufferMutex); ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; if (portIndex == INPUT_PORT_INDEX) { pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); pSECComponent->getAllDelayBuffer = OMX_FALSE; pSECComponent->bSaveFlagEOS = OMX_FALSE; pSECComponent->remainOutputData = OMX_FALSE; pSECComponent->reInputData = OMX_FALSE; } } EXIT: if (ret != OMX_ErrorNone) { pSECComponent->pCallbacks->EventHandler(pOMXComponent, pSECComponent->callbackData, OMX_EventError, ret, 0, NULL); } FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; SEC_OMX_BASEPORT *pSECPort = NULL; OMX_U32 i = 0, cnt = 0; FunctionIn(); pSECPort = &pSECComponent->pSECPort[portIndex]; pSECPort->portDefinition.bEnabled = OMX_TRUE; if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { ret = pSECComponent->sec_AllocateTunnelBuffer(pSECPort, portIndex); if (OMX_ErrorNone != ret) { goto EXIT; } pSECPort->portDefinition.bPopulated = OMX_TRUE; if (pSECComponent->currentState == OMX_StateExecuting) { for (i=0; itunnelBufferNum; i++) { SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID); } } } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { SEC_OSAL_SemaphoreWait(pSECPort->loadedResource); pSECPort->portDefinition.bPopulated = OMX_TRUE; } } else { if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { SEC_OSAL_SemaphoreWait(pSECPort->loadedResource); pSECPort->portDefinition.bPopulated = OMX_TRUE; } } ret = OMX_ErrorNone; EXIT: FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; SEC_OMX_BASECOMPONENT *pSECComponent = NULL; OMX_S32 portIndex = 0; OMX_U32 i = 0, cnt = 0; FunctionIn(); if (pOMXComponent == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if (pOMXComponent->pComponentPrivate == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1; for (i = 0; i < cnt; i++) { if (nPortIndex == ALL_PORT_INDEX) portIndex = i; else portIndex = nPortIndex; ret = SEC_OMX_EnablePort(pOMXComponent, portIndex); if (ret == OMX_ErrorNone) { pSECComponent->pCallbacks->EventHandler(pOMXComponent, pSECComponent->callbackData, OMX_EventCmdComplete, OMX_CommandPortEnable, portIndex, NULL); } } EXIT: if (ret != OMX_ErrorNone) { pSECComponent->pCallbacks->EventHandler(pOMXComponent, pSECComponent->callbackData, OMX_EventError, ret, 0, NULL); } FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; SEC_OMX_BASEPORT *pSECPort = NULL; OMX_U32 i = 0, elemNum = 0; SEC_OMX_MESSAGE *message; FunctionIn(); pSECPort = &pSECComponent->pSECPort[portIndex]; if (!CHECK_PORT_ENABLED(pSECPort)) { ret = OMX_ErrorNone; goto EXIT; } if (pSECComponent->currentState!=OMX_StateLoaded) { if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) { message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); SEC_OSAL_Free(message); } ret = pSECComponent->sec_FreeTunnelBuffer(pSECPort, portIndex); if (OMX_ErrorNone != ret) { goto EXIT; } pSECPort->portDefinition.bPopulated = OMX_FALSE; } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { pSECPort->portDefinition.bPopulated = OMX_FALSE; SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); } else { if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) { message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); SEC_OSAL_Free(message); } } pSECPort->portDefinition.bPopulated = OMX_FALSE; SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); } } pSECPort->portDefinition.bEnabled = OMX_FALSE; ret = OMX_ErrorNone; EXIT: FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; SEC_OMX_BASECOMPONENT *pSECComponent = NULL; OMX_S32 portIndex = 0; OMX_U32 i = 0, cnt = 0; SEC_OMX_DATABUFFER *flushBuffer = NULL; FunctionIn(); if (pOMXComponent == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if (pOMXComponent->pComponentPrivate == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; /* port flush*/ for(i = 0; i < cnt; i++) { if (nPortIndex == ALL_PORT_INDEX) portIndex = i; else portIndex = nPortIndex; pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_TRUE; flushBuffer = &pSECComponent->secDataBuffer[portIndex]; SEC_OSAL_MutexLock(flushBuffer->bufferMutex); ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; if (portIndex == INPUT_PORT_INDEX) { pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); pSECComponent->getAllDelayBuffer = OMX_FALSE; pSECComponent->bSaveFlagEOS = OMX_FALSE; pSECComponent->reInputData = OMX_FALSE; } else if (portIndex == OUTPUT_PORT_INDEX) { pSECComponent->remainOutputData = OMX_FALSE; } } for(i = 0; i < cnt; i++) { if (nPortIndex == ALL_PORT_INDEX) portIndex = i; else portIndex = nPortIndex; ret = SEC_OMX_DisablePort(pOMXComponent, portIndex); pSECComponent->pSECPort[portIndex].bIsPortDisabled = OMX_FALSE; if (ret == OMX_ErrorNone) { pSECComponent->pCallbacks->EventHandler(pOMXComponent, pSECComponent->callbackData, OMX_EventCmdComplete, OMX_CommandPortDisable, portIndex, NULL); } } EXIT: if (ret != OMX_ErrorNone) { pSECComponent->pCallbacks->EventHandler(pOMXComponent, pSECComponent->callbackData, OMX_EventError, ret, 0, NULL); } FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_EmptyThisBuffer( OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) { OMX_ERRORTYPE ret = OMX_ErrorNone; OMX_COMPONENTTYPE *pOMXComponent = NULL; SEC_OMX_BASECOMPONENT *pSECComponent = NULL; SEC_OMX_BASEPORT *pSECPort = NULL; OMX_BOOL findBuffer = OMX_FALSE; SEC_OMX_MESSAGE *message; OMX_U32 i = 0; FunctionIn(); if (hComponent == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if (pOMXComponent->pComponentPrivate == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; if (pSECComponent->currentState == OMX_StateInvalid) { ret = OMX_ErrorInvalidState; goto EXIT; } if (pBuffer == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) { ret = OMX_ErrorBadPortIndex; goto EXIT; } ret = SEC_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if ((pSECComponent->currentState != OMX_StateIdle) && (pSECComponent->currentState != OMX_StateExecuting) && (pSECComponent->currentState != OMX_StatePause)) { ret = OMX_ErrorIncorrectStateOperation; goto EXIT; } pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; if ((!CHECK_PORT_ENABLED(pSECPort)) || ((CHECK_PORT_BEING_FLUSHED(pSECPort) || CHECK_PORT_BEING_DISABLED(pSECPort)) && (!CHECK_PORT_TUNNELED(pSECPort) || !CHECK_PORT_BUFFER_SUPPLIER(pSECPort))) || ((pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle) && (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)))) { ret = OMX_ErrorIncorrectStateOperation; goto EXIT; } for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { if (pBuffer == pSECPort->bufferHeader[i]) { findBuffer = OMX_TRUE; break; } } if (findBuffer == OMX_FALSE) { ret = OMX_ErrorBadParameter; goto EXIT; } else { ret = OMX_ErrorNone; } message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); if (message == NULL) { ret = OMX_ErrorInsufficientResources; goto EXIT; } message->messageType = SEC_OMX_CommandEmptyBuffer; message->messageParam = (OMX_U32) i; message->pCmdData = (OMX_PTR)pBuffer; SEC_OSAL_Queue(&pSECPort->bufferQ, (void *)message); SEC_OSAL_SemaphorePost(pSECPort->bufferSemID); EXIT: FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_FillThisBuffer( OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) { OMX_ERRORTYPE ret = OMX_ErrorNone; OMX_COMPONENTTYPE *pOMXComponent = NULL; SEC_OMX_BASECOMPONENT *pSECComponent = NULL; SEC_OMX_BASEPORT *pSECPort = NULL; OMX_BOOL findBuffer = OMX_FALSE; SEC_OMX_MESSAGE *message; OMX_U32 i = 0; FunctionIn(); if (hComponent == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if (pOMXComponent->pComponentPrivate == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; if (pSECComponent->currentState == OMX_StateInvalid) { ret = OMX_ErrorInvalidState; goto EXIT; } if (pBuffer == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) { ret = OMX_ErrorBadPortIndex; goto EXIT; } ret = SEC_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if ((pSECComponent->currentState != OMX_StateIdle) && (pSECComponent->currentState != OMX_StateExecuting) && (pSECComponent->currentState != OMX_StatePause)) { ret = OMX_ErrorIncorrectStateOperation; goto EXIT; } pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; if ((!CHECK_PORT_ENABLED(pSECPort)) || ((CHECK_PORT_BEING_FLUSHED(pSECPort) || CHECK_PORT_BEING_DISABLED(pSECPort)) && (!CHECK_PORT_TUNNELED(pSECPort) || !CHECK_PORT_BUFFER_SUPPLIER(pSECPort))) || ((pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle) && (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)))) { ret = OMX_ErrorIncorrectStateOperation; goto EXIT; } for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { if (pBuffer == pSECPort->bufferHeader[i]) { findBuffer = OMX_TRUE; break; } } if (findBuffer == OMX_FALSE) { ret = OMX_ErrorBadParameter; goto EXIT; } else { ret = OMX_ErrorNone; } message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); if (message == NULL) { ret = OMX_ErrorInsufficientResources; goto EXIT; } message->messageType = SEC_OMX_CommandFillBuffer; message->messageParam = (OMX_U32) i; message->pCmdData = (OMX_PTR)pBuffer; SEC_OSAL_Queue(&pSECPort->bufferQ, (void *)message); SEC_OSAL_SemaphorePost(pSECPort->bufferSemID); EXIT: FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_Port_Constructor(OMX_HANDLETYPE hComponent) { OMX_ERRORTYPE ret = OMX_ErrorNone; OMX_COMPONENTTYPE *pOMXComponent = NULL; SEC_OMX_BASECOMPONENT *pSECComponent = NULL; SEC_OMX_BASEPORT *pSECPort = NULL; SEC_OMX_BASEPORT *pSECInputPort = NULL; SEC_OMX_BASEPORT *pSECOutputPort = NULL; int i = 0; FunctionIn(); if (hComponent == NULL) { ret = OMX_ErrorBadParameter; SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); goto EXIT; } pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if (pOMXComponent->pComponentPrivate == NULL) { ret = OMX_ErrorBadParameter; SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); goto EXIT; } pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; INIT_SET_SIZE_VERSION(&pSECComponent->portParam, OMX_PORT_PARAM_TYPE); pSECComponent->portParam.nPorts = ALL_PORT_NUM; pSECComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX; pSECPort = SEC_OSAL_Malloc(sizeof(SEC_OMX_BASEPORT) * ALL_PORT_NUM); if (pSECPort == NULL) { ret = OMX_ErrorInsufficientResources; SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); goto EXIT; } SEC_OSAL_Memset(pSECPort, 0, sizeof(SEC_OMX_BASEPORT) * ALL_PORT_NUM); pSECComponent->pSECPort = pSECPort; /* Input Port */ pSECInputPort = &pSECPort[INPUT_PORT_INDEX]; SEC_OSAL_QueueCreate(&pSECInputPort->bufferQ); pSECInputPort->bufferHeader = SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); if (pSECInputPort->bufferHeader == NULL) { SEC_OSAL_Free(pSECPort); pSECPort = NULL; ret = OMX_ErrorInsufficientResources; SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); goto EXIT; } SEC_OSAL_Memset(pSECInputPort->bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); pSECInputPort->bufferStateAllocate = SEC_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); if (pSECInputPort->bufferStateAllocate == NULL) { SEC_OSAL_Free(pSECInputPort->bufferHeader); pSECInputPort->bufferHeader = NULL; SEC_OSAL_Free(pSECPort); pSECPort = NULL; ret = OMX_ErrorInsufficientResources; SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); goto EXIT; } SEC_OSAL_Memset(pSECInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); pSECInputPort->bufferSemID = NULL; pSECInputPort->assignedBufferNum = 0; pSECInputPort->portState = OMX_StateMax; pSECInputPort->bIsPortFlushed = OMX_FALSE; pSECInputPort->bIsPortDisabled = OMX_FALSE; pSECInputPort->tunneledComponent = NULL; pSECInputPort->tunneledPort = 0; pSECInputPort->tunnelBufferNum = 0; pSECInputPort->bufferSupplier = OMX_BufferSupplyUnspecified; pSECInputPort->tunnelFlags = 0; pSECInputPort->eControlRate = OMX_Video_ControlRateDisable; ret = SEC_OSAL_SemaphoreCreate(&pSECInputPort->loadedResource); if (ret != OMX_ErrorNone) { SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); pSECInputPort->bufferStateAllocate = NULL; SEC_OSAL_Free(pSECInputPort->bufferHeader); pSECInputPort->bufferHeader = NULL; SEC_OSAL_Free(pSECPort); pSECPort = NULL; goto EXIT; } ret = SEC_OSAL_SemaphoreCreate(&pSECInputPort->unloadedResource); if (ret != OMX_ErrorNone) { SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); pSECInputPort->loadedResource = NULL; SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); pSECInputPort->bufferStateAllocate = NULL; SEC_OSAL_Free(pSECInputPort->bufferHeader); pSECInputPort->bufferHeader = NULL; SEC_OSAL_Free(pSECPort); pSECPort = NULL; goto EXIT; } INIT_SET_SIZE_VERSION(&pSECInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); pSECInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX; pSECInputPort->portDefinition.eDir = OMX_DirInput; pSECInputPort->portDefinition.nBufferCountActual = 0; pSECInputPort->portDefinition.nBufferCountMin = 0; pSECInputPort->portDefinition.nBufferSize = 0; pSECInputPort->portDefinition.bEnabled = OMX_FALSE; pSECInputPort->portDefinition.bPopulated = OMX_FALSE; pSECInputPort->portDefinition.eDomain = OMX_PortDomainMax; pSECInputPort->portDefinition.bBuffersContiguous = OMX_FALSE; pSECInputPort->portDefinition.nBufferAlignment = 0; pSECInputPort->markType.hMarkTargetComponent = NULL; pSECInputPort->markType.pMarkData = NULL; pSECInputPort->bUseAndroidNativeBuffer = OMX_FALSE; pSECInputPort->bStoreMetaDataInBuffer = OMX_FALSE; /* Output Port */ pSECOutputPort = &pSECPort[OUTPUT_PORT_INDEX]; SEC_OSAL_QueueCreate(&pSECOutputPort->bufferQ); pSECOutputPort->bufferHeader = SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); if (pSECOutputPort->bufferHeader == NULL) { SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); pSECInputPort->unloadedResource = NULL; SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); pSECInputPort->loadedResource = NULL; SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); pSECInputPort->bufferStateAllocate = NULL; SEC_OSAL_Free(pSECInputPort->bufferHeader); pSECInputPort->bufferHeader = NULL; SEC_OSAL_Free(pSECPort); pSECPort = NULL; ret = OMX_ErrorInsufficientResources; goto EXIT; } SEC_OSAL_Memset(pSECOutputPort->bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); pSECOutputPort->bufferStateAllocate = SEC_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); if (pSECOutputPort->bufferStateAllocate == NULL) { SEC_OSAL_Free(pSECOutputPort->bufferHeader); pSECOutputPort->bufferHeader = NULL; SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); pSECInputPort->unloadedResource = NULL; SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); pSECInputPort->loadedResource = NULL; SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); pSECInputPort->bufferStateAllocate = NULL; SEC_OSAL_Free(pSECInputPort->bufferHeader); pSECInputPort->bufferHeader = NULL; SEC_OSAL_Free(pSECPort); pSECPort = NULL; ret = OMX_ErrorInsufficientResources; goto EXIT; } SEC_OSAL_Memset(pSECOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); pSECOutputPort->bufferSemID = NULL; pSECOutputPort->assignedBufferNum = 0; pSECOutputPort->portState = OMX_StateMax; pSECOutputPort->bIsPortFlushed = OMX_FALSE; pSECOutputPort->bIsPortDisabled = OMX_FALSE; pSECOutputPort->tunneledComponent = NULL; pSECOutputPort->tunneledPort = 0; pSECOutputPort->tunnelBufferNum = 0; pSECOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified; pSECOutputPort->tunnelFlags = 0; pSECOutputPort->eControlRate = OMX_Video_ControlRateDisable; ret = SEC_OSAL_SemaphoreCreate(&pSECOutputPort->loadedResource); if (ret != OMX_ErrorNone) { SEC_OSAL_Free(pSECOutputPort->bufferStateAllocate); pSECOutputPort->bufferStateAllocate = NULL; SEC_OSAL_Free(pSECOutputPort->bufferHeader); pSECOutputPort->bufferHeader = NULL; SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); pSECInputPort->unloadedResource = NULL; SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); pSECInputPort->loadedResource = NULL; SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); pSECInputPort->bufferStateAllocate = NULL; SEC_OSAL_Free(pSECInputPort->bufferHeader); pSECInputPort->bufferHeader = NULL; SEC_OSAL_Free(pSECPort); pSECPort = NULL; goto EXIT; } ret = SEC_OSAL_SemaphoreCreate(&pSECOutputPort->unloadedResource); if (ret != OMX_ErrorNone) { SEC_OSAL_SemaphoreTerminate(pSECOutputPort->loadedResource); pSECOutputPort->loadedResource = NULL; SEC_OSAL_Free(pSECOutputPort->bufferStateAllocate); pSECOutputPort->bufferStateAllocate = NULL; SEC_OSAL_Free(pSECOutputPort->bufferHeader); pSECOutputPort->bufferHeader = NULL; SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); pSECInputPort->unloadedResource = NULL; SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); pSECInputPort->loadedResource = NULL; SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); pSECInputPort->bufferStateAllocate = NULL; SEC_OSAL_Free(pSECInputPort->bufferHeader); pSECInputPort->bufferHeader = NULL; SEC_OSAL_Free(pSECPort); pSECPort = NULL; goto EXIT; } INIT_SET_SIZE_VERSION(&pSECOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); pSECOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX; pSECOutputPort->portDefinition.eDir = OMX_DirOutput; pSECOutputPort->portDefinition.nBufferCountActual = 0; pSECOutputPort->portDefinition.nBufferCountMin = 0; pSECOutputPort->portDefinition.nBufferSize = 0; pSECOutputPort->portDefinition.bEnabled = OMX_FALSE; pSECOutputPort->portDefinition.bPopulated = OMX_FALSE; pSECOutputPort->portDefinition.eDomain = OMX_PortDomainMax; pSECOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE; pSECOutputPort->portDefinition.nBufferAlignment = 0; pSECOutputPort->markType.hMarkTargetComponent = NULL; pSECOutputPort->markType.pMarkData = NULL; pSECOutputPort->bUseAndroidNativeBuffer = OMX_FALSE; pSECOutputPort->bStoreMetaDataInBuffer = OMX_FALSE; pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; pSECComponent->checkTimeStamp.startTimeStamp = 0; pSECComponent->checkTimeStamp.nStartFlags = 0x0; pOMXComponent->EmptyThisBuffer = &SEC_OMX_EmptyThisBuffer; pOMXComponent->FillThisBuffer = &SEC_OMX_FillThisBuffer; ret = OMX_ErrorNone; EXIT: FunctionOut(); return ret; } OMX_ERRORTYPE SEC_OMX_Port_Destructor(OMX_HANDLETYPE hComponent) { OMX_ERRORTYPE ret = OMX_ErrorNone; OMX_COMPONENTTYPE *pOMXComponent = NULL; SEC_OMX_BASECOMPONENT *pSECComponent = NULL; SEC_OMX_BASEPORT *pSECPort = NULL; FunctionIn(); int i = 0; if (hComponent == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); if (ret != OMX_ErrorNone) { goto EXIT; } if (pOMXComponent->pComponentPrivate == NULL) { ret = OMX_ErrorBadParameter; goto EXIT; } pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; for (i = 0; i < ALL_PORT_NUM; i++) { pSECPort = &pSECComponent->pSECPort[i]; SEC_OSAL_SemaphoreTerminate(pSECPort->loadedResource); pSECPort->loadedResource = NULL; SEC_OSAL_SemaphoreTerminate(pSECPort->unloadedResource); pSECPort->unloadedResource = NULL; SEC_OSAL_Free(pSECPort->bufferStateAllocate); pSECPort->bufferStateAllocate = NULL; SEC_OSAL_Free(pSECPort->bufferHeader); pSECPort->bufferHeader = NULL; SEC_OSAL_QueueTerminate(&pSECPort->bufferQ); } SEC_OSAL_Free(pSECComponent->pSECPort); pSECComponent->pSECPort = NULL; ret = OMX_ErrorNone; EXIT: FunctionOut(); return ret; }