From: Ethan Chen Date: Thu, 26 Jun 2014 07:43:53 +0000 (-0700) Subject: OpenMax: Update from ODROID-XU 04212014 BSP X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=refs%2Fheads%2Fstable%2Fcm-11.0;p=GitHub%2FLineageOS%2Fandroid_hardware_samsung_slsi_openmax.git OpenMax: Update from ODROID-XU 04212014 BSP Change-Id: I3f3a000cee43c0ae20f8d0d117195d115025af7b --- diff --git a/Android.mk b/Android.mk index c871a4a..276894e 100644 --- a/Android.mk +++ b/Android.mk @@ -41,6 +41,9 @@ include $(EXYNOS_OMX_COMPONENT)/video/dec/vc1/Android.mk include $(EXYNOS_OMX_COMPONENT)/video/enc/Android.mk include $(EXYNOS_OMX_COMPONENT)/video/enc/h264/Android.mk include $(EXYNOS_OMX_COMPONENT)/video/enc/mpeg4/Android.mk +ifeq ($(BOARD_USE_VP8ENC_SUPPORT), true) +include $(EXYNOS_OMX_COMPONENT)/video/enc/vp8/Android.mk +endif ifeq ($(BOARD_USE_ALP_AUDIO), true) include $(EXYNOS_OMX_COMPONENT)/audio/dec/Android.mk diff --git a/component/common/Exynos_OMX_Basecomponent.c b/component/common/Exynos_OMX_Basecomponent.c index 91cbf3f..6b03907 100644 --- a/component/common/Exynos_OMX_Basecomponent.c +++ b/component/common/Exynos_OMX_Basecomponent.c @@ -191,6 +191,7 @@ OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX if ((currentState == OMX_StateLoaded) && (destState == OMX_StateIdle)) { ret = Exynos_OMX_Get_Resource(pOMXComponent); if (ret != OMX_ErrorNone) { + Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent); goto EXIT; } } @@ -236,7 +237,7 @@ OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); pExynosComponent->pExynosPort[i].pauseEvent = NULL; if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) { - Exynos_OSAL_SignalTerminate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; } } @@ -281,7 +282,7 @@ OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); pExynosComponent->pExynosPort[i].pauseEvent = NULL; if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) { - Exynos_OSAL_SignalTerminate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; } } @@ -422,7 +423,7 @@ OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); pExynosComponent->pExynosPort[i].pauseEvent = NULL; if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) { - Exynos_OSAL_SignalTerminate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; } } diff --git a/component/common/Exynos_OMX_Baseport.c b/component/common/Exynos_OMX_Baseport.c index 87b918a..073e288 100644 --- a/component/common/Exynos_OMX_Baseport.c +++ b/component/common/Exynos_OMX_Baseport.c @@ -74,7 +74,7 @@ OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OM OMX_U32 i = 0; Exynos_OSAL_MutexLock(pExynosPort->hPortMutex); - for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + for (i = 0; i < MAX_BUFFER_NUM; i++) { if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) { pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE; break; @@ -292,14 +292,17 @@ OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OM 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; + if ((pExynosComponent->currentState == OMX_StateExecuting) || + (pExynosComponent->currentState == OMX_StatePause)) { + /* port flush*/ + for(i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; - Exynos_OMX_BufferFlushProcess(pOMXComponent, portIndex, OMX_FALSE); + Exynos_OMX_BufferFlushProcess(pOMXComponent, portIndex, OMX_FALSE); + } } for(i = 0; i < cnt; i++) { @@ -614,6 +617,7 @@ OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent) pExynosInputPort->bufferSemID = NULL; pExynosInputPort->assignedBufferNum = 0; + pExynosInputPort->nPlaneCnt = 0; pExynosInputPort->portState = OMX_StateMax; pExynosInputPort->bIsPortFlushed = OMX_FALSE; pExynosInputPort->bIsPortDisabled = OMX_FALSE; @@ -705,6 +709,7 @@ OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent) pExynosOutputPort->bufferSemID = NULL; pExynosOutputPort->assignedBufferNum = 0; + pExynosOutputPort->nPlaneCnt = 0; pExynosOutputPort->portState = OMX_StateMax; pExynosOutputPort->bIsPortFlushed = OMX_FALSE; pExynosOutputPort->bIsPortDisabled = OMX_FALSE; diff --git a/component/common/Exynos_OMX_Baseport.h b/component/common/Exynos_OMX_Baseport.h index 6972471..4a8ae62 100644 --- a/component/common/Exynos_OMX_Baseport.h +++ b/component/common/Exynos_OMX_Baseport.h @@ -151,6 +151,7 @@ typedef struct _EXYNOS_OMX_BASEPORT OMX_HANDLETYPE bufferSemID; EXYNOS_QUEUE bufferQ; OMX_U32 assignedBufferNum; + OMX_U32 nPlaneCnt; OMX_STATETYPE portState; OMX_HANDLETYPE loadedResource; OMX_HANDLETYPE unloadedResource; @@ -207,6 +208,7 @@ OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent); OMX_ERRORTYPE Exynos_ResetDataBuffer(EXYNOS_OMX_DATABUFFER *pDataBuffer); OMX_ERRORTYPE Exynos_ResetCodecData(EXYNOS_OMX_DATA *pData); OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_PLANE nPlane); +OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader); #ifdef __cplusplus }; diff --git a/component/common/Exynos_OMX_Resourcemanager.c b/component/common/Exynos_OMX_Resourcemanager.c index 7cfdfae..c040b6a 100644 --- a/component/common/Exynos_OMX_Resourcemanager.c +++ b/component/common/Exynos_OMX_Resourcemanager.c @@ -39,22 +39,109 @@ #include "Exynos_OSAL_Log.h" -#define MAX_RESOURCE_VIDEO_DEC 8 /* for Android */ -#define MAX_RESOURCE_VIDEO_ENC 8 /* for Android */ +#define MAX_RESOURCE_VIDEO_DEC 8 +#define MAX_RESOURCE_VIDEO_ENC 8 +#define MAX_RESOURCE_AUDIO_DEC 1 +/* Add new resource block */ -/* Max allowable video scheduler component instance */ -static EXYNOS_OMX_RM_COMPONENT_LIST *gpVideoDecRMComponentList = NULL; -static EXYNOS_OMX_RM_COMPONENT_LIST *gpVideoDecRMWaitingList = NULL; -static EXYNOS_OMX_RM_COMPONENT_LIST *gpVideoEncRMComponentList = NULL; -static EXYNOS_OMX_RM_COMPONENT_LIST *gpVideoEncRMWaitingList = NULL; -static OMX_HANDLETYPE ghVideoRMComponentListMutex = NULL; +typedef enum _EXYNOS_OMX_RESOURCE +{ + VIDEO_DEC, + VIDEO_ENC, + AUDIO_DEC, + /* Add new resource block */ + RESOURCE_MAX +} EXYNOS_OMX_RESOURCE; + +typedef struct _EXYNOS_OMX_RM_COMPONENT_LIST +{ + OMX_COMPONENTTYPE *pOMXStandComp; + OMX_U32 groupPriority; + struct _EXYNOS_OMX_RM_COMPONENT_LIST *pNext; +} EXYNOS_OMX_RM_COMPONENT_LIST; + +/* Max allowable scheduler component instance */ +static EXYNOS_OMX_RM_COMPONENT_LIST *gpRMList[RESOURCE_MAX]; +static EXYNOS_OMX_RM_COMPONENT_LIST *gpRMWaitList[RESOURCE_MAX]; +static OMX_HANDLETYPE ghVideoRMComponentListMutex = NULL; + +EXYNOS_OMX_RM_COMPONENT_LIST *getRMList( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent, + EXYNOS_OMX_RM_COMPONENT_LIST *pRMList[], + int *pMaxResource) +{ + EXYNOS_OMX_RM_COMPONENT_LIST *ret = NULL; + + if (pExynosComponent == NULL) + goto EXIT; + + switch (pExynosComponent->codecType) { + case HW_VIDEO_DEC_CODEC: + ret = pRMList[VIDEO_DEC]; + if (pMaxResource != NULL) + *pMaxResource = MAX_RESOURCE_VIDEO_DEC; + break; + case HW_VIDEO_ENC_CODEC: + ret = pRMList[VIDEO_ENC]; + if (pMaxResource != NULL) + *pMaxResource = MAX_RESOURCE_VIDEO_ENC; + break; + case HW_AUDIO_DEC_CODEC: + ret = pRMList[AUDIO_DEC]; + if (pMaxResource != NULL) + *pMaxResource = MAX_RESOURCE_AUDIO_DEC; + break; + /* Add new resource block */ + default: + ret = NULL; + if (pMaxResource != NULL) + *pMaxResource = 0; + break; + } +EXIT: + return ret; +} -OMX_ERRORTYPE addElementList(EXYNOS_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) +OMX_ERRORTYPE setRMList( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent, + EXYNOS_OMX_RM_COMPONENT_LIST *pRMList[], + EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentList) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_RM_COMPONENT_LIST *pTempComp = NULL; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (pExynosComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (pExynosComponent->codecType) { + case HW_VIDEO_DEC_CODEC: + pRMList[VIDEO_DEC] = pRMComponentList; + break; + case HW_VIDEO_ENC_CODEC: + pRMList[VIDEO_ENC] = pRMComponentList; + break; + case HW_AUDIO_DEC_CODEC: + pRMList[AUDIO_DEC] = pRMComponentList; + break; + /* Add new resource block */ + default: + ret = OMX_ErrorUndefined; + break; + } + +EXIT: + return ret; +} + +OMX_ERRORTYPE addElementList( + EXYNOS_OMX_RM_COMPONENT_LIST **ppList, + OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_RM_COMPONENT_LIST *pTempComp = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; if (*ppList != NULL) { @@ -62,11 +149,13 @@ OMX_ERRORTYPE addElementList(EXYNOS_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONEN while (pTempComp->pNext != NULL) { pTempComp = pTempComp->pNext; } + pTempComp->pNext = (EXYNOS_OMX_RM_COMPONENT_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_RM_COMPONENT_LIST)); if (pTempComp->pNext == NULL) { ret = OMX_ErrorInsufficientResources; goto EXIT; } + ((EXYNOS_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pNext = NULL; ((EXYNOS_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pOMXStandComp = pOMXComponent; ((EXYNOS_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->groupPriority = pExynosComponent->compPriority.nGroupPriority; @@ -77,6 +166,7 @@ OMX_ERRORTYPE addElementList(EXYNOS_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONEN ret = OMX_ErrorInsufficientResources; goto EXIT; } + pTempComp = *ppList; pTempComp->pNext = NULL; pTempComp->pOMXStandComp = pOMXComponent; @@ -87,12 +177,14 @@ EXIT: return ret; } -OMX_ERRORTYPE removeElementList(EXYNOS_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) +OMX_ERRORTYPE removeElementList( + EXYNOS_OMX_RM_COMPONENT_LIST **ppList, + OMX_COMPONENTTYPE *pOMXComponent) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_RM_COMPONENT_LIST *pCurrComp = NULL; - EXYNOS_OMX_RM_COMPONENT_LIST *pPrevComp = NULL; - OMX_BOOL bDetectComp = OMX_FALSE; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_RM_COMPONENT_LIST *pCurrComp = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pPrevComp = NULL; + OMX_BOOL bDetectComp = OMX_FALSE; if (*ppList == NULL) { ret = OMX_ErrorUndefined; @@ -105,12 +197,15 @@ OMX_ERRORTYPE removeElementList(EXYNOS_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPO if (*ppList == pCurrComp) { *ppList = pCurrComp->pNext; Exynos_OSAL_Free(pCurrComp); + pCurrComp = NULL; } else { if (pPrevComp != NULL) pPrevComp->pNext = pCurrComp->pNext; Exynos_OSAL_Free(pCurrComp); + pCurrComp = NULL; } + bDetectComp = OMX_TRUE; break; } else { @@ -128,16 +223,19 @@ EXIT: return ret; } -int searchLowPriority(EXYNOS_OMX_RM_COMPONENT_LIST *RMComp_list, OMX_U32 inComp_priority, EXYNOS_OMX_RM_COMPONENT_LIST **outLowComp) +int searchLowPriority( + EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentList, + OMX_U32 inComp_priority, + EXYNOS_OMX_RM_COMPONENT_LIST **outLowComp) { - int ret = 0; - EXYNOS_OMX_RM_COMPONENT_LIST *pTempComp = NULL; - EXYNOS_OMX_RM_COMPONENT_LIST *pCandidateComp = NULL; + int ret = 0; + EXYNOS_OMX_RM_COMPONENT_LIST *pTempComp = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pCandidateComp = NULL; - if (RMComp_list == NULL) + if (pRMComponentList == NULL) ret = -1; - pTempComp = RMComp_list; + pTempComp = pRMComponentList; *outLowComp = 0; while (pTempComp != NULL) { @@ -165,20 +263,24 @@ EXIT: OMX_ERRORTYPE removeComponent(OMX_COMPONENTTYPE *pOMXComponent) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; if (pExynosComponent->currentState == OMX_StateIdle) { - (*(pExynosComponent->pCallbacks->EventHandler)) - (pOMXComponent, pExynosComponent->callbackData, - OMX_EventError, OMX_ErrorResourcesLost, 0, NULL); + (*(pExynosComponent->pCallbacks->EventHandler))(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, + OMX_ErrorResourcesLost, + 0, + NULL); ret = OMX_SendCommand(pOMXComponent, OMX_CommandStateSet, OMX_StateLoaded, NULL); if (ret != OMX_ErrorNone) { ret = OMX_ErrorUndefined; goto EXIT; } - } else if ((pExynosComponent->currentState == OMX_StateExecuting) || (pExynosComponent->currentState == OMX_StatePause)) { + } else if ((pExynosComponent->currentState == OMX_StateExecuting) || + (pExynosComponent->currentState == OMX_StatePause)) { /* Todo */ } @@ -194,7 +296,16 @@ OMX_ERRORTYPE Exynos_OMX_ResourceManager_Init() OMX_ERRORTYPE ret = OMX_ErrorNone; FunctionIn(); + ret = Exynos_OSAL_MutexCreate(&ghVideoRMComponentListMutex); + + if (ret == OMX_ErrorNone) { + Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); + Exynos_OSAL_Memset(gpRMList, NULL, (sizeof(EXYNOS_OMX_RM_COMPONENT_LIST*) * RESOURCE_MAX)); + Exynos_OSAL_Memset(gpRMWaitList, NULL, (sizeof(EXYNOS_OMX_RM_COMPONENT_LIST*) * RESOURCE_MAX)); + Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + } + FunctionOut(); return ret; @@ -202,50 +313,35 @@ OMX_ERRORTYPE Exynos_OMX_ResourceManager_Init() OMX_ERRORTYPE Exynos_OMX_ResourceManager_Deinit() { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_RM_COMPONENT_LIST *pCurrComponent; - EXYNOS_OMX_RM_COMPONENT_LIST *pNextComponent; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_RM_COMPONENT_LIST *pCurrComponent = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pNextComponent = NULL; + int i = 0; FunctionIn(); Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); - if (gpVideoDecRMComponentList) { - pCurrComponent = gpVideoDecRMComponentList; - while (pCurrComponent != NULL) { - pNextComponent = pCurrComponent->pNext; - Exynos_OSAL_Free(pCurrComponent); - pCurrComponent = pNextComponent; - } - gpVideoDecRMComponentList = NULL; - } - if (gpVideoDecRMWaitingList) { - pCurrComponent = gpVideoDecRMWaitingList; - while (pCurrComponent != NULL) { - pNextComponent = pCurrComponent->pNext; - Exynos_OSAL_Free(pCurrComponent); - pCurrComponent = pNextComponent; + for (i = 0; i < RESOURCE_MAX; i++) { + if (gpRMList[i]) { + pCurrComponent = gpRMList[i]; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + Exynos_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpRMList[i] = NULL; } - gpVideoDecRMWaitingList = NULL; - } - if (gpVideoEncRMComponentList) { - pCurrComponent = gpVideoEncRMComponentList; - while (pCurrComponent != NULL) { - pNextComponent = pCurrComponent->pNext; - Exynos_OSAL_Free(pCurrComponent); - pCurrComponent = pNextComponent; - } - gpVideoEncRMComponentList = NULL; - } - if (gpVideoEncRMWaitingList) { - pCurrComponent = gpVideoEncRMWaitingList; - while (pCurrComponent != NULL) { - pNextComponent = pCurrComponent->pNext; - Exynos_OSAL_Free(pCurrComponent); - pCurrComponent = pNextComponent; + if (gpRMWaitList[i]) { + pCurrComponent = gpRMWaitList[i]; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + Exynos_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpRMWaitList[i] = NULL; } - gpVideoEncRMWaitingList = NULL; } Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); @@ -254,6 +350,7 @@ OMX_ERRORTYPE Exynos_OMX_ResourceManager_Deinit() ghVideoRMComponentListMutex = NULL; ret = OMX_ErrorNone; + EXIT: FunctionOut(); @@ -262,96 +359,67 @@ EXIT: OMX_ERRORTYPE Exynos_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; - EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; - EXYNOS_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL; - int numElem = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentList = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL; + int numElem = 0; int lowCompDetect = 0; + int maxResource = 0; FunctionIn(); Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pRMComponentList = getRMList(pExynosComponent, gpRMList, &maxResource); - if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) { - pComponentTemp = gpVideoDecRMComponentList; - if (pComponentTemp != NULL) { - while (pComponentTemp) { - numElem++; - pComponentTemp = pComponentTemp->pNext; - } - } else { - numElem = 0; + pComponentTemp = pRMComponentList; + if (pComponentTemp != NULL) { + while (pComponentTemp) { + numElem++; + pComponentTemp = pComponentTemp->pNext; } - if (numElem >= MAX_RESOURCE_VIDEO_DEC) { - lowCompDetect = searchLowPriority(gpVideoDecRMComponentList, pExynosComponent->compPriority.nGroupPriority, &pComponentCandidate); - if (lowCompDetect <= 0) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } else { - ret = removeComponent(pComponentCandidate->pOMXStandComp); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } else { - ret = removeElementList(&gpVideoDecRMComponentList, pComponentCandidate->pOMXStandComp); - ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } + } else { + numElem = 0; + } + + if (numElem >= maxResource) { + lowCompDetect = searchLowPriority(pRMComponentList, + pExynosComponent->compPriority.nGroupPriority, + &pComponentCandidate); + if (lowCompDetect <= 0) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; } else { - ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent); + ret = removeComponent(pComponentCandidate->pOMXStandComp); if (ret != OMX_ErrorNone) { ret = OMX_ErrorInsufficientResources; goto EXIT; - } - } - } else if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) { - pComponentTemp = gpVideoEncRMComponentList; - if (pComponentTemp != NULL) { - while (pComponentTemp) { - numElem++; - pComponentTemp = pComponentTemp->pNext; - } - } else { - numElem = 0; - } - if (numElem >= MAX_RESOURCE_VIDEO_ENC) { - lowCompDetect = searchLowPriority(gpVideoEncRMComponentList, pExynosComponent->compPriority.nGroupPriority, &pComponentCandidate); - if (lowCompDetect <= 0) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; } else { - ret = removeComponent(pComponentCandidate->pOMXStandComp); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; + ret = removeElementList(&pRMComponentList, pComponentCandidate->pOMXStandComp); + if (ret != OMX_ErrorNone) + goto EXIT; + + ret = addElementList(&pRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) goto EXIT; - } else { - ret = removeElementList(&gpVideoEncRMComponentList, pComponentCandidate->pOMXStandComp); - ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } - } else { - ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; } } + } else { + ret = addElementList(&pRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; } + + ret = setRMList(pExynosComponent, gpRMList, pRMComponentList); + if (ret != OMX_ErrorNone) + goto EXIT; + ret = OMX_ErrorNone; EXIT: - Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); FunctionOut(); @@ -361,10 +429,12 @@ EXIT: OMX_ERRORTYPE Exynos_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; - EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; - OMX_COMPONENTTYPE *pOMXWaitComponent = NULL; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentList = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentWaitList = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; + OMX_COMPONENTTYPE *pOMXWaitComponent = NULL; int numElem = 0; FunctionIn(); @@ -372,59 +442,44 @@ OMX_ERRORTYPE Exynos_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent) Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pRMComponentList = getRMList(pExynosComponent, gpRMList, NULL); + if (pRMComponentList == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } - if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) { - pComponentTemp = gpVideoDecRMWaitingList; - if (gpVideoDecRMComponentList == NULL) { - ret = OMX_ErrorUndefined; - goto EXIT; - } + ret = removeElementList(&pRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; - ret = removeElementList(&gpVideoDecRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorUndefined; + ret = setRMList(pExynosComponent, gpRMList, pRMComponentList); + if (ret != OMX_ErrorNone) + goto EXIT; + + pRMComponentWaitList = getRMList(pExynosComponent, gpRMWaitList, NULL); + pComponentTemp = pRMComponentWaitList; + + while (pComponentTemp) { + numElem++; + pComponentTemp = pComponentTemp->pNext; + } + + if (numElem > 0) { + pOMXWaitComponent = pRMComponentWaitList->pOMXStandComp; + ret = removeElementList(&pRMComponentWaitList, pOMXWaitComponent); + if (ret != OMX_ErrorNone) goto EXIT; - } - while (pComponentTemp) { - numElem++; - pComponentTemp = pComponentTemp->pNext; - } - if (numElem > 0) { - pOMXWaitComponent = gpVideoDecRMWaitingList->pOMXStandComp; - removeElementList(&gpVideoDecRMWaitingList, pOMXWaitComponent); - ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - } - } else if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) { - pComponentTemp = gpVideoEncRMWaitingList; - if (gpVideoEncRMComponentList == NULL) { - ret = OMX_ErrorUndefined; + + ret = setRMList(pExynosComponent, gpRMWaitList, pRMComponentWaitList); + if (ret != OMX_ErrorNone) goto EXIT; - } - ret = removeElementList(&gpVideoEncRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorUndefined; + ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL); + if (ret != OMX_ErrorNone) goto EXIT; - } - while (pComponentTemp) { - numElem++; - pComponentTemp = pComponentTemp->pNext; - } - if (numElem > 0) { - pOMXWaitComponent = gpVideoEncRMWaitingList->pOMXStandComp; - removeElementList(&gpVideoEncRMWaitingList, pOMXWaitComponent); - ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - } } EXIT: - Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); FunctionOut(); @@ -434,19 +489,24 @@ EXIT: OMX_ERRORTYPE Exynos_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentWaitList = NULL; FunctionIn(); Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); - pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) - ret = addElementList(&gpVideoDecRMWaitingList, pOMXComponent); - else if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) - ret = addElementList(&gpVideoEncRMWaitingList, pOMXComponent); + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pRMComponentWaitList = getRMList(pExynosComponent, gpRMWaitList, NULL); + + ret = addElementList(&pRMComponentWaitList, pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + ret = setRMList(pExynosComponent, gpRMWaitList, pRMComponentWaitList); + +EXIT: Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); FunctionOut(); @@ -456,19 +516,24 @@ OMX_ERRORTYPE Exynos_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) OMX_ERRORTYPE Exynos_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentWaitList = NULL; FunctionIn(); Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); - pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) - ret = removeElementList(&gpVideoDecRMWaitingList, pOMXComponent); - else if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) - ret = removeElementList(&gpVideoEncRMWaitingList, pOMXComponent); + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pRMComponentWaitList = getRMList(pExynosComponent, gpRMWaitList, NULL); + ret = removeElementList(&pRMComponentWaitList, pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + + ret = setRMList(pExynosComponent, gpRMWaitList, pRMComponentWaitList); + +EXIT: Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); FunctionOut(); diff --git a/component/common/Exynos_OMX_Resourcemanager.h b/component/common/Exynos_OMX_Resourcemanager.h index e9db7c4..fb896a7 100644 --- a/component/common/Exynos_OMX_Resourcemanager.h +++ b/component/common/Exynos_OMX_Resourcemanager.h @@ -32,15 +32,6 @@ #include "OMX_Component.h" -struct EXYNOS_OMX_RM_COMPONENT_LIST; -typedef struct _EXYNOS_OMX_RM_COMPONENT_LIST -{ - OMX_COMPONENTTYPE *pOMXStandComp; - OMX_U32 groupPriority; - struct _EXYNOS_OMX_RM_COMPONENT_LIST *pNext; -} EXYNOS_OMX_RM_COMPONENT_LIST; - - #ifdef __cplusplus extern "C" { #endif diff --git a/component/video/dec/Android.mk b/component/video/dec/Android.mk index 3a81f07..b2b71d3 100644 --- a/component/video/dec/Android.mk +++ b/component/video/dec/Android.mk @@ -47,4 +47,12 @@ ifeq ($(BOARD_USE_CSC_HW), true) LOCAL_CFLAGS += -DUSE_CSC_HW endif +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_DUALDPB_MODE), true) +LOCAL_CFLAGS += -DUSE_DUALDPB_MODE +endif + include $(BUILD_STATIC_LIBRARY) diff --git a/component/video/dec/Exynos_OMX_Vdec.c b/component/video/dec/Exynos_OMX_Vdec.c index 2d39d32..d3442fa 100644 --- a/component/video/dec/Exynos_OMX_Vdec.c +++ b/component/video/dec/Exynos_OMX_Vdec.c @@ -78,6 +78,8 @@ inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) case OMX_COLOR_FormatYUV420Planar: case OMX_COLOR_FormatYUV420SemiPlanar: case OMX_SEC_COLOR_FormatNV12Tiled: + case OMX_SEC_COLOR_FormatYVU420Planar: + case OMX_SEC_COLOR_FormatNV21Linear: if (width && height) exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; break; @@ -108,12 +110,11 @@ void Exynos_Free_CodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]); nBufferCnt = MFC_INPUT_BUFFER_NUM_MAX; - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; } else { ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]); nBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX; - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; for (i = 0; i < nBufferCnt; i++) { if (ppCodecBuffer[i] != NULL) { @@ -134,7 +135,7 @@ OMX_ERRORTYPE Exynos_Allocate_CodecBuffers( OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex, OMX_U32 nBufferCnt, - OMX_U32 nPlaneSize[MFC_OUTPUT_BUFFER_PLANE]) + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE]) { OMX_ERRORTYPE ret = OMX_ErrorNone; EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; @@ -149,14 +150,13 @@ OMX_ERRORTYPE Exynos_Allocate_CodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]); - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; } else { ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]); - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; #ifdef USE_CSC_HW eMemoryType = NORMAL_MEMORY; #endif } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; if (pVideoDec->bDRMPlayerMode == OMX_TRUE) eMemoryType = SECURE_MEMORY; @@ -235,6 +235,7 @@ OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent) pInputPort->bufferProcessType = BUFFER_SHARE; pInputPort->portWayType = WAY2_PORT; + pInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE; /* Output port */ pOutputPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; @@ -251,6 +252,7 @@ OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent) pOutputPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE; pOutputPort->bIsANBEnabled = OMX_FALSE; pOutputPort->portWayType = WAY2_PORT; + pOutputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420Planar); return ret; } @@ -335,103 +337,142 @@ OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; OMX_U32 copySize = 0; DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; + OMX_COLOR_FORMATTYPE eColorFormat = exynosOutputPort->portDefinition.format.video.eColorFormat; FunctionIn(); - OMX_U32 width = 0, height = 0; - int imageSize = 0; - OMX_COLOR_FORMATTYPE colorFormat; - - void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer; + void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer; void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, }; void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, }; - CSC_ERRORCODE cscRet = CSC_ErrorNone; - CSC_METHOD csc_method = CSC_METHOD_SW; - CSC_MEMTYPE csc_memType = CSC_MEMORY_USERPTR; + ExynosVideoPlane planes[MAX_BUFFER_PLANE]; + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {0, 0, 0}; + + OMX_U32 nFrameWidth = 0, nFrameHeight = 0; + OMX_U32 nImageWidth = 0, nImageHeight = 0, stride = 0; + CSC_MEMTYPE csc_memType = CSC_MEMORY_USERPTR; + CSC_METHOD csc_method = CSC_METHOD_SW; + CSC_ERRORCODE cscRet = CSC_ErrorNone; unsigned int srcCacheable = 1, dstCacheable = 1; - pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo; + nFrameWidth = exynosOutputPort->portDefinition.format.video.nStride; + nFrameHeight = exynosOutputPort->portDefinition.format.video.nSliceHeight; - width = pBufferInfo->imageWidth; - height = pBufferInfo->imageHeight; - imageSize = width * height; - colorFormat = pBufferInfo->ColorFormat; + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo; + nImageWidth = pBufferInfo->imageWidth; + nImageHeight = pBufferInfo->imageHeight; pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0]; pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1]; pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[2]; - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; + Exynos_OSAL_GetPlaneSize(eColorFormat, nImageWidth, nImageHeight, nPlaneSize); - csc_get_method(pVideoDec->csc_handle, &csc_method); - if (csc_method == CSC_METHOD_HW) - srcCacheable = 0; - -#ifdef USE_DMA_BUF - if (csc_method == CSC_METHOD_HW) { - csc_memType = CSC_MEMORY_DMABUF; - pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0]; - pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1]; - pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2]; - } -#endif + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + nPlaneSize[0]; + pYUVBuf[2] = (unsigned char *)pOutputBuf + nPlaneSize[0] + nPlaneSize[1]; #ifdef USE_ANB if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) { - ExynosVideoPlane planes[MAX_BUFFER_PLANE]; - OMX_U32 stride; - Exynos_OSAL_LockANB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes); - width = stride; + Exynos_OSAL_LockANB(pOutputBuf, nImageWidth, nImageHeight, eColorFormat, &stride, planes); + nImageWidth = stride; outputUseBuffer->dataLen = sizeof(void *); pYUVBuf[0] = (unsigned char *)planes[0].addr; pYUVBuf[1] = (unsigned char *)planes[1].addr; pYUVBuf[2] = (unsigned char *)planes[2].addr; + } +#endif + + if (pVideoDec->bDualDPBMode == OMX_TRUE) { + switch (eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear: + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled: + case OMX_COLOR_FormatYUV420Planar: + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar: + csc_set_method(pVideoDec->csc_handle, CSC_METHOD_SW); + csc_memType = CSC_MEMORY_MFC; + if (pVideoDec->csc_set_format == OMX_FALSE) { + csc_set_src_format( + pVideoDec->csc_handle, /* handle */ + nFrameWidth, /* width */ + nFrameHeight, /* height */ + 0, /* crop_left */ + 0, /* crop_right */ + nImageWidth, /* crop_width */ + nImageHeight, /* crop_height */ + omx_2_hal_pixel_format(pBufferInfo->ColorFormat), /* color_format */ + 0); /* cacheable */ + csc_set_dst_format( + pVideoDec->csc_handle, /* handle */ + nImageWidth, /* width */ + nImageHeight, /* height */ + 0, /* crop_left */ + 0, /* crop_right */ + nImageWidth, /* crop_width */ + nImageHeight, /* crop_height */ + omx_2_hal_pixel_format(eColorFormat), /* color_format */ + 0); /* cacheable */ + pVideoDec->csc_set_format = OMX_TRUE; + } + break; + default: + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unspported color format : %x. can't support this format", __FUNCTION__, eColorFormat); + ret = OMX_FALSE; + goto EXIT; + break; + } + } else { + csc_get_method(pVideoDec->csc_handle, &csc_method); + if (csc_method == CSC_METHOD_HW) + srcCacheable = 0; + #ifdef USE_DMA_BUF if (csc_method == CSC_METHOD_HW) { - pYUVBuf[0] = (unsigned char *)planes[0].fd; - pYUVBuf[1] = (unsigned char *)planes[1].fd; - pYUVBuf[2] = (unsigned char *)planes[2].fd; + csc_memType = CSC_MEMORY_DMABUF; + + pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0]; + pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1]; + pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2]; + + if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) { + pYUVBuf[0] = (unsigned char *)planes[0].fd; + pYUVBuf[1] = (unsigned char *)planes[1].fd; + pYUVBuf[2] = (unsigned char *)planes[2].fd; + } else { + pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf); + pYUVBuf[1] = NULL; + pYUVBuf[2] = NULL; + } } #endif + if (pVideoDec->csc_set_format == OMX_FALSE) { + csc_set_src_format( + pVideoDec->csc_handle, /* handle */ + nImageWidth, /* width */ + nImageHeight, /* height */ + 0, /* crop_left */ + 0, /* crop_right */ + nImageWidth, /* crop_width */ + nImageHeight, /* crop_height */ + omx_2_hal_pixel_format(pBufferInfo->ColorFormat), /* color_format */ + srcCacheable); /* cacheable */ + csc_set_dst_format( + pVideoDec->csc_handle, /* handle */ + nImageWidth, /* width */ + nImageHeight, /* height */ + 0, /* crop_left */ + 0, /* crop_right */ + nImageWidth, /* crop_width */ + nImageHeight, /* crop_height */ + omx_2_hal_pixel_format(eColorFormat), /* color_format */ + dstCacheable); /* cacheable */ + pVideoDec->csc_set_format = OMX_TRUE; + } } -#endif -#ifdef USE_DMA_BUF - if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) && - (csc_method == CSC_METHOD_HW)) { - pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf); - pYUVBuf[1] = NULL; - pYUVBuf[2] = NULL; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - omx_2_hal_pixel_format(colorFormat), /* color_format */ - srcCacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - omx_2_hal_pixel_format(exynosOutputPort->portDefinition.format.video.eColorFormat), /* color_format */ - dstCacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } csc_set_src_buffer( pVideoDec->csc_handle, /* handle */ pSrcBuf, @@ -493,7 +534,12 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ goto EXIT; } + srcInputData->buffer.singlePlaneBuffer.fd = srcInputData->buffer.singlePlaneBuffer.dataBuffer; srcInputData->buffer.singlePlaneBuffer.dataBuffer = dataBuffer; + } else { + srcInputData->buffer.singlePlaneBuffer.fd = + Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, + srcInputData->buffer.singlePlaneBuffer.dataBuffer); } /* reset dataBuffer */ @@ -619,16 +665,6 @@ OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ } if (exynosOutputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 width = 0, height = 0; - int imageSize = 0; - void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer; - - pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo; - - width = pBufferInfo->imageWidth; - height = pBufferInfo->imageHeight; - imageSize = width * height; - if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) && (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { copySize = dstOutputData->remainDataLen; @@ -1229,6 +1265,9 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone pVideoDec->bReconfigDPB = OMX_FALSE; pVideoDec->nSavedDPBCnt = 0; pVideoDec->bDTSMode = OMX_FALSE; + pVideoDec->bQosChanged = OMX_FALSE; + pVideoDec->nQosRatio = 0; + pVideoDec->bDualDPBMode = OMX_FALSE; pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec; pExynosComponent->bSaveFlagEOS = OMX_FALSE; diff --git a/component/video/dec/Exynos_OMX_Vdec.h b/component/video/dec/Exynos_OMX_Vdec.h index 48497e6..d72524a 100644 --- a/component/video/dec/Exynos_OMX_Vdec.h +++ b/component/video/dec/Exynos_OMX_Vdec.h @@ -52,12 +52,18 @@ #define DEFAULT_MFC_OUTPUT_CBUFFER_SIZE 1920 * 1080 / 2 #define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 +#ifdef USE_DUALDPB_MODE +#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 5 +#else #define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 4 +#endif #define EXTRA_DPB_NUM 5 -#define MFC_INPUT_BUFFER_PLANE 1 -#define MFC_OUTPUT_BUFFER_PLANE 2 +#define MFC_DEFAULT_INPUT_BUFFER_PLANE 1 +#define MFC_DEFAULT_OUTPUT_BUFFER_PLANE 2 + +#define MAX_INPUTBUFFER_NUM_DYNAMIC 0 /* Dynamic number of metadata buffer */ typedef struct { @@ -65,6 +71,12 @@ typedef struct void *pAddrC; } CODEC_DEC_ADDR_INFO; +typedef struct _BYPASS_BUFFER_INFO +{ + OMX_U32 nFlags; + OMX_TICKS timeStamp; +} BYPASS_BUFFER_INFO; + typedef struct _CODEC_DEC_BUFFER { void *pVirAddr[MAX_BUFFER_PLANE]; /* virtual address */ @@ -87,6 +99,8 @@ typedef struct _EXYNOS_OMX_VIDEODEC_COMPONENT OMX_BOOL bThumbnailMode; OMX_BOOL bDTSMode; /* true:Decoding Time Stamp, false:Presentation Time Stamp */ OMX_BOOL bFirstFrame; + OMX_BOOL bQosChanged; + OMX_U32 nQosRatio; CODEC_DEC_BUFFER *pMFCDecInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; CODEC_DEC_BUFFER *pMFCDecOutputBuffer[MFC_OUTPUT_BUFFER_NUM_MAX]; @@ -107,6 +121,9 @@ typedef struct _EXYNOS_OMX_VIDEODEC_COMPONENT OMX_BOOL bReconfigDPB; OMX_U32 nSavedDPBCnt; + /* For Dual DPB */ + OMX_BOOL bDualDPBMode; + /* CSC handle */ OMX_PTR csc_handle; OMX_U32 csc_set_format; diff --git a/component/video/dec/Exynos_OMX_VdecControl.c b/component/video/dec/Exynos_OMX_VdecControl.c index ae85de6..4357ae8 100644 --- a/component/video/dec/Exynos_OMX_VdecControl.c +++ b/component/video/dec/Exynos_OMX_VdecControl.c @@ -503,12 +503,18 @@ OMX_ERRORTYPE Exynos_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 por Exynos_ResetCodecData(&pExynosPort->processData); } - while(1) { - OMX_S32 cnt = 0; - Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &cnt); - if (cnt <= 0) - break; - Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[portIndex].bufferSemID); + if (pExynosPort->bufferSemID != NULL) { + while (1) { + OMX_S32 cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt); + if (cnt == 0) + break; + else if (cnt > 0) + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + else if (cnt < 0) + Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + Exynos_OSAL_SleepMillisec(0); + } } Exynos_OSAL_ResetQueue(&pExynosPort->bufferQ); @@ -560,7 +566,18 @@ OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 n if (pExynosComponent->pExynosPort[nPortIndex].bufferProcessType & BUFFER_COPY) Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID); - Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + + if (pExynosPort->bufferSemID != NULL) { + while (1) { + OMX_S32 cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt); + if (cnt > 0) + break; + else + Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + Exynos_OSAL_SleepMillisec(0); + } + } pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, nPortIndex); Exynos_OSAL_MutexLock(flushPortBuffer[0]->bufferMutex); @@ -1043,6 +1060,18 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetParameter( portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; portFormat->xFramerate = portDefinition->format.video.xFramerate; break; +#ifdef USE_DUALDPB_MODE + case supportFormat_3: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV21Linear; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_4: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatYVU420Planar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; +#endif default: if (index > supportFormat_0) { ret = OMX_ErrorNoMore; @@ -1427,6 +1456,23 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetConfig( ret = OMX_ErrorNone; } break; +#ifdef USE_QOS_CTRL + case OMX_IndexVendorSetQosRatio: + { + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *pQosInfo = (EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *)pComponentConfigStructure; + + ret = Exynos_OMX_Check_SizeVersion(pQosInfo, sizeof(EXYNOS_OMX_VIDEO_CONFIG_QOSINFO)); + if (ret != OMX_ErrorNone) + goto EXIT; + + pVideoDec->nQosRatio = pQosInfo->nQosRatio; + pVideoDec->bQosChanged = OMX_TRUE; + + ret = OMX_ErrorNone; + } + break; +#endif default: ret = Exynos_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); break; @@ -1487,6 +1533,13 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetExtensionIndex( ret = OMX_ErrorNone; goto EXIT; } +#ifdef USE_QOS_CTRL + else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_SET_QOS_RATIO) == 0) { + *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorSetQosRatio; + ret = OMX_ErrorNone; + goto EXIT; + } +#endif #ifdef USE_ANB if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_ANB) == 0) diff --git a/component/video/dec/Exynos_OMX_VdecControl.h b/component/video/dec/Exynos_OMX_VdecControl.h index 1d41198..eae42b5 100644 --- a/component/video/dec/Exynos_OMX_VdecControl.h +++ b/component/video/dec/Exynos_OMX_VdecControl.h @@ -97,6 +97,7 @@ OMX_ERRORTYPE Exynos_Shared_DataToANBBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_D #endif OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer); +OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(EXYNOS_OMX_BASECOMPONENT *pExynosComponent); #ifdef __cplusplus } diff --git a/component/video/dec/h264/Android.mk b/component/video/dec/h264/Android.mk index e297018..8f92860 100644 --- a/component/video/dec/h264/Android.mk +++ b/component/video/dec/h264/Android.mk @@ -24,13 +24,27 @@ LOCAL_CFLAGS += -DUSE_DMA_BUF endif ifeq ($(BOARD_USE_S3D_SUPPORT), true) +ifeq ($(BOARD_USES_HWC_SERVICES), true) LOCAL_CFLAGS += -DUSE_S3D_SUPPORT +else +ifeq ($(TARGET_BOARD_PLATFORM), exynos5) +LOCAL_CFLAGS += -DUSE_S3D_SUPPORT +endif +endif endif ifeq ($(BOARD_USE_CSC_HW), true) LOCAL_CFLAGS += -DUSE_CSC_HW endif +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_DUALDPB_MODE), true) +LOCAL_CFLAGS += -DUSE_DUALDPB_MODE +endif + LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ diff --git a/component/video/dec/h264/Exynos_OMX_H264dec.c b/component/video/dec/h264/Exynos_OMX_H264dec.c index 4afc1de..ee6eced 100644 --- a/component/video/dec/h264/Exynos_OMX_H264dec.c +++ b/component/video/dec/h264/Exynos_OMX_H264dec.c @@ -32,6 +32,7 @@ #include "Exynos_OMX_Basecomponent.h" #include "Exynos_OMX_Baseport.h" #include "Exynos_OMX_Vdec.h" +#include "Exynos_OMX_VdecControl.h" #include "Exynos_OSAL_ETC.h" #include "Exynos_OSAL_Semaphore.h" #include "Exynos_OSAL_Thread.h" @@ -566,13 +567,12 @@ OMX_ERRORTYPE H264CodecRegistCodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]); - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; pBufOps = pH264Dec->hMFCH264Handle.pInbufOps; } else { ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]); - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; pBufOps = pH264Dec->hMFCH264Handle.pOutbufOps; } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt); if (pPlanes == NULL) { @@ -751,9 +751,12 @@ OMX_BOOL H264CodecCheckFramePacking(OMX_COMPONENTTYPE *pOMXComponent) NULL); Exynos_OSAL_SleepMillisec(0); - ret = OMX_TRUE; + } else { + pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE; } + ret = OMX_TRUE; + EXIT: return ret; } @@ -894,16 +897,16 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT FunctionIn(); if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; - OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); - if (OMXBuffer == NULL) { - ret = OMX_ErrorUndefined; + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO)); + if (pBufferInfo == NULL) { + ret = OMX_ErrorInsufficientResources; goto EXIT; } - OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; - OMXBuffer->nFlags = pSrcInputData->nFlags; - Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + pBufferInfo->nFlags = pSrcInputData->nFlags; + pBufferInfo->timeStamp = pSrcInputData->timeStamp; + ret = Exynos_OSAL_Queue(&pH264Dec->bypassBufferInfoQ, (void *)pBufferInfo); + Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent); ret = OMX_ErrorNone; goto EXIT; @@ -923,11 +926,11 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; - inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; - inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; } + bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt; + inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC; /* should be done before prepare input buffer */ if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -949,32 +952,46 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT goto EXIT; } - if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - ret = H264CodecRegistCodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX); - if (ret != OMX_ErrorNone) - goto EXIT; - } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { - /* Register input buffer */ - for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { - ExynosVideoPlane plane; - if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { - plane.addr = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer); - } else { - plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; - } - plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; - plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; - if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } - /* set output geometry */ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + +#ifdef USE_DUALDPB_MODE + switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12; + break; + case OMX_COLOR_FormatYUV420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_I420; + break; + case OMX_SEC_COLOR_FormatYVU420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_YV12; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV21; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + default: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + } + + if (bufferConf.eColorFormat != VIDEO_COLORFORMAT_NV12_TILED) { + if ((pDecOps->Enable_DualDPBMode != NULL) && + (pDecOps->Enable_DualDPBMode(hMFCHandle) == VIDEO_ERROR_NONE)) { + pVideoDec->bDualDPBMode = OMX_TRUE; + pExynosOutputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(pExynosOutputPort->portDefinition.format.video.eColorFormat); + } else { + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; + } + } + pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat; +#else pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; +#endif + bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt; if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); ret = OMX_ErrorInsufficientResources; @@ -983,8 +1000,12 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT /* input buffer enqueue for header parsing */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); - if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + if (pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); // ret = OMX_ErrorInsufficientResources; ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; @@ -998,7 +1019,12 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT goto EXIT; } - H264CodecCheckResolutionChange(pOMXComponent); + ret = H264CodecCheckResolutionChange(pOMXComponent); + if (ret != OMX_ErrorNone) { + H264CodecStop(pOMXComponent, INPUT_PORT_INDEX); + pInbufOps->Cleanup_Buffer(hMFCHandle); + goto EXIT; + } Exynos_OSAL_SleepMillisec(0); ret = OMX_ErrorInputDataDecodeYet; @@ -1026,13 +1052,13 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) int i, nOutbufs; - OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; FunctionIn(); - nAllocLen[0] = pH264Dec->hMFCH264Handle.codecOutbufConf.nAlignPlaneSize[0]; - nAllocLen[1] = pH264Dec->hMFCH264Handle.codecOutbufConf.nAlignPlaneSize[1]; + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) + nAllocLen[i] = pH264Dec->hMFCH264Handle.codecOutbufConf.nAlignPlaneSize[i]; pOutbufOps->Set_Shareable(hMFCHandle); @@ -1062,7 +1088,7 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) /* Enqueue output buffer */ for (i = 0; i < nOutbufs; i++) { pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -1071,7 +1097,7 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { - ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + ExynosVideoPlane planes[MAX_BUFFER_PLANE] = {0, 0, 0}; int plane; /* get dpb count */ @@ -1089,19 +1115,19 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) #ifdef USE_ANB if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; planes[plane].allocSize = nAllocLen[plane]; } - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + if (pOutbufOps->Register(hMFCHandle, planes, pExynosOutputPort->nPlaneCnt) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; } pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -1669,8 +1695,9 @@ OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE; if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE}; + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0}; Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1687,6 +1714,7 @@ OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) /* Does not require any actions. */ } + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1709,6 +1737,8 @@ OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pExynosComponent->getAllDelayBuffer = OMX_FALSE; + Exynos_OSAL_QueueCreate(&pH264Dec->bypassBufferInfoQ, QUEUE_ELEMENTS); + #ifdef USE_CSC_HW csc_method = CSC_METHOD_HW; #endif @@ -1756,6 +1786,8 @@ OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) pVideoDec->csc_handle = NULL; } + Exynos_OSAL_QueueTerminate(&pH264Dec->bypassBufferInfoQ); + Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationStartEvent); pH264Dec->hDestinationStartEvent = NULL; pH264Dec->bDestinationStart = OMX_FALSE; @@ -1796,19 +1828,25 @@ EXIT: OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + OMX_BUFFERHEADERTYPE tempBufferHeader; + void *pPrivate = NULL; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; OMX_BOOL bInStartCode = OMX_FALSE; - ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; - ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; - ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; FunctionIn(); @@ -1830,11 +1868,29 @@ OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ pDecOps->Set_FrameTag(hMFCHandle, pH264Dec->hMFCH264Handle.indexTimestamp); pH264Dec->hMFCH264Handle.indexTimestamp++; pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; - +#ifdef USE_QOS_CTRL + if ((pVideoDec->bQosChanged == OMX_TRUE) && + (pDecOps->Set_QosRatio != NULL)) { + pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio); + pVideoDec->bQosChanged = OMX_FALSE; + } +#endif /* queue work for input buffer */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); - codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + + if (pExynosInputPort->bufferProcessType == BUFFER_COPY) { + tempBufferHeader.nFlags = pSrcInputData->nFlags; + tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp; + pPrivate = (void *)&tempBufferHeader; + } else { + pPrivate = (void *)pSrcInputData->bufferHeader; + } + codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pPrivate); if (codecReturn != VIDEO_ERROR_NONE) { ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1875,22 +1931,26 @@ OMX_ERRORTYPE Exynos_H264Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; FunctionIn(); - pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) + pVideoBuffer = &videoBuffer; + else + pVideoBuffer = NULL; pSrcOutputData->dataLen = 0; pSrcOutputData->usedDataLen = 0; pSrcOutputData->remainDataLen = 0; - pSrcOutputData->nFlags = 0; - pSrcOutputData->timeStamp = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + pSrcOutputData->bufferHeader = NULL; if (pVideoBuffer == NULL) { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; pSrcOutputData->allocSize = 0; pSrcOutputData->pPrivate = NULL; - pSrcOutputData->bufferHeader = NULL; } else { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; @@ -1915,7 +1975,8 @@ OMX_ERRORTYPE Exynos_H264Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX } /* For Share Buffer */ - pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; } ret = OMX_ErrorNone; @@ -1928,16 +1989,19 @@ EXIT: OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; - ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; - ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,}; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + int i; FunctionIn(); @@ -1947,9 +2011,10 @@ OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ goto EXIT; } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[%d]: 0x%x", __FUNCTION__, __LINE__, i, + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[i]); + } if ((pVideoDec->bReconfigDPB == OMX_TRUE) && (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) && @@ -1961,7 +2026,7 @@ OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ } codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -2029,24 +2094,32 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX } } + +#ifdef USE_S3D_SUPPORT + /* Check Whether frame packing information is available */ + if ((pH264Dec->hMFCH264Handle.S3DFPArgmtType == OMX_SEC_FPARGMT_INVALID) && + (pVideoDec->bThumbnailMode == OMX_FALSE) && + ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) || + (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) || + (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) { + if (H264CodecCheckFramePacking(pOMXComponent) != OMX_TRUE) { + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + } +#endif + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) { if (pVideoDec->bReconfigDPB != OMX_TRUE) { pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH; pVideoDec->bReconfigDPB = OMX_TRUE; -#ifdef USE_S3D_SUPPORT - /* Check Whether frame packing information is available */ - if ((displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D) && - (pH264Dec->hMFCH264Handle.S3DFPArgmtType == OMX_SEC_FPARGMT_NONE)) { - if (H264CodecCheckFramePacking(pOMXComponent) != OMX_TRUE) { - ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; - goto EXIT; - } - } -#endif H264CodecCheckResolutionChange(pOMXComponent); pVideoDec->csc_set_format = OMX_FALSE; +#ifdef USE_S3D_SUPPORT + pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID; +#endif } ret = OMX_ErrorNone; goto EXIT; @@ -2056,7 +2129,7 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP; pDstOutputData->allocSize = pDstOutputData->dataLen = 0; - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; @@ -2093,6 +2166,17 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX case VIDEO_COLORFORMAT_NV12: pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; break; +#ifdef USE_DUALDPB_MODE + case VIDEO_COLORFORMAT_I420: + pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420Planar; + break; + case VIDEO_COLORFORMAT_YV12: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatYVU420Planar; + break; + case VIDEO_COLORFORMAT_NV21: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV21Linear; + break; +#endif case VIDEO_COLORFORMAT_NV12_TILED: default: pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; @@ -2122,7 +2206,10 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX /* NEED TIMESTAMP REORDER */ if (pVideoDec->bDTSMode == OMX_TRUE) { - if (pVideoBuffer->frameType == VIDEO_FRAME_I) + if ((pVideoBuffer->frameType == VIDEO_FRAME_I) || + ((pVideoBuffer->frameType == VIDEO_FRAME_OTHERS) && + ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) || + (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE)) pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp; else indexTimestamp = pH264Dec->hMFCH264Handle.outputIndexTimestamp; @@ -2251,6 +2338,21 @@ OMX_ERRORTYPE Exynos_H264Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXCompon Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent); } + if (Exynos_OSAL_GetElemNum(&pH264Dec->bypassBufferInfoQ) > 0) { + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pH264Dec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags; + pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader); + Exynos_OSAL_Free(pBufferInfo); + + ret = OMX_ErrorNone; + goto EXIT; + } } if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) { ret = Exynos_H264Dec_DstIn(pOMXComponent, pDstInputData); @@ -2291,6 +2393,38 @@ OMX_ERRORTYPE Exynos_H264Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXCompo Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent); } + + if (Exynos_OSAL_GetElemNum(&pH264Dec->bypassBufferInfoQ) > 0) { + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL; + BYPASS_BUFFER_INFO *pBufferInfo = NULL; + + if (dstOutputUseBuffer->dataValid == OMX_FALSE) { + pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (pOMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else { + pOMXBuffer = dstOutputUseBuffer->bufferHeader; + } + + pBufferInfo = Exynos_OSAL_Dequeue(&pH264Dec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOMXBuffer->nFlags = pBufferInfo->nFlags; + pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer); + Exynos_OSAL_Free(pBufferInfo); + + dstOutputUseBuffer->dataValid = OMX_FALSE; + + ret = OMX_ErrorNone; + goto EXIT; + } } ret = Exynos_H264Dec_DstOut(pOMXComponent, pDstOutputData); if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) { @@ -2369,7 +2503,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent pVideoDec->bDRMPlayerMode = bDRMPlayerMode; #ifdef USE_S3D_SUPPORT - pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE; + pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID; #endif /* Set componentVersion */ diff --git a/component/video/dec/h264/Exynos_OMX_H264dec.h b/component/video/dec/h264/Exynos_OMX_H264dec.h index 6ef20e8..cb9910c 100644 --- a/component/video/dec/h264/Exynos_OMX_H264dec.h +++ b/component/video/dec/h264/Exynos_OMX_H264dec.h @@ -64,6 +64,8 @@ typedef struct _EXYNOS_H264DEC_HANDLE OMX_BOOL bDestinationStart; OMX_HANDLETYPE hSourceStartEvent; OMX_HANDLETYPE hDestinationStartEvent; + + EXYNOS_QUEUE bypassBufferInfoQ; } EXYNOS_H264DEC_HANDLE; #ifdef __cplusplus diff --git a/component/video/dec/mpeg2/Android.mk b/component/video/dec/mpeg2/Android.mk index 92b7e09..e6d869b 100644 --- a/component/video/dec/mpeg2/Android.mk +++ b/component/video/dec/mpeg2/Android.mk @@ -27,6 +27,14 @@ ifeq ($(BOARD_USE_CSC_HW), true) LOCAL_CFLAGS += -DUSE_CSC_HW endif +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_DUALDPB_MODE), true) +LOCAL_CFLAGS += -DUSE_DUALDPB_MODE +endif + LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ diff --git a/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c b/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c index 8e5141c..3fc810e 100644 --- a/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c +++ b/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c @@ -32,6 +32,7 @@ #include "Exynos_OMX_Basecomponent.h" #include "Exynos_OMX_Baseport.h" #include "Exynos_OMX_Vdec.h" +#include "Exynos_OMX_VdecControl.h" #include "Exynos_OSAL_ETC.h" #include "Exynos_OSAL_Semaphore.h" #include "Exynos_OSAL_Thread.h" @@ -441,13 +442,12 @@ OMX_ERRORTYPE Mpeg2CodecRegistCodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]); - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; pBufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; } else { ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]); - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; pBufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt); if (pPlanes == NULL) { @@ -555,16 +555,16 @@ OMX_ERRORTYPE Mpeg2CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA FunctionIn(); if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; - OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); - if (OMXBuffer == NULL) { - ret = OMX_ErrorUndefined; + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO)); + if (pBufferInfo == NULL) { + ret = OMX_ErrorInsufficientResources; goto EXIT; } - OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; - OMXBuffer->nFlags = pSrcInputData->nFlags; - Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + pBufferInfo->nFlags = pSrcInputData->nFlags; + pBufferInfo->timeStamp = pSrcInputData->timeStamp; + ret = Exynos_OSAL_Queue(&pMpeg2Dec->bypassBufferInfoQ, (void *)pBufferInfo); + Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationStartEvent); ret = OMX_ErrorNone; goto EXIT; @@ -584,11 +584,11 @@ OMX_ERRORTYPE Mpeg2CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; - inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; - inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; } + bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt; + inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC; /* should be done before prepare input buffer */ if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -610,28 +610,46 @@ OMX_ERRORTYPE Mpeg2CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA goto EXIT; } - if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - ret = Mpeg2CodecRegistCodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX); - if (ret != OMX_ErrorNone) - goto EXIT; - } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { - /* Register input buffer */ - for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { - ExynosVideoPlane plane; - plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; - plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; - plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; - if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "BUFFER_SHARE Failed to Register input buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } - /* set output geometry */ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + +#ifdef USE_DUALDPB_MODE + switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12; + break; + case OMX_COLOR_FormatYUV420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_I420; + break; + case OMX_SEC_COLOR_FormatYVU420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_YV12; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV21; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + default: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + } + + if (bufferConf.eColorFormat != VIDEO_COLORFORMAT_NV12_TILED) { + if ((pDecOps->Enable_DualDPBMode != NULL) && + (pDecOps->Enable_DualDPBMode(hMFCHandle) == VIDEO_ERROR_NONE)) { + pVideoDec->bDualDPBMode = OMX_TRUE; + pExynosOutputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(pExynosOutputPort->portDefinition.format.video.eColorFormat); + } else { + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; + } + } + pMpeg2Dec->hMFCMpeg2Handle.MFCOutputColorType = bufferConf.eColorFormat; +#else pMpeg2Dec->hMFCMpeg2Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; +#endif + bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt; if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); ret = OMX_ErrorInsufficientResources; @@ -640,8 +658,12 @@ OMX_ERRORTYPE Mpeg2CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA /* input buffer enqueue for header parsing */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); - if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + if (pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); // ret = OMX_ErrorInsufficientResources; ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; @@ -659,6 +681,8 @@ OMX_ERRORTYPE Mpeg2CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA Exynos_OSAL_Memset(&pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); + Mpeg2CodecStop(pOMXComponent, INPUT_PORT_INDEX); + pInbufOps->Cleanup_Buffer(hMFCHandle); ret = OMX_ErrorInsufficientResources; goto EXIT; } @@ -744,13 +768,13 @@ OMX_ERRORTYPE Mpeg2CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) int i, nOutbufs; - OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; FunctionIn(); - nAllocLen[0] = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nAlignPlaneSize[0]; - nAllocLen[1] = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nAlignPlaneSize[1]; + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) + nAllocLen[i] = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nAlignPlaneSize[i]; pOutbufOps->Set_Shareable(hMFCHandle); @@ -780,7 +804,7 @@ OMX_ERRORTYPE Mpeg2CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) /* Enqueue output buffer */ for (i = 0; i < nOutbufs; i++) { pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -789,7 +813,7 @@ OMX_ERRORTYPE Mpeg2CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { - ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + ExynosVideoPlane planes[MAX_BUFFER_PLANE] = {0, 0, 0}; int plane; /* get dpb count */ @@ -807,19 +831,19 @@ OMX_ERRORTYPE Mpeg2CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) #ifdef USE_ANB if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; planes[plane].allocSize = nAllocLen[plane]; } - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + if (pOutbufOps->Register(hMFCHandle, planes, pExynosOutputPort->nPlaneCnt) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; } pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -886,13 +910,12 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_GetParameter( EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; ret = Exynos_OMX_Check_SizeVersion(pDstMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE)); if (ret != OMX_ErrorNone) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "1"); goto EXIT; } if (pDstMpeg2Param->nPortIndex > OUTPUT_PORT_INDEX) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "2"); ret = OMX_ErrorBadPortIndex; + goto EXIT; } pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; @@ -1300,8 +1323,9 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE; if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE}; + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0}; Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize); @@ -1317,6 +1341,7 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) /* Does not require any actions. */ } + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1339,6 +1364,8 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pExynosComponent->getAllDelayBuffer = OMX_FALSE; + Exynos_OSAL_QueueCreate(&pMpeg2Dec->bypassBufferInfoQ, QUEUE_ELEMENTS); + #ifdef USE_CSC_HW csc_method = CSC_METHOD_HW; #endif @@ -1379,6 +1406,8 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) pVideoDec->csc_handle = NULL; } + Exynos_OSAL_QueueTerminate(&pMpeg2Dec->bypassBufferInfoQ); + Exynos_OSAL_SignalTerminate(pMpeg2Dec->hDestinationStartEvent); pMpeg2Dec->hDestinationStartEvent = NULL; pMpeg2Dec->bDestinationStart = OMX_FALSE; @@ -1419,19 +1448,25 @@ EXIT: OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + OMX_BUFFERHEADERTYPE tempBufferHeader; + void *pPrivate = NULL; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; OMX_BOOL bInStartCode = OMX_FALSE; - ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; - ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; - ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; FunctionIn(); @@ -1452,11 +1487,29 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX pDecOps->Set_FrameTag(hMFCHandle, pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp); pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp++; pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp %= MAX_TIMESTAMP; - +#ifdef USE_QOS_CTRL + if ((pVideoDec->bQosChanged == OMX_TRUE) && + (pDecOps->Set_QosRatio != NULL)) { + pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio); + pVideoDec->bQosChanged = OMX_FALSE; + } +#endif /* queue work for input buffer */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); - codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + + if (pExynosInputPort->bufferProcessType == BUFFER_COPY) { + tempBufferHeader.nFlags = pSrcInputData->nFlags; + tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp; + pPrivate = (void *)&tempBufferHeader; + } else { + pPrivate = (void *)pSrcInputData->bufferHeader; + } + codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pPrivate); if (codecReturn != VIDEO_ERROR_NONE) { ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1497,22 +1550,26 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; FunctionIn(); - pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) + pVideoBuffer = &videoBuffer; + else + pVideoBuffer = NULL; pSrcOutputData->dataLen = 0; pSrcOutputData->usedDataLen = 0; pSrcOutputData->remainDataLen = 0; - pSrcOutputData->nFlags = 0; - pSrcOutputData->timeStamp = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + pSrcOutputData->bufferHeader = NULL; if (pVideoBuffer == NULL) { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; pSrcOutputData->allocSize = 0; pSrcOutputData->pPrivate = NULL; - pSrcOutputData->bufferHeader = NULL; } else { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; @@ -1537,7 +1594,8 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM } /* For Share Buffer */ - pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; } ret = OMX_ErrorNone; @@ -1550,16 +1608,19 @@ EXIT: OMX_ERRORTYPE Exynos_Mpeg2Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; - ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; - ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,}; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + int i; FunctionIn(); @@ -1569,12 +1630,13 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX goto EXIT; } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[i]: 0x%x", __FUNCTION__, __LINE__, i, + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[i]); + } codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1645,7 +1707,7 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp %= MAX_TIMESTAMP; pDstOutputData->allocSize = pDstOutputData->dataLen = 0; - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; @@ -1682,6 +1744,17 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM case VIDEO_COLORFORMAT_NV12: pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; break; +#ifdef USE_DUALDPB_MODE + case VIDEO_COLORFORMAT_I420: + pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420Planar; + break; + case VIDEO_COLORFORMAT_YV12: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatYVU420Planar; + break; + case VIDEO_COLORFORMAT_NV21: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV21Linear; + break; +#endif case VIDEO_COLORFORMAT_NV12_TILED: default: pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; @@ -1711,7 +1784,10 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM /* NEED TIMESTAMP REORDER */ if (pVideoDec->bDTSMode == OMX_TRUE) { - if (pVideoBuffer->frameType == VIDEO_FRAME_I) + if ((pVideoBuffer->frameType == VIDEO_FRAME_I) || + ((pVideoBuffer->frameType == VIDEO_FRAME_OTHERS) && + ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) || + (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE)) pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp = indexTimestamp; else indexTimestamp = pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp; @@ -1842,6 +1918,21 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXCompo Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationStartEvent); } + if (Exynos_OSAL_GetElemNum(&pMpeg2Dec->bypassBufferInfoQ) > 0) { + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pMpeg2Dec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags; + pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader); + Exynos_OSAL_Free(pBufferInfo); + + ret = OMX_ErrorNone; + goto EXIT; + } } if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_TRUE) { ret = Exynos_Mpeg2Dec_DstIn(pOMXComponent, pDstInputData); @@ -1882,6 +1973,37 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComp Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationStartEvent); } + if (Exynos_OSAL_GetElemNum(&pMpeg2Dec->bypassBufferInfoQ) > 0) { + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL; + BYPASS_BUFFER_INFO *pBufferInfo = NULL; + + if (dstOutputUseBuffer->dataValid == OMX_FALSE) { + pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (pOMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else { + pOMXBuffer = dstOutputUseBuffer->bufferHeader; + } + + pBufferInfo = Exynos_OSAL_Dequeue(&pMpeg2Dec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOMXBuffer->nFlags = pBufferInfo->nFlags; + pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer); + Exynos_OSAL_Free(pBufferInfo); + + dstOutputUseBuffer->dataValid = OMX_FALSE; + + ret = OMX_ErrorNone; + goto EXIT; + } } ret = Exynos_Mpeg2Dec_DstOut(pOMXComponent, pDstOutputData); if ((ret != OMX_ErrorNone) && diff --git a/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h b/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h index 914ed64..b11731b 100644 --- a/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h +++ b/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h @@ -62,6 +62,8 @@ typedef struct _EXYNOS_MPEG2DEC_HANDLE OMX_BOOL bDestinationStart; OMX_HANDLETYPE hSourceStartEvent; OMX_HANDLETYPE hDestinationStartEvent; + + EXYNOS_QUEUE bypassBufferInfoQ; } EXYNOS_MPEG2DEC_HANDLE; #ifdef __cplusplus diff --git a/component/video/dec/mpeg4/Android.mk b/component/video/dec/mpeg4/Android.mk index 09d0089..9a70f18 100644 --- a/component/video/dec/mpeg4/Android.mk +++ b/component/video/dec/mpeg4/Android.mk @@ -27,6 +27,14 @@ ifeq ($(BOARD_USE_CSC_HW), true) LOCAL_CFLAGS += -DUSE_CSC_HW endif +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_DUALDPB_MODE), true) +LOCAL_CFLAGS += -DUSE_DUALDPB_MODE +endif + LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ diff --git a/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c index 6b3b3fa..d81b2e5 100644 --- a/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c +++ b/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c @@ -33,6 +33,7 @@ #include "Exynos_OMX_Basecomponent.h" #include "Exynos_OMX_Baseport.h" #include "Exynos_OMX_Vdec.h" +#include "Exynos_OMX_VdecControl.h" #include "Exynos_OSAL_ETC.h" #include "Exynos_OSAL_Semaphore.h" #include "Exynos_OSAL_Thread.h" @@ -658,13 +659,12 @@ OMX_ERRORTYPE Mpeg4CodecRegistCodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]); - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; pBufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; } else { ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]); - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; pBufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt); if (pPlanes == NULL) { @@ -772,16 +772,16 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA FunctionIn(); if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; - OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); - if (OMXBuffer == NULL) { - ret = OMX_ErrorUndefined; + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO)); + if (pBufferInfo == NULL) { + ret = OMX_ErrorInsufficientResources; goto EXIT; } - OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; - OMXBuffer->nFlags = pSrcInputData->nFlags; - Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + pBufferInfo->nFlags = pSrcInputData->nFlags; + pBufferInfo->timeStamp = pSrcInputData->timeStamp; + ret = Exynos_OSAL_Queue(&pMpeg4Dec->bypassBufferInfoQ, (void *)pBufferInfo); + Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationStartEvent); ret = OMX_ErrorNone; goto EXIT; @@ -805,11 +805,11 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; - inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; - inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; } + bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt; + inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC; /* should be done before prepare input buffer */ if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -831,28 +831,46 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA goto EXIT; } - if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - ret = Mpeg4CodecRegistCodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX); - if (ret != OMX_ErrorNone) - goto EXIT; - } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { - /* Register input buffer */ - for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { - ExynosVideoPlane plane; - plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; - plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; - plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; - if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } - /* set output geometry */ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + +#ifdef USE_DUALDPB_MODE + switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12; + break; + case OMX_COLOR_FormatYUV420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_I420; + break; + case OMX_SEC_COLOR_FormatYVU420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_YV12; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV21; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + default: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + } + + if (bufferConf.eColorFormat != VIDEO_COLORFORMAT_NV12_TILED) { + if ((pDecOps->Enable_DualDPBMode != NULL) && + (pDecOps->Enable_DualDPBMode(hMFCHandle) == VIDEO_ERROR_NONE)) { + pVideoDec->bDualDPBMode = OMX_TRUE; + pExynosOutputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(pExynosOutputPort->portDefinition.format.video.eColorFormat); + } else { + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; + } + } + pMpeg4Dec->hMFCMpeg4Handle.MFCOutputColorType = bufferConf.eColorFormat; +#else pMpeg4Dec->hMFCMpeg4Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; +#endif + bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt; if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); ret = OMX_ErrorInsufficientResources; @@ -861,8 +879,12 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA /* input buffer enqueue for header parsing */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); - if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + if (pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); // ret = OMX_ErrorInsufficientResources; ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; @@ -880,6 +902,8 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA Exynos_OSAL_Memset(&pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); + Mpeg4CodecStop(pOMXComponent, INPUT_PORT_INDEX); + pInbufOps->Cleanup_Buffer(hMFCHandle); ret = OMX_ErrorInsufficientResources; goto EXIT; } @@ -965,13 +989,13 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) int i, nOutbufs; - OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; FunctionIn(); - nAllocLen[0] = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nAlignPlaneSize[0]; - nAllocLen[1] = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nAlignPlaneSize[1]; + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) + nAllocLen[i] = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nAlignPlaneSize[i]; pOutbufOps->Set_Shareable(hMFCHandle); @@ -1001,7 +1025,7 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) /* Enqueue output buffer */ for (i = 0; i < nOutbufs; i++) { pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -1010,7 +1034,7 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { - ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + ExynosVideoPlane planes[MAX_BUFFER_PLANE] = {0, 0, 0}; int plane; /* get dpb count */ @@ -1028,19 +1052,19 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) #ifdef USE_ANB if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; planes[plane].allocSize = nAllocLen[plane]; } - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + if (pOutbufOps->Register(hMFCHandle, planes, pExynosOutputPort->nPlaneCnt) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; } pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -1653,8 +1677,9 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE; if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE}; + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0}; Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize); @@ -1670,6 +1695,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) /* Does not require any actions. */ } + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1692,6 +1718,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pExynosComponent->getAllDelayBuffer = OMX_FALSE; + Exynos_OSAL_QueueCreate(&pMpeg4Dec->bypassBufferInfoQ, QUEUE_ELEMENTS); + #ifdef USE_CSC_HW csc_method = CSC_METHOD_HW; #endif @@ -1732,6 +1760,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) pVideoDec->csc_handle = NULL; } + Exynos_OSAL_QueueTerminate(&pMpeg4Dec->bypassBufferInfoQ); + Exynos_OSAL_SignalTerminate(pMpeg4Dec->hDestinationStartEvent); pMpeg4Dec->hDestinationStartEvent = NULL; pMpeg4Dec->bDestinationStart = OMX_FALSE; @@ -1772,19 +1802,25 @@ EXIT: OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + OMX_BUFFERHEADERTYPE tempBufferHeader; + void *pPrivate = NULL; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; OMX_BOOL bInStartCode = OMX_FALSE; - ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; - ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; - ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; FunctionIn(); @@ -1805,11 +1841,29 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX pDecOps->Set_FrameTag(hMFCHandle, pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp); pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++; pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; - +#ifdef USE_QOS_CTRL + if ((pVideoDec->bQosChanged == OMX_TRUE) && + (pDecOps->Set_QosRatio != NULL)) { + pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio); + pVideoDec->bQosChanged = OMX_FALSE; + } +#endif /* queue work for input buffer */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); - codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + + if (pExynosInputPort->bufferProcessType == BUFFER_COPY) { + tempBufferHeader.nFlags = pSrcInputData->nFlags; + tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp; + pPrivate = (void *)&tempBufferHeader; + } else { + pPrivate = (void *)pSrcInputData->bufferHeader; + } + codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pPrivate); if (codecReturn != VIDEO_ERROR_NONE) { ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1850,22 +1904,26 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; FunctionIn(); - pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) + pVideoBuffer = &videoBuffer; + else + pVideoBuffer = NULL; pSrcOutputData->dataLen = 0; pSrcOutputData->usedDataLen = 0; pSrcOutputData->remainDataLen = 0; - pSrcOutputData->nFlags = 0; - pSrcOutputData->timeStamp = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + pSrcOutputData->bufferHeader = NULL; if (pVideoBuffer == NULL) { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; pSrcOutputData->allocSize = 0; pSrcOutputData->pPrivate = NULL; - pSrcOutputData->bufferHeader = NULL; } else { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; @@ -1890,7 +1948,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM } /* For Share Buffer */ - pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; } ret = OMX_ErrorNone; @@ -1903,16 +1962,19 @@ EXIT: OMX_ERRORTYPE Exynos_Mpeg4Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; - ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; - ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,}; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + int i; FunctionIn(); @@ -1922,12 +1984,13 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX goto EXIT; } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[i]: 0x%x", __FUNCTION__, __LINE__, i, + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[i]); + } codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1998,7 +2061,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP; pDstOutputData->allocSize = pDstOutputData->dataLen = 0; - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; @@ -2035,6 +2098,17 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM case VIDEO_COLORFORMAT_NV12: pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; break; +#ifdef USE_DUALDPB_MODE + case VIDEO_COLORFORMAT_I420: + pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420Planar; + break; + case VIDEO_COLORFORMAT_YV12: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatYVU420Planar; + break; + case VIDEO_COLORFORMAT_NV21: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV21Linear; + break; +#endif case VIDEO_COLORFORMAT_NV12_TILED: default: pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; @@ -2064,7 +2138,10 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM /* NEED TIMESTAMP REORDER */ if (pVideoDec->bDTSMode == OMX_TRUE) { - if (pVideoBuffer->frameType == VIDEO_FRAME_I) + if ((pVideoBuffer->frameType == VIDEO_FRAME_I) || + ((pVideoBuffer->frameType == VIDEO_FRAME_OTHERS) && + ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) || + (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE)) pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = indexTimestamp; else indexTimestamp = pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp; @@ -2195,6 +2272,21 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXCompo Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent); } + if (Exynos_OSAL_GetElemNum(&pMpeg4Dec->bypassBufferInfoQ) > 0) { + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pMpeg4Dec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags; + pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader); + Exynos_OSAL_Free(pBufferInfo); + + ret = OMX_ErrorNone; + goto EXIT; + } } if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE) { ret = Exynos_Mpeg4Dec_DstIn(pOMXComponent, pDstInputData); @@ -2235,6 +2327,37 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComp Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent); } + if (Exynos_OSAL_GetElemNum(&pMpeg4Dec->bypassBufferInfoQ) > 0) { + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL; + BYPASS_BUFFER_INFO *pBufferInfo = NULL; + + if (dstOutputUseBuffer->dataValid == OMX_FALSE) { + pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (pOMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else { + pOMXBuffer = dstOutputUseBuffer->bufferHeader; + } + + pBufferInfo = Exynos_OSAL_Dequeue(&pMpeg4Dec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOMXBuffer->nFlags = pBufferInfo->nFlags; + pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer); + Exynos_OSAL_Free(pBufferInfo); + + dstOutputUseBuffer->dataValid = OMX_FALSE; + + ret = OMX_ErrorNone; + goto EXIT; + } } ret = Exynos_Mpeg4Dec_DstOut(pOMXComponent, pDstOutputData); if ((ret != OMX_ErrorNone) && diff --git a/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h b/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h index bfde6c9..5d4323e 100644 --- a/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h +++ b/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h @@ -89,6 +89,8 @@ typedef struct _EXYNOS_MPEG4DEC_HANDLE OMX_BOOL bDestinationStart; OMX_HANDLETYPE hSourceStartEvent; OMX_HANDLETYPE hDestinationStartEvent; + + EXYNOS_QUEUE bypassBufferInfoQ; } EXYNOS_MPEG4DEC_HANDLE; #ifdef __cplusplus diff --git a/component/video/dec/vc1/Android.mk b/component/video/dec/vc1/Android.mk index a180aa0..53e13b8 100644 --- a/component/video/dec/vc1/Android.mk +++ b/component/video/dec/vc1/Android.mk @@ -27,6 +27,14 @@ ifeq ($(BOARD_USE_CSC_HW), true) LOCAL_CFLAGS += -DUSE_CSC_HW endif +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_DUALDPB_MODE), true) +LOCAL_CFLAGS += -DUSE_DUALDPB_MODE +endif + LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ diff --git a/component/video/dec/vc1/Exynos_OMX_Wmvdec.c b/component/video/dec/vc1/Exynos_OMX_Wmvdec.c index d7e7d54..45ced56 100644 --- a/component/video/dec/vc1/Exynos_OMX_Wmvdec.c +++ b/component/video/dec/vc1/Exynos_OMX_Wmvdec.c @@ -35,6 +35,7 @@ #include "Exynos_OMX_Basecomponent.h" #include "Exynos_OMX_Baseport.h" #include "Exynos_OMX_Vdec.h" +#include "Exynos_OMX_VdecControl.h" #include "Exynos_OSAL_ETC.h" #include "Exynos_OSAL_Semaphore.h" #include "Exynos_OSAL_Thread.h" @@ -675,13 +676,12 @@ OMX_ERRORTYPE WMVCodecRegistCodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]); - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; pBufOps = pWmvDec->hMFCWmvHandle.pInbufOps; } else { ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]); - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; pBufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt); if (pPlanes == NULL) { @@ -790,16 +790,16 @@ OMX_ERRORTYPE WmvCodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA FunctionIn(); if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; - OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); - if (OMXBuffer == NULL) { - ret = OMX_ErrorUndefined; + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO)); + if (pBufferInfo == NULL) { + ret = OMX_ErrorInsufficientResources; goto EXIT; } - OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; - OMXBuffer->nFlags = pSrcInputData->nFlags; - Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + pBufferInfo->nFlags = pSrcInputData->nFlags; + pBufferInfo->timeStamp = pSrcInputData->timeStamp; + ret = Exynos_OSAL_Queue(&pWmvDec->bypassBufferInfoQ, (void *)pBufferInfo); + Exynos_OSAL_SignalSet(pWmvDec->hDestinationStartEvent); ret = OMX_ErrorNone; goto EXIT; @@ -841,11 +841,11 @@ OMX_ERRORTYPE WmvCodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; - inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; - inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; } + bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt; + inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC; /* should be done before prepare input buffer */ if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -867,28 +867,46 @@ OMX_ERRORTYPE WmvCodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA goto EXIT; } - if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - ret = WMVCodecRegistCodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX); - if (ret != OMX_ErrorNone) - goto EXIT; - } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { - /* Register input buffer */ - for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { - ExynosVideoPlane plane; - plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; - plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; - plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; - if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } - /* set output geometry */ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + +#ifdef USE_DUALDPB_MODE + switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12; + break; + case OMX_COLOR_FormatYUV420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_I420; + break; + case OMX_SEC_COLOR_FormatYVU420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_YV12; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV21; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + default: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + } + + if (bufferConf.eColorFormat != VIDEO_COLORFORMAT_NV12_TILED) { + if ((pDecOps->Enable_DualDPBMode != NULL) && + (pDecOps->Enable_DualDPBMode(hMFCHandle) == VIDEO_ERROR_NONE)) { + pVideoDec->bDualDPBMode = OMX_TRUE; + pExynosOutputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(pExynosOutputPort->portDefinition.format.video.eColorFormat); + } else { + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; + } + } + pWmvDec->hMFCWmvHandle.MFCOutputColorType = bufferConf.eColorFormat; +#else pWmvDec->hMFCWmvHandle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; +#endif + bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt; if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); ret = OMX_ErrorInsufficientResources; @@ -904,8 +922,12 @@ OMX_ERRORTYPE WmvCodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA /* input buffer enqueue for header parsing */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); - if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + if (pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); // ret = OMX_ErrorInsufficientResources; ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; @@ -923,6 +945,8 @@ OMX_ERRORTYPE WmvCodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA Exynos_OSAL_Memset(&pWmvDec->hMFCWmvHandle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); if (pOutbufOps->Get_Geometry(hMFCHandle, &pWmvDec->hMFCWmvHandle.codecOutbufConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); + WmvCodecStop(pOMXComponent, INPUT_PORT_INDEX); + pInbufOps->Cleanup_Buffer(hMFCHandle); ret = OMX_ErrorInsufficientResources; goto EXIT; } @@ -1008,13 +1032,13 @@ OMX_ERRORTYPE WmvCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) int i, nOutbufs; - OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; FunctionIn(); - nAllocLen[0] = pWmvDec->hMFCWmvHandle.codecOutbufConf.nAlignPlaneSize[0]; - nAllocLen[1] = pWmvDec->hMFCWmvHandle.codecOutbufConf.nAlignPlaneSize[1]; + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) + nAllocLen[i] = pWmvDec->hMFCWmvHandle.codecOutbufConf.nAlignPlaneSize[i]; pOutbufOps->Set_Shareable(hMFCHandle); @@ -1044,7 +1068,7 @@ OMX_ERRORTYPE WmvCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) /* Enqueue output buffer */ for (i = 0; i < nOutbufs; i++) { pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -1053,7 +1077,7 @@ OMX_ERRORTYPE WmvCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { - ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + ExynosVideoPlane planes[MAX_BUFFER_PLANE] = {0, 0, 0}; int plane; /* get dpb count */ @@ -1071,19 +1095,19 @@ OMX_ERRORTYPE WmvCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) #ifdef USE_ANB if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; planes[plane].allocSize = nAllocLen[plane]; } - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + if (pOutbufOps->Register(hMFCHandle, planes, pExynosOutputPort->nPlaneCnt) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; } pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -1519,8 +1543,9 @@ OMX_ERRORTYPE Exynos_WmvDec_Init(OMX_COMPONENTTYPE *pOMXComponent) pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE; if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE}; + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0}; Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize); @@ -1536,6 +1561,7 @@ OMX_ERRORTYPE Exynos_WmvDec_Init(OMX_COMPONENTTYPE *pOMXComponent) /* Does not require any actions. */ } + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1560,6 +1586,8 @@ OMX_ERRORTYPE Exynos_WmvDec_Init(OMX_COMPONENTTYPE *pOMXComponent) pExynosComponent->getAllDelayBuffer = OMX_FALSE; + Exynos_OSAL_QueueCreate(&pWmvDec->bypassBufferInfoQ, QUEUE_ELEMENTS); + #ifdef USE_CSC_HW csc_method = CSC_METHOD_HW; #endif @@ -1600,6 +1628,8 @@ OMX_ERRORTYPE Exynos_WmvDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) pVideoDec->csc_handle = NULL; } + Exynos_OSAL_QueueTerminate(&pWmvDec->bypassBufferInfoQ); + Exynos_OSAL_SignalTerminate(pWmvDec->hDestinationStartEvent); pWmvDec->hDestinationStartEvent = NULL; pWmvDec->bDestinationStart = OMX_FALSE; @@ -1640,19 +1670,25 @@ EXIT: OMX_ERRORTYPE Exynos_WmvDec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + OMX_BUFFERHEADERTYPE tempBufferHeader; + void *pPrivate = NULL; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; - OMX_BOOL bStartCode = OMX_FALSE; - ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; - ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; - ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + OMX_BOOL bStartCode = OMX_FALSE; + + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; FunctionIn(); @@ -1689,11 +1725,29 @@ OMX_ERRORTYPE Exynos_WmvDec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_D pDecOps->Set_FrameTag(hMFCHandle, pWmvDec->hMFCWmvHandle.indexTimestamp); pWmvDec->hMFCWmvHandle.indexTimestamp++; pWmvDec->hMFCWmvHandle.indexTimestamp %= MAX_TIMESTAMP; - +#ifdef USE_QOS_CTRL + if ((pVideoDec->bQosChanged == OMX_TRUE) && + (pDecOps->Set_QosRatio != NULL)) { + pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio); + pVideoDec->bQosChanged = OMX_FALSE; + } +#endif /* queue work for input buffer */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); - codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + + if (pExynosInputPort->bufferProcessType == BUFFER_COPY) { + tempBufferHeader.nFlags = pSrcInputData->nFlags; + tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp; + pPrivate = (void *)&tempBufferHeader; + } else { + pPrivate = (void *)pSrcInputData->bufferHeader; + } + codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pPrivate); if (codecReturn != VIDEO_ERROR_NONE) { ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1731,16 +1785,21 @@ OMX_ERRORTYPE Exynos_WmvDec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; FunctionIn(); - pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) + pVideoBuffer = &videoBuffer; + else + pVideoBuffer = NULL; pSrcOutputData->dataLen = 0; pSrcOutputData->usedDataLen = 0; pSrcOutputData->remainDataLen = 0; - pSrcOutputData->nFlags = 0; - pSrcOutputData->timeStamp = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + pSrcOutputData->bufferHeader = NULL; if (pVideoBuffer == NULL) { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; @@ -1771,7 +1830,8 @@ OMX_ERRORTYPE Exynos_WmvDec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ } /* For Share Buffer */ - pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; } ret = OMX_ErrorNone; @@ -1784,15 +1844,19 @@ EXIT: OMX_ERRORTYPE Exynos_WmvDec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; - ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; - ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; - OMX_U32 dataLen[2] = {0,}; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + int i; FunctionIn(); @@ -1802,12 +1866,13 @@ OMX_ERRORTYPE Exynos_WmvDec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_D goto EXIT; } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[i]: 0x%x", __FUNCTION__, __LINE__, i, + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[i]); + } codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1878,7 +1943,7 @@ OMX_ERRORTYPE Exynos_WmvDec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ pWmvDec->hMFCWmvHandle.outputIndexTimestamp %= MAX_TIMESTAMP; pDstOutputData->allocSize = pDstOutputData->dataLen = 0; - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; @@ -1915,6 +1980,17 @@ OMX_ERRORTYPE Exynos_WmvDec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ case VIDEO_COLORFORMAT_NV12: pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; break; +#ifdef USE_DUALDPB_MODE + case VIDEO_COLORFORMAT_I420: + pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420Planar; + break; + case VIDEO_COLORFORMAT_YV12: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatYVU420Planar; + break; + case VIDEO_COLORFORMAT_NV21: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV21Linear; + break; +#endif case VIDEO_COLORFORMAT_NV12_TILED: default: pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; @@ -1946,7 +2022,8 @@ OMX_ERRORTYPE Exynos_WmvDec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ if (pVideoDec->bDTSMode == OMX_TRUE) { if ((pVideoBuffer->frameType == VIDEO_FRAME_I) || ((pVideoBuffer->frameType == VIDEO_FRAME_OTHERS) && - ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS))) + ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) || + (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE)) pWmvDec->hMFCWmvHandle.outputIndexTimestamp = indexTimestamp; else indexTimestamp = pWmvDec->hMFCWmvHandle.outputIndexTimestamp; @@ -2075,6 +2152,21 @@ OMX_ERRORTYPE Exynos_WmvDec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXCompone Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent); } + if (Exynos_OSAL_GetElemNum(&pWmvDec->bypassBufferInfoQ) > 0) { + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pWmvDec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags; + pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader); + Exynos_OSAL_Free(pBufferInfo); + + ret = OMX_ErrorNone; + goto EXIT; + } } if (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_TRUE) { ret = Exynos_WmvDec_DstIn(pOMXComponent, pDstInputData); @@ -2115,6 +2207,37 @@ OMX_ERRORTYPE Exynos_WmvDec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXCompon Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent); } + if (Exynos_OSAL_GetElemNum(&pWmvDec->bypassBufferInfoQ) > 0) { + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL; + BYPASS_BUFFER_INFO *pBufferInfo = NULL; + + if (dstOutputUseBuffer->dataValid == OMX_FALSE) { + pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (pOMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else { + pOMXBuffer = dstOutputUseBuffer->bufferHeader; + } + + pBufferInfo = Exynos_OSAL_Dequeue(&pWmvDec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOMXBuffer->nFlags = pBufferInfo->nFlags; + pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer); + Exynos_OSAL_Free(pBufferInfo); + + dstOutputUseBuffer->dataValid = OMX_FALSE; + + ret = OMX_ErrorNone; + goto EXIT; + } } ret = Exynos_WmvDec_DstOut(pOMXComponent, pDstOutputData); if ((ret != OMX_ErrorNone) && diff --git a/component/video/dec/vc1/Exynos_OMX_Wmvdec.h b/component/video/dec/vc1/Exynos_OMX_Wmvdec.h index 3bd45da..02d07f6 100644 --- a/component/video/dec/vc1/Exynos_OMX_Wmvdec.h +++ b/component/video/dec/vc1/Exynos_OMX_Wmvdec.h @@ -91,6 +91,8 @@ typedef struct _EXYNOS_WMVDEC_HANDLE OMX_BOOL bDestinationStart; OMX_HANDLETYPE hSourceStartEvent; OMX_HANDLETYPE hDestinationStartEvent; + + EXYNOS_QUEUE bypassBufferInfoQ; } EXYNOS_WMVDEC_HANDLE; #ifdef __cplusplus diff --git a/component/video/dec/vp8/Android.mk b/component/video/dec/vp8/Android.mk index e9a4322..4fd0960 100644 --- a/component/video/dec/vp8/Android.mk +++ b/component/video/dec/vp8/Android.mk @@ -27,6 +27,14 @@ ifeq ($(BOARD_USE_CSC_HW), true) LOCAL_CFLAGS += -DUSE_CSC_HW endif +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_DUALDPB_MODE), true) +LOCAL_CFLAGS += -DUSE_DUALDPB_MODE +endif + LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ diff --git a/component/video/dec/vp8/Exynos_OMX_Vp8dec.c b/component/video/dec/vp8/Exynos_OMX_Vp8dec.c index 5e5d1b9..21d4177 100644 --- a/component/video/dec/vp8/Exynos_OMX_Vp8dec.c +++ b/component/video/dec/vp8/Exynos_OMX_Vp8dec.c @@ -33,6 +33,7 @@ #include "Exynos_OMX_Basecomponent.h" #include "Exynos_OMX_Baseport.h" #include "Exynos_OMX_Vdec.h" +#include "Exynos_OMX_VdecControl.h" #include "Exynos_OSAL_ETC.h" #include "Exynos_OSAL_Semaphore.h" #include "Exynos_OSAL_Thread.h" @@ -473,13 +474,12 @@ OMX_ERRORTYPE VP8CodecRegistCodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]); - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; pBufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; } else { ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]); - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; pBufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt); if (pPlanes == NULL) { @@ -587,16 +587,16 @@ OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA FunctionIn(); if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; - OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); - if (OMXBuffer == NULL) { - ret = OMX_ErrorUndefined; + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO)); + if (pBufferInfo == NULL) { + ret = OMX_ErrorInsufficientResources; goto EXIT; } - OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; - OMXBuffer->nFlags = pSrcInputData->nFlags; - Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + pBufferInfo->nFlags = pSrcInputData->nFlags; + pBufferInfo->timeStamp = pSrcInputData->timeStamp; + ret = Exynos_OSAL_Queue(&pVp8Dec->bypassBufferInfoQ, (void *)pBufferInfo); + Exynos_OSAL_SignalSet(pVp8Dec->hDestinationStartEvent); ret = OMX_ErrorNone; goto EXIT; @@ -616,11 +616,11 @@ OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; - inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; - inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; } + bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt; + inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC; /* should be done before prepare input buffer */ if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -642,28 +642,46 @@ OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA goto EXIT; } - if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - ret = VP8CodecRegistCodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX); - if (ret != OMX_ErrorNone) - goto EXIT; - } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { - /* Register input buffer */ - for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { - ExynosVideoPlane plane; - plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; - plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; - plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; - if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } - /* set output geometry */ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + +#ifdef USE_DUALDPB_MODE + switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12; + break; + case OMX_COLOR_FormatYUV420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_I420; + break; + case OMX_SEC_COLOR_FormatYVU420Planar: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_YV12; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV21; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + default: + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + break; + } + + if (bufferConf.eColorFormat != VIDEO_COLORFORMAT_NV12_TILED) { + if ((pDecOps->Enable_DualDPBMode != NULL) && + (pDecOps->Enable_DualDPBMode(hMFCHandle) == VIDEO_ERROR_NONE)) { + pVideoDec->bDualDPBMode = OMX_TRUE; + pExynosOutputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(pExynosOutputPort->portDefinition.format.video.eColorFormat); + } else { + bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; + } + } + pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat; +#else pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; +#endif + bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt; if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); ret = OMX_ErrorInsufficientResources; @@ -672,8 +690,12 @@ OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA /* input buffer enqueue for header parsing */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); - if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + if (pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); // ret = OMX_ErrorInsufficientResources; ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; @@ -691,6 +713,8 @@ OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA Exynos_OSAL_Memset(&pVp8Dec->hMFCVp8Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); if (pOutbufOps->Get_Geometry(hMFCHandle, &pVp8Dec->hMFCVp8Handle.codecOutbufConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); + VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX); + pInbufOps->Cleanup_Buffer(hMFCHandle); ret = OMX_ErrorInsufficientResources; goto EXIT; } @@ -776,13 +800,13 @@ OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) int i, nOutbufs; - OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; FunctionIn(); - nAllocLen[0] = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nAlignPlaneSize[0]; - nAllocLen[1] = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nAlignPlaneSize[1]; + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) + nAllocLen[i] = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nAlignPlaneSize[i]; pOutbufOps->Set_Shareable(hMFCHandle); @@ -812,7 +836,7 @@ OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) /* Enqueue output buffer */ for (i = 0; i < nOutbufs; i++) { pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -821,7 +845,7 @@ OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { - ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + ExynosVideoPlane planes[MAX_BUFFER_PLANE] = {0, 0, 0}; int plane; /* get dpb count */ @@ -839,19 +863,19 @@ OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) #ifdef USE_ANB if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; planes[plane].allocSize = nAllocLen[plane]; } - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + if (pOutbufOps->Register(hMFCHandle, planes, pExynosOutputPort->nPlaneCnt) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; } pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); } if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) { @@ -1005,7 +1029,7 @@ OMX_ERRORTYPE Exynos_VP8Dec_SetParameter( } if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE)) { - pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; + pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; } else { ret = OMX_ErrorBadParameter; goto EXIT; @@ -1244,8 +1268,9 @@ OMX_ERRORTYPE Exynos_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; + pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE; if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE}; + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0}; Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize); @@ -1261,6 +1286,7 @@ OMX_ERRORTYPE Exynos_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) /* Does not require any actions. */ } + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1283,6 +1309,8 @@ OMX_ERRORTYPE Exynos_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pExynosComponent->getAllDelayBuffer = OMX_FALSE; + Exynos_OSAL_QueueCreate(&pVp8Dec->bypassBufferInfoQ, QUEUE_ELEMENTS); + #ifdef USE_CSC_HW csc_method = CSC_METHOD_HW; #endif @@ -1323,6 +1351,8 @@ OMX_ERRORTYPE Exynos_VP8Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) pVideoDec->csc_handle = NULL; } + Exynos_OSAL_QueueTerminate(&pVp8Dec->bypassBufferInfoQ); + Exynos_OSAL_SignalTerminate(pVp8Dec->hDestinationStartEvent); pVp8Dec->hDestinationStartEvent = NULL; pVp8Dec->bDestinationStart = OMX_FALSE; @@ -1363,19 +1393,25 @@ EXIT: OMX_ERRORTYPE Exynos_VP8Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + OMX_BUFFERHEADERTYPE tempBufferHeader; + void *pPrivate = NULL; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; OMX_BOOL bInStartCode = OMX_FALSE; - ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; - ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; - ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; FunctionIn(); @@ -1396,11 +1432,29 @@ OMX_ERRORTYPE Exynos_VP8Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_D pDecOps->Set_FrameTag(hMFCHandle, pVp8Dec->hMFCVp8Handle.indexTimestamp); pVp8Dec->hMFCVp8Handle.indexTimestamp++; pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP; - +#ifdef USE_QOS_CTRL + if ((pVideoDec->bQosChanged == OMX_TRUE) && + (pDecOps->Set_QosRatio != NULL)) { + pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio); + pVideoDec->bQosChanged = OMX_FALSE; + } +#endif /* queue work for input buffer */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); - codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0}; + + if (pExynosInputPort->bufferProcessType == BUFFER_COPY) { + tempBufferHeader.nFlags = pSrcInputData->nFlags; + tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp; + pPrivate = (void *)&tempBufferHeader; + } else { + pPrivate = (void *)pSrcInputData->bufferHeader; + } + codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize, + pExynosInputPort->nPlaneCnt, pPrivate); if (codecReturn != VIDEO_ERROR_NONE) { ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1441,22 +1495,26 @@ OMX_ERRORTYPE Exynos_VP8Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; FunctionIn(); - pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) + pVideoBuffer = &videoBuffer; + else + pVideoBuffer = NULL; pSrcOutputData->dataLen = 0; pSrcOutputData->usedDataLen = 0; pSrcOutputData->remainDataLen = 0; - pSrcOutputData->nFlags = 0; - pSrcOutputData->timeStamp = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + pSrcOutputData->bufferHeader = NULL; if (pVideoBuffer == NULL) { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; pSrcOutputData->allocSize = 0; pSrcOutputData->pPrivate = NULL; - pSrcOutputData->bufferHeader = NULL; } else { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; @@ -1481,7 +1539,8 @@ OMX_ERRORTYPE Exynos_VP8Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ } /* For Share Buffer */ - pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; } ret = OMX_ErrorNone; @@ -1494,16 +1553,19 @@ EXIT: OMX_ERRORTYPE Exynos_VP8Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; - ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; - ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,}; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + int i; FunctionIn(); @@ -1513,12 +1575,13 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_D goto EXIT; } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[i]: 0x%x", __FUNCTION__, __LINE__, i, + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[i]); + } codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1589,7 +1652,7 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP; pDstOutputData->allocSize = pDstOutputData->dataLen = 0; - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) { pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; @@ -1626,6 +1689,17 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ case VIDEO_COLORFORMAT_NV12: pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; break; +#ifdef USE_DUALDPB_MODE + case VIDEO_COLORFORMAT_I420: + pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420Planar; + break; + case VIDEO_COLORFORMAT_YV12: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatYVU420Planar; + break; + case VIDEO_COLORFORMAT_NV21: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV21Linear; + break; +#endif case VIDEO_COLORFORMAT_NV12_TILED: default: pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; @@ -1655,7 +1729,10 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ /* NEED TIMESTAMP REORDER */ if (pVideoDec->bDTSMode == OMX_TRUE) { - if (pVideoBuffer->frameType == VIDEO_FRAME_I) + if ((pVideoBuffer->frameType == VIDEO_FRAME_I) || + ((pVideoBuffer->frameType == VIDEO_FRAME_OTHERS) && + ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) || + (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE)) pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp; else indexTimestamp = pVp8Dec->hMFCVp8Handle.outputIndexTimestamp; @@ -1786,6 +1863,21 @@ OMX_ERRORTYPE Exynos_VP8Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXCompone Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent); } + if (Exynos_OSAL_GetElemNum(&pVp8Dec->bypassBufferInfoQ) > 0) { + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp8Dec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags; + pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader); + Exynos_OSAL_Free(pBufferInfo); + + ret = OMX_ErrorNone; + goto EXIT; + } } if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE) { ret = Exynos_VP8Dec_DstIn(pOMXComponent, pDstInputData); @@ -1826,6 +1918,37 @@ OMX_ERRORTYPE Exynos_VP8Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXCompon Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent); } + if (Exynos_OSAL_GetElemNum(&pVp8Dec->bypassBufferInfoQ) > 0) { + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL; + BYPASS_BUFFER_INFO *pBufferInfo = NULL; + + if (dstOutputUseBuffer->dataValid == OMX_FALSE) { + pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (pOMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else { + pOMXBuffer = dstOutputUseBuffer->bufferHeader; + } + + pBufferInfo = Exynos_OSAL_Dequeue(&pVp8Dec->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOMXBuffer->nFlags = pBufferInfo->nFlags; + pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer); + Exynos_OSAL_Free(pBufferInfo); + + dstOutputUseBuffer->dataValid = OMX_FALSE; + + ret = OMX_ErrorNone; + goto EXIT; + } } ret = Exynos_VP8Dec_DstOut(pOMXComponent, pDstOutputData); if ((ret != OMX_ErrorNone) && @@ -1915,7 +2038,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ pExynosPort->portDefinition.format.video.nSliceHeight = 0; pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; - pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp8"); pExynosPort->portDefinition.format.video.pNativeRender = 0; diff --git a/component/video/dec/vp8/Exynos_OMX_Vp8dec.h b/component/video/dec/vp8/Exynos_OMX_Vp8dec.h index 0b66406..2c29c5a 100644 --- a/component/video/dec/vp8/Exynos_OMX_Vp8dec.h +++ b/component/video/dec/vp8/Exynos_OMX_Vp8dec.h @@ -62,6 +62,8 @@ typedef struct _EXYNOS_VP8DEC_HANDLE OMX_BOOL bDestinationStart; OMX_HANDLETYPE hSourceStartEvent; OMX_HANDLETYPE hDestinationStartEvent; + + EXYNOS_QUEUE bypassBufferInfoQ; } EXYNOS_VP8DEC_HANDLE; #ifdef __cplusplus diff --git a/component/video/enc/Android.mk b/component/video/enc/Android.mk index 5b62002..e47310d 100644 --- a/component/video/enc/Android.mk +++ b/component/video/enc/Android.mk @@ -56,6 +56,14 @@ ifeq ($(BOARD_USE_CSC_HW), true) LOCAL_CFLAGS += -DUSE_CSC_HW endif +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_ENCODER_RGBINPUT_SUPPORT), true) +LOCAL_CFLAGS += -DUSE_ENCODER_RGBINPUT_SUPPORT +endif + LOCAL_SHARED_LIBRARIES := libcsc include $(BUILD_STATIC_LIBRARY) diff --git a/component/video/enc/Exynos_OMX_Venc.c b/component/video/enc/Exynos_OMX_Venc.c index bd748e6..6e6438e 100644 --- a/component/video/enc/Exynos_OMX_Venc.c +++ b/component/video/enc/Exynos_OMX_Venc.c @@ -51,7 +51,6 @@ //#define EXYNOS_TRACE_ON #include "Exynos_OSAL_Log.h" - inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) { EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; @@ -97,12 +96,11 @@ void Exynos_Free_CodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]); nBufferCnt = MFC_INPUT_BUFFER_NUM_MAX; - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; } else { ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]); nBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX; - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; for (i = 0; i < nBufferCnt; i++) { if (ppCodecBuffer[i] != NULL) { @@ -123,7 +121,7 @@ OMX_ERRORTYPE Exynos_Allocate_CodecBuffers( OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex, OMX_U32 nBufferCnt, - OMX_U32 nPlaneSize[MFC_OUTPUT_BUFFER_PLANE]) + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE]) { OMX_ERRORTYPE ret = OMX_ErrorNone; EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; @@ -138,14 +136,13 @@ OMX_ERRORTYPE Exynos_Allocate_CodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]); - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; } else { ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]); - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; #ifdef USE_CSC_HW eMemoryType = NORMAL_MEMORY; #endif } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; if (pVideoEnc->bDRMPlayerMode == OMX_TRUE) eMemoryType = SECURE_MEMORY; @@ -203,17 +200,25 @@ OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosCompo return ret; } -OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData) +OMX_ERRORTYPE Exynos_Input_CodecBufferToData( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent, + OMX_PTR codecBuffer, + EXYNOS_OMX_DATA *pData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - CODEC_ENC_BUFFER *pInputCodecBuffer = (CODEC_ENC_BUFFER*)codecBuffer; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + CODEC_ENC_BUFFER *pInputCodecBuffer = (CODEC_ENC_BUFFER*)codecBuffer; + + int i; + + pData->allocSize = 0; + for (i = 0; i < pExynosComponent->pExynosPort[INPUT_PORT_INDEX].nPlaneCnt; i++) { + pData->buffer.multiPlaneBuffer.dataBuffer[i] = pInputCodecBuffer->pVirAddr[i]; + pData->buffer.multiPlaneBuffer.fd[i] = pInputCodecBuffer->fd[i]; + + pData->allocSize += pInputCodecBuffer->bufferSize[i]; + } - pData->buffer.multiPlaneBuffer.dataBuffer[0] = pInputCodecBuffer->pVirAddr[0]; - pData->buffer.multiPlaneBuffer.dataBuffer[1] = pInputCodecBuffer->pVirAddr[1]; - pData->buffer.multiPlaneBuffer.fd[0] = pInputCodecBuffer->fd[0]; - pData->buffer.multiPlaneBuffer.fd[1] = pInputCodecBuffer->fd[1]; - pData->allocSize = pInputCodecBuffer->bufferSize[0] + pInputCodecBuffer->bufferSize[1]; pData->dataLen = pInputCodecBuffer->dataSize; pData->usedDataLen = 0; pData->remainDataLen = pInputCodecBuffer->dataSize; @@ -274,23 +279,22 @@ void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U3 OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData) { - OMX_BOOL ret = OMX_FALSE; + OMX_BOOL ret = OMX_FALSE; EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; - OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth; - OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight; - OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; - OMX_BYTE checkInputStream = NULL; - OMX_BOOL flagEOS = OMX_FALSE; - - FunctionIn(); - - checkInputStream = inputUseBuffer->bufferHeader->pBuffer; - - CODEC_ENC_BUFFER *codecInputBuffer = (CODEC_ENC_BUFFER *)srcInputData->pPrivate; - codecInputBuffer->dataSize = ((nFrameWidth * nFrameHeight) * 3) / 2; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; + OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth; + OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight; + OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; + OMX_BYTE checkInputStream = inputUseBuffer->bufferHeader->pBuffer; + OMX_BOOL flagEOS = OMX_FALSE; + CODEC_ENC_BUFFER *codecInputBuffer = (CODEC_ENC_BUFFER *)srcInputData->pPrivate; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = (ENCODE_CODEC_EXTRA_BUFFERINFO *)srcInputData->extInfo; + + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {0, 0, 0}; + OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL}; + int i; unsigned int csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); unsigned int csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); @@ -304,94 +308,147 @@ OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA unsigned char *pSrcBuf[3] = {NULL, }; unsigned char *pDstBuf[3] = {NULL, }; - pSrcBuf[0] = checkInputStream; - pSrcBuf[1] = checkInputStream + (nFrameWidth * nFrameHeight); - pSrcBuf[2] = checkInputStream + (((nFrameWidth * nFrameHeight) * 5) / 4); + FunctionIn(); pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[0]; pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[1]; pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[2]; csc_get_method(pVideoEnc->csc_handle, &csc_method); - if (csc_method == CSC_METHOD_HW) - dstCacheable = 0; + if ((exynosInputPort->bStoreMetaData == OMX_TRUE) && + (eColorFormat == OMX_COLOR_FormatAndroidOpaque)) { #ifdef USE_METADATABUFFERTYPE - OMX_PTR ppBuf[MAX_BUFFER_PLANE]; - - /* kMetadataBufferTypeGrallocSource */ - if (exynosInputPort->bStoreMetaData == OMX_TRUE) { + /* kMetadataBufferTypeGrallocSource */ /* ARGB8888 converted to YUV420SemiPlanar */ + ExynosVideoPlane planes[MAX_BUFFER_PLANE]; + csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_Format32bitARGB8888); csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); - if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { - ExynosVideoPlane planes[MAX_BUFFER_PLANE]; - OMX_U32 stride; - int imageSize; + if (OMX_ErrorNone != Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf)) { + ret = OMX_FALSE; + goto EXIT; + } - ret = Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, planes); - if (ret != OMX_ErrorNone) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_LockANBHandle() failed", __FUNCTION__); - ret = OMX_FALSE; - goto EXIT; - } + Exynos_OSAL_GetPlaneSize(pExtBufferInfo->eColorFormat, nFrameWidth, nFrameHeight, nPlaneSize); + codecInputBuffer->dataSize = 0; + for (i = 0; i < exynosInputPort->nPlaneCnt; i++) + codecInputBuffer->dataSize += nPlaneSize[i]; - imageSize = nFrameWidth * nFrameHeight * 3; /* RGB888 */ + csc_src_color_format = omx_2_hal_pixel_format((unsigned int)pVideoEnc->ANBColorFormat); + if (OMX_ErrorNone != Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, planes)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_LockANBHandle() failed", __FUNCTION__); + ret = OMX_FALSE; + goto EXIT; + } #ifdef USE_GSC_RGB_ENCODER - if (pVideoEnc->csc_set_format == OMX_FALSE) { - cscRet = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_HW); - if (cscRet != CSC_ErrorNone) { - ret = OMX_FALSE; - goto EXIT; - } + if (pVideoEnc->csc_set_format == OMX_FALSE) { + cscRet = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_HW); + if (cscRet != CSC_ErrorNone) { + ret = OMX_FALSE; + goto EXIT; } -#endif - -#ifdef USE_DMA_BUF - if (csc_method == CSC_METHOD_HW) { - csc_memType = CSC_MEMORY_DMABUF; - pSrcBuf[0] = (unsigned char *)planes[0].fd; - } else -#endif - pSrcBuf[0] = planes[0].addr; - pSrcBuf[1] = NULL; - pSrcBuf[2] = NULL; + csc_method = CSC_METHOD_HW; } - } else #endif - { + pSrcBuf[0] = planes[0].addr; + pSrcBuf[1] = NULL; + pSrcBuf[2] = NULL; + #ifdef USE_DMA_BUF if (csc_method == CSC_METHOD_HW) { - csc_memType = CSC_MEMORY_DMABUF; - pSrcBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, checkInputStream); - pSrcBuf[1] = NULL; - pSrcBuf[2] = NULL; + srcCacheable = 0; + csc_memType = CSC_MEMORY_DMABUF; + pSrcBuf[0] = (unsigned char *)planes[0].fd; + pSrcBuf[1] = NULL; + pSrcBuf[2] = NULL; } #endif +#endif + } else { + Exynos_OSAL_GetPlaneSize(eColorFormat, nFrameWidth, nFrameHeight, nPlaneSize); + codecInputBuffer->dataSize = 0; + for (i = 0; i < exynosInputPort->nPlaneCnt; i++) + codecInputBuffer->dataSize += nPlaneSize[i]; + + pSrcBuf[0] = checkInputStream; + pSrcBuf[1] = checkInputStream + nPlaneSize[0]; + pSrcBuf[2] = checkInputStream + nPlaneSize[0] + nPlaneSize[1]; + + if (pVideoEnc->bRGBSupport == OMX_TRUE) { + switch (eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12Tiled: + case OMX_SEC_COLOR_FormatNV21Linear: + Exynos_OSAL_Memcpy(srcInputData->buffer.multiPlaneBuffer.dataBuffer[0], pSrcBuf[0], nPlaneSize[0]); + Exynos_OSAL_Memcpy(srcInputData->buffer.multiPlaneBuffer.dataBuffer[1], pSrcBuf[1], nPlaneSize[1]); + break; + case OMX_COLOR_FormatYUV420Planar: + case OMX_SEC_COLOR_FormatYVU420Planar: + Exynos_OSAL_Memcpy(srcInputData->buffer.multiPlaneBuffer.dataBuffer[0], pSrcBuf[0], nPlaneSize[0]); + Exynos_OSAL_Memcpy(srcInputData->buffer.multiPlaneBuffer.dataBuffer[1], pSrcBuf[1], nPlaneSize[1]); + Exynos_OSAL_Memcpy(srcInputData->buffer.multiPlaneBuffer.dataBuffer[2], pSrcBuf[2], nPlaneSize[2]); + break; + case OMX_COLOR_Format32bitBGRA8888: + Exynos_OSAL_Memcpy(srcInputData->buffer.multiPlaneBuffer.dataBuffer[0], checkInputStream, codecInputBuffer->dataSize); + break; + default: + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unspported color format : %x. can't support this format", __FUNCTION__, eColorFormat); + codecInputBuffer->dataSize = 0; + ret = OMX_FALSE; + goto EXIT; + break; + } - switch (eColorFormat) { - case OMX_COLOR_FormatYUV420Planar: - /* YUV420Planar converted to YUV420Semiplanar (interleaved UV plane) as per MFC spec.*/ - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatNV12Tiled: - case OMX_SEC_COLOR_FormatNV21Linear: - /* Just copied to MFC input buffer */ - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - default: - break; + pExtBufferInfo->eColorFormat = eColorFormat; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "actual input color format = %x", pExtBufferInfo->eColorFormat); + ret = OMX_TRUE; + goto EXIT; + } else { + switch (eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + /* YUV420Planar converted to YUV420Semiplanar (interleaved UV plane) as per MFC spec.*/ + csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); + csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12Tiled: + case OMX_SEC_COLOR_FormatNV21Linear: + /* Just copied to MFC input buffer */ + csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); + csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); + break; + case OMX_COLOR_Format32bitARGB8888: + csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_Format32bitARGB8888); + csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); + break; + default: + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unspported color format : %x. can't support CSC", __FUNCTION__, eColorFormat); + codecInputBuffer->dataSize = 0; + ret = OMX_FALSE; + goto EXIT; + break; + } + + pExtBufferInfo->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; +#ifdef USE_DMA_BUF + if (csc_method == CSC_METHOD_HW) { + srcCacheable = 0; + csc_memType = CSC_MEMORY_DMABUF; + pSrcBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, checkInputStream); + pSrcBuf[1] = NULL; + pSrcBuf[2] = NULL; + } +#endif } } #ifdef USE_DMA_BUF if (csc_method == CSC_METHOD_HW) { + dstCacheable = 0; + csc_memType = CSC_MEMORY_DMABUF; pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.fd[0]; pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.fd[1]; pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.fd[2]; @@ -400,24 +457,24 @@ OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA csc_set_src_format( pVideoEnc->csc_handle, /* handle */ - nFrameWidth, /* width */ - nFrameHeight, /* height */ + nFrameWidth, /* width */ + nFrameHeight, /* height */ 0, /* crop_left */ 0, /* crop_right */ - nFrameWidth, /* crop_width */ - nFrameHeight, /* crop_height */ + nFrameWidth, /* crop_width */ + nFrameHeight, /* crop_height */ csc_src_color_format, /* color_format */ - srcCacheable); /* cacheable */ + srcCacheable); /* cacheable */ csc_set_dst_format( pVideoEnc->csc_handle, /* handle */ - nFrameWidth, /* width */ - nFrameHeight, /* height */ + nFrameWidth, /* width */ + nFrameHeight, /* height */ 0, /* crop_left */ 0, /* crop_right */ - nFrameWidth, /* crop_width */ - nFrameHeight, /* crop_height */ + nFrameWidth, /* crop_width */ + nFrameHeight, /* crop_height */ csc_dst_color_format, /* color_format */ - dstCacheable); /* cacheable */ + dstCacheable); /* cacheable */ csc_set_src_buffer( pVideoEnc->csc_handle, /* handle */ pSrcBuf, @@ -438,8 +495,6 @@ OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA } #endif - ret = OMX_TRUE; - EXIT: FunctionOut(); @@ -448,18 +503,20 @@ EXIT: OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData) { - OMX_BOOL ret = OMX_FALSE; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; - OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth; - OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight; - OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; - OMX_U32 copySize = 0; - OMX_BYTE checkInputStream = NULL; - OMX_U32 checkInputStreamLen = 0; - OMX_BOOL flagEOS = OMX_FALSE; + OMX_BOOL ret = OMX_FALSE; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; + OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth; + OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight; + OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = (ENCODE_CODEC_EXTRA_BUFFERINFO *)srcInputData->extInfo; + + OMX_U32 copySize = 0; + OMX_BYTE checkInputStream = NULL; + OMX_U32 checkInputStreamLen = 0; + OMX_BOOL flagEOS = OMX_FALSE; FunctionIn(); @@ -476,60 +533,84 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE); #ifdef USE_METADATABUFFERTYPE if (exynosInputPort->bStoreMetaData == OMX_TRUE) { - OMX_PTR ppBuf[MAX_BUFFER_PLANE]; - OMX_PTR allocSize[MAX_BUFFER_PLANE]; + OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL}; + OMX_U32 allocSize[MAX_BUFFER_PLANE] = {0, 0, 0}; int plane = 0; - if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { - Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); - ExynosVideoPlane planes[MAX_BUFFER_PLANE]; + Exynos_OSAL_GetPlaneSize(pExtBufferInfo->eColorFormat, nFrameWidth, nFrameHeight, allocSize); + + if (pVideoEnc->nInbufSpareSize > 0) { + for (plane = 0; plane < exynosInputPort->nPlaneCnt; plane++) + allocSize[plane] += pVideoEnc->nInbufSpareSize; + } - Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatYUV420SemiPlanar, planes); + for (plane = 0; plane < MAX_BUFFER_PLANE; plane++) { + srcInputData->buffer.multiPlaneBuffer.fd[plane] = -1; + srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = NULL; + } - srcInputData->buffer.multiPlaneBuffer.fd[0] = planes[0].fd; - srcInputData->buffer.multiPlaneBuffer.fd[1] = planes[1].fd; - allocSize[0] = nFrameWidth * nFrameHeight; - allocSize[1] = nFrameWidth * nFrameHeight >> 1; + if (inputUseBuffer->dataLen <= 0) { + if (!(inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { + Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer); - for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { - srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = - Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.fd[plane]); - if(srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] == NULL) { + /* reset dataBuffer */ + Exynos_ResetDataBuffer(inputUseBuffer); + } else { + /* Make EOS Buffer for MFC Processing scheme */ + /* Use ION Allocator */ + for (plane = 0; plane < exynosInputPort->nPlaneCnt; plane++) { srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = - Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, allocSize[plane], srcInputData->buffer.multiPlaneBuffer.fd[plane]); + (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, allocSize[plane], NORMAL_MEMORY); + srcInputData->buffer.multiPlaneBuffer.fd[plane] = + Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane]); } } - /* input buffers are 2 plane. */ - srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; - srcInputData->buffer.multiPlaneBuffer.fd[2] = -1; - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__, __LINE__, (unsigned int)ppBuf[0], (unsigned int)ppBuf[0]); } else { - /* kMetadataBufferTypeCameraSource */ Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); #ifdef USE_DMA_BUF - srcInputData->buffer.multiPlaneBuffer.fd[0] = ppBuf[0]; - srcInputData->buffer.multiPlaneBuffer.fd[1] = ppBuf[1]; - allocSize[0] = nFrameWidth * nFrameHeight; - allocSize[1] = nFrameWidth * nFrameHeight >> 1; - - for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { - srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = - Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.fd[plane]); - if(srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] == NULL) { + if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + ExynosVideoPlane planes[MAX_BUFFER_PLANE]; + + Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, planes); + + for (plane = 0; plane < exynosInputPort->nPlaneCnt; plane++) { + srcInputData->buffer.multiPlaneBuffer.fd[plane] = planes[plane].fd; + srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = planes[plane].addr; + } + } else { + /* kMetadataBufferTypeCameraSource */ + for (plane = 0; plane < exynosInputPort->nPlaneCnt; plane++) { + srcInputData->buffer.multiPlaneBuffer.fd[plane] = ppBuf[plane]; + } + } + + for (plane = 0; plane < exynosInputPort->nPlaneCnt; plane++) { + if ((srcInputData->buffer.multiPlaneBuffer.fd[plane] != -1) && + (srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] == NULL)) { srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = - Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, allocSize[plane], srcInputData->buffer.multiPlaneBuffer.fd[plane]); + Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.fd[plane]); + if(srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] == NULL) { + srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = + Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, allocSize[plane], srcInputData->buffer.multiPlaneBuffer.fd[plane]); + } } } - /* input buffers are 2 plane. */ - srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; - srcInputData->buffer.multiPlaneBuffer.fd[2] = -1; #else - for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { - srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = ppBuf[plane]; + if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_COLOR_FormatAndroidOpaque share don't implemented in UserPtr mode."); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, OMX_ErrorNotImplemented, 0, NULL); + ret = OMX_FALSE; + goto EXIT; + } else { + /* kMetadataBufferTypeCameraSource */ + for (plane = 0; plane < MAX_BUFFER_PLANE; plane++) { + srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = ppBuf[plane]; + } } - srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; #endif - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__, __LINE__, (unsigned int)ppBuf[0], (unsigned int)ppBuf[1]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__, __LINE__, (unsigned int)ppBuf[0], (unsigned int)ppBuf[0]); } } #endif @@ -550,20 +631,30 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE"); if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) { - ret = Exynos_CSC_InputData(pOMXComponent, srcInputData); - if (ret == OMX_FALSE) - goto EXIT; - - inputUseBuffer->dataLen -= copySize; - inputUseBuffer->remainDataLen -= copySize; - inputUseBuffer->usedDataLen += copySize; - - srcInputData->dataLen += copySize; - srcInputData->remainDataLen += copySize; - - srcInputData->timeStamp = inputUseBuffer->timeStamp; - srcInputData->nFlags = inputUseBuffer->nFlags; - srcInputData->bufferHeader = inputUseBuffer->bufferHeader; + if ((copySize > 0) || (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { + ret = OMX_TRUE; + if (copySize > 0) + ret = Exynos_CSC_InputData(pOMXComponent, srcInputData); + if (ret) { + inputUseBuffer->dataLen -= copySize; + inputUseBuffer->remainDataLen -= copySize; + inputUseBuffer->usedDataLen += copySize; + + srcInputData->dataLen += copySize; + srcInputData->remainDataLen += copySize; + + srcInputData->timeStamp = inputUseBuffer->timeStamp; + srcInputData->nFlags = inputUseBuffer->nFlags; + srcInputData->bufferHeader = inputUseBuffer->bufferHeader; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_CSC_InputData() failure"); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, OMX_ErrorUndefined, 0, NULL); + } + } else { + ret = OMX_FALSE; + } } else { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length"); pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, @@ -685,36 +776,65 @@ EXIT: #ifdef USE_METADATABUFFERTYPE OMX_ERRORTYPE Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; - EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData; - OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; + EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData; + OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = (ENCODE_CODEC_EXTRA_BUFFERINFO *)pSrcInputData->extInfo; int i = 0; OMX_PTR ppBuf[MAX_BUFFER_PLANE]; - - /* kMetadataBufferTypeGrallocSource */ if (exynosInputPort->bStoreMetaData == OMX_TRUE) { Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)srcInputUseBuffer->bufferHeader->pBuffer, ppBuf); if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + /* kMetadataBufferTypeGrallocSource */ pVideoEnc->ANBColorFormat = Exynos_OSAL_GetANBColorFormat(ppBuf[0]); - if ((pVideoEnc->ANBColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) || - (pVideoEnc->ANBColorFormat == OMX_SEC_COLOR_FormatNV12Tiled)) { + pExtBufferInfo->eColorFormat = pVideoEnc->ANBColorFormat; + + switch (pVideoEnc->ANBColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12Tiled: exynosInputPort->bufferProcessType = BUFFER_SHARE; - } else { + exynosInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(pVideoEnc->ANBColorFormat); + break; + case OMX_COLOR_Format32bitARGB8888: + exynosInputPort->bufferProcessType = BUFFER_COPY; + exynosInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420SemiPlanar); + pExtBufferInfo->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + break; + case OMX_COLOR_Format32bitBGRA8888: + if (pVideoEnc->bRGBSupport == OMX_TRUE) { + exynosInputPort->bufferProcessType = BUFFER_SHARE; + exynosInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(pVideoEnc->ANBColorFormat); + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported color format : ANB color is %x", __func__, pVideoEnc->ANBColorFormat); + ret = OMX_ErrorNotImplemented; + goto EXIT; + } + break; + default: exynosInputPort->bufferProcessType = BUFFER_COPY; + exynosInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420SemiPlanar); + pExtBufferInfo->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + break; } if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {0, }; + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {0, 0, 0}; + nPlaneSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE; nPlaneSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE; + if (pVideoEnc->nInbufSpareSize > 0) { + nPlaneSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE + pVideoEnc->nInbufSpareSize; + nPlaneSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE + pVideoEnc->nInbufSpareSize; + } + Exynos_OSAL_SemaphoreCreate(&exynosInputPort->codecSemID); Exynos_OSAL_QueueCreate(&exynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -730,6 +850,8 @@ OMX_ERRORTYPE Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent) /*************/ /* Does not require any actions. */ } + } else { + pExtBufferInfo->eColorFormat = eColorFormat; } } @@ -790,6 +912,11 @@ OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent) (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) { ret = Exynos_InputBufferGetQueue(pExynosComponent); #ifdef USE_METADATABUFFERTYPE + if (ret != OMX_ErrorNone) { + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + break; + } + if ((pVideoEnc->bFirstInput == OMX_TRUE) && (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) { Exynos_OMX_ExtensionSetup(hComponent); @@ -930,8 +1057,13 @@ OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent) ret = OMX_ErrorUndefined; break; } - + dstInputData.buffer.singlePlaneBuffer.fd = + dstInputData.buffer.singlePlaneBuffer.dataBuffer; dstInputData.buffer.singlePlaneBuffer.dataBuffer = dataBuffer; + } else { + dstInputData.buffer.singlePlaneBuffer.fd = + Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, + dstInputData.buffer.singlePlaneBuffer.dataBuffer); } Exynos_ResetDataBuffer(dstInputUseBuffer); } @@ -1275,9 +1407,13 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone pVideoEnc->bFirstInput = OMX_FALSE; pVideoEnc->bFirstOutput = OMX_FALSE; pVideoEnc->configChange = OMX_FALSE; + pVideoEnc->bQosChanged = OMX_FALSE; + pVideoEnc->nQosRatio = 0; + pVideoEnc->nInbufSpareSize = 0; pVideoEnc->quantization.nQpI = 4; // I frame quantization parameter pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter + pVideoEnc->bRGBSupport = OMX_FALSE; pExynosComponent->bMultiThreadProcess = OMX_TRUE; @@ -1305,6 +1441,8 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; pExynosPort->bStoreMetaData = OMX_FALSE; + pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(ENCODE_CODEC_EXTRA_BUFFERINFO)); + ((ENCODE_CODEC_EXTRA_BUFFERINFO *)(pExynosPort->processData.extInfo))->eColorFormat = OMX_COLOR_FormatUnused; /* Output port */ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; @@ -1378,6 +1516,12 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hCompo Exynos_OSAL_Free(pVideoEnc); pExynosComponent->hComponentHandle = pVideoEnc = NULL; + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + if (pExynosPort->processData.extInfo != NULL) { + Exynos_OSAL_Free(pExynosPort->processData.extInfo); + pExynosPort->processData.extInfo = NULL; + } + for(i = 0; i < ALL_PORT_NUM; i++) { pExynosPort = &pExynosComponent->pExynosPort[i]; Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType); diff --git a/component/video/enc/Exynos_OMX_Venc.h b/component/video/enc/Exynos_OMX_Venc.h index d0d35f7..c6d0880 100644 --- a/component/video/enc/Exynos_OMX_Venc.h +++ b/component/video/enc/Exynos_OMX_Venc.h @@ -51,13 +51,18 @@ #define DEFAULT_MFC_INPUT_CBUFFER_SIZE ALIGN((DEFAULT_MFC_INPUT_YBUFFER_SIZE / 2), 256) #define DEFAULT_MFC_OUTPUT_BUFFER_SIZE 1920 * 1080 * 3 / 2 +#ifdef USE_ENCODER_RGBINPUT_SUPPORT +#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 8 +#else #define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 5 +#endif #define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 -#define MFC_INPUT_BUFFER_PLANE 2 -#define MFC_OUTPUT_BUFFER_PLANE 1 +#define MFC_DEFAULT_INPUT_BUFFER_PLANE 2 +#define MFC_DEFAULT_OUTPUT_BUFFER_PLANE 1 #define MAX_INPUTBUFFER_NUM_DYNAMIC 0 /* Dynamic number of metadata buffer */ +#define MAX_OUTPUTBUFFER_NUM_DYNAMIC 0 /* Dynamic number of metadata buffer */ // The largest metadata buffer size advertised // when metadata buffer mode is used for video encoding @@ -69,6 +74,12 @@ typedef struct void *pAddrC; } CODEC_ENC_ADDR_INFO; +typedef struct _BYPASS_BUFFER_INFO +{ + OMX_U32 nFlags; + OMX_TICKS timeStamp; +} BYPASS_BUFFER_INFO; + typedef struct _CODEC_ENC_BUFFER { void *pVirAddr[MAX_BUFFER_PLANE]; /* virtual address */ @@ -77,10 +88,19 @@ typedef struct _CODEC_ENC_BUFFER int dataSize; /* total data length */ } CODEC_ENC_BUFFER; +typedef struct _ENCODE_CODEC_EXTRA_BUFFERINFO +{ + /* For Encode Input */ + OMX_COLOR_FORMATTYPE eColorFormat; +} ENCODE_CODEC_EXTRA_BUFFERINFO; + typedef struct _EXYNOS_OMX_VIDEOENC_COMPONENT { OMX_HANDLETYPE hCodecHandle; OMX_BOOL bFirstFrame; + OMX_BOOL bQosChanged; + OMX_U32 nQosRatio; + OMX_U32 nInbufSpareSize; CODEC_ENC_BUFFER *pMFCEncInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; CODEC_ENC_BUFFER *pMFCEncOutputBuffer[MFC_OUTPUT_BUFFER_NUM_MAX]; @@ -107,6 +127,7 @@ typedef struct _EXYNOS_OMX_VIDEOENC_COMPONENT OMX_BOOL bFirstOutput; OMX_COLOR_FORMATTYPE ANBColorFormat; + OMX_BOOL bRGBSupport; /* CSC handle */ OMX_PTR csc_handle; diff --git a/component/video/enc/Exynos_OMX_VencControl.c b/component/video/enc/Exynos_OMX_VencControl.c index 869531f..81b9502 100644 --- a/component/video/enc/Exynos_OMX_VencControl.c +++ b/component/video/enc/Exynos_OMX_VencControl.c @@ -522,8 +522,9 @@ OMX_ERRORTYPE Exynos_OMX_FlushPort( if ((pExynosPort->bStoreMetaData == OMX_TRUE) && (pExynosPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque)) { OMX_PTR ppBuf[MAX_BUFFER_PLANE]; - Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pExynosPort->processData.bufferHeader->pBuffer, ppBuf); - Exynos_OSAL_UnlockANBHandle(ppBuf[0]); + if (OMX_ErrorNone == + Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pExynosPort->processData.bufferHeader->pBuffer, ppBuf)) + Exynos_OSAL_UnlockANBHandle(ppBuf[0]); } #endif Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader); @@ -543,8 +544,9 @@ OMX_ERRORTYPE Exynos_OMX_FlushPort( if ((pExynosPort->bStoreMetaData == OMX_TRUE) && (pExynosPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque)) { OMX_PTR ppBuf[MAX_BUFFER_PLANE]; - Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, ppBuf); - Exynos_OSAL_UnlockANBHandle(ppBuf[0]); + if (OMX_ErrorNone == + Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, ppBuf)) + Exynos_OSAL_UnlockANBHandle(ppBuf[0]); } #endif Exynos_OMX_InputBufferReturn(pOMXComponent, @@ -557,12 +559,18 @@ OMX_ERRORTYPE Exynos_OMX_FlushPort( Exynos_ResetCodecData(&pExynosPort->processData); } - while (1) { - OMX_S32 cnt = 0; - Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt); - if (cnt <= 0) - break; - Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + if (pExynosPort->bufferSemID != NULL) { + while (1) { + OMX_S32 cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt); + if (cnt == 0) + break; + else if (cnt > 0) + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + else if (cnt < 0) + Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + Exynos_OSAL_SleepMillisec(0); + } } Exynos_OSAL_ResetQueue(&pExynosPort->bufferQ); @@ -633,7 +641,18 @@ OMX_ERRORTYPE Exynos_OMX_BufferFlush( if (pExynosPort->bufferProcessType & BUFFER_COPY) Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID); - Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + + if (pExynosPort->bufferSemID != NULL) { + while (1) { + OMX_S32 cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt); + if (cnt > 0) + break; + else + Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + Exynos_OSAL_SleepMillisec(0); + } + } pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, nPortIndex); @@ -1190,12 +1209,12 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetParameter( break; case supportFormat_2: pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - pPortFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + pPortFormat->eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; pPortFormat->xFramerate = pPortDef->format.video.xFramerate; break; case supportFormat_3: pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - pPortFormat->eColorFormat = OMX_SEC_COLOR_FormatNV21Linear; + pPortFormat->eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear; pPortFormat->xFramerate = pPortDef->format.video.xFramerate; break; case supportFormat_4: @@ -1203,6 +1222,23 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetParameter( pPortFormat->eColorFormat = OMX_COLOR_FormatAndroidOpaque; pPortFormat->xFramerate = pPortDef->format.video.xFramerate; break; +#ifdef USE_ENCODER_RGBINPUT_SUPPORT + case supportFormat_5: + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + break; + case supportFormat_6: + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = OMX_COLOR_Format32bitARGB8888; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + break; + case supportFormat_7: + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = OMX_COLOR_Format32bitBGRA8888; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + break; +#endif default: if (nIndex > supportFormat_0) { ret = OMX_ErrorNoMore; @@ -1778,6 +1814,29 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetConfig( } } break; +#ifdef USE_QOS_CTRL + case OMX_IndexVendorSetQosRatio: + { + EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *pQosInfo = (EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *)pComponentConfigStructure; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + + if (pExynosComponent->hComponentHandle == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + ret = Exynos_OMX_Check_SizeVersion(pQosInfo, sizeof(EXYNOS_OMX_VIDEO_CONFIG_QOSINFO)); + if (ret != OMX_ErrorNone) + goto EXIT; + + pVideoEnc->nQosRatio = pQosInfo->nQosRatio; + pVideoEnc->bQosChanged = OMX_TRUE; + + ret = OMX_ErrorNone; + } + break; +#endif default: { ret = Exynos_OMX_SetConfig(hComponent, nParamIndex, pComponentConfigStructure); @@ -1837,6 +1896,13 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetExtensionIndex( ret = OMX_ErrorNone; goto EXIT; } +#ifdef USE_QOS_CTRL + else if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_CONFIG_SET_QOS_RATIO) == 0) { + *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorSetQosRatio; + ret = OMX_ErrorNone; + goto EXIT; + } +#endif #ifdef USE_STOREMETADATA if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) { @@ -1868,8 +1934,9 @@ OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATA if ((bNeedUnlock == OMX_TRUE) && (pUseBuffer->bufferHeader != NULL)) { OMX_PTR ppBuf[MAX_BUFFER_PLANE]; - Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pUseBuffer->bufferHeader->pBuffer, ppBuf); - Exynos_OSAL_UnlockANBHandle(ppBuf[0]); + if (OMX_ErrorNone == + Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pUseBuffer->bufferHeader->pBuffer, ppBuf)) + Exynos_OSAL_UnlockANBHandle(ppBuf[0]); } return ret; diff --git a/component/video/enc/Exynos_OMX_VencControl.h b/component/video/enc/Exynos_OMX_VencControl.h index fa618eb..c500704 100644 --- a/component/video/enc/Exynos_OMX_VencControl.h +++ b/component/video/enc/Exynos_OMX_VencControl.h @@ -91,6 +91,7 @@ OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *pDataBuffer); OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent); OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer, OMX_BOOL bNeedUnlock); +OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(EXYNOS_OMX_BASECOMPONENT *pExynosComponent); #ifdef __cplusplus } diff --git a/component/video/enc/h264/Android.mk b/component/video/enc/h264/Android.mk index 8932ac4..441a7ca 100644 --- a/component/video/enc/h264/Android.mk +++ b/component/video/enc/h264/Android.mk @@ -31,6 +31,14 @@ ifeq ($(BOARD_USE_H264_PREPEND_SPS_PPS), true) LOCAL_CFLAGS += -DUSE_H264_PREPEND_SPS_PPS endif +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_ENCODER_RGBINPUT_SUPPORT), true) +LOCAL_CFLAGS += -DUSE_ENCODER_RGBINPUT_SUPPORT +endif + LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \ diff --git a/component/video/enc/h264/Exynos_OMX_H264enc.c b/component/video/enc/h264/Exynos_OMX_H264enc.c index d3f323d..c8622ac 100644 --- a/component/video/enc/h264/Exynos_OMX_H264enc.c +++ b/component/video/enc/h264/Exynos_OMX_H264enc.c @@ -32,6 +32,7 @@ #include "Exynos_OMX_Basecomponent.h" #include "Exynos_OMX_Baseport.h" #include "Exynos_OMX_Venc.h" +#include "Exynos_OMX_VencControl.h" #include "Exynos_OSAL_ETC.h" #include "Exynos_OSAL_Semaphore.h" #include "Exynos_OSAL_Thread.h" @@ -218,20 +219,23 @@ static void Set_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = NULL; ExynosVideoEncParam *pEncParam = NULL; ExynosVideoEncCommonParam *pCommonParam = NULL; ExynosVideoEncH264Param *pH264Param = NULL; - pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - pMFCH264Handle = &pH264Enc->hMFCH264Handle; - pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle; + pMFCH264Handle = &pH264Enc->hMFCH264Handle; + pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExtBufferInfo = (ENCODE_CODEC_EXTRA_BUFFERINFO *)pExynosInputPort->processData.extInfo; + + pEncParam = &pMFCH264Handle->encParam; + pCommonParam = &pEncParam->commonParam; + pH264Param = &pEncParam->codecParam.h264; - pEncParam = &pMFCH264Handle->encParam; - pCommonParam = &pEncParam->commonParam; - pH264Param = &pEncParam->codecParam.h264; pEncParam->eCompressionFormat = VIDEO_CODING_AVC; Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat); @@ -239,7 +243,7 @@ static void Set_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameWidth; pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameHeight; pCommonParam->IDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; - pCommonParam->SliceMode = 0; + pCommonParam->SliceMode = pH264Enc->AVCSliceFmo.eSliceMode; pCommonParam->Bitrate = pExynosOutputPort->portDefinition.format.video.nBitrate; pCommonParam->FrameQp = pVideoEnc->quantization.nQpI; pCommonParam->FrameQp_P = pVideoEnc->quantization.nQpP; @@ -259,34 +263,25 @@ static void Set_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) pCommonParam->RandomIntraMBRefresh = 0; } - switch ((EXYNOS_OMX_COLOR_FORMATTYPE)pExynosInputPort->portDefinition.format.video.eColorFormat) { + switch (pExtBufferInfo->eColorFormat) { case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_COLOR_FormatYUV420Planar: /* Converted to NV12 in Exynos_CSC_InputData */ pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; break; -#ifdef USE_METADATABUFFERTYPE - case OMX_COLOR_FormatAndroidOpaque: - if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { - switch (pVideoEnc->ANBColorFormat) { - case OMX_COLOR_FormatYUV420SemiPlanar: - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; - break; - case OMX_SEC_COLOR_FormatNV12Tiled: - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; - break; - default: - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; - break; - } - } else { - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; - } - break; -#endif - case OMX_SEC_COLOR_FormatNV21Linear: + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear: pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV21; break; - case OMX_SEC_COLOR_FormatNV12Tiled: +#ifdef USE_ENCODER_RGBINPUT_SUPPORT + case OMX_COLOR_FormatYUV420Planar: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_I420; + break; + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_YV12; + break; + case OMX_COLOR_Format32bitBGRA8888: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_ARGB8888; + break; +#endif + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled: default: pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; break; @@ -297,7 +292,10 @@ static void Set_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) pH264Param->LevelIDC = OMXAVCLevelToLevelIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eLevel); /*40: OMX_VIDEO_AVCLevel4 */ pH264Param->FrameQp_B = pVideoEnc->quantization.nQpB; pH264Param->FrameRate = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16; - pH264Param->SliceArgument = 0; /* Slice mb/byte size number */ + if (pH264Enc->AVCSliceFmo.eSliceMode == OMX_VIDEO_SLICEMODE_AVCDefault) + pH264Param->SliceArgument = 0; /* Slice mb/byte size number */ + else + pH264Param->SliceArgument = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nSliceHeaderSpacing; pH264Param->NumberBFrames = 0; /* 0 ~ 2 */ pH264Param->NumberReferenceFrames = 1; pH264Param->NumberRefForPframes = 1; @@ -724,13 +722,12 @@ OMX_ERRORTYPE H264CodecRegistCodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]); - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; pBufOps = pH264Enc->hMFCH264Handle.pInbufOps; } else { ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]); - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; pBufOps = pH264Enc->hMFCH264Handle.pOutbufOps; } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt); if (pPlanes == NULL) { @@ -843,16 +840,16 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT FunctionIn(); if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; - OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); - if (OMXBuffer == NULL) { - ret = OMX_ErrorUndefined; + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO)); + if (pBufferInfo == NULL) { + ret = OMX_ErrorInsufficientResources; goto EXIT; } - OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; - OMXBuffer->nFlags = pSrcInputData->nFlags; - Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + pBufferInfo->nFlags = pSrcInputData->nFlags; + pBufferInfo->timeStamp = pSrcInputData->timeStamp; + ret = Exynos_OSAL_Queue(&pH264Enc->bypassBufferInfoQ, (void *)pBufferInfo); + Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent); ret = OMX_ErrorNone; goto EXIT; @@ -880,12 +877,9 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT bufferConf.eColorFormat = pEncParam->commonParam.FrameMap; bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth; bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight; + bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt; pInbufOps->Set_Shareable(hMFCHandle); - if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { - inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC; - } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; - } + inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC; if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { /* should be done before prepare input buffer */ @@ -911,23 +905,10 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT goto EXIT; } - ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE]; - int plane; - - if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - ret = H264CodecRegistCodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX); - if (ret != OMX_ErrorNone) - goto EXIT; - } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { - if (pExynosInputPort->bStoreMetaData == OMX_TRUE) { - /*************/ - /* TBD */ - /*************/ - /* Does not require any actions. */ - } else { - ret = OMX_ErrorNotImplemented; - goto EXIT; - } + if ((pExynosInputPort->bufferProcessType & BUFFER_SHARE) && + (pExynosInputPort->bStoreMetaData != OMX_TRUE)) { + ret = OMX_ErrorNotImplemented; + goto EXIT; } pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE; @@ -958,12 +939,14 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) FunctionIn(); - int OutBufferSize = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + int OutBufferSize = pExynosOutputPort->portDefinition.nBufferSize; + /* set geometry for output (dst) */ if (pOutbufOps->Set_Geometry) { /* output buffer info: only 2 config values needed */ bufferConf.eCompressionFormat = VIDEO_CODING_AVC; bufferConf.nSizeImage = OutBufferSize; + bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt; if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); @@ -992,43 +975,33 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0}; + OMX_U32 dataLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0 ,0}; if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_OUTPUT_BUFFER_PLANE] = {0}; + OMX_U32 nPlaneSize[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; nPlaneSize[0] = OutBufferSize; ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nPlaneSize); if (ret != OMX_ErrorNone) goto EXIT; - ret = H264CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX); - if (ret != OMX_ErrorNone) - goto EXIT; - /* Enqueue output buffer */ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr, + (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->fd, + (unsigned int *)pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize, + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); + } + + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; } } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { /* Register output buffer */ /*************/ /* TBD */ /*************/ - for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) { - ExynosVideoPlane plane; - if (pVideoEnc->bDRMPlayerMode == OMX_TRUE) { - plane.addr = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer); - } else { - plane.addr = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; - } - plane.fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[0]; - plane.allocSize = OutBufferSize; - if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } } pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE; @@ -1094,6 +1067,23 @@ OMX_ERRORTYPE Exynos_H264Enc_GetParameter( Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); } break; + case OMX_IndexParamVideoSliceFMO: + { + OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pDstSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcSliceFmo = &pH264Enc->AVCSliceFmo; + + Exynos_OSAL_Memcpy(pDstSliceFmo, pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO)); + } + break; case OMX_IndexParamStandardComponentRole: { OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; @@ -1247,6 +1237,23 @@ OMX_ERRORTYPE Exynos_H264Enc_SetParameter( Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); } break; + case OMX_IndexParamVideoSliceFMO: + { + OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstSliceFmo = &pH264Enc->AVCSliceFmo; + + Exynos_OSAL_Memcpy(pDstSliceFmo, pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO)); + } + break; case OMX_IndexParamStandardComponentRole: { OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; @@ -1551,15 +1558,16 @@ EXIT: /* MFC Init */ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; - EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;; - EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle; - OMX_PTR hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; - OMX_COLOR_FORMATTYPE eColorFormat; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;; + EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = pExynosInputPort->processData.extInfo; + OMX_PTR hMFCHandle = NULL; + OMX_COLOR_FORMATTYPE eColorFormat; ExynosVideoEncOps *pEncOps = NULL; ExynosVideoEncBufferOps *pInbufOps = NULL; @@ -1597,13 +1605,34 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pEncOps = pH264Enc->hMFCH264Handle.pEncOps; pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + +#ifdef USE_ENCODER_RGBINPUT_SUPPORT + if (pEncOps->Check_RGBSupport(hMFCHandle) != VIDEO_ERROR_NOSUPPORT) + pVideoEnc->bRGBSupport = OMX_TRUE; +#endif + pVideoEnc->nInbufSpareSize = pInbufOps->Get_SpareSize(hMFCHandle); + + pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE; if ((pExynosInputPort->bStoreMetaData != OMX_TRUE) && (eColorFormat != OMX_COLOR_FormatAndroidOpaque)) { if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {0, }; - nPlaneSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE; - nPlaneSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE; + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {0, 0, 0}; + + if (pVideoEnc->bRGBSupport == OMX_TRUE) { + pExynosInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(eColorFormat); + Exynos_OSAL_GetPlaneSize(eColorFormat, ALIGN_TO_16B(1920), ALIGN_TO_16B(1080), nPlaneSize); + } else { + pExtBufferInfo->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + pExynosInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420SemiPlanar); + Exynos_OSAL_GetPlaneSize(OMX_COLOR_FormatYUV420SemiPlanar, ALIGN_TO_16B(1920), ALIGN_TO_16B(1080), nPlaneSize); + } + + if (pVideoEnc->nInbufSpareSize > 0) { + for (i = 0; i < pExynosInputPort->nPlaneCnt; i++) + nPlaneSize[i] += pVideoEnc->nInbufSpareSize; + } Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1622,6 +1651,7 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) } } + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1644,6 +1674,8 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pExynosComponent->getAllDelayBuffer = OMX_FALSE; + Exynos_OSAL_QueueCreate(&pH264Enc->bypassBufferInfoQ, QUEUE_ELEMENTS); + #ifdef USE_CSC_HW csc_method = CSC_METHOD_HW; #endif @@ -1690,6 +1722,8 @@ OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) pVideoEnc->csc_handle = NULL; } + Exynos_OSAL_QueueTerminate(&pH264Enc->bypassBufferInfoQ); + Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationStartEvent); pH264Enc->hDestinationStartEvent = NULL; pH264Enc->bDestinationStart = OMX_FALSE; @@ -1728,18 +1762,24 @@ EXIT: OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; - OMX_U32 oneFrameSize = pSrcInputData->dataLen; - ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; - ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; - ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle; + void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = pSrcInputData->extInfo; + + OMX_BUFFERHEADERTYPE tempBufferHeader; + void *pPrivate = NULL; + + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; FunctionIn(); @@ -1760,10 +1800,8 @@ OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ if ((pSrcInputData->dataLen > 0) || ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { - OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0}; - OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL}; - ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE]; - int plane; + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + OMX_U32 nMFCYUVDataSize[MAX_BUFFER_PLANE] = {0, 0, 0}; pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp; pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags; @@ -1771,32 +1809,39 @@ OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ pEncOps->Set_FrameTag(hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp); pH264Enc->hMFCH264Handle.indexTimestamp++; pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; - +#ifdef USE_QOS_CTRL + if ((pVideoEnc->bQosChanged == OMX_TRUE) && + (pEncOps->Set_QosRatio != NULL)) { + pEncOps->Set_QosRatio(hMFCHandle, pVideoEnc->nQosRatio); + pVideoEnc->bQosChanged = OMX_FALSE; + } +#endif /* queue work for input buffer */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_H264Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader); - pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; - pMFCYUVDataSize[1] = pMFCYUVDataSize[0] / 2; - -#ifdef USE_METADATABUFFERTYPE - nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) * - ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight); - nAllocLen[1] = ALIGN(nAllocLen[0] / 2,256); - - if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) && - (pExynosInputPort->bufferProcessType & BUFFER_SHARE)) { - codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, - (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.fd, - (unsigned int *)nAllocLen, (unsigned int *)pMFCYUVDataSize, - MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + + if (pExynosInputPort->bufferProcessType == BUFFER_COPY) { + Exynos_OSAL_GetPlaneSize(pExtBufferInfo->eColorFormat, ALIGN_TO_16B(1920), ALIGN_TO_16B(1080), nMFCYUVDataSize); + tempBufferHeader.nFlags = pSrcInputData->nFlags; + tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp; + pPrivate = (void *)&tempBufferHeader; } else { - codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + Exynos_OSAL_GetPlaneSize(pExtBufferInfo->eColorFormat, + pExynosInputPort->portDefinition.format.video.nFrameWidth, + pExynosInputPort->portDefinition.format.video.nFrameHeight, + nMFCYUVDataSize); + pPrivate = (void *)pSrcInputData->bufferHeader; } -#else - codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); -#endif + + if (pVideoEnc->nInbufSpareSize> 0) { + for (i = 0; i < pExynosInputPort->nPlaneCnt; i++) + nAllocLen[i] = nMFCYUVDataSize[i] + pVideoEnc->nInbufSpareSize; + } + + codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)nMFCYUVDataSize, + pExynosInputPort->nPlaneCnt, pPrivate); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__); ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; @@ -1825,49 +1870,44 @@ EXIT: OMX_ERRORTYPE Exynos_H264Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; - ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; - ExynosVideoBuffer *pVideoBuffer; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle; + void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + ExynosVideoBuffer *pVideoBuffer = NULL; ExynosVideoBuffer videoBuffer; FunctionIn(); - if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) && - (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) { - if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) - pVideoBuffer = &videoBuffer; - else - pVideoBuffer = NULL; - } else { - pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); - } + if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) + pVideoBuffer = &videoBuffer; + else + pVideoBuffer = NULL; pSrcOutputData->dataLen = 0; pSrcOutputData->usedDataLen = 0; pSrcOutputData->remainDataLen = 0; - pSrcOutputData->nFlags = 0; - pSrcOutputData->timeStamp = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + pSrcOutputData->allocSize = 0; + pSrcOutputData->bufferHeader = NULL; if (pVideoBuffer == NULL) { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; - pSrcOutputData->allocSize = 0; pSrcOutputData->pPrivate = NULL; - pSrcOutputData->bufferHeader = NULL; } else { int plane = 0; - for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosInputPort->nPlaneCnt; plane++) { pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pSrcOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + + pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; } - pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize + - pVideoBuffer->planes[1].allocSize + - pVideoBuffer->planes[2].allocSize; if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { int i; @@ -1888,7 +1928,8 @@ OMX_ERRORTYPE Exynos_H264Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX } /* For Share Buffer */ - pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; } ret = OMX_ErrorNone; @@ -1906,6 +1947,7 @@ OMX_ERRORTYPE Exynos_H264Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; OMX_U32 dataLen = 0; @@ -1919,9 +1961,14 @@ OMX_ERRORTYPE Exynos_H264Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ goto EXIT; } - codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + OMX_U32 nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; + nAllocLen[0] = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&dataLen, + pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__); ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; @@ -1948,6 +1995,7 @@ OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; ExynosVideoGeometry bufferGeometry; OMX_S32 indexTimestamp = 0; @@ -1959,7 +2007,10 @@ OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX goto EXIT; } - if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { + if (pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) { + pVideoBuffer = &videoBuffer; + } else { + pVideoBuffer = NULL; ret = OMX_ErrorNone; goto EXIT; } @@ -1980,7 +2031,7 @@ OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { if (pDstOutputData->buffer.singlePlaneBuffer.dataBuffer == pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) { - pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]; + pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i]; break; } } @@ -2150,6 +2201,22 @@ OMX_ERRORTYPE Exynos_H264Enc_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXCompon Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent); } + + if (Exynos_OSAL_GetElemNum(&pH264Enc->bypassBufferInfoQ) > 0) { + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pH264Enc->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags; + pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader); + Exynos_OSAL_Free(pBufferInfo); + + ret = OMX_ErrorNone; + goto EXIT; + } } if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) { ret = Exynos_H264Enc_DstIn(pOMXComponent, pDstInputData); @@ -2191,6 +2258,38 @@ OMX_ERRORTYPE Exynos_H264Enc_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXCompo Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent); } + + if (Exynos_OSAL_GetElemNum(&pH264Enc->bypassBufferInfoQ) > 0) { + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL; + BYPASS_BUFFER_INFO *pBufferInfo = NULL; + + if (dstOutputUseBuffer->dataValid == OMX_FALSE) { + pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (pOMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else { + pOMXBuffer = dstOutputUseBuffer->bufferHeader; + } + + pBufferInfo = Exynos_OSAL_Dequeue(&pH264Enc->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOMXBuffer->nFlags = pBufferInfo->nFlags; + pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer); + Exynos_OSAL_Free(pBufferInfo); + + dstOutputUseBuffer->dataValid = OMX_FALSE; + + ret = OMX_ErrorNone; + goto EXIT; + } } ret = Exynos_H264Enc_DstOut(pOMXComponent, pDstOutputData); if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) { diff --git a/component/video/enc/h264/Exynos_OMX_H264enc.h b/component/video/enc/h264/Exynos_OMX_H264enc.h index 9c49934..934506b 100644 --- a/component/video/enc/h264/Exynos_OMX_H264enc.h +++ b/component/video/enc/h264/Exynos_OMX_H264enc.h @@ -61,8 +61,9 @@ typedef struct _EXYNOS_MFC_H264ENC_HANDLE typedef struct _EXYNOS_H264ENC_HANDLE { /* OMX Codec specific */ - OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_AVCSLICEFMO AVCSliceFmo; /* SEC MFC Codec specific */ EXYNOS_MFC_H264ENC_HANDLE hMFCH264Handle; @@ -71,6 +72,8 @@ typedef struct _EXYNOS_H264ENC_HANDLE OMX_BOOL bDestinationStart; OMX_HANDLETYPE hSourceStartEvent; OMX_HANDLETYPE hDestinationStartEvent; + + EXYNOS_QUEUE bypassBufferInfoQ; } EXYNOS_H264ENC_HANDLE; #ifdef __cplusplus diff --git a/component/video/enc/mpeg4/Android.mk b/component/video/enc/mpeg4/Android.mk index 5eef044..be3b06d 100644 --- a/component/video/enc/mpeg4/Android.mk +++ b/component/video/enc/mpeg4/Android.mk @@ -27,6 +27,14 @@ ifeq ($(BOARD_USE_CSC_HW), true) LOCAL_CFLAGS += -DUSE_CSC_HW endif +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_ENCODER_RGBINPUT_SUPPORT), true) +LOCAL_CFLAGS += -DUSE_ENCODER_RGBINPUT_SUPPORT +endif + LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \ diff --git a/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c b/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c index 801f720..c282f24 100644 --- a/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c +++ b/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c @@ -32,6 +32,7 @@ #include "Exynos_OMX_Basecomponent.h" #include "Exynos_OMX_Baseport.h" #include "Exynos_OMX_Venc.h" +#include "Exynos_OMX_VencControl.h" #include "Exynos_OSAL_ETC.h" #include "Exynos_OSAL_Semaphore.h" #include "Exynos_OSAL_Thread.h" @@ -208,17 +209,19 @@ static void Set_Mpeg4Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = NULL; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = NULL; ExynosVideoEncParam *pEncParam = NULL; ExynosVideoEncCommonParam *pCommonParam = NULL; ExynosVideoEncMpeg4Param *pMpeg4Param = NULL; - pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - pMpeg4Enc = pVideoEnc->hCodecHandle; - pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; - pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle; + pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExtBufferInfo = (ENCODE_CODEC_EXTRA_BUFFERINFO *)pExynosInputPort->processData.extInfo; pEncParam = &pMFCMpeg4Handle->encParam; pCommonParam = &pEncParam->commonParam; @@ -250,34 +253,27 @@ static void Set_Mpeg4Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) pCommonParam->RandomIntraMBRefresh = 0; } - switch ((EXYNOS_OMX_COLOR_FORMATTYPE)pExynosInputPort->portDefinition.format.video.eColorFormat) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "extInfo color = %x", pExtBufferInfo->eColorFormat); + + switch (pExtBufferInfo->eColorFormat) { case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_COLOR_FormatYUV420Planar: /* Converted to NV12 in Exynos_CSC_InputData */ pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; break; -#ifdef USE_METADATABUFFERTYPE - case OMX_COLOR_FormatAndroidOpaque: - if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { - switch (pVideoEnc->ANBColorFormat) { - case OMX_COLOR_FormatYUV420SemiPlanar: - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; - break; - case OMX_SEC_COLOR_FormatNV12Tiled: - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; - break; - default: - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; - break; - } - } else { - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; - } - break; -#endif - case OMX_SEC_COLOR_FormatNV21Linear: + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear: pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV21; break; - case OMX_SEC_COLOR_FormatNV12Tiled: +#ifdef USE_ENCODER_RGBINPUT_SUPPORT + case OMX_COLOR_FormatYUV420Planar: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_I420; + break; + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_YV12; + break; + case OMX_COLOR_Format32bitBGRA8888: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_ARGB8888; + break; +#endif + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled: default: pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; break; @@ -326,17 +322,19 @@ static void Set_H263Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = NULL; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = NULL; ExynosVideoEncParam *pEncParam = NULL; ExynosVideoEncCommonParam *pCommonParam = NULL; ExynosVideoEncH263Param *pH263Param = NULL; - pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - pMpeg4Enc = pVideoEnc->hCodecHandle; + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pMpeg4Enc = pVideoEnc->hCodecHandle; pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; - pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExtBufferInfo = (ENCODE_CODEC_EXTRA_BUFFERINFO *)pExynosInputPort->processData.extInfo; pEncParam = &pMFCMpeg4Handle->encParam; pCommonParam = &pEncParam->commonParam; @@ -368,34 +366,25 @@ static void Set_H263Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) pCommonParam->RandomIntraMBRefresh = 0; } - switch ((EXYNOS_OMX_COLOR_FORMATTYPE)pExynosInputPort->portDefinition.format.video.eColorFormat) { + switch (pExtBufferInfo->eColorFormat) { case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_COLOR_FormatYUV420Planar: /* Converted to NV12 in Exynos_CSC_InputData */ pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; break; -#ifdef USE_METADATABUFFERTYPE - case OMX_COLOR_FormatAndroidOpaque: - if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { - switch (pVideoEnc->ANBColorFormat) { - case OMX_COLOR_FormatYUV420SemiPlanar: - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; - break; - case OMX_SEC_COLOR_FormatNV12Tiled: - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; - break; - default: - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; - break; - } - } else { - pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; - } - break; -#endif - case OMX_SEC_COLOR_FormatNV21Linear: + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear: pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV21; break; - case OMX_SEC_COLOR_FormatNV12Tiled: +#ifdef USE_ENCODER_RGBINPUT_SUPPORT + case OMX_COLOR_FormatYUV420Planar: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_I420; + break; + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_YV12; + break; + case OMX_COLOR_Format32bitBGRA8888: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_ARGB8888; + break; +#endif + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled: default: pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; break; @@ -863,13 +852,12 @@ OMX_ERRORTYPE Mpeg4CodecRegistCodecBuffers( if (nPortIndex == INPUT_PORT_INDEX) { ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]); - nPlaneCnt = MFC_INPUT_BUFFER_PLANE; pBufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; } else { ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]); - nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE; pBufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt); if (pPlanes == NULL) { @@ -982,16 +970,16 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA FunctionIn(); if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; - OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); - if (OMXBuffer == NULL) { - ret = OMX_ErrorUndefined; + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO)); + if (pBufferInfo == NULL) { + ret = OMX_ErrorInsufficientResources; goto EXIT; } - OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; - OMXBuffer->nFlags = pSrcInputData->nFlags; - Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + pBufferInfo->nFlags = pSrcInputData->nFlags; + pBufferInfo->timeStamp = pSrcInputData->timeStamp; + ret = Exynos_OSAL_Queue(&pMpeg4Enc->bypassBufferInfoQ, (void *)pBufferInfo); + Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationStartEvent); ret = OMX_ErrorNone; goto EXIT; @@ -1016,12 +1004,9 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA bufferConf.eColorFormat = pEncParam->commonParam.FrameMap; bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth; bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight; + bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt; pInbufOps->Set_Shareable(hMFCHandle); - if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { - inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC; - } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; - } + inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC; if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { /* should be done before prepare input buffer */ @@ -1047,23 +1032,10 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA goto EXIT; } - ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE]; - int plane; - - if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - ret = Mpeg4CodecRegistCodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX); - if (ret != OMX_ErrorNone) - goto EXIT; - } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { - if (pExynosInputPort->bStoreMetaData == OMX_TRUE) { - /*************/ - /* TBD */ - /*************/ - /* Does not require any actions. */ - } else { - ret = OMX_ErrorNotImplemented; - goto EXIT; - } + if ((pExynosInputPort->bufferProcessType & BUFFER_SHARE) && + (pExynosInputPort->bStoreMetaData != OMX_TRUE)) { + ret = OMX_ErrorNotImplemented; + goto EXIT; } pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE; @@ -1094,7 +1066,8 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) FunctionIn(); - int OutBufferSize = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + int OutBufferSize = pExynosOutputPort->portDefinition.nBufferSize; + /* set geometry for output (dst) */ if (pOutbufOps->Set_Geometry) { /* only 2 config values needed */ @@ -1103,6 +1076,7 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) else bufferConf.eCompressionFormat = VIDEO_CODING_H263; bufferConf.nSizeImage = OutBufferSize; + bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt; if (pOutbufOps->Set_Geometry(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); @@ -1135,39 +1109,33 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } - OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0}; + OMX_U32 dataLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_OUTPUT_BUFFER_PLANE] = {0}; + OMX_U32 nPlaneSize[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; nPlaneSize[0] = OutBufferSize; ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nPlaneSize); if (ret != OMX_ErrorNone) goto EXIT; - ret = Mpeg4CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX); - if (ret != OMX_ErrorNone) - goto EXIT; - /* Enqueue output buffer */ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr, + (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->fd, + (unsigned int *)pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize, + (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL); + } + + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; } } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { /* Register output buffer */ /*************/ /* TBD */ /*************/ - ExynosVideoPlane plane; - for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) { - plane.addr = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; - plane.fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[0]; - plane.allocSize = OutBufferSize; - if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } } pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE; @@ -1751,15 +1719,16 @@ EXIT: /* MFC Init */ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; - EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;; - EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; - OMX_PTR hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; - OMX_COLOR_FORMATTYPE eColorFormat; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = pExynosInputPort->processData.extInfo; + OMX_PTR hMFCHandle = NULL; + OMX_COLOR_FORMATTYPE eColorFormat; ExynosVideoEncOps *pEncOps = NULL; ExynosVideoEncBufferOps *pInbufOps = NULL; @@ -1797,13 +1766,34 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + +#ifdef USE_ENCODER_RGBINPUT_SUPPORT + if (pEncOps->Check_RGBSupport(hMFCHandle) != VIDEO_ERROR_NOSUPPORT) + pVideoEnc->bRGBSupport = OMX_TRUE; +#endif + pVideoEnc->nInbufSpareSize = pInbufOps->Get_SpareSize(hMFCHandle); + + pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE; if ((pExynosInputPort->bStoreMetaData != OMX_TRUE) && (eColorFormat != OMX_COLOR_FormatAndroidOpaque)) { if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { - OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {0, }; - nPlaneSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE; - nPlaneSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE; + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {0, 0, 0}; + + if (pVideoEnc->bRGBSupport == OMX_TRUE) { + pExynosInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(eColorFormat); + Exynos_OSAL_GetPlaneSize(eColorFormat, ALIGN_TO_16B(1920), ALIGN_TO_16B(1080), nPlaneSize); + } else { + pExtBufferInfo->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + pExynosInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420SemiPlanar); + Exynos_OSAL_GetPlaneSize(OMX_COLOR_FormatYUV420SemiPlanar, ALIGN_TO_16B(1920), ALIGN_TO_16B(1080), nPlaneSize); + } + + if (pVideoEnc->nInbufSpareSize > 0) { + for (i = 0; i < pExynosInputPort->nPlaneCnt; i++) + nPlaneSize[i] += pVideoEnc->nInbufSpareSize; + } Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1822,6 +1812,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) } } + pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); @@ -1844,6 +1835,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pExynosComponent->getAllDelayBuffer = OMX_FALSE; + Exynos_OSAL_QueueCreate(&pMpeg4Enc->bypassBufferInfoQ, QUEUE_ELEMENTS); + #ifdef USE_CSC_HW csc_method = CSC_METHOD_HW; #endif @@ -1884,6 +1877,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) pVideoEnc->csc_handle = NULL; } + Exynos_OSAL_QueueTerminate(&pMpeg4Enc->bypassBufferInfoQ); + Exynos_OSAL_SignalTerminate(pMpeg4Enc->hDestinationStartEvent); pMpeg4Enc->hDestinationStartEvent = NULL; pMpeg4Enc->bDestinationStart = OMX_FALSE; @@ -1922,18 +1917,24 @@ EXIT: OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; - OMX_U32 oneFrameSize = pSrcInputData->dataLen; - ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; - ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; - ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; - ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle; + void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = pSrcInputData->extInfo; + + OMX_BUFFERHEADERTYPE tempBufferHeader; + void *pPrivate = NULL; + + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; FunctionIn(); @@ -1958,10 +1959,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX if ((pSrcInputData->dataLen > 0) || ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { - OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0}; - OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL}; - ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE]; - int plane; + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + OMX_U32 nMFCYUVDataSize[MAX_BUFFER_PLANE] = {0, 0, 0}; pExynosComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->timeStamp; pExynosComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->nFlags; @@ -1969,32 +1968,39 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX pEncOps->Set_FrameTag(hMFCHandle, pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp); pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++; pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; - +#ifdef USE_QOS_CTRL + if ((pVideoEnc->bQosChanged == OMX_TRUE) && + (pEncOps->Set_QosRatio != NULL)) { + pEncOps->Set_QosRatio(hMFCHandle, pVideoEnc->nQosRatio); + pVideoEnc->bQosChanged = OMX_FALSE; + } +#endif /* queue work for input buffer */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_Mpeg4Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader); - pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; - pMFCYUVDataSize[1] = pMFCYUVDataSize[0] / 2; - -#ifdef USE_METADATABUFFERTYPE - nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) * - ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight); - nAllocLen[1] = ALIGN(nAllocLen[0] / 2,256); - - if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) && - (pExynosInputPort->bufferProcessType & BUFFER_SHARE)) { - codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, - (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.fd, - (unsigned int *)nAllocLen, (unsigned int *)pMFCYUVDataSize, - MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + + if (pExynosInputPort->bufferProcessType == BUFFER_COPY) { + Exynos_OSAL_GetPlaneSize(pExtBufferInfo->eColorFormat, ALIGN_TO_16B(1920), ALIGN_TO_16B(1080), nMFCYUVDataSize); + tempBufferHeader.nFlags = pSrcInputData->nFlags; + tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp; + pPrivate = (void *)&tempBufferHeader; } else { - codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + Exynos_OSAL_GetPlaneSize(pExtBufferInfo->eColorFormat, + pExynosInputPort->portDefinition.format.video.nFrameWidth, + pExynosInputPort->portDefinition.format.video.nFrameHeight, + nMFCYUVDataSize); + pPrivate = (void *)pSrcInputData->bufferHeader; } -#else - codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); -#endif + + if (pVideoEnc->nInbufSpareSize> 0) { + for (i = 0; i < pExynosInputPort->nPlaneCnt; i++) + nAllocLen[i] = nMFCYUVDataSize[i] + pVideoEnc->nInbufSpareSize; + } + + codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)nMFCYUVDataSize, + pExynosInputPort->nPlaneCnt, pPrivate); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__); ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; @@ -2023,49 +2029,44 @@ EXIT: OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) { - OMX_ERRORTYPE ret = OMX_ErrorNone; - EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; - EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; - void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; - EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; - ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; - ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; - ExynosVideoBuffer *pVideoBuffer; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle; + void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + ExynosVideoBuffer *pVideoBuffer = NULL; ExynosVideoBuffer videoBuffer; FunctionIn(); - if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) && - (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) { - if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) - pVideoBuffer = &videoBuffer; - else - pVideoBuffer = NULL; - } else { - pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); - } + if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) + pVideoBuffer = &videoBuffer; + else + pVideoBuffer = NULL; pSrcOutputData->dataLen = 0; pSrcOutputData->usedDataLen = 0; pSrcOutputData->remainDataLen = 0; - pSrcOutputData->nFlags = 0; - pSrcOutputData->timeStamp = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + pSrcOutputData->allocSize = 0; + pSrcOutputData->bufferHeader = NULL; if (pVideoBuffer == NULL) { pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; - pSrcOutputData->allocSize = 0; pSrcOutputData->pPrivate = NULL; - pSrcOutputData->bufferHeader = NULL; } else { int plane = 0; - for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + for (plane = 0; plane < pExynosInputPort->nPlaneCnt; plane++) { pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pSrcOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + + pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; } - pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize + - pVideoBuffer->planes[1].allocSize + - pVideoBuffer->planes[2].allocSize; if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { int i; @@ -2086,7 +2087,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM } /* For Share Buffer */ - pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; } ret = OMX_ErrorNone; @@ -2104,6 +2106,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; OMX_U32 dataLen = 0; @@ -2117,9 +2120,14 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX goto EXIT; } - codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer, - (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + OMX_U32 nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; + nAllocLen[0] = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&dataLen, + pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__); ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; @@ -2146,6 +2154,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; ExynosVideoGeometry bufferGeometry; OMX_S32 indexTimestamp = 0; @@ -2157,7 +2166,10 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM goto EXIT; } - if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { + if (pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) { + pVideoBuffer = &videoBuffer; + } else { + pVideoBuffer = NULL; ret = OMX_ErrorNone; goto EXIT; } @@ -2178,7 +2190,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { if (pDstOutputData->buffer.singlePlaneBuffer.dataBuffer == pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) { - pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]; + pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i]; break; } } @@ -2330,6 +2342,22 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXCompo Exynos_OSAL_SignalWait(pMpeg4Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pMpeg4Enc->hDestinationStartEvent); } + + if (Exynos_OSAL_GetElemNum(&pMpeg4Enc->bypassBufferInfoQ) > 0) { + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pMpeg4Enc->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags; + pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader); + Exynos_OSAL_Free(pBufferInfo); + + ret = OMX_ErrorNone; + goto EXIT; + } } if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE) { ret = Exynos_Mpeg4Enc_DstIn(pOMXComponent, pDstInputData); @@ -2371,6 +2399,38 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComp Exynos_OSAL_SignalWait(pMpeg4Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); Exynos_OSAL_SignalReset(pMpeg4Enc->hDestinationStartEvent); } + + if (Exynos_OSAL_GetElemNum(&pMpeg4Enc->bypassBufferInfoQ) > 0) { + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL; + BYPASS_BUFFER_INFO *pBufferInfo = NULL; + + if (dstOutputUseBuffer->dataValid == OMX_FALSE) { + pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (pOMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else { + pOMXBuffer = dstOutputUseBuffer->bufferHeader; + } + + pBufferInfo = Exynos_OSAL_Dequeue(&pMpeg4Enc->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOMXBuffer->nFlags = pBufferInfo->nFlags; + pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer); + Exynos_OSAL_Free(pBufferInfo); + + dstOutputUseBuffer->dataValid = OMX_FALSE; + + ret = OMX_ErrorNone; + goto EXIT; + } } ret = Exynos_Mpeg4Enc_DstOut(pOMXComponent, pDstOutputData); if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) { diff --git a/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h b/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h index aaf9477..762e043 100644 --- a/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h +++ b/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h @@ -69,6 +69,8 @@ typedef struct _EXYNOS_MPEG4ENC_HANDLE OMX_BOOL bDestinationStart; OMX_HANDLETYPE hSourceStartEvent; OMX_HANDLETYPE hDestinationStartEvent; + + EXYNOS_QUEUE bypassBufferInfoQ; } EXYNOS_MPEG4ENC_HANDLE; diff --git a/component/video/enc/vp8/Android.mk b/component/video/enc/vp8/Android.mk new file mode 100644 index 0000000..f514c09 --- /dev/null +++ b/component/video/enc/vp8/Android.mk @@ -0,0 +1,66 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)-insignal + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_Vp8enc.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.Exynos.VP8.Encoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := -DUSE_VP8ENC_SUPPORT + +ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) +LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +ifeq ($(BOARD_USE_CSC_HW), true) +LOCAL_CFLAGS += -DUSE_CSC_HW +endif + +ifeq ($(BOARD_USE_QOS_CTRL), true) +LOCAL_CFLAGS += -DUSE_QOS_CTRL +endif + +ifeq ($(BOARD_USE_ENCODER_RGBINPUT_SUPPORT), true) +LOCAL_CFLAGS += -DUSE_ENCODER_RGBINPUT_SUPPORT +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \ + libswconverter libExynosVideoApi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos + +LOCAL_C_INCLUDES := \ + $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/enc \ + $(EXYNOS_VIDEO_CODEC)/v4l2/include \ + $(TOP)/hardware/samsung_slsi/exynos/include \ + $(TOP)/hardware/samsung_slsi/$(PLATFORM_DIR)/include + +LOCAL_ADDITIONAL_DEPENDENCIES += \ + $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/component/video/enc/vp8/Exynos_OMX_Vp8enc.c b/component/video/enc/vp8/Exynos_OMX_Vp8enc.c new file mode 100644 index 0000000..b977f1c --- /dev/null +++ b/component/video/enc/vp8/Exynos_OMX_Vp8enc.c @@ -0,0 +1,2363 @@ +/* + * + * Copyright 2013 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_Vp8enc.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Taehwan Kim (t_h.kim@samsung.com) + * @version 2.0.0 + * @history + * 2013.02.14 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Macros.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Venc.h" +#include "Exynos_OMX_VencControl.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Thread.h" +#include "Exynos_OSAL_Android.h" +#include "library_register.h" +#include "Exynos_OMX_Vp8enc.h" +#include "Exynos_OSAL_SharedMemory.h" +#include "Exynos_OSAL_Event.h" + +/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */ +/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ +#include "csc.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_VP8_ENC" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + +/* VP8 Encoder Supported Levels & profiles */ +EXYNOS_OMX_VIDEO_PROFILELEVEL supportedVP8ProfileLevels[] ={ + {OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version0}, + {OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version1}, + {OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version2}, + {OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version3}}; + +static OMX_U32 OMXVP8ProfileToProfileIDC(OMX_VIDEO_VP8PROFILETYPE eProfile) +{ + OMX_U32 ret; + + switch (eProfile) { + case OMX_VIDEO_VP8ProfileMain: + ret = 0; + break; + default: + ret = 0; + break; + } + + return ret; +} + +static OMX_U32 OMXVP8LevelToMFCVersion(OMX_VIDEO_VP8LEVELTYPE eLevel) +{ + OMX_U32 ret; + + switch (eLevel) { + case OMX_VIDEO_VP8Level_Version0: + ret = 0; + break; + case OMX_VIDEO_VP8Level_Version1: + ret = 1; + break; + case OMX_VIDEO_VP8Level_Version2: + ret = 2; + break; + case OMX_VIDEO_VP8Level_Version3: + ret = 3; + break; + default: + ret = 0; + break; + } + + return ret; +} + +static void Print_VP8Enc_Param(ExynosVideoEncParam *pEncParam) +{ + ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam; + ExynosVideoEncVp8Param *pVp8Param = &pEncParam->codecParam.vp8; + + /* common parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceWidth : %d", pCommonParam->SourceWidth); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceHeight : %d", pCommonParam->SourceHeight); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "IDRPeriod : %d", pCommonParam->IDRPeriod); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceMode : %d", pCommonParam->SliceMode); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh : %d", pCommonParam->RandomIntraMBRefresh); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Bitrate : %d", pCommonParam->Bitrate); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp : %d", pCommonParam->FrameQp); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_P : %d", pCommonParam->FrameQp_P); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMax : %d", pCommonParam->QSCodeMax); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMin : %d", pCommonParam->QSCodeMin); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PadControlOn : %d", pCommonParam->PadControlOn); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LumaPadVal : %d", pCommonParam->LumaPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CbPadVal : %d", pCommonParam->CbPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CrPadVal : %d", pCommonParam->CrPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameMap : %d", pCommonParam->FrameMap); + + /* Vp8 specific parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameRate : %d", pVp8Param->FrameRate); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8Version : %d", pVp8Param->Vp8Version); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8NumberOfPartitions : %d", pVp8Param->Vp8NumberOfPartitions); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8FilterLevel : %d", pVp8Param->Vp8FilterLevel); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8FilterSharpness : %d", pVp8Param->Vp8FilterSharpness); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8GoldenFrameSel : %d", pVp8Param->Vp8GoldenFrameSel); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8GFRefreshPeriod : %d", pVp8Param->Vp8GFRefreshPeriod); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "HierarchyQpEnable : %d", pVp8Param->HierarchyQpEnable); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "HierarchyQPLayer0 : %d", pVp8Param->HierarchyQPLayer0); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "HierarchyQPLayer1 : %d", pVp8Param->HierarchyQPLayer1); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "HierarchyQPLayer2 : %d", pVp8Param->HierarchyQPLayer2); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RefNumberForPFrame : %d", pVp8Param->RefNumberForPFrame); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "DisableIntraMd4x4 : %d", pVp8Param->DisableIntraMd4x4); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumTemporalLayer : %d", pVp8Param->NumTemporalLayer); + + /* rate control related parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableFRMRateControl : %d", pCommonParam->EnableFRMRateControl); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableMBRateControl : %d", pCommonParam->EnableMBRateControl); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CBRPeriodRf : %d", pCommonParam->CBRPeriodRf); +} + +static void Set_VP8Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + EXYNOS_OMX_BASEPORT *pInputPort = NULL; + EXYNOS_OMX_BASEPORT *pOutputPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + EXYNOS_MFC_VP8ENC_HANDLE *pMFCVp8Handle = NULL; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = NULL; + + ExynosVideoEncParam *pEncParam = NULL; + ExynosVideoEncCommonParam *pCommonParam = NULL; + ExynosVideoEncVp8Param *pVp8Param = NULL; + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + pMFCVp8Handle = &pVp8Enc->hMFCVp8Handle; + pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pEncParam = &pMFCVp8Handle->encParam; + pCommonParam = &pEncParam->commonParam; + pVp8Param = &pEncParam->codecParam.vp8; + pExtBufferInfo = (ENCODE_CODEC_EXTRA_BUFFERINFO *)pInputPort->processData.extInfo; + + pEncParam->eCompressionFormat = VIDEO_CODING_VP8; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat); + + /* common parameters */ + pCommonParam->SourceWidth = pOutputPort->portDefinition.format.video.nFrameWidth; + pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameHeight; + pCommonParam->IDRPeriod = 0; /* unuseable value */ + pCommonParam->SliceMode = 0; + pCommonParam->Bitrate = pOutputPort->portDefinition.format.video.nBitrate; + pCommonParam->FrameQp = pVideoEnc->quantization.nQpI; + pCommonParam->FrameQp_P = pVideoEnc->quantization.nQpP; + pCommonParam->QSCodeMax = 115; + pCommonParam->QSCodeMin = 10; + pCommonParam->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */ + pCommonParam->LumaPadVal = 0; + pCommonParam->CbPadVal = 0; + pCommonParam->CrPadVal = 0; + + if (pVideoEnc->intraRefresh.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) { + /* Cyclic Mode */ + pCommonParam->RandomIntraMBRefresh = pVideoEnc->intraRefresh.nCirMBs; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh: %d", pCommonParam->RandomIntraMBRefresh); + } else { + /* Don't support "Adaptive" and "Cyclic + Adaptive" */ + pCommonParam->RandomIntraMBRefresh = 0; + } + + switch (pExtBufferInfo->eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; + break; + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV21; + break; +#ifdef USE_ENCODER_RGBINPUT_SUPPORT + case OMX_COLOR_FormatYUV420Planar: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_I420; + break; + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_YV12; + break; + case OMX_COLOR_Format32bitBGRA8888: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_ARGB8888; + break; +#endif + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled: + default: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; + break; + } + + /* Vp8 specific parameters */ + pVp8Param->FrameRate = (pInputPort->portDefinition.format.video.xFramerate) >> 16; + pVp8Param->Vp8Version = OMXVP8LevelToMFCVersion(pVp8Enc->VP8Component[OUTPUT_PORT_INDEX].eLevel); + pVp8Param->Vp8NumberOfPartitions = pVp8Enc->VP8Component[OUTPUT_PORT_INDEX].nDCTPartitions; + pVp8Param->Vp8FilterLevel = 28; + pVp8Param->Vp8FilterSharpness = 6; + pVp8Param->Vp8GoldenFrameSel = 0; + pVp8Param->Vp8GFRefreshPeriod = 10; + pVp8Param->HierarchyQpEnable = 0; + pVp8Param->HierarchyQPLayer0 = 0; + pVp8Param->HierarchyQPLayer1 = 0; + pVp8Param->HierarchyQPLayer2 = 0; + pVp8Param->RefNumberForPFrame = 2; + pVp8Param->DisableIntraMd4x4 = 0; + pVp8Param->NumTemporalLayer = 0; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); + /* rate control related parameters */ + switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { + case OMX_Video_ControlRateDisable: + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR"); + pCommonParam->EnableFRMRateControl = 0; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 0; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 200; + break; + case OMX_Video_ControlRateConstant: + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR"); + pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 1; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 9; + break; + case OMX_Video_ControlRateVariable: + default: /*Android default */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR"); + pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 1; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 200; + break; + } + + Print_VP8Enc_Param(pEncParam); +} + +static void Change_VP8Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + EXYNOS_OMX_BASEPORT *pInputPort = NULL; + EXYNOS_OMX_BASEPORT *pOutputPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + EXYNOS_MFC_VP8ENC_HANDLE *pMFCVp8Handle = NULL; + + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncParam *pEncParam = NULL; + ExynosVideoEncCommonParam *pCommonParam = NULL; + ExynosVideoEncVp8Param *pVp8Param = NULL; + + int setParam = 0; + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + pMFCVp8Handle = &pVp8Enc->hMFCVp8Handle; + pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pEncOps = pMFCVp8Handle->pEncOps; + + pEncParam = &pMFCVp8Handle->encParam; + pCommonParam = &pEncParam->commonParam; + pVp8Param = &pEncParam->codecParam.vp8; + + if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { + setParam = VIDEO_FRAME_I; + pEncOps->Set_FrameType(pVp8Enc->hMFCVp8Handle.hMFCHandle, setParam); + pVideoEnc->IntraRefreshVOP = OMX_FALSE; + } + + if (pCommonParam->Bitrate != (int)pOutputPort->portDefinition.format.video.nBitrate) { + setParam = pOutputPort->portDefinition.format.video.nBitrate; + pEncOps->Set_BitRate(pVp8Enc->hMFCVp8Handle.hMFCHandle, setParam); + } + + if (pVp8Param->FrameRate != (int)((pInputPort->portDefinition.format.video.xFramerate) >> 16)) { + setParam = (pInputPort->portDefinition.format.video.xFramerate) >> 16; + pEncOps->Set_FrameRate(pVp8Enc->hMFCVp8Handle.hMFCHandle, setParam); + } + + Set_VP8Enc_Param(pExynosComponent); +} + +OMX_ERRORTYPE GetCodecInputPrivateData( + OMX_PTR pCodecBuffer, + OMX_PTR pVirtAddr[], + OMX_U32 nSize[]) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +OMX_ERRORTYPE GetCodecOutputPrivateData( + OMX_PTR pCodecBuffer, + OMX_PTR *pVirtAddr, + OMX_U32 *pDataSize) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoBuffer *pVideoBuffer = NULL; + + if (pCodecBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoBuffer = (ExynosVideoBuffer *)pCodecBuffer; + + if (pVirtAddr != NULL) + *pVirtAddr = pVideoBuffer->planes[0].addr; + + if (pDataSize != NULL) + *pDataSize = pVideoBuffer->planes[0].allocSize; + +EXIT: + return ret; +} + +OMX_ERRORTYPE VP8CodecOpen(EXYNOS_VP8ENC_HANDLE *pVp8Enc) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pVp8Enc == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + + /* alloc ops structure */ + pEncOps = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps)); + pInbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps)); + pOutbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps)); + + if ((pEncOps == NULL) || + (pInbufOps == NULL) || + (pOutbufOps == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate encoder ops buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pVp8Enc->hMFCVp8Handle.pEncOps = pEncOps; + pVp8Enc->hMFCVp8Handle.pInbufOps = pInbufOps; + pVp8Enc->hMFCVp8Handle.pOutbufOps = pOutbufOps; + + /* function pointer mapping */ + pEncOps->nSize = sizeof(ExynosVideoEncOps); + pInbufOps->nSize = sizeof(ExynosVideoEncBufferOps); + pOutbufOps->nSize = sizeof(ExynosVideoEncBufferOps); + + Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps); + + /* check mandatory functions for encoder ops */ + if ((pEncOps->Init == NULL) || + (pEncOps->Finalize == NULL) || + (pEncOps->Set_FrameTag == NULL) || + (pEncOps->Get_FrameTag == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* check mandatory functions for buffer ops */ + if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) || + (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) || + (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) || + (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) || + (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* alloc context, open, querycap */ +#ifdef USE_DMA_BUF + pVp8Enc->hMFCVp8Handle.hMFCHandle = pVp8Enc->hMFCVp8Handle.pEncOps->Init(V4L2_MEMORY_DMABUF); +#else + pVp8Enc->hMFCVp8Handle.hMFCHandle = pVp8Enc->hMFCVp8Handle.pEncOps->Init(V4L2_MEMORY_USERPTR); +#endif + + if (pVp8Enc->hMFCVp8Handle.hMFCHandle == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + if (ret != OMX_ErrorNone) { + if (pEncOps != NULL) { + Exynos_OSAL_Free(pEncOps); + pVp8Enc->hMFCVp8Handle.pEncOps = NULL; + } + + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pVp8Enc->hMFCVp8Handle.pInbufOps = NULL; + } + + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pVp8Enc->hMFCVp8Handle.pOutbufOps = NULL; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE VP8CodecClose(EXYNOS_VP8ENC_HANDLE *pVp8Enc) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pVp8Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps; + pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + + if (hMFCHandle != NULL) { + pEncOps->Finalize(hMFCHandle); + hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle = NULL; + } + + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps = NULL; + } + + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps = NULL; + } + + if (pEncOps != NULL) { + Exynos_OSAL_Free(pEncOps); + pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps = NULL; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE VP8CodecStart( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pVp8Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) + pInbufOps->Run(hMFCHandle); + else if (nPortIndex == OUTPUT_PORT_INDEX) + pOutbufOps->Run(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE VP8CodecStop( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pVp8Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + + if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) + pInbufOps->Stop(hMFCHandle); + else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) + pOutbufOps->Stop(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE VP8CodecOutputBufferProcessRun( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pVp8Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) { + if (pVp8Enc->bSourceStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pVp8Enc->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + if (nPortIndex == OUTPUT_PORT_INDEX) { + if (pVp8Enc->bDestinationStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pVp8Enc->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE VP8CodecRegistCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nPortIndex, + OMX_U32 nBufferCnt) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + void *hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + CODEC_ENC_BUFFER **ppCodecBuffer = NULL; + ExynosVideoEncBufferOps *pBufOps = NULL; + ExynosVideoPlane *pPlanes = NULL; + + OMX_U32 nPlaneCnt = 0; + int i, j; + + FunctionIn(); + + if (nPortIndex == INPUT_PORT_INDEX) { + ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]); + pBufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + } else { + ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]); + pBufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + } + nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt; + + pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt); + if (pPlanes == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* Register buffer */ + for (i = 0; i < nBufferCnt; i++) { + for (j = 0; j < nPlaneCnt; j++) { + pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j]; + pPlanes[j].fd = ppCodecBuffer[i]->fd[j]; + pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j]; + } + + if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Free(pPlanes); + goto EXIT; + } + } + + Exynos_OSAL_Free(pPlanes); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE VP8CodecEnqueueAllBuffer( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + void *hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + int i, nOutbufs; + + ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + + FunctionIn(); + + if ((nPortIndex != INPUT_PORT_INDEX) && + (nPortIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pVp8Enc->bSourceStart == OMX_TRUE)) { + Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX); + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + + Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); + } + + pInbufOps->Clear_Queue(hMFCHandle); + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pVp8Enc->bDestinationStart == OMX_TRUE)) { + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + + Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoEnc->pMFCEncOutputBuffer[i]); + } + + pOutbufOps->Clear_Queue(hMFCHandle); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + EXYNOS_MFC_VP8ENC_HANDLE *pMFCVp8Handle = &pVp8Enc->hMFCVp8Handle; + void *hMFCHandle = pMFCVp8Handle->hMFCHandle; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + ExynosVideoEncParam *pEncParam = NULL; + + ExynosVideoGeometry bufferConf; + OMX_U32 nInputBufferCnt = 0; + int i, nOutbufs; + + FunctionIn(); + + if ((pSrcInputData->dataLen <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO)); + if (pBufferInfo == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pBufferInfo->nFlags = pSrcInputData->nFlags; + pBufferInfo->timeStamp = pSrcInputData->timeStamp; + ret = Exynos_OSAL_Queue(&pVp8Enc->bypassBufferInfoQ, (void *)pBufferInfo); + Exynos_OSAL_SignalSet(pVp8Enc->hDestinationStartEvent); + + ret = OMX_ErrorNone; + goto EXIT; + } + + Set_VP8Enc_Param(pExynosComponent); + + pEncParam = &pMFCVp8Handle->encParam; + if (pEncOps->Set_EncParam) { + if(pEncOps->Set_EncParam(pVp8Enc->hMFCVp8Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* input buffer info: only 3 config values needed */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + bufferConf.eColorFormat = pEncParam->commonParam.FrameMap; + bufferConf.nFrameWidth = pInputPort->portDefinition.format.video.nFrameWidth; + bufferConf.nFrameHeight = pInputPort->portDefinition.format.video.nFrameHeight; + bufferConf.nPlaneCnt = pInputPort->nPlaneCnt; + pInbufOps->Set_Shareable(hMFCHandle); + nInputBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC; + + + if (pInputPort->bufferProcessType & BUFFER_COPY) { + /* should be done before prepare input buffer */ + if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* set input buffer geometry */ + if (pInbufOps->Set_Geometry) { + if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* setup input buffer */ + if (pInbufOps->Setup(hMFCHandle, nInputBufferCnt) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if ((pInputPort->bufferProcessType & BUFFER_SHARE) && + (pInputPort->bStoreMetaData != OMX_TRUE)) { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } + + pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc = OMX_TRUE; + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + EXYNOS_MFC_VP8ENC_HANDLE *pMFCVp8Handle = &pVp8Enc->hMFCVp8Handle; + void *hMFCHandle = pMFCVp8Handle->hMFCHandle; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + + ExynosVideoGeometry bufferConf; + int i, nOutBufferSize = 0, nOutputBufferCnt = 0; + + FunctionIn(); + + nOutBufferSize = pOutputPort->portDefinition.nBufferSize; + + /* set geometry for output (dst) */ + if (pOutbufOps->Set_Geometry) { + /* only 2 config values needed */ + bufferConf.eCompressionFormat = VIDEO_CODING_VP8; + bufferConf.nSizeImage = nOutBufferSize; + bufferConf.nPlaneCnt = pOutputPort->nPlaneCnt; + + if (pOutbufOps->Set_Geometry(pVp8Enc->hMFCVp8Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* should be done before prepare output buffer */ + if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pOutbufOps->Set_Shareable(hMFCHandle); + + if (pOutputPort->bufferProcessType & BUFFER_COPY) + nOutputBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX; + else + nOutputBufferCnt = pOutputPort->portDefinition.nBufferCountActual; + + if (pOutbufOps->Setup(pVp8Enc->hMFCVp8Handle.hMFCHandle, nOutputBufferCnt) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + OMX_U32 dataLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; + OMX_U32 nPlaneSize[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; + nPlaneSize[0] = nOutBufferSize; + + ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nPlaneSize); + if (ret != OMX_ErrorNone) + goto EXIT; + + /* Enqueue output buffer */ + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr, + (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->fd, + (unsigned int *)pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize, + (unsigned int *)dataLen, pOutputPort->nPlaneCnt, NULL); + } + + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) { + /* Register output buffer */ + /*************/ + /* TBD */ + /*************/ + } + + pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || + (pComponentParameterStructure == 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; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoVp8: + { + OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = (OMX_VIDEO_PARAM_VP8TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_VP8TYPE *pSrcVP8Component = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pDstVP8Component, sizeof(OMX_VIDEO_PARAM_VP8TYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pDstVP8Component->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcVP8Component = &pVp8Enc->VP8Component[pDstVP8Component->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstVP8Component, pSrcVP8Component, sizeof(OMX_VIDEO_PARAM_VP8TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 nMaxProfileLevel = 0; + + ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pProfileLevel = supportedVP8ProfileLevels; + nMaxProfileLevel = sizeof(supportedVP8ProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL); + + if (pDstProfileLevel->nProfileIndex >= nMaxProfileLevel) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pProfileLevel += pDstProfileLevel->nProfileIndex; + pDstProfileLevel->eProfile = pProfileLevel->profile; + pDstProfileLevel->eLevel = pProfileLevel->level; + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + OMX_VIDEO_PARAM_VP8TYPE *pSrcVP8Component = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcVP8Component = &pVp8Enc->VP8Component[pDstProfileLevel->nPortIndex]; + + pDstProfileLevel->eProfile = pSrcVP8Component->eProfile; + pDstProfileLevel->eLevel = pSrcVP8Component->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcErrorCorrectionType = &pVp8Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || + (pComponentParameterStructure == 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; + } + + switch (nIndex) { + case OMX_IndexParamVideoVp8: + { + OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = NULL; + OMX_VIDEO_PARAM_VP8TYPE *pSrcVP8Component = (OMX_VIDEO_PARAM_VP8TYPE *)pComponentParameterStructure; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pSrcVP8Component, sizeof(OMX_VIDEO_PARAM_VP8TYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pSrcVP8Component->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstVP8Component = &pVp8Enc->VP8Component[pSrcVP8Component->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstVP8Component, pSrcVP8Component, sizeof(OMX_VIDEO_PARAM_VP8TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if ((pExynosComponent->currentState != OMX_StateLoaded) && + (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE)) { + pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstVP8Component = &pVp8Enc->VP8Component[pSrcProfileLevel->nPortIndex]; + + pDstVP8Component->eProfile = pSrcProfileLevel->eProfile; + pDstVP8Component->eLevel = pSrcProfileLevel->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstErrorCorrectionType = &pVp8Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || + (pComponentConfigStructure == 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; + } + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || + (pComponentConfigStructure == 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; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + if (ret == OMX_ErrorNone) + pVideoEnc->configChange = OMX_TRUE; + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_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) { + 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 ((cParameterName == NULL) || + (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) { + *pIndexType = OMX_IndexConfigVideoIntraPeriod; + ret = OMX_ErrorNone; + } else { + ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_ComponentRoleEnum( + OMX_HANDLETYPE hComponent, + OMX_U8 *cRole, + OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + if ((hComponent == NULL) || + (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE Exynos_VP8Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = pInputPort->processData.extInfo; + OMX_PTR hMFCHandle = NULL; + OMX_COLOR_FORMATTYPE eColorFormat; + + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + + CSC_METHOD csc_method = CSC_METHOD_SW; + + int i = 0; + + FunctionIn(); + + pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE; + pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE; + pVideoEnc->bFirstOutput = OMX_FALSE; + pExynosComponent->bUseFlagEOF = OMX_TRUE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bBehaviorEOS = OMX_FALSE; + + eColorFormat = pInputPort->portDefinition.format.video.eColorFormat; + if (pInputPort->bStoreMetaData == OMX_TRUE) { + if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) + pInputPort->bufferProcessType = BUFFER_COPY; + else + pInputPort->bufferProcessType = BUFFER_SHARE; + } else { + pInputPort->bufferProcessType = BUFFER_COPY; + } + + /* VP8 Codec Open */ + ret = VP8CodecOpen(pVp8Enc); + if (ret != OMX_ErrorNone) + goto EXIT; + + pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps; + pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + +#ifdef USE_ENCODER_RGBINPUT_SUPPORT + if (pEncOps->Check_RGBSupport(hMFCHandle) != VIDEO_ERROR_NOSUPPORT) + pVideoEnc->bRGBSupport = OMX_TRUE; +#endif + + pVideoEnc->nInbufSpareSize = pInbufOps->Get_SpareSize(hMFCHandle); + + pInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE; + if ((pInputPort->bStoreMetaData != OMX_TRUE) && + (eColorFormat != OMX_COLOR_FormatAndroidOpaque)) { + if (pInputPort->bufferProcessType & BUFFER_COPY) { + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {0, 0, 0}; + + if (pVideoEnc->bRGBSupport == OMX_TRUE) { + pInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(eColorFormat); + Exynos_OSAL_GetPlaneSize(eColorFormat, ALIGN_TO_16B(1920), ALIGN_TO_16B(1080), nPlaneSize); + } else { + pExtBufferInfo->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + pInputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420SemiPlanar); + Exynos_OSAL_GetPlaneSize(OMX_COLOR_FormatYUV420SemiPlanar, ALIGN_TO_16B(1920), ALIGN_TO_16B(1080), nPlaneSize); + } + + if (pVideoEnc->nInbufSpareSize > 0) { + for (i = 0; i < pInputPort->nPlaneCnt; i++) + nPlaneSize[i] += pVideoEnc->nInbufSpareSize; + } + + Exynos_OSAL_SemaphoreCreate(&pInputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + + ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize); + if (ret != OMX_ErrorNone) + goto EXIT; + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) + Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); + } else if (pInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + } + + pOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE; + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pOutputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + pVp8Enc->bSourceStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pVp8Enc->hSourceStartEvent); + pVp8Enc->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pVp8Enc->hDestinationStartEvent); + + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pVp8Enc->hMFCVp8Handle.indexTimestamp = 0; + pVp8Enc->hMFCVp8Handle.outputIndexTimestamp = 0; + + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + + Exynos_OSAL_QueueCreate(&pVp8Enc->bypassBufferInfoQ, QUEUE_ELEMENTS); + +#ifdef USE_CSC_HW + csc_method = CSC_METHOD_HW; +#endif + + pVideoEnc->csc_handle = csc_init(csc_method); + if (pVideoEnc->csc_handle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pVideoEnc->csc_set_format = OMX_FALSE; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE Exynos_VP8Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle); + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + + int i = 0, plane = 0; + + FunctionIn(); + + if (pVideoEnc->csc_handle != NULL) { + csc_deinit(pVideoEnc->csc_handle); + pVideoEnc->csc_handle = NULL; + } + + Exynos_OSAL_QueueTerminate(&pVp8Enc->bypassBufferInfoQ); + + Exynos_OSAL_SignalTerminate(pVp8Enc->hDestinationStartEvent); + pVp8Enc->hDestinationStartEvent = NULL; + pVp8Enc->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalTerminate(pVp8Enc->hSourceStartEvent); + pVp8Enc->hSourceStartEvent = NULL; + pVp8Enc->bSourceStart = OMX_FALSE; + + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX); + Exynos_OSAL_QueueTerminate(&pOutputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pOutputPort->codecSemID); + } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pInputPort->bufferProcessType & BUFFER_COPY) { + Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX); + Exynos_OSAL_QueueTerminate(&pInputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pInputPort->codecSemID); + } else if (pInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + VP8CodecClose(pVp8Enc); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_SrcIn( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + void *hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + ENCODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo = pSrcInputData->extInfo; + + OMX_BUFFERHEADERTYPE tempBufferHeader; + void *pPrivate = NULL; + + ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; + + FunctionIn(); + + if (pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc == OMX_FALSE) { + ret = VP8CodecSrcSetup(pOMXComponent, pSrcInputData); + if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) + goto EXIT; + } + + if (pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE) + ret = VP8CodecDstSetup(pOMXComponent); + + if (pVideoEnc->configChange == OMX_TRUE) { + Change_VP8Enc_Param(pExynosComponent); + pVideoEnc->configChange = OMX_FALSE; + } + + if ((pSrcInputData->dataLen > 0) || + ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0}; + OMX_U32 nMFCYUVDataSize[MAX_BUFFER_PLANE] = {0, 0, 0}; + + pExynosComponent->timeStamp[pVp8Enc->hMFCVp8Handle.indexTimestamp] = pSrcInputData->timeStamp; + pExynosComponent->nFlags[pVp8Enc->hMFCVp8Handle.indexTimestamp] = pSrcInputData->nFlags; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pVp8Enc->hMFCVp8Handle.indexTimestamp, pSrcInputData->nFlags); + + pEncOps->Set_FrameTag(hMFCHandle, pVp8Enc->hMFCVp8Handle.indexTimestamp); + pVp8Enc->hMFCVp8Handle.indexTimestamp++; + pVp8Enc->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP; +#ifdef USE_QOS_CTRL + if ((pVideoEnc->bQosChanged == OMX_TRUE) && + (pEncOps->Set_QosRatio != NULL)) { + pEncOps->Set_QosRatio(hMFCHandle, pVideoEnc->nQosRatio); + pVideoEnc->bQosChanged = OMX_FALSE; + } +#endif + /* queue work for input buffer */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_VP8Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", pSrcInputData->dataLen, pSrcInputData->bufferHeader); + + if (pInputPort->bufferProcessType == BUFFER_COPY) { + Exynos_OSAL_GetPlaneSize(pExtBufferInfo->eColorFormat, ALIGN_TO_16B(1920), ALIGN_TO_16B(1080), nMFCYUVDataSize); + tempBufferHeader.nFlags = pSrcInputData->nFlags; + tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp; + pPrivate = (void *)&tempBufferHeader; + } else { + Exynos_OSAL_GetPlaneSize(pExtBufferInfo->eColorFormat, + pInputPort->portDefinition.format.video.nFrameWidth, + pInputPort->portDefinition.format.video.nFrameHeight, + nMFCYUVDataSize); + pPrivate = (void *)pSrcInputData->bufferHeader; + } + + if (pVideoEnc->nInbufSpareSize> 0) { + for (i = 0; i < pInputPort->nPlaneCnt; i++) + nAllocLen[i] = nMFCYUVDataSize[i] + pVideoEnc->nInbufSpareSize; + } + + codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)nMFCYUVDataSize, + pInputPort->nPlaneCnt, pPrivate); + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + + VP8CodecStart(pOMXComponent, INPUT_PORT_INDEX); + + if (pVp8Enc->bSourceStart == OMX_FALSE) { + pVp8Enc->bSourceStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pVp8Enc->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + + if (pVp8Enc->bDestinationStart == OMX_FALSE) { + pVp8Enc->bDestinationStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pVp8Enc->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_SrcOut( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + void *hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + ExynosVideoEncBufferOps *pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps; + ExynosVideoBuffer *pVideoBuffer = NULL; + ExynosVideoBuffer videoBuffer; + + FunctionIn(); + + if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) + pVideoBuffer = &videoBuffer; + else + pVideoBuffer = NULL; + + pSrcOutputData->dataLen = 0; + pSrcOutputData->usedDataLen = 0; + pSrcOutputData->remainDataLen = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + pSrcOutputData->allocSize = 0; + pSrcOutputData->bufferHeader = NULL; + + if (pVideoBuffer == NULL) { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; + pSrcOutputData->pPrivate = NULL; + } else { + int plane = 0; + for (plane = 0; plane < pInputPort->nPlaneCnt; plane++) { + pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; + pSrcOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + + pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; + } + + if (pInputPort->bufferProcessType & BUFFER_COPY) { + int i; + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + if (pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] == + pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) { + pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0; + pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i]; + break; + } + } + + if (i >= MFC_INPUT_BUFFER_NUM_MAX) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + } + + /* For Share Buffer */ + if (pInputPort->bufferProcessType == BUFFER_SHARE) + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_DstIn( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + void *hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps; + ExynosVideoEncBufferOps *pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + OMX_U32 dataLen = 0; + + FunctionIn(); + + if (pDstInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer"); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + OMX_U32 nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; + nAllocLen[0] = pOutputPort->portDefinition.format.video.nFrameWidth * pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + + codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)&dataLen, + pOutputPort->nPlaneCnt, pDstInputData->bufferHeader); + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + + VP8CodecStart(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_DstOut( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + void *hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle; + + ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps; + ExynosVideoEncBufferOps *pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps; + ExynosVideoBuffer *pVideoBuffer = NULL; + ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; + ExynosVideoGeometry bufferGeometry; + ExynosVideoBuffer videoBuffer; + + OMX_S32 indexTimestamp = 0; + + FunctionIn(); + + if (pVp8Enc->bDestinationStart == OMX_FALSE) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) { + pVideoBuffer = &videoBuffer; + } else { + pVideoBuffer = NULL; + ret = OMX_ErrorNone; + goto EXIT; + } + + pVp8Enc->hMFCVp8Handle.outputIndexTimestamp++; + pVp8Enc->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + + pDstOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; + pDstOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; + pDstOutputData->allocSize = pVideoBuffer->planes[0].allocSize; + pDstOutputData->dataLen = pVideoBuffer->planes[0].dataSize; + pDstOutputData->remainDataLen = pVideoBuffer->planes[0].dataSize; + pDstOutputData->usedDataLen = 0; + pDstOutputData->pPrivate = pVideoBuffer; + + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + int i = 0; + pDstOutputData->pPrivate = NULL; + + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + if (pDstOutputData->buffer.singlePlaneBuffer.dataBuffer == + pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) { + pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i]; + break; + } + } + + if (pDstOutputData->pPrivate == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + } + + /* For Share Buffer */ + pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; + + if (pVideoEnc->bFirstOutput == OMX_FALSE) { + pDstOutputData->timeStamp = 0; + pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + pVideoEnc->bFirstOutput = OMX_TRUE; + } else { + indexTimestamp = pEncOps->Get_FrameTag(pVp8Enc->hMFCVp8Handle.hMFCHandle); + if ((indexTimestamp < 0) || + (indexTimestamp >= MAX_TIMESTAMP)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pVp8Enc->hMFCVp8Handle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pVp8Enc->hMFCVp8Handle.outputIndexTimestamp]; + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + } + + pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + + if (pVideoBuffer->frameType == VIDEO_FRAME_I) + pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + } + + if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (pExynosComponent->bBehaviorEOS == OMX_FALSE))) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags); + pDstOutputData->remainDataLen = 0; + } + + if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (pExynosComponent->bBehaviorEOS == OMX_TRUE)) + pExynosComponent->bBehaviorEOS = OMX_FALSE; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_srcInputBufferProcess( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pInputPort)) || + (!CHECK_PORT_POPULATED(pInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = Exynos_VP8Enc_SrcIn(pOMXComponent, pSrcInputData); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_srcOutputBufferProcess( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pInputPort)) || + (!CHECK_PORT_POPULATED(pInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pInputPort->bufferProcessType & BUFFER_COPY) { + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + } + + if ((pVp8Enc->bSourceStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pInputPort))) { + Exynos_OSAL_SignalWait(pVp8Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pVp8Enc->hSourceStartEvent); + } + + ret = Exynos_VP8Enc_SrcOut(pOMXComponent, pSrcOutputData); + if ((ret != OMX_ErrorNone) && + (pExynosComponent->currentState == OMX_StateExecuting)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_dstInputBufferProcess( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pOutputPort)) || + (!CHECK_PORT_POPULATED(pOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pVp8Enc->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) { + Exynos_OSAL_SignalWait(pVp8Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pVp8Enc->hDestinationStartEvent); + } + + if (Exynos_OSAL_GetElemNum(&pVp8Enc->bypassBufferInfoQ) > 0) { + BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp8Enc->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags; + pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader); + Exynos_OSAL_Free(pBufferInfo); + + ret = OMX_ErrorNone; + goto EXIT; + } + } + + if (pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE) { + ret = Exynos_VP8Enc_DstIn(pOMXComponent, pDstInputData); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_VP8Enc_dstOutputBufferProcess( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pOutputPort)) || + (!CHECK_PORT_POPULATED(pOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pVp8Enc->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) { + Exynos_OSAL_SignalWait(pVp8Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pVp8Enc->hDestinationStartEvent); + } + + if (Exynos_OSAL_GetElemNum(&pVp8Enc->bypassBufferInfoQ) > 0) { + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL; + BYPASS_BUFFER_INFO *pBufferInfo = NULL; + + if (dstOutputUseBuffer->dataValid == OMX_FALSE) { + pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (pOMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else { + pOMXBuffer = dstOutputUseBuffer->bufferHeader; + } + + pBufferInfo = Exynos_OSAL_Dequeue(&pVp8Enc->bypassBufferInfoQ); + if (pBufferInfo == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOMXBuffer->nFlags = pBufferInfo->nFlags; + pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp; + Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer); + Exynos_OSAL_Free(pBufferInfo); + + dstOutputUseBuffer->dataValid = OMX_FALSE; + + ret = OMX_ErrorNone; + goto EXIT; + } + } + + ret = Exynos_VP8Enc_DstOut(pOMXComponent, pDstOutputData); + if ((ret != OMX_ErrorNone) && + (pExynosComponent->currentState == OMX_StateExecuting)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( + OMX_HANDLETYPE hComponent, + OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || + (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + + if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_ENC, componentName) != 0) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosComponent->codecType = HW_VIDEO_ENC_CODEC; + + pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pExynosComponent->componentName == NULL) { + Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pVp8Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP8ENC_HANDLE)); + if (pVp8Enc == NULL) { + Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pVp8Enc, 0, sizeof(EXYNOS_VP8ENC_HANDLE)); + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pVp8Enc; + pVideoEnc->quantization.nQpI = 20; + pVideoEnc->quantization.nQpP = 20; + pVideoEnc->quantization.nQpB = 20; + + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_VP8_ENC); + + pVideoEnc->bDRMPlayerMode = OMX_FALSE; + + /* Set componentVersion */ + pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portWayType = WAY2_PORT; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc"); + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->bufferProcessType = BUFFER_SHARE; + pExynosPort->portWayType = WAY2_PORT; + + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pVp8Enc->VP8Component[i], OMX_VIDEO_PARAM_VP8TYPE); + pVp8Enc->VP8Component[i].nPortIndex = i; + pVp8Enc->VP8Component[i].eProfile = OMX_VIDEO_VP8ProfileMain; + pVp8Enc->VP8Component[i].eLevel = OMX_VIDEO_VP8Level_Version0; + } + + pOMXComponent->GetParameter = &Exynos_VP8Enc_GetParameter; + pOMXComponent->SetParameter = &Exynos_VP8Enc_SetParameter; + pOMXComponent->GetConfig = &Exynos_VP8Enc_GetConfig; + pOMXComponent->SetConfig = &Exynos_VP8Enc_SetConfig; + pOMXComponent->GetExtensionIndex = &Exynos_VP8Enc_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &Exynos_VP8Enc_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; + + pExynosComponent->exynos_codec_componentInit = &Exynos_VP8Enc_Init; + pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP8Enc_Terminate; + + pVideoEnc->exynos_codec_srcInputProcess = &Exynos_VP8Enc_srcInputBufferProcess; + pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_VP8Enc_srcOutputBufferProcess; + pVideoEnc->exynos_codec_dstInputProcess = &Exynos_VP8Enc_dstInputBufferProcess; + pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_VP8Enc_dstOutputBufferProcess; + + pVideoEnc->exynos_codec_start = &VP8CodecStart; + pVideoEnc->exynos_codec_stop = &VP8CodecStop; + pVideoEnc->exynos_codec_bufferProcessRun = &VP8CodecOutputBufferProcessRun; + pVideoEnc->exynos_codec_enqueueAllBuffer = &VP8CodecEnqueueAllBuffer; + + pVideoEnc->exynos_checkInputFrame = NULL; + pVideoEnc->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; + pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; + + pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); + if (pVideoEnc->hSharedMemory == NULL) { + Exynos_OSAL_Free(pVp8Enc); + pVp8Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; + Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pExynosComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_VP8ENC_HANDLE *pVp8Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory); + + Exynos_OSAL_Free(pExynosComponent->componentName); + pExynosComponent->componentName = NULL; + + pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pVp8Enc != NULL) { + Exynos_OSAL_Free(pVp8Enc); + pVp8Enc = pVideoEnc->hCodecHandle = NULL; + } + + ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/component/video/enc/vp8/Exynos_OMX_Vp8enc.h b/component/video/enc/vp8/Exynos_OMX_Vp8enc.h new file mode 100644 index 0000000..6ad851a --- /dev/null +++ b/component/video/enc/vp8/Exynos_OMX_Vp8enc.h @@ -0,0 +1,80 @@ +/* + * + * Copyright 2013 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_Vp8enc.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Taehwan Kim (t_h.kim@samsung.com) + * @version 2.0.0 + * @history + * 2013.02.14 : Create + */ + +#ifndef EXYNOS_OMX_VP8_ENC_COMPONENT +#define EXYNOS_OMX_VP8_ENC_COMPONENT + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" + +#include "ExynosVideoApi.h" + +typedef struct _EXYNOS_MFC_VP8ENC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFCSrc; + OMX_BOOL bConfiguredMFCDst; + + ExynosVideoDecOps *pEncOps; + ExynosVideoDecBufferOps *pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps; + ExynosVideoEncParam encParam; +} EXYNOS_MFC_VP8ENC_HANDLE; + +typedef struct _EXYNOS_VP8ENC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_VP8TYPE VP8Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + EXYNOS_MFC_VP8ENC_HANDLE hMFCVp8Handle; + + OMX_BOOL bSourceStart; + OMX_BOOL bDestinationStart; + OMX_HANDLETYPE hSourceStartEvent; + OMX_HANDLETYPE hDestinationStartEvent; + + EXYNOS_QUEUE bypassBufferInfoQ; +} EXYNOS_VP8ENC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/component/video/enc/vp8/library_register.c b/component/video/enc/vp8/library_register.c new file mode 100644 index 0000000..03e9036 --- /dev/null +++ b/component/video/enc/vp8/library_register.c @@ -0,0 +1,58 @@ +/* + * + * Copyright 2013 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 library_register.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Taehwan Kim (t_h.kim@samsung.com) + * @version 2.0.0 + * @history + * 2013.02.14 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "library_register.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_VP8_ENC" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent) +{ + FunctionIn(); + + if (ppExynosComponent == NULL) + goto EXIT; + + /* component 1 - video encoder VP8 */ + Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_VP8_ENC); + Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE); + ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + + return MAX_COMPONENT_NUM; +} diff --git a/component/video/enc/vp8/library_register.h b/component/video/enc/vp8/library_register.h new file mode 100644 index 0000000..c002a30 --- /dev/null +++ b/component/video/enc/vp8/library_register.h @@ -0,0 +1,56 @@ +/* + * + * Copyright 2013 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 library_register.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Taehwan Kim (t_h.kim@samsung.com) + * @version 2.0.0 + * @history + * 2013.02.14 : Create + */ + +#ifndef EXYNOS_OMX_VP8_ENC_REG +#define EXYNOS_OMX_VP8_ENC_REG + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "Exynos_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* VP8 */ +#define EXYNOS_OMX_COMPONENT_VP8_ENC "OMX.Exynos.VP8.Encoder" +#define EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE "video_encoder.vpx" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/include/exynos/Exynos_OMX_Def.h b/include/exynos/Exynos_OMX_Def.h index ee30600..46b2741 100644 --- a/include/exynos/Exynos_OMX_Def.h +++ b/include/exynos/Exynos_OMX_Def.h @@ -88,6 +88,63 @@ typedef struct _EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO { OMX_S32 OMX_OUT fd; } EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO; +typedef struct _EXYNOS_OMX_VIDEO_CONFIG_QOSINFO { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nQosRatio; +} EXYNOS_OMX_VIDEO_CONFIG_QOSINFO; + +#ifdef USE_VP8ENC_SUPPORT +typedef enum OMX_VIDEO_VP84PROFILETYPE { + OMX_VIDEO_VP8ProfileMain = 0x01, + OMX_VIDEO_VP8ProfileUnknown = 0x6EFFFFFF, + OMX_VIDEO_VP8ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_VP8ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_VP8ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_VP8PROFILETYPE; + +typedef enum OMX_VIDEO_VP8LEVELTYPE { + OMX_VIDEO_VP8Level_Version0 = 0x01, + OMX_VIDEO_VP8Level_Version1 = 0x02, + OMX_VIDEO_VP8Level_Version2 = 0x04, + OMX_VIDEO_VP8Level_Version3 = 0x08, + OMX_VIDEO_VP8LevelUnknown = 0x6EFFFFFF, + OMX_VIDEO_VP8LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_VP8LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_VP8LevelMax = 0x7FFFFFFF +} OMX_VIDEO_VP8LEVELTYPE; + +typedef struct OMX_VIDEO_PARAM_VP8TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_VP8PROFILETYPE eProfile; + OMX_VIDEO_VP8LEVELTYPE eLevel; + OMX_U32 nDCTPartitions; + OMX_BOOL bErrorResilientMode; +} OMX_VIDEO_PARAM_VP8TYPE; + +typedef struct OMX_VIDEO_VP8REFERENCEFRAMETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL nPreviousFrameRefresh; + OMX_BOOL bGoldenFrameRefresh; + OMX_BOOL bAlternateFrameRefresh; + OMX_BOOL bUsePreviousFrame; + OMX_BOOL bUseGoldenFrame; + OMX_BOOL bUseAlternateFrame; +} OMX_VIDEO_VP8REFERENCEFRAMETYPE; + +typedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bIsIntraFrame; + OMX_BOOL bIsGoldenOrAlternateFrame; +} OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE; +#endif + typedef enum _EXYNOS_OMX_INDEXTYPE { #define EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL "OMX.SEC.index.ThumbnailMode" @@ -104,6 +161,8 @@ typedef enum _EXYNOS_OMX_INDEXTYPE OMX_IndexVendorGetBufferFD = 0x7F000005, #define EXYNOS_INDEX_PARAM_SET_DTS_MODE "OMX.SEC.index.SetDTSMode" OMX_IndexVendorSetDTSMode = 0x7F000006, +#define EXYNOS_INDEX_CONFIG_SET_QOS_RATIO "OMX.SEC.index.SetQosRatio" + OMX_IndexVendorSetQosRatio = 0x7F000007, /* for Android Native Window */ #define EXYNOS_INDEX_PARAM_ENABLE_ANB "OMX.google.android.index.enableAndroidNativeBuffers" @@ -119,6 +178,16 @@ typedef enum _EXYNOS_OMX_INDEXTYPE #define EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR "OMX.google.android.index.prependSPSPPSToIDRFrames" OMX_IndexParamPrependSPSPPSToIDR = 0x7F000015, +#ifdef USE_VP8ENC_SUPPORT + /* for VP8 encoder */ +#define EXYNOS_INDEX_PARAM_VIDEO_VP8_TYPE "OMX.SEC.index.VideoVp8Type" + OMX_IndexParamVideoVp8 = 0x7F00016, +#define EXYNOS_INDEX_CONFIG_VIDEO_VP8_REFERENCEFRAME "OMX.SEC.index.VideoVp8ReferenceFrame" + OMX_IndexConfigVideoVp8ReferenceFrame = 0x7F00017, +#define EXYNOS_INDEX_CONFIG_VIDEO_VP8_REFERENCEFRAMETYPE "OMX.SEC.index.VideoVp8ReferenceFrameType" + OMX_IndexConfigVideoVp8ReferenceFrameType = 0x7F00018, +#endif + /* for Android PV OpenCore*/ OMX_COMPONENT_CAPABILITY_TYPE_INDEX = 0xFF7A347 } EXYNOS_OMX_INDEXTYPE; @@ -157,11 +226,9 @@ typedef enum _EXYNOS_OMX_COLOR_FORMATTYPE { OMX_SEC_COLOR_FormatNV12TPhysicalAddress = 0x7F000001, /**< Reserved region for introducing Vendor Extensions */ OMX_SEC_COLOR_FormatNV12LPhysicalAddress = 0x7F000002, OMX_SEC_COLOR_FormatNV12LVirtualAddress = 0x7F000003, -#ifndef USE_NATIVE_SEC_NV12TILED - OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002, /* 0x7FC00002 */ -#endif OMX_SEC_COLOR_FormatNV21LPhysicalAddress = 0x7F000010, OMX_SEC_COLOR_FormatNV21Linear = 0x7F000011, + OMX_SEC_COLOR_FormatYVU420Planar = 0x7F000012, /* to copy a encoded data for drm component using gsc or fimc */ OMX_SEC_COLOR_FormatEncodedData = OMX_COLOR_FormatYCbYCr, @@ -180,7 +247,7 @@ typedef enum _EXYNOS_OMX_SUPPORTFORMAT_TYPE supportFormat_4, supportFormat_5, supportFormat_6, - supportFormat_7 + supportFormat_7, } EXYNOS_OMX_SUPPORTFORMAT_TYPE; typedef enum _EXYNOS_OMX_BUFFERPROCESS_TYPE @@ -201,6 +268,7 @@ typedef struct _EXYNOS_OMX_VIDEO_PROFILELEVEL #ifdef USE_S3D_SUPPORT typedef enum _EXYNOS_OMX_FPARGMT_TYPE { + OMX_SEC_FPARGMT_INVALID = -1, OMX_SEC_FPARGMT_CHECKERBRD_INTERL = 0x00, OMX_SEC_FPARGMT_COLUMN_INTERL = 0x01, OMX_SEC_FPARGMT_ROW_INTERL = 0x02, diff --git a/osal/Android.mk b/osal/Android.mk index 8b01412..7e9a1fa 100644 --- a/osal/Android.mk +++ b/osal/Android.mk @@ -39,6 +39,14 @@ ifeq ($(BOARD_USE_CSC_HW), true) LOCAL_CFLAGS += -DUSE_CSC_HW endif +ifeq ($(TARGET_BOARD_PLATFORM),exynos3) +LOCAL_CFLAGS += -DUSE_MFC5X_ALIGNMENT +endif + +ifeq ($(TARGET_BOARD_PLATFORM),exynos4) +LOCAL_CFLAGS += -DUSE_MFC5X_ALIGNMENT +endif + LOCAL_STATIC_LIBRARIES := liblog libcutils libExynosVideoApi LOCAL_C_INCLUDES := \ diff --git a/osal/Exynos_OSAL_Android.cpp b/osal/Exynos_OSAL_Android.cpp index 9a71881..1efad2b 100644 --- a/osal/Exynos_OSAL_Android.cpp +++ b/osal/Exynos_OSAL_Android.cpp @@ -95,13 +95,11 @@ OMX_ERRORTYPE Exynos_OSAL_LockANBHandle( case OMX_COLOR_FormatAndroidOpaque: { OMX_COLOR_FORMATTYPE formatType; -#ifdef USE_DMA_BUF formatType = Exynos_OSAL_GetANBColorFormat((OMX_U32)priv_hnd); if ((formatType == OMX_COLOR_FormatYUV420SemiPlanar) || (formatType == OMX_SEC_COLOR_FormatNV12Tiled)) usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; else -#endif usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_VIDEO_ENCODER; } break; @@ -169,12 +167,10 @@ OMX_COLOR_FORMATTYPE Exynos_OSAL_GetANBColorFormat(OMX_IN OMX_U32 handle) FunctionIn(); OMX_COLOR_FORMATTYPE ret = OMX_COLOR_FormatUnused; -#ifdef USE_DMA_BUF private_handle_t *priv_hnd = (private_handle_t *) handle; ret = Exynos_OSAL_Hal2OMXPixelFormat(priv_hnd->format); Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ColorFormat: 0x%x", ret); -#endif EXIT: FunctionOut(); @@ -373,6 +369,12 @@ OMX_ERRORTYPE Exynos_OSAL_GetANBParameter( pANBParams->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); #if defined(USE_IMPROVED_BUFFER) && !defined(USE_CSC_HW) pANBParams->nUsage |= (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); +#endif +#if defined(USE_MFC5X_ALIGNMENT) + if ((pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferProcessType & BUFFER_SHARE) && + (pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)) { + pANBParams->nUsage |= GRALLOC_USAGE_PRIVATE_0; + } #endif } break; @@ -461,11 +463,15 @@ OMX_ERRORTYPE Exynos_OSAL_SetANBParameter( #ifdef USE_ANB_OUTBUF_SHARE /* ANB and DPB Buffer Sharing */ if ((portIndex == OUTPUT_PORT_INDEX) && - (pExynosPort->bIsANBEnabled == OMX_TRUE) && - ((pExynosPort->bufferProcessType & BUFFER_ANBSHARE) == BUFFER_ANBSHARE)) { - pExynosPort->bufferProcessType = BUFFER_SHARE; - pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; - Exynos_OSAL_Log(EXYNOS_LOG_INFO, "output buffer sharing mode is on"); + (pExynosPort->bIsANBEnabled == OMX_TRUE)) { + if ((pExynosPort->bufferProcessType & BUFFER_ANBSHARE) == BUFFER_ANBSHARE) { + pExynosPort->bufferProcessType = BUFFER_SHARE; + pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; + Exynos_OSAL_Log(EXYNOS_LOG_INFO, "output buffer sharing mode is on"); + } else { + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + } } #else if ((portIndex == OUTPUT_PORT_INDEX) && @@ -602,7 +608,9 @@ OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer, /* MetadataBufferType */ Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType)); - if (type == kMetadataBufferTypeCameraSource) { + switch (type) { + case kMetadataBufferTypeCameraSource: + { void *pAddress = NULL; /* Address. of Y */ @@ -613,12 +621,27 @@ OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer, Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType) + sizeof(void *), sizeof(void *)); ppBuf[1] = (void *)pAddress; - } else if (type == kMetadataBufferTypeGrallocSource) { + if ((ppBuf[0] == NULL) || (ppBuf[1] == NULL)) + ret = OMX_ErrorBadParameter; + } + break; + case kMetadataBufferTypeGrallocSource: + { buffer_handle_t pBufHandle; /* buffer_handle_t */ Exynos_OSAL_Memcpy(&pBufHandle, pBuffer + sizeof(MetadataBufferType), sizeof(buffer_handle_t)); ppBuf[0] = (OMX_PTR)pBufHandle; + + if (ppBuf[0] == NULL) + ret = OMX_ErrorBadParameter; + } + break; + default: + { + ret = OMX_ErrorBadParameter; + } + break; } EXIT: @@ -662,9 +685,18 @@ OMX_COLOR_FORMATTYPE Exynos_OSAL_Hal2OMXPixelFormat( case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: omx_format = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; break; - case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: omx_format = OMX_COLOR_Format32bitARGB8888; break; + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP: + omx_format = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear; + break; + case HAL_PIXEL_FORMAT_EXYNOS_YV12: + omx_format = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar; + break; + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: + omx_format = OMX_COLOR_Format32bitBGRA8888; + break; default: omx_format = OMX_COLOR_FormatYUV420Planar; break; @@ -690,8 +722,17 @@ unsigned int Exynos_OSAL_OMX2HalPixelFormat( hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED; break; case OMX_COLOR_Format32bitARGB8888: - hal_format = HAL_PIXEL_FORMAT_RGBA_8888; + hal_format = HAL_PIXEL_FORMAT_BGRA_8888; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + hal_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP; + break; + case OMX_SEC_COLOR_FormatYVU420Planar: + hal_format = HAL_PIXEL_FORMAT_EXYNOS_YV12; break; + case OMX_COLOR_Format32bitBGRA8888: + hal_format = HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888; + break; default: hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; break; diff --git a/osal/Exynos_OSAL_ETC.c b/osal/Exynos_OSAL_ETC.c index e6d73ed..90fbb2f 100644 --- a/osal/Exynos_OSAL_ETC.c +++ b/osal/Exynos_OSAL_ETC.c @@ -235,3 +235,59 @@ void Exynos_OSAL_PerfPrint(OMX_STRING prefix, PERF_ID_TYPE id) prefix, (float)perfTotal / (float)(frameCount * 1000), Exynos_OSAL_PerfOver30ms(id)); } + +unsigned int Exynos_OSAL_GetPlaneCount( + OMX_COLOR_FORMATTYPE omx_format) +{ + unsigned int plane_cnt = 0; + switch (omx_format) { + case OMX_COLOR_FormatYCbYCr: + case OMX_COLOR_FormatYUV420Planar: + case OMX_SEC_COLOR_FormatYVU420Planar: + plane_cnt = 3; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV21Linear: + case OMX_SEC_COLOR_FormatNV12Tiled: + plane_cnt = 2; + break; + case OMX_COLOR_Format32bitARGB8888: + case OMX_COLOR_Format32bitBGRA8888: + plane_cnt = 1; + break; + default: + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: unsupported color format.", __func__); + plane_cnt = 0; + break; + } + + return plane_cnt; +} + +void Exynos_OSAL_GetPlaneSize( + OMX_COLOR_FORMATTYPE eColorFormat, + OMX_U32 nWidth, + OMX_U32 nHeight, + OMX_U32 nPlaneSize[MAX_BUFFER_PLANE]) +{ + switch (eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar: + nPlaneSize[0] = nWidth * nHeight; + nPlaneSize[1] = nWidth * nHeight >> 2; + nPlaneSize[2] = nWidth * nHeight >> 2; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear: + case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled: + nPlaneSize[0] = nWidth * nHeight; + nPlaneSize[1] = nWidth * nHeight >> 1; + break; + case OMX_COLOR_Format32bitARGB8888: + case OMX_COLOR_Format32bitBGRA8888: + nPlaneSize[0] = nWidth * nHeight * 4; + break; + default: + break; + } +} diff --git a/osal/Exynos_OSAL_ETC.h b/osal/Exynos_OSAL_ETC.h index efbc51d..b5d9a8d 100644 --- a/osal/Exynos_OSAL_ETC.h +++ b/osal/Exynos_OSAL_ETC.h @@ -28,7 +28,7 @@ #define Exynos_OSAL_ETC #include "OMX_Types.h" - +#include "Exynos_OMX_Def.h" #ifdef __cplusplus extern "C" { @@ -59,6 +59,8 @@ OMX_U32 Exynos_OSAL_PerfFrameCount(PERF_ID_TYPE id); int Exynos_OSAL_PerfOver30ms(PERF_ID_TYPE id); void Exynos_OSAL_PerfPrint(OMX_STRING prefix, PERF_ID_TYPE id); +unsigned int Exynos_OSAL_GetPlaneCount(OMX_COLOR_FORMATTYPE omx_format); +void Exynos_OSAL_GetPlaneSize(OMX_COLOR_FORMATTYPE eColorFormat, OMX_U32 nWidth, OMX_U32 nHeight, OMX_U32 nPlaneSize[MAX_BUFFER_PLANE]); #ifdef __cplusplus } #endif diff --git a/osal/Exynos_OSAL_SharedMemory.h b/osal/Exynos_OSAL_SharedMemory.h index d667d80..2fa8ca5 100644 --- a/osal/Exynos_OSAL_SharedMemory.h +++ b/osal/Exynos_OSAL_SharedMemory.h @@ -49,6 +49,11 @@ void Exynos_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer); int Exynos_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer); OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_addr); +#ifdef USE_DMA_BUF +OMX_PTR Exynos_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, unsigned int ionfd); +void Exynos_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, unsigned int ionfd); +#endif + #ifdef __cplusplus } #endif