Files
luban-lite-t3e-pro/packages/artinchip/mpp/middle_media/openmax/component/OMX_VideoRenderComponent.c
刘可亮 7bbc029dae v1.0.0
2023-08-30 16:21:18 +08:00

1555 lines
66 KiB
C

/*
* Copyright (C) 2020-2023 ArtInChip Technology Co. Ltd
*
* author: <jun.ma@artinchip.com>
* Desc: OMX_VideoRenderComponent
*/
#include "OMX_VideoRenderComponent.h"
#define aic_pthread_mutex_lock(mutex)\
{\
pthread_mutex_lock(mutex);\
}
#define aic_pthread_mutex_unlock(mutex)\
{\
pthread_mutex_unlock(mutex);\
}
#define OMX_VideoRenderListEmpty(list,mutex)\
({\
int ret = 0;\
aic_pthread_mutex_lock(&mutex);\
ret = mpp_list_empty(list);\
aic_pthread_mutex_unlock(&mutex);\
(ret);\
})
static OMX_S64 OMX_ClockGetSystemTime();
static OMX_ERRORTYPE OMX_VideoRenderSendCommand(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_COMMANDTYPE Cmd,
OMX_IN OMX_U32 nParam1,
OMX_IN OMX_PTR pCmdData);
static OMX_ERRORTYPE OMX_VideoRenderGetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR pComponentParameterStructure);
static OMX_ERRORTYPE OMX_VideoRenderSetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentParameterStructure);
static OMX_ERRORTYPE OMX_VideoRenderGetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR pComponentConfigStructure);
static OMX_ERRORTYPE OMX_VideoRenderSetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentConfigStructure);
static OMX_ERRORTYPE OMX_VideoRenderGetState(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STATETYPE* pState);
static OMX_ERRORTYPE OMX_VideoRenderComponentTunnelRequest(
OMX_IN OMX_HANDLETYPE hComp,
OMX_IN OMX_U32 nPort,
OMX_IN OMX_HANDLETYPE hTunneledComp,
OMX_IN OMX_U32 nTunneledPort,
OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup);
static OMX_ERRORTYPE OMX_VideoRenderEmptyThisBuffer(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
static OMX_ERRORTYPE OMX_VideoRenderFillThisBuffer(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
static OMX_ERRORTYPE OMX_VideoRenderSetCallbacks(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
OMX_IN OMX_PTR pAppData);
static OMX_ERRORTYPE OMX_VideoRenderSendCommand(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_COMMANDTYPE Cmd,
OMX_IN OMX_U32 nParam1,
OMX_IN OMX_PTR pCmdData)
{
VIDEO_RENDER_DATA_TYPE *pVideoRenderDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
struct aic_message sMsg;
pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
sMsg.message_id = Cmd;
sMsg.param = nParam1;
sMsg.data_size = 0;
//now not use always NULL
if(pCmdData != NULL)
{
sMsg.data = pCmdData;
sMsg.data_size = strlen((char*)pCmdData);
}
aic_msg_put(&pVideoRenderDataType->sMsgQue, &sMsg);
return eError;
}
static void* OMX_VideoRenderComponentThread(void* pThreadData);
static OMX_ERRORTYPE OMX_VideoRenderGetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR pComponentParameterStructure)
{
VIDEO_RENDER_DATA_TYPE *pVideoRenderDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
//OMX_U32 tmp1,tmp2;
OMX_S32 index =(OMX_S32)nParamIndex;
pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
switch (index){
case OMX_IndexParamPortDefinition:
break;
case OMX_IndexParamVideoAvc:
break;
case OMX_IndexParamVideoProfileLevelQuerySupported:
break;
case OMX_IndexParamVideoPortFormat:
break;
case OMX_IndexParamVideoProfileLevelCurrent:
break;
case OMX_IndexParamVideoMpeg4:
break;
case OMX_IndexParamCompBufferSupplier:{
OMX_PARAM_BUFFERSUPPLIERTYPE *sBufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE*)pComponentParameterStructure;
if(sBufferSupplier->nPortIndex == VIDEO_RENDER_PORT_IN_VIDEO_INDEX){
sBufferSupplier->eBufferSupplier = pVideoRenderDataType->sInBufSupplier[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].eBufferSupplier;
}else if(sBufferSupplier->nPortIndex == VIDEO_RENDER_PORT_IN_CLOCK_INDEX){
sBufferSupplier->eBufferSupplier = pVideoRenderDataType->sInBufSupplier[VIDEO_RENDER_PORT_IN_CLOCK_INDEX].eBufferSupplier;
}else{
loge("error nPortIndex\n");
eError = OMX_ErrorBadPortIndex;
}
break;
}
case OMX_IndexConfigCommonOutputCrop:
((OMX_CONFIG_RECTTYPE*)pComponentParameterStructure)->nLeft = pVideoRenderDataType->sDisRect.x;
((OMX_CONFIG_RECTTYPE*)pComponentParameterStructure)->nTop = pVideoRenderDataType->sDisRect.y;
((OMX_CONFIG_RECTTYPE*)pComponentParameterStructure)->nWidth = pVideoRenderDataType->sDisRect.width;
((OMX_CONFIG_RECTTYPE*)pComponentParameterStructure)->nHeight = pVideoRenderDataType->sDisRect.height;
break;
case OMX_IndexVendorVideoRenderScreenSize:{
struct mpp_size sSize;
if(pVideoRenderDataType->nVideoRenderInitFlag != 1){
loge("pVideoRenderDataType->render not init!!!\n");
eError = OMX_ErrorUndefined;
break;
}
pVideoRenderDataType->render->get_screen_size(pVideoRenderDataType->render,&sSize);
((OMX_PARAM_SCREEN_SIZE*)pComponentParameterStructure)->nWidth = sSize.width;
((OMX_PARAM_SCREEN_SIZE*)pComponentParameterStructure)->nHeight = sSize.height;
break;
}
default:
eError = OMX_ErrorNotImplemented;
break;
}
return eError;
}
static OMX_ERRORTYPE OMX_VideoRenderSetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_IN OMX_PTR pComponentParameterStructure)
{
VIDEO_RENDER_DATA_TYPE *pVideoRenderDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
//OMX_S32 tmp1,tmp2;
OMX_PARAM_FRAMEEND *sFrameEnd;
OMX_S32 index = (OMX_S32)nParamIndex;
pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
if(pComponentParameterStructure == NULL){
loge("param error!!!\n");
return OMX_ErrorBadParameter;
}
switch (index){
case OMX_IndexParamPortDefinition:
break;
case OMX_IndexParamVideoPortFormat:
break;
case OMX_IndexParamVideoAvc:
break;
case OMX_IndexParamVideoProfileLevelQuerySupported:
break;
case OMX_IndexParamVideoProfileLevelCurrent:
break;
case OMX_IndexParamVideoMpeg4:
break;
case OMX_IndexConfigCommonOutputCrop:
pVideoRenderDataType->sDisRect.x = ((OMX_CONFIG_RECTTYPE*)pComponentParameterStructure)->nLeft;
pVideoRenderDataType->sDisRect.y = ((OMX_CONFIG_RECTTYPE*)pComponentParameterStructure)->nTop;
pVideoRenderDataType->sDisRect.width = ((OMX_CONFIG_RECTTYPE*)pComponentParameterStructure)->nWidth;
pVideoRenderDataType->sDisRect.height =((OMX_CONFIG_RECTTYPE*)pComponentParameterStructure)->nHeight;
pVideoRenderDataType->nDisRectChange = OMX_TRUE;
break;
case OMX_IndexVendorStreamFrameEnd:
sFrameEnd = (OMX_PARAM_FRAMEEND*)pComponentParameterStructure;
if(sFrameEnd->bFrameEnd == OMX_TRUE){
pVideoRenderDataType->nFrameEndFlag = OMX_TRUE;
logi("setup nFrameEndFlag\n");
}else{
pVideoRenderDataType->nFrameEndFlag = OMX_FALSE;
logi("cancel nFrameEndFlag\n");
}
break;
default:
break;
}
return eError;
}
static OMX_ERRORTYPE OMX_VideoRenderGetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR pComponentConfigStructure)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
return eError;
}
static OMX_ERRORTYPE OMX_VideoRenderSetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentConfigStructure)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
int ret;
OMX_S32 index = (OMX_S32)nIndex;
switch (index){
case OMX_IndexConfigTimePosition:
//1 clear input buffer list
//2 reset firstshow flag
break;
case OMX_IndexConfigTimeSeekMode:
break;
case OMX_IndexConfigTimeClockState:{
OMX_TIME_CONFIG_CLOCKSTATETYPE* state = (OMX_TIME_CONFIG_CLOCKSTATETYPE *)pComponentConfigStructure;
pVideoRenderDataType->eClockState = state->eState;
printf("[%s:%d]pVideoRenderDataType->eClockState:%d\n",__FUNCTION__,__LINE__,pVideoRenderDataType->eClockState);
break;
}
case OMX_IndexVendorVideoRenderInit:
if(!pVideoRenderDataType->render){
ret = aic_video_render_create(&pVideoRenderDataType->render);
if(ret){
eError = OMX_ErrorInsufficientResources;
loge("aic_video_render_create error!!!!\n");
break;
}
ret = pVideoRenderDataType->render->init(pVideoRenderDataType->render,
pVideoRenderDataType->nLayerId,pVideoRenderDataType->nDevId);
if(!ret){
printf("[%s:%d]pVideoRenderDataType->render->init ok\n",__FUNCTION__,__LINE__);
pVideoRenderDataType->nVideoRenderInitFlag = 1;
}else{
loge("pVideoRenderDataType->render->init fail\n");
eError = OMX_ErrorInsufficientResources;
}
}else{
loge("pVideoRenderDataType->render has been created!!1!\n");
}
break;
default:
break;
}
return eError;
}
static OMX_ERRORTYPE OMX_VideoRenderGetState(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STATETYPE* pState)
{
VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
aic_pthread_mutex_lock(&pVideoRenderDataType->stateLock);
*pState = pVideoRenderDataType->state;
aic_pthread_mutex_unlock(&pVideoRenderDataType->stateLock);
return eError;
}
static OMX_ERRORTYPE OMX_VideoRenderComponentTunnelRequest(
OMX_IN OMX_HANDLETYPE hComp,
OMX_IN OMX_U32 nPort,
OMX_IN OMX_HANDLETYPE hTunneledComp,
OMX_IN OMX_U32 nTunneledPort,
OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
OMX_PARAM_PORTDEFINITIONTYPE *pPort;
OMX_PORT_TUNNELEDINFO *pTunneledInfo;
OMX_PARAM_BUFFERSUPPLIERTYPE *pBufSupplier;
VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType;
pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComp)->pComponentPrivate);
if(pVideoRenderDataType->state != OMX_StateLoaded)
{
loge("Component is not in OMX_StateLoaded,it is in%d,it can not tunnel\n",pVideoRenderDataType->state);
return OMX_ErrorInvalidState;
}
if(nPort == VIDEO_RENDER_PORT_IN_VIDEO_INDEX){
pPort = &pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_VIDEO_INDEX];
pTunneledInfo = &pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_VIDEO_INDEX];
pBufSupplier = &pVideoRenderDataType->sInBufSupplier[VIDEO_RENDER_PORT_IN_VIDEO_INDEX];
}else if(nPort == VIDEO_RENDER_PORT_IN_CLOCK_INDEX){
pPort = &pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_CLOCK_INDEX];
pTunneledInfo = &pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_CLOCK_INDEX];
pBufSupplier = &pVideoRenderDataType->sInBufSupplier[VIDEO_RENDER_PORT_IN_CLOCK_INDEX];
}else{
loge("component can not find port :%d,VIDEO_RENDER_PORT_IN_VIDEO_INDEX:%d\n",nPort,VIDEO_RENDER_PORT_IN_VIDEO_INDEX);
return OMX_ErrorBadParameter;
}
// cancle setup tunnel
if(NULL == hTunneledComp && 0 == nTunneledPort && NULL == pTunnelSetup){
pTunneledInfo->nTunneledFlag = OMX_FALSE;
pTunneledInfo->nTunnelPortIndex = nTunneledPort;
pTunneledInfo->pTunneledComp = hTunneledComp;
return OMX_ErrorNone;
}
if(pPort->eDir == OMX_DirOutput){
pTunneledInfo->nTunnelPortIndex = nTunneledPort;
pTunneledInfo->pTunneledComp = hTunneledComp;
pTunneledInfo->nTunneledFlag = OMX_TRUE;
pTunnelSetup->nTunnelFlags = 0;
pTunnelSetup->eSupplier = pBufSupplier->eBufferSupplier;
}else if(pPort->eDir == OMX_DirInput){
OMX_PARAM_PORTDEFINITIONTYPE sTunneledPort;
OMX_PARAM_BUFFERSUPPLIERTYPE sBuffSupplier;
sTunneledPort.nPortIndex = nTunneledPort;
sBuffSupplier.nPortIndex = nTunneledPort;
if (pTunnelSetup->eSupplier == OMX_BufferSupplyMax)
{
loge("both ports are input.\n");
return OMX_ErrorPortsNotCompatible;
}
OMX_GetParameter(hTunneledComp, OMX_IndexParamPortDefinition,&sTunneledPort);
if (pPort->eDomain != sTunneledPort.eDomain){
loge("ports domain are not compatible: %d %d.\n",
pPort->eDomain, sTunneledPort.eDomain);
return OMX_ErrorPortsNotCompatible;
}
if(sTunneledPort.eDir != OMX_DirOutput){
loge("both ports are input.\n");
return OMX_ErrorPortsNotCompatible;
}
//negotiate buffer supplier
OMX_GetParameter(hTunneledComp, OMX_IndexParamCompBufferSupplier,&sBuffSupplier);
if(sBuffSupplier.eBufferSupplier != pTunnelSetup->eSupplier){
loge("out_port and in_port supplier are different,please check code!!!!\n");
return OMX_ErrorPortsNotCompatible;
}
pTunneledInfo->nTunnelPortIndex = nTunneledPort;
pTunneledInfo->pTunneledComp = hTunneledComp;
pTunneledInfo->nTunneledFlag = OMX_TRUE;
pBufSupplier->eBufferSupplier = pTunnelSetup->eSupplier;
}else{
loge("port is neither output nor input.\n");
return OMX_ErrorPortsNotCompatible;
}
return eError;
}
static OMX_ERRORTYPE OMX_VideoRenderEmptyThisBuffer(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType;
VIDEO_RENDER_IN_FRAME *pFrame;
struct aic_message sMsg;
pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
aic_pthread_mutex_lock(&pVideoRenderDataType->stateLock);
if(pVideoRenderDataType->state != OMX_StateExecuting && (pVideoRenderDataType->state != OMX_StateIdle)){
logw("component is not in OMX_StateExecuting,it is in [%d]!!!\n",pVideoRenderDataType->state);
aic_pthread_mutex_unlock(&pVideoRenderDataType->stateLock);
return OMX_ErrorIncorrectStateOperation;
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->stateLock);
// if(OMX_VideoRenderListEmpty(&pVideoRenderDataType->sInEmptyFrame,pVideoRenderDataType->sInFrameLock))
// {
// if(pVideoRenderDataType->nInFrameNodeNum + 1> VIDEO_RENDER_FRAME_NUM_MAX){
// loge("empty node has aready increase to max [%d]!!!\n",pVideoRenderDataType->nInFrameNodeNum);
// eError = OMX_ErrorInsufficientResources;
// return eError;
// }else{
// int i;
// loge("no empty node,need to extend!!!\n");
// for(i =0 ; i < VIDEO_RENDER_FRAME_ONE_TIME_CREATE_NUM; i++ ){
// VIDEO_RENDER_IN_FRAME *pFrameNode = (VIDEO_RENDER_IN_FRAME*)mpp_alloc(sizeof(VIDEO_RENDER_IN_FRAME));
// if(NULL == pFrameNode){
// break;
// }
// memset(pFrameNode,0x00,sizeof(VIDEO_RENDER_IN_FRAME));
// aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
// mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInEmptyFrame);
// aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
// pVideoRenderDataType->nInFrameNodeNum++;
// }
// if(i == 0){
// loge("mpp_alloc empty video node fail\n");
// eError = OMX_ErrorInsufficientResources;
// return eError;
// }
// }
// }
if(OMX_VideoRenderListEmpty(&pVideoRenderDataType->sInEmptyFrame,pVideoRenderDataType->sInFrameLock)){
VIDEO_RENDER_IN_FRAME *pFrameNode = (VIDEO_RENDER_IN_FRAME*)mpp_alloc(sizeof(VIDEO_RENDER_IN_FRAME));
if(NULL == pFrameNode){
loge("OMX_ErrorInsufficientResources\n");
return OMX_ErrorInsufficientResources;
}
memset(pFrameNode,0x00,sizeof(VIDEO_RENDER_IN_FRAME));
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInEmptyFrame);
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
pVideoRenderDataType->nInFrameNodeNum++;
}
if(pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].nTunneledFlag){// now Tunneled and non-Tunneled are same
// static struct timespec pev = {0},cur = {0};
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
pFrame = mpp_list_first_entry(&pVideoRenderDataType->sInEmptyFrame, VIDEO_RENDER_IN_FRAME, sList);
memcpy(&pFrame->sFrameInfo,pBuffer->pBuffer,sizeof(struct mpp_frame));
mpp_list_del(&pFrame->sList);
mpp_list_add_tail(&pFrame->sList, &pVideoRenderDataType->sInReadyFrame);
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
pVideoRenderDataType->nReceiveFrameNum++;
logd("nReceiveFrameNum:%d\n",pVideoRenderDataType->nReceiveFrameNum);
{
static int nRenderFrameNum = 0;
static struct timespec pre = {0},cur = {0};
long diff;
int nCnt = 0;
VIDEO_RENDER_IN_FRAME *pFrameNode;
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
mpp_list_for_each_entry(pFrameNode, &pVideoRenderDataType->sInReadyFrame, sList){
nCnt++;
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
nRenderFrameNum++;
clock_gettime(CLOCK_REALTIME,&cur);
diff = (cur.tv_sec - pre.tv_sec)*1000*1000 + (cur.tv_nsec - pre.tv_nsec)/1000;
if(diff > 1*1000*1000){
//printf("[%s:%d]:%ld:%d:%d\n",__FUNCTION__,__LINE__,diff,nRenderFrameNum,nCnt);
pre = cur;
nRenderFrameNum = 0;
}
}
}else{ // now Tunneled and non-Tunneled are same
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
pFrame = mpp_list_first_entry(&pVideoRenderDataType->sInEmptyFrame, VIDEO_RENDER_IN_FRAME, sList);
memcpy(&pFrame->sFrameInfo,pBuffer->pBuffer,sizeof(struct mpp_frame));
mpp_list_del(&pFrame->sList);
mpp_list_add_tail(&pFrame->sList, &pVideoRenderDataType->sInReadyFrame);
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
pVideoRenderDataType->nReceiveFrameNum++;
logw("nReceiveFrameNum:%d\n",pVideoRenderDataType->nReceiveFrameNum);
}
aic_pthread_mutex_lock(&pVideoRenderDataType->sWaitReayFrameLock);
if(pVideoRenderDataType->nWaitReayFrameFlag){
sMsg.message_id = OMX_CommandNops;
sMsg.data_size = 0;
aic_msg_put(&pVideoRenderDataType->sMsgQue, &sMsg);
pVideoRenderDataType->nWaitReayFrameFlag = 0;
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->sWaitReayFrameLock);
return eError;
#if 0
pFrame->sFrameInfo.flags = pFrame1->sFrameInfo.flags;
pFrame->sFrameInfo.id = pFrame1->sFrameInfo.id;
pFrame->sFrameInfo.pts = pFrame1->sFrameInfo.pts;
pFrame->sFrameInfo.buf.buf_type = pFrame1->sFrameInfo.buf.buf_type;
pFrame->sFrameInfo.buf.crop.x = pFrame1->sFrameInfo.buf.crop.x;
pFrame->sFrameInfo.buf.crop.y = pFrame1->sFrameInfo.buf.crop.y;
pFrame->sFrameInfo.buf.crop.width = pFrame1->sFrameInfo.buf.crop.width;
pFrame->sFrameInfo.buf.crop.height = pFrame1->sFrameInfo.buf.crop.height;
pFrame->sFrameInfo.buf.crop_en = pFrame1->sFrameInfo.buf.crop_en;
pFrame->sFrameInfo.buf.phy_addr[0] = pFrame1->sFrameInfo.buf.phy_addr[0];
pFrame->sFrameInfo.buf.phy_addr[1] = pFrame1->sFrameInfo.buf.phy_addr[1];
pFrame->sFrameInfo.buf.phy_addr[2] = pFrame1->sFrameInfo.buf.phy_addr[2];
pFrame->sFrameInfo.buf.fd[0] = pFrame1->sFrameInfo.buf.fd[0];
pFrame->sFrameInfo.buf.fd[1] = pFrame1->sFrameInfo.buf.fd[1];
pFrame->sFrameInfo.buf.fd[2] = pFrame1->sFrameInfo.buf.fd[2];
pFrame->sFrameInfo.buf.flags = pFrame1->sFrameInfo.buf.flags;
pFrame->sFrameInfo.buf.format = pFrame1->sFrameInfo.buf.format;
pFrame->sFrameInfo.buf.size.width = pFrame1->sFrameInfo.buf.size.width;
pFrame->sFrameInfo.buf.size.height = pFrame1->sFrameInfo.buf.size.height;
pFrame->sFrameInfo.buf.stride[0] = pFrame1->sFrameInfo.buf.stride[0];
pFrame->sFrameInfo.buf.stride[1] = pFrame1->sFrameInfo.buf.stride[1];
pFrame->sFrameInfo.buf.stride[2] = pFrame1->sFrameInfo.buf.stride[2];
#endif
}
static OMX_ERRORTYPE OMX_VideoRenderFillThisBuffer(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
return eError;
}
static OMX_ERRORTYPE OMX_VideoRenderSetCallbacks(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
OMX_IN OMX_PTR pAppData)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType;
pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
pVideoRenderDataType->pCallbacks = pCallbacks;
pVideoRenderDataType->pAppData = pAppData;
return eError;
}
OMX_ERRORTYPE OMX_VideoRenderComponentDeInit(
OMX_IN OMX_HANDLETYPE hComponent) {
OMX_ERRORTYPE eError = OMX_ErrorNone;
OMX_COMPONENTTYPE *pComp;
VIDEO_RENDER_DATA_TYPE *pVideoRenderDataType;
VIDEO_RENDER_IN_FRAME *pFrameNode = NULL,*pFrameNode1 = NULL;
pComp = (OMX_COMPONENTTYPE *)hComponent;
struct aic_message sMsg;
pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)pComp->pComponentPrivate;
aic_pthread_mutex_lock(&pVideoRenderDataType->stateLock);
if(pVideoRenderDataType->state != OMX_StateLoaded){
logw("compoent is in %d,but not in OMX_StateLoaded(1),can ont FreeHandle.\n",pVideoRenderDataType->state);
aic_pthread_mutex_unlock(&pVideoRenderDataType->stateLock);
return OMX_ErrorIncorrectStateOperation;
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->stateLock);
sMsg.message_id = OMX_CommandStop;
sMsg.data_size = 0;
aic_msg_put(&pVideoRenderDataType->sMsgQue, &sMsg);
pthread_join(pVideoRenderDataType->threadId, (void*)&eError);
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
if(!mpp_list_empty(&pVideoRenderDataType->sInEmptyFrame)){
mpp_list_for_each_entry_safe(pFrameNode, pFrameNode1, &pVideoRenderDataType->sInEmptyFrame, sList){
mpp_list_del(&pFrameNode->sList);
mpp_free(pFrameNode);
}
}
if(!mpp_list_empty(&pVideoRenderDataType->sInReadyFrame)){
mpp_list_for_each_entry_safe(pFrameNode, pFrameNode1, &pVideoRenderDataType->sInReadyFrame, sList){
mpp_list_del(&pFrameNode->sList);
mpp_free(pFrameNode);
}
}
if(!mpp_list_empty(&pVideoRenderDataType->sInProcessedFrmae)){
mpp_list_for_each_entry_safe(pFrameNode, pFrameNode1, &pVideoRenderDataType->sInProcessedFrmae, sList){
mpp_list_del(&pFrameNode->sList);
mpp_free(pFrameNode);
}
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
pthread_mutex_destroy(&pVideoRenderDataType->sInFrameLock);
pthread_mutex_destroy(&pVideoRenderDataType->stateLock);
aic_msg_destroy(&pVideoRenderDataType->sMsgQue);
if (pVideoRenderDataType->render) {
pVideoRenderDataType->render->set_on_off(pVideoRenderDataType->render,0);
aic_video_render_destroy(pVideoRenderDataType->render);
pVideoRenderDataType->render = NULL;
}
mpp_free(pVideoRenderDataType);
pVideoRenderDataType = NULL;
logw("OMX_VideoRenderComponentDeInit\n");
return eError;
}
static int dec_thread_attr_init(pthread_attr_t *attr)
{
// default stack size is 2K, it is not enough for decode thread
if (attr == NULL) {
return EINVAL;
}
pthread_attr_init(attr);
attr->stacksize = 16*1024;
//attr->schedparam.sched_priority = 23;
attr->schedparam.sched_priority = 21;
return 0;
}
OMX_ERRORTYPE OMX_VideoRenderComponentInit(
OMX_IN OMX_HANDLETYPE hComponent)
{
OMX_COMPONENTTYPE *pComp;
VIDEO_RENDER_DATA_TYPE *pVideoRenderDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
OMX_U32 err;
OMX_U32 i;
//OMX_U32 cnt;
pthread_attr_t *attr = NULL;
attr = (pthread_attr_t*)mpp_alloc(sizeof(pthread_attr_t));
dec_thread_attr_init(attr);
logw("OMX_VideoRenderComponentInit....");
pComp = (OMX_COMPONENTTYPE *)hComponent;
pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE *)mpp_alloc(sizeof(VIDEO_RENDER_DATA_TYPE));
if (NULL == pVideoRenderDataType) {
loge("mpp_alloc(sizeof(VIDEO_RENDER_DATA_TYPE) fail!");
eError = OMX_ErrorInsufficientResources;
goto _EXIT1;
}
memset(pVideoRenderDataType, 0x0, sizeof(VIDEO_RENDER_DATA_TYPE));
pComp->pComponentPrivate = (void*) pVideoRenderDataType;
pVideoRenderDataType->nFrameFisrtShowFlag = OMX_TRUE;
pVideoRenderDataType->state = OMX_StateLoaded;
pVideoRenderDataType->hSelf = pComp;
pComp->SetCallbacks = OMX_VideoRenderSetCallbacks;
pComp->SendCommand = OMX_VideoRenderSendCommand;
pComp->GetState = OMX_VideoRenderGetState;
pComp->GetParameter = OMX_VideoRenderGetParameter;
pComp->SetParameter = OMX_VideoRenderSetParameter;
pComp->GetConfig = OMX_VideoRenderGetConfig;
pComp->SetConfig = OMX_VideoRenderSetConfig;
pComp->ComponentTunnelRequest = OMX_VideoRenderComponentTunnelRequest;
pComp->ComponentDeInit = OMX_VideoRenderComponentDeInit;
pComp->FillThisBuffer = OMX_VideoRenderFillThisBuffer;
pComp->EmptyThisBuffer = OMX_VideoRenderEmptyThisBuffer;
pVideoRenderDataType->sPortParam.nPorts = 2;
pVideoRenderDataType->sPortParam.nStartPortNumber = 0x0;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].nPortIndex = VIDEO_RENDER_PORT_IN_VIDEO_INDEX;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].bPopulated = OMX_TRUE;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].bEnabled = OMX_TRUE;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].eDomain = OMX_PortDomainVideo;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].eDir = OMX_DirInput;
pVideoRenderDataType->sInBufSupplier[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].nPortIndex = 0x0;
pVideoRenderDataType->sInBufSupplier[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].eBufferSupplier = OMX_BufferSupplyOutput;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_CLOCK_INDEX].nPortIndex = VIDEO_RENDER_PORT_IN_CLOCK_INDEX;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_CLOCK_INDEX].bPopulated = OMX_TRUE;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_CLOCK_INDEX].bEnabled = OMX_TRUE;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_CLOCK_INDEX].eDomain = OMX_PortDomainOther;
pVideoRenderDataType->sInPortDef[VIDEO_RENDER_PORT_IN_CLOCK_INDEX].eDir = OMX_DirInput;
pVideoRenderDataType->sInBufSupplier[VIDEO_RENDER_PORT_IN_CLOCK_INDEX].nPortIndex = 0x0;
pVideoRenderDataType->sInBufSupplier[VIDEO_RENDER_PORT_IN_CLOCK_INDEX].eBufferSupplier = OMX_BufferSupplyOutput;
pVideoRenderDataType->nInFrameNodeNum = 0;
mpp_list_init(&pVideoRenderDataType->sInEmptyFrame);
mpp_list_init(&pVideoRenderDataType->sInReadyFrame);
mpp_list_init(&pVideoRenderDataType->sInProcessedFrmae);
pthread_mutex_init(&pVideoRenderDataType->sInFrameLock, NULL);
for(i =0 ; i < VIDEO_RENDER_FRAME_ONE_TIME_CREATE_NUM; i++ ){
VIDEO_RENDER_IN_FRAME *pFrameNode = (VIDEO_RENDER_IN_FRAME*)mpp_alloc(sizeof(VIDEO_RENDER_IN_FRAME));
if(NULL == pFrameNode){
break;
}
memset(pFrameNode,0x00,sizeof(VIDEO_RENDER_IN_FRAME));
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInEmptyFrame);
pVideoRenderDataType->nInFrameNodeNum++;
}
if(pVideoRenderDataType->nInFrameNodeNum == 0){
loge("mpp_alloc empty video node fail\n");
eError = OMX_ErrorInsufficientResources;
goto _EXIT2;
}
if(aic_msg_create(&pVideoRenderDataType->sMsgQue)<0)
{
loge("aic_msg_create fail!");
eError = OMX_ErrorInsufficientResources;
goto _EXIT4;
}
pVideoRenderDataType->eClockState = OMX_TIME_ClockStateStopped;
pthread_mutex_init(&pVideoRenderDataType->sWaitReayFrameLock, NULL);
pthread_mutex_init(&pVideoRenderDataType->stateLock, NULL);
// Create the component thread
err = pthread_create(&pVideoRenderDataType->threadId, attr, OMX_VideoRenderComponentThread, pVideoRenderDataType);
//if (err || !pVideoRenderDataType->threadId)
if (err)
{
loge("pthread_create fail!");
eError = OMX_ErrorInsufficientResources;
goto _EXIT5;
}
return eError;
_EXIT5:
aic_msg_destroy(&pVideoRenderDataType->sMsgQue);
pthread_mutex_destroy(&pVideoRenderDataType->stateLock);
_EXIT4:
if(!mpp_list_empty(&pVideoRenderDataType->sInEmptyFrame)){
VIDEO_RENDER_IN_FRAME *pFrameNode = NULL,*pFrameNode1 = NULL;
mpp_list_for_each_entry_safe(pFrameNode, pFrameNode1, &pVideoRenderDataType->sInEmptyFrame, sList){
mpp_list_del(&pFrameNode->sList);
mpp_free(pFrameNode);
}
}
_EXIT2:
if(pVideoRenderDataType){
mpp_free(pVideoRenderDataType);
pVideoRenderDataType = NULL;
}
_EXIT1:
return eError;
}
static void OMX_VideoRenderEventNotify(
VIDEO_RENDER_DATA_TYPE * pVideoRenderDataType,
OMX_EVENTTYPE event,
OMX_U32 nData1,
OMX_U32 nData2,
OMX_PTR pEventData)
{
if(pVideoRenderDataType && pVideoRenderDataType->pCallbacks && pVideoRenderDataType->pCallbacks->EventHandler) {
pVideoRenderDataType->pCallbacks->EventHandler(
pVideoRenderDataType->hSelf,
pVideoRenderDataType->pAppData,event,
nData1, nData2, pEventData);
}
}
static void OMX_VideoRenderStateChangeToInvalid(VIDEO_RENDER_DATA_TYPE * pVideoRenderDataType)
{
pVideoRenderDataType->state = OMX_StateInvalid;
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventError
,OMX_ErrorInvalidState,0,NULL);
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
,pVideoRenderDataType->state,NULL);
}
static void OMX_VideoRenderStateChangeToLoaded(VIDEO_RENDER_DATA_TYPE * pVideoRenderDataType)
{
int ret;
if(pVideoRenderDataType->state == OMX_StateIdle){
// 1 move ready node to using list
logi("Before OMX_VideoRenderComponentThread exit,move node in sInReadyFrame to sInProcessedFrmae\n");
if(!OMX_VideoRenderListEmpty(&pVideoRenderDataType->sInReadyFrame,pVideoRenderDataType->sInFrameLock)){
VIDEO_RENDER_IN_FRAME *pFrameNode,*pFrameNode1;
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
mpp_list_for_each_entry_safe(pFrameNode, pFrameNode1, &pVideoRenderDataType->sInReadyFrame, sList){
pVideoRenderDataType->nLeftReadyFrameWhenCompoentExitNum++;
mpp_list_del(&pFrameNode->sList);
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInProcessedFrmae);
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
}
// 2 give back frames in using list to vdec or app
logi("Before OMX_AudioRenderComponentThread exit,give all frames back to Vdec\n");
if(!OMX_VideoRenderListEmpty(&pVideoRenderDataType->sInProcessedFrmae,pVideoRenderDataType->sInFrameLock)){
VIDEO_RENDER_IN_FRAME *pFrameNode = NULL;
OMX_BUFFERHEADERTYPE sBuffHead;
while(!OMX_VideoRenderListEmpty(&pVideoRenderDataType->sInProcessedFrmae,pVideoRenderDataType->sInFrameLock)){
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
pFrameNode = mpp_list_first_entry(&pVideoRenderDataType->sInProcessedFrmae, VIDEO_RENDER_IN_FRAME, sList);
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
ret = -1;
if(pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].nTunneledFlag){
sBuffHead.nInputPortIndex = VIDEO_RENDER_PORT_IN_VIDEO_INDEX;
sBuffHead.nOutputPortIndex = pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].nTunnelPortIndex;
sBuffHead.pBuffer = (OMX_U8 *)&pFrameNode->sFrameInfo;
ret = OMX_FillThisBuffer(pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_VIDEO_INDEX].pTunneledComp,&sBuffHead);
}else{
if(pVideoRenderDataType->pCallbacks != NULL && pVideoRenderDataType->pCallbacks->EmptyBufferDone!= NULL){
sBuffHead.pBuffer = (OMX_U8 *)&pFrameNode->sFrameInfo;
ret = pVideoRenderDataType->pCallbacks->EmptyBufferDone(pVideoRenderDataType->hSelf,pVideoRenderDataType->pAppData,&sBuffHead);
}
}
if(ret == 0){ // how to do
logd("give back frame to vdec ok");
pVideoRenderDataType->nGiveBackFrameOkNum++;
}else{
logw("give back frame to vdec fail\n");
pVideoRenderDataType->nGiveBackFrameFailNum++;
}
logi("nGiveBackFrameOkNum:%d,nGiveBackFrameFailNum:%d\n"
,pVideoRenderDataType->nGiveBackFrameOkNum
,pVideoRenderDataType->nGiveBackFrameFailNum);
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
mpp_list_del(&pFrameNode->sList);
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInEmptyFrame);
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
}
}
}else if(pVideoRenderDataType->state == OMX_StateExecuting){
}else if(pVideoRenderDataType->state == OMX_StatePause){
}else {
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
,pVideoRenderDataType->state,NULL);
return;
}
pVideoRenderDataType->state = OMX_StateLoaded;
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
,pVideoRenderDataType->state,NULL);
}
static void OMX_VideoRenderStateChangeToIdle(VIDEO_RENDER_DATA_TYPE * pVideoRenderDataType)
{
int ret = 0;
if(pVideoRenderDataType->state == OMX_StateLoaded){
//create video_handle
if(!pVideoRenderDataType->render){
ret = aic_video_render_create(&pVideoRenderDataType->render);
}
if(ret != 0){
loge("aic_video_render_create fail\n");
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
,pVideoRenderDataType->state,NULL);
return;
}
}else if(pVideoRenderDataType->state == OMX_StatePause){
}else if(pVideoRenderDataType->state == OMX_StateExecuting){
}else{
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
,pVideoRenderDataType->state,NULL);
return;
}
pVideoRenderDataType->state = OMX_StateIdle;
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
,pVideoRenderDataType->state,NULL);
}
static void OMX_VideoRenderStateChangeToPause(VIDEO_RENDER_DATA_TYPE * pVideoRenderDataType)
{
OMX_PORT_TUNNELEDINFO *pTunneldClock = &pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_CLOCK_INDEX];
if(pVideoRenderDataType->state == OMX_StateLoaded){
}else if(pVideoRenderDataType->state == OMX_StateIdle){
}else if(pVideoRenderDataType->state == OMX_StateExecuting){
OMX_TIME_CONFIG_TIMESTAMPTYPE sTimeStamp;
if(pTunneldClock->nTunneledFlag){
OMX_GetConfig(pTunneldClock->pTunneledComp,OMX_IndexConfigTimeCurrentMediaTime, &sTimeStamp);
printf("[%s:%d]Excuting--->Pause,sTimeStamp:%ld\n",__FUNCTION__,__LINE__,sTimeStamp.nTimestamp);
}else{
pVideoRenderDataType->sPauseTimePoint = OMX_ClockGetSystemTime();
printf("[%s:%d]Excuting--->Pause,sPauseTimePoint:%ld\n",__FUNCTION__,__LINE__,pVideoRenderDataType->sPauseTimePoint);
}
}else{
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
,pVideoRenderDataType->state,NULL);
return;
}
pVideoRenderDataType->state = OMX_StatePause;
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
,pVideoRenderDataType->state,NULL);
}
static void OMX_VideoRenderStateChangeToExecuting(VIDEO_RENDER_DATA_TYPE * pVideoRenderDataType)
{
if(pVideoRenderDataType->state == OMX_StateLoaded){
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
,pVideoRenderDataType->state,NULL);
return;
}else if(pVideoRenderDataType->state == OMX_StateIdle){
}else if(pVideoRenderDataType->state == OMX_StatePause){
OMX_TIME_CONFIG_TIMESTAMPTYPE sTimeStamp;
OMX_PORT_TUNNELEDINFO *pTunneldClock = &pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_CLOCK_INDEX];
if(pTunneldClock->nTunneledFlag){
OMX_GetConfig(pTunneldClock->pTunneledComp,OMX_IndexConfigTimeCurrentMediaTime, &sTimeStamp);
printf("[%s:%d]Pause--->Excuting,sTimeStamp:%ld\n",__FUNCTION__,__LINE__,sTimeStamp.nTimestamp);
}else{
pVideoRenderDataType->sPauseTimeDurtion += (OMX_ClockGetSystemTime() - pVideoRenderDataType->sPauseTimePoint);
printf("[%s:%d]Pause--->Excuting,sPauseTimePoint:%ld,curTime:%ld,pauseDura:%ld\n"
,__FUNCTION__,__LINE__,pVideoRenderDataType->sPauseTimePoint,OMX_ClockGetSystemTime(),pVideoRenderDataType->sPauseTimeDurtion);
}
}else{
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
,pVideoRenderDataType->state,NULL);
return;
}
pVideoRenderDataType->state = OMX_StateExecuting;
OMX_VideoRenderEventNotify(pVideoRenderDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
,pVideoRenderDataType->state,NULL);
}
static OMX_S64 OMX_ClockGetSystemTime()
{
struct timespec ts = {0,0};
OMX_S64 tick = 0;
//clock_gettime(CLOCK_MONOTONIC,&ts);
clock_gettime(CLOCK_REALTIME,&ts);
tick = ts.tv_sec*1000000 + ts.tv_nsec/1000;
return tick;
}
/*
static int OMX_VideoRenderDumpPic(struct mpp_buf* video,int index)
{
int i;
int data_size[3] = {0, 0, 0};
unsigned char* hw_data[3] = {0};
int comp = 3;
FILE* fp_save = NULL;
char fileName[255] = {0};
if(video->format == MPP_FMT_YUV420P) {
comp = 3;
data_size[0] = video->size.height * video->stride[0];
data_size[1] = data_size[2] = data_size[0]/4;
} else if(video->format == MPP_FMT_NV12 || video->format == MPP_FMT_NV21) {
comp = 2;
data_size[0] = video->size.height * video->stride[0];
data_size[1] = data_size[0]/2;
} else if(video->format == MPP_FMT_YUV444P) {
comp = 3;
data_size[0] = video->size.height * video->stride[0];
data_size[1] = data_size[2] = data_size[0];
} else if(video->format == MPP_FMT_YUV422P) {
comp = 3;
data_size[0] = video->size.height * video->stride[0];
data_size[1] = data_size[2] = data_size[0]/2;
} else if(video->format == MPP_FMT_RGBA_8888 || video->format == MPP_FMT_BGRA_8888
|| video->format == MPP_FMT_ARGB_8888 || video->format == MPP_FMT_ABGR_8888) {
comp = 1;
data_size[0] = video->size.height * video->stride[0];
} else if(video->format == MPP_FMT_RGB_888 || video->format == MPP_FMT_BGR_888) {
comp = 1;
data_size[0] = video->size.height * video->stride[0];
} else if(video->format == MPP_FMT_RGB_565 || video->format == MPP_FMT_BGR_565) {
comp = 1;
data_size[0] = video->size.height * video->stride[0];
}
loge("data_size: %d %d %d, height: %d, stride: %d, format: %d",
data_size[0], data_size[1], data_size[2],
video->size.height, video->stride[0], video->format);
snprintf(fileName,sizeof(fileName),"Pic%d.yuv",index);
fp_save = fopen(fileName, "wb");
if(fp_save == NULL){
loge("fopen %s error\n",fileName);
return -1;
}
loge("fopen %s ok\n",fileName);
// mmap dmabuf to virtual space and save the frame yuv data
for(i=0; i<comp; i++) {
hw_data[i] = mmap(NULL, data_size[i], PROT_READ, MAP_SHARED, video->fd[i], 0);
if (hw_data[i] == MAP_FAILED) {
loge("dmabuf alloc mmap failed!");
return -1;
}
if(fp_save)
fwrite(hw_data[i], 1, data_size[i], fp_save);
}
fclose(fp_save);
for(i=0; i<comp; i++) {
munmap(hw_data[i], data_size[i]);
}
return 0;
}
*/
typedef enum OMX_VIDEO_SYNC_TYPE{
OMX_VIDEO_SYNC_INVAILD = -1,
OMX_VIDEO_SYNC_DROP = 0,
OMX_VIDEO_SYNC_DEALY,
OMX_VIDEO_SYNC_SHOW,
}OMX_VIDEO_SYNC_TYPE;
static OMX_TICKS OMX_VdieoRenderGetMediaTime(VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType)
{
OMX_TICKS sMeidaTime;
sMeidaTime = OMX_ClockGetSystemTime()- pVideoRenderDataType->sWallTimeBase
- pVideoRenderDataType->sPauseTimeDurtion + pVideoRenderDataType->sFisrtShowPts;
return sMeidaTime;
}
static void OMX_VdieoRenderSetMediaClock(VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType,struct mpp_frame *pFrameInfo)
{
pVideoRenderDataType->sWallTimeBase = OMX_ClockGetSystemTime();
pVideoRenderDataType->sPauseTimeDurtion = 0;
pVideoRenderDataType->sFisrtShowPts = pFrameInfo->pts;
pVideoRenderDataType->sPreFramePts = pFrameInfo->pts;
logw("pVideoRenderDataType->sFisrtShowPts:%ld,pVideoRenderDataType->sWallTimeBase:%ld\n"
,pVideoRenderDataType->sFisrtShowPts
,pVideoRenderDataType->sWallTimeBase);
}
static int OMX_GiveBackProcessedFrames(VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType){
int ret = 0;
OMX_S32 nCntInUsingList = 0;
VIDEO_RENDER_IN_FRAME *pFrameNode;
OMX_PORT_TUNNELEDINFO *pTunneldVideo;
pTunneldVideo = &pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_VIDEO_INDEX];
mpp_list_for_each_entry(pFrameNode, &pVideoRenderDataType->sInProcessedFrmae, sList){
nCntInUsingList++;
}
while(nCntInUsingList > 1){
OMX_BUFFERHEADERTYPE sBuffHead;
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
pFrameNode = mpp_list_first_entry(&pVideoRenderDataType->sInProcessedFrmae, VIDEO_RENDER_IN_FRAME, sList);
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
ret = -1;
if(pTunneldVideo->nTunneledFlag){
sBuffHead.pBuffer = (OMX_U8 *)&pFrameNode->sFrameInfo;
sBuffHead.nInputPortIndex = VIDEO_RENDER_PORT_IN_VIDEO_INDEX;
sBuffHead.nOutputPortIndex = pTunneldVideo->nTunnelPortIndex;
ret = OMX_FillThisBuffer(pTunneldVideo->pTunneledComp,&sBuffHead);
}else{
sBuffHead.pBuffer = (OMX_U8 *)&pFrameNode->sFrameInfo;
if(pVideoRenderDataType->pCallbacks->EmptyBufferDone){
ret = pVideoRenderDataType->pCallbacks->EmptyBufferDone(pVideoRenderDataType->hSelf
,pVideoRenderDataType->pAppData,&sBuffHead);
}
}
if(ret == 0){
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
mpp_list_del(&pFrameNode->sList);
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInEmptyFrame);
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
pVideoRenderDataType->nGiveBackFrameOkNum++;
logd("give back frame to vdec ok");
nCntInUsingList--;
}else{ // how to do ,do nothing or move to empty list,now move to empty list
logw("give back frame to vdec fail\n");
pVideoRenderDataType->nGiveBackFrameFailNum++;
break;
}
logi("nGiveBackFrameOkNum:%d,nGiveBackFrameFailNum:%d\n"
,pVideoRenderDataType->nGiveBackFrameOkNum,pVideoRenderDataType->nGiveBackFrameFailNum);
}
return ret;
}
#define MAX_DIFFF_TIME (10*1000) // 5ms need to to discuss
static OMX_VIDEO_SYNC_TYPE OMX_VdieoRenderProcessVideoSync(VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType,struct mpp_frame *pFrameInfo,OMX_TICKS *nDelay)
{
OMX_TICKS sDelayime;
OMX_TIME_CONFIG_TIMESTAMPTYPE sTimeStamp;
OMX_VIDEO_SYNC_TYPE eSyncType;
OMX_PORT_TUNNELEDINFO *pTunneldClock = &pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_CLOCK_INDEX];
if(pVideoRenderDataType == NULL || pFrameInfo == NULL || nDelay == NULL){
return OMX_VIDEO_SYNC_INVAILD;
}
if(pTunneldClock->nTunneledFlag){
sTimeStamp.nPortIndex = pTunneldClock->nTunnelPortIndex;
OMX_GetConfig(pTunneldClock->pTunneledComp,OMX_IndexConfigTimeCurrentMediaTime, &sTimeStamp);
if(sTimeStamp.nTimestamp == -1){
/*
1 need to define valid pts,suppose pts = -1.
2 after start up or seek, audio do not come yet,so get media time is invaild.
when vaild audio do not come,control by video self
*/
sDelayime = pFrameInfo->pts - OMX_VdieoRenderGetMediaTime(pVideoRenderDataType);
//
if(sDelayime > 10*1000*1000 || sDelayime < -10*1000*1000){
loge("tunneld clock ,but audio do not come ,vidoe pts jump event!!!\n");
sDelayime = 40*1000;//this should arccording to fame rate
OMX_VdieoRenderSetMediaClock(pVideoRenderDataType,pFrameInfo);
}
}else{
sDelayime = pFrameInfo->pts - sTimeStamp.nTimestamp;
// if(sDelayime > 100*1000 || sDelayime <-100*1000)
// printf("pFrameInfo->pts:%lld,sTimeStamp.nTimestamp:%ld\n",pFrameInfo->pts,sTimeStamp.nTimestamp);
if(sDelayime > 10*1000*1000 || sDelayime < -10*1000*1000){
if( pFrameInfo->pts - pVideoRenderDataType->sPreFramePts > 10*1000*1000
|| pFrameInfo->pts - pVideoRenderDataType->sPreFramePts < -10*1000*1000)
{// case by video pts jump event
/*
video pts jump,
*/
loge("video pts jump event!!!\n");
}else{//case by audio pts jump event
/*
audio pts jump
*/
loge("audio pts jump event!!!\n");
}
}
}
}else{// frame rate control by videoRender self
sDelayime = pFrameInfo->pts - OMX_VdieoRenderGetMediaTime(pVideoRenderDataType);
if(sDelayime > 10*1000*1000 || sDelayime < -10*1000*1000){//pts jump event
loge("not tunneled clock ,vidoe pts jump event!!!\n");
sDelayime = 40*1000;//this should arccording to fame rate
OMX_VdieoRenderSetMediaClock(pVideoRenderDataType,pFrameInfo);
}
}
if(pFrameInfo->flags & FRAME_FLAG_EOS){
printf("[%s:%d]pts:%lld,sDiffTime:%ld\n",__FUNCTION__,__LINE__,pFrameInfo->pts,sDelayime);
}
if(sDelayime > 2*MAX_DIFFF_TIME){
eSyncType = OMX_VIDEO_SYNC_DEALY;
}else if(sDelayime > (-2)*MAX_DIFFF_TIME){
eSyncType = OMX_VIDEO_SYNC_SHOW;
}else{
eSyncType = OMX_VIDEO_SYNC_DROP;
}
*nDelay = sDelayime;
return eSyncType;
}
static void* OMX_VideoRenderComponentThread(void* pThreadData)
{
struct aic_message message;
OMX_S32 nCmd; //OMX_COMMANDTYPE
OMX_S32 nCmdData; //OMX_STATETYPE
VIDEO_RENDER_DATA_TYPE* pVideoRenderDataType = (VIDEO_RENDER_DATA_TYPE*)pThreadData;
OMX_S32 ret;
//OMX_S32 i;
OMX_S32 bNotifyFrameEnd = 0;
//struct mpp_frame sFrame;
VIDEO_RENDER_IN_FRAME *pFrameNode;
//prctl(PR_SET_NAME,(u32)"VideoRender");
OMX_PORT_TUNNELEDINFO *pTunneldClock;
pTunneldClock = &pVideoRenderDataType->sInPortTunneledInfo[VIDEO_RENDER_PORT_IN_CLOCK_INDEX];
OMX_S32 nEmptyNum = 0;
pVideoRenderDataType->nWaitReayFrameFlag = 1;
while(1){
_AIC_MSG_GET_:
if (aic_msg_get(&pVideoRenderDataType->sMsgQue, &message) == 0){
nCmd = message.message_id;
nCmdData = message.param;
logi("nCmd:%d, nCmdData:%d\n",nCmd,nCmdData);
if(OMX_CommandStateSet == nCmd){
aic_pthread_mutex_lock(&pVideoRenderDataType->stateLock);
if(pVideoRenderDataType->state == (OMX_STATETYPE)(nCmdData)){
OMX_VideoRenderEventNotify(pVideoRenderDataType,OMX_EventError,OMX_ErrorSameState,0,NULL);
aic_pthread_mutex_unlock(&pVideoRenderDataType->stateLock);
continue;
}
switch(nCmdData){
case OMX_StateInvalid:
OMX_VideoRenderStateChangeToInvalid(pVideoRenderDataType);
break;
case OMX_StateLoaded:
OMX_VideoRenderStateChangeToLoaded(pVideoRenderDataType);
break;
case OMX_StateIdle:
OMX_VideoRenderStateChangeToIdle(pVideoRenderDataType);
break;
case OMX_StateExecuting:
OMX_VideoRenderStateChangeToExecuting(pVideoRenderDataType);
break;
case OMX_StatePause:
OMX_VideoRenderStateChangeToPause(pVideoRenderDataType);
break;
default:
break;
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->stateLock);
}else if(OMX_CommandFlush == nCmd){
}else if(OMX_CommandPortDisable == nCmd){
}else if(OMX_CommandPortEnable == nCmd){
}else if(OMX_CommandMarkBuffer == nCmd){
}else if(OMX_CommandStop == nCmd){
logi("OMX_VideoRenderComponentThread ready to exit!!!\n");
goto _EXIT;
}else{
}
}
if(pVideoRenderDataType->state != OMX_StateExecuting){
//usleep(1000);
aic_msg_wait_new_msg(&pVideoRenderDataType->sMsgQue, 0);
continue;
}
if(pVideoRenderDataType->nFlags & VIDEO_RENDER_INPORT_SEND_ALL_FRAME_FLAG){
if(!bNotifyFrameEnd){
OMX_VideoRenderEventNotify(pVideoRenderDataType,OMX_EventBufferFlag,0,0,NULL);
bNotifyFrameEnd = 1;
}
aic_msg_wait_new_msg(&pVideoRenderDataType->sMsgQue, 0);
//usleep(1000);
continue;
}
bNotifyFrameEnd = 0;
OMX_GiveBackProcessedFrames(pVideoRenderDataType);
if(OMX_VideoRenderListEmpty(&pVideoRenderDataType->sInReadyFrame,pVideoRenderDataType->sInFrameLock))
{
struct timespec before = {0},after = {0};
long diff;
aic_pthread_mutex_lock(&pVideoRenderDataType->sWaitReayFrameLock);
pVideoRenderDataType->nWaitReayFrameFlag = 1;
aic_pthread_mutex_unlock(&pVideoRenderDataType->sWaitReayFrameLock);
clock_gettime(CLOCK_REALTIME,&before);
aic_msg_wait_new_msg(&pVideoRenderDataType->sMsgQue, 0);
clock_gettime(CLOCK_REALTIME,&after);
diff = (after.tv_sec - before.tv_sec)*1000*1000 + (after.tv_nsec - before.tv_nsec)/1000;
if(diff > 50*1000){
printf("[%s:%d]:%ld\n",__FUNCTION__,__LINE__,diff);
}
nEmptyNum++;
goto _AIC_MSG_GET_;
}
while(!OMX_VideoRenderListEmpty(&pVideoRenderDataType->sInReadyFrame,pVideoRenderDataType->sInFrameLock)){
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
pFrameNode = mpp_list_first_entry(&pVideoRenderDataType->sInReadyFrame, VIDEO_RENDER_IN_FRAME, sList);
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
if(pVideoRenderDataType->nFrameFisrtShowFlag){
struct mpp_size sSize;
struct mpp_rect sDisRect;
if(!pVideoRenderDataType->nVideoRenderInitFlag){
ret = pVideoRenderDataType->render->init(pVideoRenderDataType->render,pVideoRenderDataType->nLayerId,pVideoRenderDataType->nDevId);
if(!ret){
printf("[%s:%d]pVideoRenderDataType->render->init ok\n",__FUNCTION__,__LINE__);
pVideoRenderDataType->nVideoRenderInitFlag = 1;
}else{
loge("pVideoRenderDataType->render->init fail\n");
}
}
//pVideoRenderDataType->render->set_on_off(pVideoRenderDataType->render,0);
pVideoRenderDataType->render->get_screen_size(pVideoRenderDataType->render,&sSize);
sDisRect.x = 0;
sDisRect.y = 0;
sDisRect.width = sSize.width;
sDisRect.height = sSize.height;
//sDisRect.width = 1024;
//sDisRect.height = 600;
if(pVideoRenderDataType->nDisRectChange)
{
pVideoRenderDataType->render->set_dis_rect(pVideoRenderDataType->render,&pVideoRenderDataType->sDisRect);
logi("init dis rect:[%d,%d,%d,%d]!!!\n"
,pVideoRenderDataType->sDisRect.x
,pVideoRenderDataType->sDisRect.y
,pVideoRenderDataType->sDisRect.width
,pVideoRenderDataType->sDisRect.height);
pVideoRenderDataType->nDisRectChange = OMX_FALSE;
}else{
pVideoRenderDataType->render->set_dis_rect(pVideoRenderDataType->render,&sDisRect);
printf("[%s:%d]init dis rect:[%d,%d,%d,%d]!!!\n",__FUNCTION__,__LINE__,sDisRect.x,sDisRect.y,sDisRect.width,sDisRect.height);
}
//pVideoRenderDataType->render->set_on_off(pVideoRenderDataType->render,1);
printf("[%s:%d]stride[0]:%d,stride[1]:%d,stride[2]:%d,format:%d,width:%d,height:%d"\
"crop_en:%d,crop.x:%d,crop.y:%d,crop.width:%d,crop.height:%d\n"
,__FUNCTION__,__LINE__
,pFrameNode->sFrameInfo.buf.stride[0]
,pFrameNode->sFrameInfo.buf.stride[1]
,pFrameNode->sFrameInfo.buf.stride[2]
,pFrameNode->sFrameInfo.buf.format
,pFrameNode->sFrameInfo.buf.size.width
,pFrameNode->sFrameInfo.buf.size.height
,pFrameNode->sFrameInfo.buf.crop_en
,pFrameNode->sFrameInfo.buf.crop.x
,pFrameNode->sFrameInfo.buf.crop.y
,pFrameNode->sFrameInfo.buf.crop.width
,pFrameNode->sFrameInfo.buf.crop.height);
if(pTunneldClock->nTunneledFlag){
OMX_TIME_CONFIG_TIMESTAMPTYPE sTimeStamp;
sTimeStamp.nPortIndex = pTunneldClock->nTunnelPortIndex;
sTimeStamp.nTimestamp = pFrameNode->sFrameInfo.pts;
OMX_SetConfig(pTunneldClock->pTunneledComp,OMX_IndexConfigTimeClientStartTime, &sTimeStamp);
// whether need to wait????
printf("[%s:%d]wait audio start time\n",__FUNCTION__,__LINE__);
while(pVideoRenderDataType->eClockState != OMX_TIME_ClockStateRunning){
usleep(1*1000);
}
printf("[%s:%d]audio start time arrive\n",__FUNCTION__,__LINE__);
}else{//if it does not tunneld with clock ,it need calcuaute media time by self for control frame rate
OMX_VdieoRenderSetMediaClock(pVideoRenderDataType,&pFrameNode->sFrameInfo);
}
pVideoRenderDataType->nDumpIndex = 0;
//OMX_VideoRenderDumpPic(&pFrameNode->sFrameInfo.buf,pVideoRenderDataType->nDumpIndex++);
ret = pVideoRenderDataType->render->rend(pVideoRenderDataType->render,&pFrameNode->sFrameInfo);
//pVideoRenderDataType->render->set_on_off(pVideoRenderDataType->render,1);
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
if(ret == 0){
mpp_list_del(&pFrameNode->sList);
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInProcessedFrmae);
pVideoRenderDataType->nShowFrameOkNum++;
pVideoRenderDataType->nFrameFisrtShowFlag = OMX_FALSE;
if(pFrameNode->sFrameInfo.flags & FRAME_FLAG_EOS){
pVideoRenderDataType->nFlags |= VIDEO_RENDER_INPORT_SEND_ALL_FRAME_FLAG;
//pVideoRenderDataType->nFrameEndFlag = OMX_TRUE;
printf("[%s:%d]receive nFrameEndFlag\n",__FUNCTION__,__LINE__);
}
}else{
// how to do ,now deal with same success
loge("render error");
mpp_list_del(&pFrameNode->sList);
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInProcessedFrmae);
pVideoRenderDataType->nShowFrameFailNum++;
break;
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
logd("nReceiveFrameNum:%d,nShowFrameOkNum:%d,nShowFrameFailNum:%d\n"
,pVideoRenderDataType->nReceiveFrameNum
,pVideoRenderDataType->nShowFrameOkNum
,pVideoRenderDataType->nShowFrameFailNum);
}else {// not fisrt show
OMX_S32 data1,data2;
OMX_TICKS sDelayime;
OMX_VIDEO_SYNC_TYPE eSyncType;
static struct timespec pev = {0},cur = {0};
//loge("!!!!!!!!!!!!!!! ReadyFrame!!!!!!!!! \n");
eSyncType = OMX_VdieoRenderProcessVideoSync(pVideoRenderDataType,&pFrameNode->sFrameInfo,&sDelayime);
//eSyncType = OMX_VIDEO_SYNC_SHOW;
if(pev.tv_sec == 0){
clock_gettime(CLOCK_REALTIME,&pev);
}else{
long diff = 0;
clock_gettime(CLOCK_REALTIME,&cur);
diff = (cur.tv_sec - pev.tv_sec)*1000*1000 + (cur.tv_nsec - pev.tv_nsec)/1000;
if(diff > 42*1000){
printf("[%s:%d]:%ld,sDelayime:%ld,eSyncType:%d,pts:%lld\n"
,__FUNCTION__,__LINE__
,diff
,sDelayime
,eSyncType
,pFrameNode->sFrameInfo.pts);
}
pev = cur;
}
if(eSyncType == OMX_VIDEO_SYNC_SHOW){
if(pVideoRenderDataType->nDumpIndex < 24){
//OMX_VideoRenderDumpPicK&pFrameNode->sFrameInfo.buf,pVideoRenderDataType->nDumpIndex++);
}
ret = pVideoRenderDataType->render->rend(pVideoRenderDataType->render,&pFrameNode->sFrameInfo);
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
if(ret == 0){
mpp_list_del(&pFrameNode->sList);
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInProcessedFrmae);
pVideoRenderDataType->nShowFrameOkNum++;
if(pFrameNode->sFrameInfo.flags & FRAME_FLAG_EOS){
pVideoRenderDataType->nFlags |= VIDEO_RENDER_INPORT_SEND_ALL_FRAME_FLAG;
//pVideoRenderDataType->nFrameEndFlag = OMX_TRUE;
printf("[%s:%d]receive nFrameEndFlag\n",__FUNCTION__,__LINE__);
}
}else{
// how to do ,now deal with same success
loge("render error");
mpp_list_del(&pFrameNode->sList);
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInProcessedFrmae);
pVideoRenderDataType->nShowFrameFailNum++;
break;
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
//OMX_GiveBackProcessedFrames(pVideoRenderDataType);
data1 = (pFrameNode->sFrameInfo.pts >> 32) & 0x00000000ffffffff;
data2 = pFrameNode->sFrameInfo.pts & 0x00000000ffffffff;
//loge("OMX_VIDEO_SYNC_SHOW:%ld\n",sDelayime);
OMX_VideoRenderEventNotify(pVideoRenderDataType,OMX_EventVideoRenderPts,data1,data2,NULL);
}else if(eSyncType == OMX_VIDEO_SYNC_DROP){
static int nDropNum = 0;
if(pFrameNode->sFrameInfo.flags & FRAME_FLAG_EOS){
pVideoRenderDataType->nFlags |= VIDEO_RENDER_INPORT_SEND_ALL_FRAME_FLAG;
printf("[%s:%d]receive nFrameEndFlag\n",__FUNCTION__,__LINE__);
}
aic_pthread_mutex_lock(&pVideoRenderDataType->sInFrameLock);
mpp_list_del(&pFrameNode->sList);
mpp_list_add_tail(&pFrameNode->sList, &pVideoRenderDataType->sInProcessedFrmae);
pVideoRenderDataType->nDropFrameNum++;
nDropNum++;
if( nDropNum > 50){
nDropNum = 0;
printf("[%s:%d]OMX_VIDEO_SYNC_DROP:nDropFrameNum:%d,sDelayime:%ld:%d\n",__FUNCTION__,__LINE__,pVideoRenderDataType->nDropFrameNum,sDelayime,nEmptyNum);
}
aic_pthread_mutex_unlock(&pVideoRenderDataType->sInFrameLock);
//OMX_GiveBackProcessedFrames(pVideoRenderDataType);
}else if(eSyncType == OMX_VIDEO_SYNC_DEALY){
struct timespec delay_before = {0},delay_after = {0};
//long delay = 0;
//loge("OMX_VIDEO_SYNC_DEALY:%ld,%ld\n",sDelayime,sDelayime-MAX_DIFFF_TIME);
clock_gettime(CLOCK_REALTIME,&delay_before);
aic_msg_wait_new_msg(&pVideoRenderDataType->sMsgQue, sDelayime - MAX_DIFFF_TIME);
//usleep(sDelayime - MAX_DIFFF_TIME);
//aic_udelay(sDelayime - MAX_DIFFF_TIME);
clock_gettime(CLOCK_REALTIME,&delay_after);
//delay = (delay_after.tv_sec - delay_before.tv_sec)*1000*1000 + (delay_after.tv_nsec - delay_before.tv_nsec)/1000;
//printf("[%s:%d]:%ld,%ld\n",__FUNCTION__,__LINE__,delay,sDelayime - MAX_DIFFF_TIME);
}else{
//logd("OMX_VIDEO_SYNC_DEALY:%lld\n",sDelayime);
}
}
if(pVideoRenderDataType->nDisRectChange)
{
pVideoRenderDataType->render->set_dis_rect(pVideoRenderDataType->render,&pVideoRenderDataType->sDisRect);
logi("init dis rect:[%d,%d,%d,%d]!!!\n"
,pVideoRenderDataType->sDisRect.x
,pVideoRenderDataType->sDisRect.y
,pVideoRenderDataType->sDisRect.width
,pVideoRenderDataType->sDisRect.height);
pVideoRenderDataType->nDisRectChange = OMX_FALSE;
}
}
}
_EXIT:
printf("[%s:%d]nReceiveFrameNum:%d,"\
"nLeftReadyFrameWhenCompoentExitNum:%d,"\
"nShowFrameOkNum:%d,"\
"nShowFrameFailNum:%d,"\
"nGiveBackFrameOkNum:%d,"\
"nGiveBackFrameFailNum:%d\n"
,__FUNCTION__,__LINE__
,pVideoRenderDataType->nReceiveFrameNum
,pVideoRenderDataType->nLeftReadyFrameWhenCompoentExitNum
,pVideoRenderDataType->nShowFrameOkNum
,pVideoRenderDataType->nShowFrameFailNum
,pVideoRenderDataType->nGiveBackFrameOkNum
,pVideoRenderDataType->nGiveBackFrameFailNum);
printf("[%s:%d]OMX_VideoRenderComponentThread EXIT\n",__FUNCTION__,__LINE__);
return (void*)OMX_ErrorNone;
}