diff options
Diffstat (limited to 'domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c')
-rw-r--r-- | domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c | 185 |
1 files changed, 170 insertions, 15 deletions
diff --git a/domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c b/domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c index b6a6431..9767d89 100644 --- a/domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c +++ b/domx/omx_proxy_component/omx_mpeg4_enc/src/omx_proxy_mpeg4enc.c @@ -75,6 +75,9 @@ #include <VideoMetadata.h> #endif +#include <stdlib.h> +#include <cutils/properties.h> + #define COMPONENT_NAME "OMX.TI.DUCATI1.VIDEO.MPEG4E" /* needs to be specific for every configuration wrapper */ @@ -94,6 +97,26 @@ OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_SetParameter(OMX_IN OMX_HANDLETYPE hComponent, #endif + +#define OMX_INIT_STRUCT(_s_, _name_) \ + memset(&(_s_), 0x0, sizeof(_name_)); \ + (_s_).nSize = sizeof(_name_); \ + (_s_).nVersion.s.nVersionMajor = 0x1; \ + (_s_).nVersion.s.nVersionMinor = 0x1; \ + (_s_).nVersion.s.nRevision = 0x0; \ + (_s_).nVersion.s.nStep = 0x0 + + +/* Params needed for Dynamic Frame Rate Control*/ +#define FRAME_RATE_THRESHOLD 1 /* Change in Frame rate to configure the encoder */ +OMX_U32 nFrameRateThreshold = 0;/* Frame Rate threshold for every frame rate update */ +OMX_U32 nPortFrameRate = 0; /* Port FPS initially set to the Encoder */ +OMX_U32 nFrameCounter = 0; /* Number of input frames recieved since last framerate calculation */ +OMX_TICKS nVideoTime = 0; /* Video duration since last framerate calculation */ +OMX_TICKS nLastFrameRateUpdateTime = 0; /*Time stamp at last frame rate update */ +OMX_U16 nBFrames = 0; /* Number of B Frames in H264 Encoder */ + + #ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT #define OMX_MPEG4E_NUM_INTERNAL_BUF (8) #define HAL_PIXEL_FORMAT_TI_NV12 (0x100) @@ -129,6 +152,11 @@ typedef struct _OMX_PROXY_MPEG4E_PRIVATE OMX_S32 nCurBufIndex; alloc_device_t* mAllocDev; }OMX_PROXY_MPEG4E_PRIVATE; + +RPC_OMX_ERRORTYPE RPC_RegisterBuffer(OMX_HANDLETYPE hRPCCtx, int fd, + OMX_PTR *handle1, OMX_PTR *handle2, + PROXY_BUFFER_TYPE proxyBufferType); +RPC_OMX_ERRORTYPE RPC_UnRegisterBuffer(OMX_HANDLETYPE hRPCCtx, OMX_PTR handle); #endif OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hComponent, @@ -137,6 +165,109 @@ OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hCompon OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE * pBufferHdr); +static OMX_ERRORTYPE OMX_ConfigureDynamicFrameRate( OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_U32 nTargetFrameRate = 0; /* Target Frame Rate to be provided to Encoder */ + OMX_U32 nCurrentFrameRate = 0; /* Current Frame Rate currently set in Encoder */ + OMX_CONFIG_FRAMERATETYPE tFrameRate; + OMX_COMPONENTTYPE *pHandle; + if (hComponent == NULL){ + DOMX_ERROR("Component is invalid/ not present "); + return OMX_ErrorBadParameter; + } + pHandle = (OMX_COMPONENTTYPE *) hComponent; + + /* Initialise the OMX structures */ + OMX_INIT_STRUCT(tFrameRate,OMX_CONFIG_FRAMERATETYPE); + + /* Intialise nLastFrameRateUpdateTime for the 1st frame */ + if((!nFrameCounter) && (!nLastFrameRateUpdateTime)){ + nLastFrameRateUpdateTime = pBufferHdr-> nTimeStamp; + } + + /* Increment the Frame Counter and Calculate Frame Rate*/ + nFrameCounter++; + nVideoTime = pBufferHdr->nTimeStamp - nLastFrameRateUpdateTime; + + if(nVideoTime < 0) { + return OMX_ErrorBadParameter; + } + + /*Get Port Frame Rate if not read yet*/ + if(!nFrameRateThreshold) { + tFrameRate.nPortIndex = OMX_MPEG4E_INPUT_PORT; /* As per ducati support-set for input port */ + + /* Read Current FrameRate */ + eError = pHandle->GetConfig(hComponent,OMX_IndexConfigVideoFramerate,&tFrameRate); + if (eError != OMX_ErrorNone) + DOMX_ERROR ("pHandle->GetConfig OMX_IndexConfigVideoFramerate eError :0x%x \n",eError); + nFrameRateThreshold = tFrameRate.xEncodeFramerate >>16; + nPortFrameRate = nFrameRateThreshold; + DOMX_DEBUG(" Port Frame Rate is %d ", nPortFrameRate); + } + nCurrentFrameRate = nFrameRateThreshold; + + /* If Number of frames is less than the Threshold + * Frame Rate udpate is not necessary + */ + if(nFrameCounter < nFrameRateThreshold){ + DOMX_EXIT(" Threshold not reached, no update necessary"); + return OMX_ErrorNone; + } + + /*Calculate the new target Frame Rate*/ + if (nVideoTime != 0) + nTargetFrameRate = nFrameCounter * 1000000 / nVideoTime; + + /* For 1080p record, max FPS supported by Codec for profile 4.1 is 30. + * When Dynamic Frame Rate is enabled, there might be scenario when FPS + * calculated is more than 30. Hence adding the check so that Dynamic Frame + * Rate set is never greater than the port FPS initially set. + */ + if(nTargetFrameRate > nPortFrameRate){ + DOMX_DEBUG("Frame Rate Calculated is more than initial port set Frame Rate"); + nTargetFrameRate = nPortFrameRate; + } + + /* Difference in Frame Rate is more than Threshold - Only then update Frame Rate*/ + if((( (OMX_S32)nTargetFrameRate) -((OMX_S32) nCurrentFrameRate) >= FRAME_RATE_THRESHOLD) || + (((OMX_S32) nCurrentFrameRate) - ( (OMX_S32)nTargetFrameRate) >= FRAME_RATE_THRESHOLD)) { + + /* Now Send the new Frame Rate */ + tFrameRate.nPortIndex = OMX_MPEG4E_INPUT_PORT; /* As per ducati support-set for input port */ + tFrameRate.xEncodeFramerate = (OMX_U32)(nTargetFrameRate * (1 << 16)); + eError = pHandle->SetConfig(hComponent,OMX_IndexConfigVideoFramerate,&tFrameRate); + if(eError != OMX_ErrorNone){ + DOMX_ERROR(" Error while configuring Dynamic Frame Rate,Error info = %d",eError); + return eError; + } else { + DOMX_DEBUG("Dynamic Frame Rate configuration successful \n"); + } + nFrameRateThreshold = nTargetFrameRate; /*Update the threshold */ + } + + /* reset all params */ + nFrameCounter = 0 ; + nVideoTime = 0; + nLastFrameRateUpdateTime = pBufferHdr->nTimeStamp; + return OMX_ErrorNone; +} + +static OMX_ERRORTYPE ComponentPrivateEmptyThisBuffer(OMX_HANDLETYPE hComponent, + OMX_BUFFERHEADERTYPE * pBufferHdr) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + + eError = OMX_ConfigureDynamicFrameRate(hComponent, pBufferHdr); + if( eError != OMX_ErrorNone) + DOMX_ERROR(" Error while configuring FrameRate Dynamically.Error info = %d",eError); + + DOMX_DEBUG("Redirection from ComponentPricateEmptyThisBuffer to PROXY_EmptyThisBuffer"); + return LOCAL_PROXY_MPEG4E_EmptyThisBuffer (hComponent,pBufferHdr); +} + OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent) { OMX_ERRORTYPE eError = OMX_ErrorNone; @@ -148,6 +279,10 @@ OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent) TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; OMX_PROXY_MPEG4E_PRIVATE *pProxy = NULL; #endif + char value[OMX_MAX_STRINGNAME_SIZE]; + OMX_U32 mEnableVFR = 1; /* Flag used to enable/disable VFR for Encoder */ + property_get("debug.vfr.enable", value, "1"); + mEnableVFR = atoi(value); DOMX_ENTER(""); @@ -220,6 +355,9 @@ OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent) pHandle->EmptyThisBuffer = LOCAL_PROXY_MPEG4E_EmptyThisBuffer; pHandle->GetExtensionIndex = LOCAL_PROXY_MPEG4E_GetExtensionIndex; + if(mEnableVFR) + pHandle->EmptyThisBuffer = ComponentPrivateEmptyThisBuffer; + EXIT: if (eError != OMX_ErrorNone) { @@ -510,7 +648,7 @@ OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_GetExtensionIndex(OMX_IN OMX_HANDLETYPE hCompon goto EXIT; } - PROXY_GetExtensionIndex(hComponent, cParameterName, pIndexType); + eError = PROXY_GetExtensionIndex(hComponent, cParameterName, pIndexType); EXIT: DOMX_EXIT("%s eError: %d",__FUNCTION__, eError); @@ -534,7 +672,7 @@ OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, OMX_ERRORTYPE eError = OMX_ErrorNone; PROXY_COMPONENT_PRIVATE *pCompPrv; OMX_COMPONENTTYPE *hComp = (OMX_COMPONENTTYPE *) hComponent; - OMX_PTR pBufferOrig = pBufferHdr->pBuffer; + OMX_PTR pBufferOrig = NULL; OMX_U32 nStride = 0, nNumLines = 0; OMX_PARAM_PORTDEFINITIONTYPE tParamStruct; OMX_U32 nFilledLen, nAllocLen; @@ -543,6 +681,11 @@ OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, TIMM_OSAL_ERRORTYPE eOSALStatus = TIMM_OSAL_ERR_NONE; OMX_U32 nBufIndex = 0, nSize=0, nRet=0; #endif +#ifdef ENABLE_GRALLOC_BUFFER + OMX_PTR pAuxBuf0 = NULL, pAuxBuf1 = NULL; + RPC_OMX_ERRORTYPE eRPCError = RPC_OMX_ErrorNone; + OMX_ERRORTYPE eCompReturn = OMX_ErrorNone; +#endif PROXY_require(pBufferHdr != NULL, OMX_ErrorBadParameter, NULL); PROXY_require(hComp->pComponentPrivate != NULL, OMX_ErrorBadParameter, @@ -650,8 +793,8 @@ OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, DOMX_DEBUG(" --COLORCONVERT_PlatformOpaqueToNV12() "); /* Update pBufferHdr with NV12 buffers for OMX component */ - pBufferHdr->pBuffer= pProxy->gralloc_handle[nBufIndex]->fd[0]; - ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)->pAuxBuf1 = pProxy->gralloc_handle[nBufIndex]->fd[1]; + pBufferHdr->pBuffer= (OMX_U8 *)(pProxy->gralloc_handle[nBufIndex]->fd[0]); + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)->pAuxBuf1 = (OMX_PTR)(pProxy->gralloc_handle[nBufIndex]->fd[1]); } #endif #endif @@ -660,9 +803,19 @@ OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, { return OMX_ErrorBadParameter; } +#ifdef ENABLE_GRALLOC_BUFFER + eRPCError = RPC_RegisterBuffer(pCompPrv->hRemoteComp, pBufferHdr->pBuffer, + &pAuxBuf0, &pAuxBuf1, + GrallocPointers); + PROXY_checkRpcError(); + if (pAuxBuf0) + pBufferHdr->pBuffer = pAuxBuf0; + if (pAuxBuf1) + ((OMX_TI_PLATFORMPRIVATE *) pBufferHdr->pPlatformPrivate)->pAuxBuf1 = pAuxBuf1; +#endif } - PROXY_EmptyThisBuffer(hComponent, pBufferHdr); + eError = PROXY_EmptyThisBuffer(hComponent, pBufferHdr); #ifdef ANDROID_CUSTOM_OPAQUECOLORFORMAT if (pProxy->bAndroidOpaqueFormat) { @@ -672,13 +825,14 @@ OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_EmptyThisBuffer(OMX_HANDLETYPE hComponent, PROXY_assert(eOSALStatus == TIMM_OSAL_ERR_NONE, OMX_ErrorBadParameter, "Pipe write failed"); } #endif - if( pCompPrv->proxyPortBuffers[pBufferHdr->nInputPortIndex].proxyBufferType == EncoderMetadataPointers) - { + + if( pCompPrv->proxyPortBuffers[pBufferHdr->nInputPortIndex].proxyBufferType == EncoderMetadataPointers) { pBufferHdr->pBuffer = pBufferOrig; - pBufferHdr->nFilledLen = nFilledLen; - pBufferHdr->nAllocLen = nAllocLen; +#ifdef ENABLE_GRALLOC_BUFFER + RPC_UnRegisterBuffer(pCompPrv->hRemoteComp, pAuxBuf0); + RPC_UnRegisterBuffer(pCompPrv->hRemoteComp, pAuxBuf1); +#endif } - EXIT: return eError; } @@ -715,8 +869,9 @@ static OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_AllocateBuffer(OMX_HANDLETYPE hComponent eError = PROXY_GetParameter(hComponent, (OMX_INDEXTYPE)OMX_TI_IndexParam2DBufferAllocDimension, &tParamRect); PROXY_assert(eError == OMX_ErrorNone, eError," Error in Proxy GetParameter from 2d index in allocate buffer"); - err = pProxy->mAllocDev->alloc(pProxy->mAllocDev,(int) tParamRect.nWidth,(int) tParamRect.nHeight, - (int) HAL_PIXEL_FORMAT_TI_NV12,(int) GRALLOC_USAGE_HW_RENDER, &(pProxy->gralloc_handle[pProxy->nCurBufIndex]), &nStride); + err = pProxy->mAllocDev->alloc(pProxy->mAllocDev,(int) tParamRect.nWidth,(int) tParamRect.nHeight, + (int) HAL_PIXEL_FORMAT_TI_NV12,(int) GRALLOC_USAGE_HW_RENDER, + (const struct native_handle_t **)(&(pProxy->gralloc_handle[pProxy->nCurBufIndex])), &nStride); } eError = PROXY_AllocateBuffer(hComponent, ppBufferHdr, nPortIndex, @@ -727,7 +882,7 @@ EXIT: { if(eError != OMX_ErrorNone) { - err = pProxy->mAllocDev->free(pProxy->mAllocDev, pProxy->gralloc_handle[pProxy->nCurBufIndex]); + err = pProxy->mAllocDev->free(pProxy->mAllocDev, (buffer_handle_t)(pProxy->gralloc_handle[pProxy->nCurBufIndex])); } else { @@ -764,7 +919,7 @@ static OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_FreeBuffer(OMX_IN OMX_HANDLETYPE hCompon if(pProxy->gralloc_handle[pProxy->nCurBufIndex]) { - pProxy->mAllocDev->free(pProxy->mAllocDev, pProxy->gralloc_handle[pProxy->nCurBufIndex]); + pProxy->mAllocDev->free(pProxy->mAllocDev, (buffer_handle_t)(pProxy->gralloc_handle[pProxy->nCurBufIndex])); pProxy->gralloc_handle[pProxy->nCurBufIndex] = NULL; } @@ -815,7 +970,7 @@ OMX_ERRORTYPE LOCAL_PROXY_MPEG4E_ComponentDeInit(OMX_HANDLETYPE hComponent) { if(pProxy->gralloc_handle[i]) { - pProxy->mAllocDev->free(pProxy->mAllocDev, pProxy->gralloc_handle[i]); + pProxy->mAllocDev->free(pProxy->mAllocDev, (buffer_handle_t)(pProxy->gralloc_handle[i])); pProxy->gralloc_handle[i] = NULL; } } |