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

815 lines
31 KiB
C

/*
* Copyright (C) 2020-2023 ArtInChip Technology Co. Ltd
*
* author: <jun.ma@artinchip.com>
* Desc: OMX_ClockComponent
*/
#include "OMX_ClockComponent.h"
static OMX_ERRORTYPE OMX_ClockSendCommand(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_COMMANDTYPE Cmd,
OMX_IN OMX_U32 nParam1,
OMX_IN OMX_PTR pCmdData);
static OMX_ERRORTYPE OMX_ClockGetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR pComponentParameterStructure);
static OMX_ERRORTYPE OMX_ClockSetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentParameterStructure);
static OMX_ERRORTYPE OMX_ClockGetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR pComponentConfigStructure);
static OMX_ERRORTYPE OMX_ClockSetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentConfigStructure);
static OMX_ERRORTYPE OMX_ClockGetState(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STATETYPE* pState);
static OMX_ERRORTYPE OMX_ClockComponentTunnelRequest(
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_ClockEmptyThisBuffer(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
static OMX_ERRORTYPE OMX_ClockFillThisBuffer(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
static OMX_ERRORTYPE OMX_ClockSetCallbacks(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
OMX_IN OMX_PTR pAppData);
static OMX_ERRORTYPE OMX_ClockGetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR pComponentParameterStructure)
{
CLOCK_DATA_TYPE *pClockDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
//OMX_U32 tmp1,tmp2;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
switch (nParamIndex){
case OMX_IndexParamPortDefinition:{
OMX_PARAM_PORTDEFINITIONTYPE *port = (OMX_PARAM_PORTDEFINITIONTYPE*)pComponentParameterStructure;
if(port->nPortIndex == CLOCK_PORT_OUT_VIDEO){
memcpy(port,&pClockDataType->sOutPortDef[CLOCK_PORT_OUT_VIDEO],sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
}else if(port->nPortIndex == CLOCK_PORT_OUT_AUDIO){
memcpy(port,&pClockDataType->sOutPortDef[CLOCK_PORT_OUT_AUDIO],sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
}else{
eError = OMX_ErrorBadParameter;
}
break;
}
case OMX_IndexParamCompBufferSupplier:{
OMX_PARAM_BUFFERSUPPLIERTYPE *sBufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE*)pComponentParameterStructure;
if(sBufferSupplier->nPortIndex == CLOCK_PORT_OUT_VIDEO){
sBufferSupplier->eBufferSupplier = pClockDataType->sOutBufSupplier[CLOCK_PORT_OUT_VIDEO].eBufferSupplier;
}else if(sBufferSupplier->nPortIndex == CLOCK_PORT_OUT_AUDIO){
sBufferSupplier->eBufferSupplier = pClockDataType->sOutBufSupplier[CLOCK_PORT_OUT_AUDIO].eBufferSupplier;
} else{
loge("error nPortIndex\n");
eError = OMX_ErrorBadPortIndex;
}
break;
}
default:
eError = OMX_ErrorNotImplemented;
break;
}
return eError;
}
static OMX_ERRORTYPE OMX_ClockSetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_IN OMX_PTR pComponentParameterStructure)
{
//CLOCK_DATA_TYPE *pClockDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
//pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
if(pComponentParameterStructure == NULL){
loge("param error!!!\n");
return OMX_ErrorBadParameter;
}
switch (nParamIndex){
case OMX_IndexParamPortDefinition:
break;
default:
break;
}
return eError;
}
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 OMX_ERRORTYPE OMX_ClockConfigTimeCurrentAudioReference(OMX_HANDLETYPE hComponent,OMX_TIME_CONFIG_TIMESTAMPTYPE *pTimeStamp)
{
OMX_S64 nCurMeidaTime;
OMX_S64 nDiffTime;
CLOCK_DATA_TYPE *pClockDataType;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
if(pClockDataType->sClockState.eState != OMX_TIME_ClockStateRunning){
loge("clockState are not in OMX_TIME_ClockStateStopped,do not set!!!\n");
pTimeStamp->nTimestamp = -1;
return OMX_ErrorUndefined;
}
nCurMeidaTime = (OMX_ClockGetSystemTime() - pClockDataType->sWallTimeBase - pClockDataType->sPauseTimeDurtion) + pClockDataType->sRefClockTimeBase;
nDiffTime = nCurMeidaTime - pTimeStamp->nTimestamp;
// loge("nDiffTime:%ld,SystemTime:%ld,sWallTimeBase:%ld,sPauseTimeDurtion:%ld,sRefClockTimeBase:%ld,nTimestamp:%ld\n"
// ,nDiffTime
// ,OMX_ClockGetSystemTime()
// ,pClockDataType->sWallTimeBase
// ,pClockDataType->sPauseTimeDurtion
// ,pClockDataType->sRefClockTimeBase
// ,pTimeStamp->nTimestamp);
if(nDiffTime > 10*1000 || nDiffTime < -10*1000){//10ms
pClockDataType->sRefClockTimeBase = pTimeStamp->nTimestamp;
pClockDataType->sWallTimeBase = OMX_ClockGetSystemTime();
pClockDataType->sPauseTimeDurtion = 0;
}
return OMX_ErrorNone;
}
static OMX_ERRORTYPE OMX_ClockGetCurrentMediaTime(OMX_HANDLETYPE hComponent,OMX_TIME_CONFIG_TIMESTAMPTYPE *pTimeStamp)
{
CLOCK_DATA_TYPE *pClockDataType;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
if(pClockDataType->sClockState.eState != OMX_TIME_ClockStateRunning){
//loge("clockState are not in OMX_TIME_ClockStateRunning,do not get media time!!!\n");
pTimeStamp->nTimestamp = -1;
return OMX_ErrorUndefined;
}
//OMX_S64 tick = OMX_ClockGetSystemTime();
pTimeStamp->nTimestamp = (OMX_ClockGetSystemTime() - pClockDataType->sWallTimeBase - pClockDataType->sPauseTimeDurtion) + pClockDataType->sRefClockTimeBase;
// loge("SystemTime:%ld,sWallTimeBase:%ld,sPauseTimeDurtion:%ld,sRefClockTimeBase:%ld,nTimestamp:%ld\n"
// ,OMX_ClockGetSystemTime()
// ,pClockDataType->sWallTimeBase
// ,pClockDataType->sPauseTimeDurtion
// ,pClockDataType->sRefClockTimeBase
// ,pTimeStamp->nTimestamp);
return OMX_ErrorNone;
}
/*
static OMX_ERRORTYPE OMX_ClockGetWallTime(OMX_HANDLETYPE hComponent,OMX_TIME_CONFIG_TIMESTAMPTYPE *pTimeStamp)
{
CLOCK_DATA_TYPE *pClockDataType;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
if(pClockDataType->sClockState.eState != OMX_TIME_ClockStateRunning){
loge("clockState are not in OMX_TIME_ClockStateStopped,do not set!!!\n");
pTimeStamp->nTimestamp = -1;
return OMX_ErrorUndefined;
}
pTimeStamp->nTimestamp = pClockDataType->sWallTimeBase;
return OMX_ErrorNone;
}
*/
static OMX_ERRORTYPE OMX_ClockConfigTimeClockState(OMX_HANDLETYPE hComponent,OMX_TIME_CONFIG_CLOCKSTATETYPE *pClockState)
{
CLOCK_DATA_TYPE *pClockDataType;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
if(pClockDataType->sClockState.eState != OMX_TIME_ClockStateStopped){
loge("clockState are not in OMX_TIME_ClockStateStopped,do not set!!!\n");
return OMX_ErrorUndefined;
}
memcpy(&pClockDataType->sClockState,pClockState,sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
printf("[%s:%d]nWaitMask:0x%x,sClockState:%d\n",__FUNCTION__,__LINE__,pClockDataType->sClockState.nWaitMask,pClockDataType->sClockState.eState);
//pClockDataType->sClockState.eState = OMX_TIME_ClockStateWaitingForStartTime;
return OMX_ErrorNone;
}
static OMX_ERRORTYPE OMX_ClockConfigTimeClientStartTime(OMX_HANDLETYPE hComponent,OMX_TIME_CONFIG_TIMESTAMPTYPE *pTimeStamp)
{
CLOCK_DATA_TYPE *pClockDataType;
int i = 0;
OMX_TICKS minTimeStamp;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
OMX_PORT_TUNNELEDINFO *pVideoTunneledInfo = &pClockDataType->sOutPortTunneledInfo[CLOCK_PORT_OUT_VIDEO];
OMX_PORT_TUNNELEDINFO *pAudioTunneledInfo = &pClockDataType->sOutPortTunneledInfo[CLOCK_PORT_OUT_AUDIO];
if(pClockDataType->sClockState.eState != OMX_TIME_ClockStateWaitingForStartTime){
loge("clockState are not in OMX_TIME_ClockStateWaitingForStartTime,do not set!!!\n");
return OMX_ErrorUndefined;
}
if(pClockDataType->sClockState.nWaitMask){
printf("[%s:%d]nPortIndex:%d,nTimestamp:%ld\n",__FUNCTION__,__LINE__,pTimeStamp->nPortIndex,pTimeStamp->nTimestamp);
if(pTimeStamp->nPortIndex == CLOCK_PORT_OUT_VIDEO){
pClockDataType->sClockState.nWaitMask &= ~OMX_CLOCKPORT0;
pClockDataType->sPortStartTime[CLOCK_PORT_OUT_VIDEO] = pTimeStamp->nTimestamp;
printf("[%s:%d]CLOCK_PORT_OUT_VIDEO nWaitMask:0x%x,nTimestamp:%ld\n",__FUNCTION__,__LINE__,pClockDataType->sClockState.nWaitMask,pTimeStamp->nTimestamp);
}else if(pTimeStamp->nPortIndex == CLOCK_PORT_OUT_AUDIO){
pClockDataType->sClockState.nWaitMask &= ~OMX_CLOCKPORT1;
pClockDataType->sPortStartTime[CLOCK_PORT_OUT_AUDIO] = pTimeStamp->nTimestamp;
printf("[%s:%d]CLOCK_PORT_OUT_AUDIO nWaitMask:0x%x,nTimestamp:%ld\n",__FUNCTION__,__LINE__,pClockDataType->sClockState.nWaitMask,pTimeStamp->nTimestamp);
}else{
return OMX_ErrorBadPortIndex;
}
}
if(!pClockDataType->sClockState.nWaitMask){//all port start time come
minTimeStamp = pClockDataType->sPortStartTime[0];
for(i = 1; i< CLOCK_PORT_NUM_MAX;i++ ){
if(pClockDataType->sPortStartTime[i] < minTimeStamp){
minTimeStamp = pClockDataType->sPortStartTime[i];
}
}
pClockDataType->sClockState.nStartTime = minTimeStamp;
pClockDataType->sRefClockTimeBase = minTimeStamp;
pClockDataType->sWallTimeBase = OMX_ClockGetSystemTime();
pClockDataType->sPauseTimeDurtion = 0;
pClockDataType->sClockState.eState = OMX_TIME_ClockStateRunning;
printf("[%s:%d]sRefClockTimeBase:%ld,sWallTimeBase:%ld\n",__FUNCTION__,__LINE__,pClockDataType->sRefClockTimeBase,pClockDataType->sWallTimeBase);
OMX_SetConfig(pVideoTunneledInfo->pTunneledComp, OMX_IndexConfigTimeClockState,&pClockDataType->sClockState);
OMX_SetConfig(pAudioTunneledInfo->pTunneledComp, OMX_IndexConfigTimeClockState,&pClockDataType->sClockState);
}
return OMX_ErrorNone;
}
static OMX_ERRORTYPE OMX_ClockGetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR pComponentConfigStructure)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
//CLOCK_DATA_TYPE *pClockDataType;
//pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
if(pComponentConfigStructure == NULL){
loge("param error!!!\n");
return OMX_ErrorBadParameter;
}
switch (nIndex){
case OMX_IndexConfigTimeCurrentMediaTime:
eError = OMX_ClockGetCurrentMediaTime(hComponent,(OMX_TIME_CONFIG_TIMESTAMPTYPE*)pComponentConfigStructure);
break;
case OMX_IndexConfigTimeCurrentWallTime:
//OMX_TIME_CONFIG_TIMESTAMPTYPE
break;
case OMX_IndexConfigTimeActiveRefClock:
//OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE
break;
case OMX_IndexConfigTimeClockState:
break;
default:
break;
}
return eError;
}
static OMX_ERRORTYPE OMX_ClockSetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentConfigStructure)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
//CLOCK_DATA_TYPE *pClockDataType;
//pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
if(pComponentConfigStructure == NULL){
loge("param error!!!\n");
return OMX_ErrorBadParameter;
}
switch (nIndex){
case OMX_IndexConfigTimeCurrentAudioReference:
eError = OMX_ClockConfigTimeCurrentAudioReference(hComponent,(OMX_TIME_CONFIG_TIMESTAMPTYPE*)pComponentConfigStructure);
break;
case OMX_IndexConfigTimeCurrentVideoReference:
break;
case OMX_IndexConfigTimeMediaTimeRequest:
break;
case OMX_IndexConfigTimeClientStartTime:
eError = OMX_ClockConfigTimeClientStartTime(hComponent,(OMX_TIME_CONFIG_TIMESTAMPTYPE*)pComponentConfigStructure);
break;
case OMX_IndexConfigTimePosition:// do seek
break;
case OMX_IndexConfigTimeActiveRefClock:
break;
case OMX_IndexConfigTimeClockState:
eError = OMX_ClockConfigTimeClockState(hComponent,(OMX_TIME_CONFIG_CLOCKSTATETYPE *)pComponentConfigStructure);
break;
default:
break;
}
return eError;
}
static OMX_ERRORTYPE OMX_ClockGetState(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STATETYPE* pState)
{
CLOCK_DATA_TYPE* pClockDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
pthread_mutex_lock(&pClockDataType->stateLock);
*pState = pClockDataType->state;
pthread_mutex_unlock(&pClockDataType->stateLock);
return eError;
}
static OMX_ERRORTYPE OMX_ClockComponentTunnelRequest(
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;
CLOCK_DATA_TYPE* pClockDataType;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComp)->pComponentPrivate);
if(pClockDataType->state != OMX_StateLoaded)
{
loge("Component is not in OMX_StateLoaded,it is in%d,it can not tunnel\n",pClockDataType->state);
return OMX_ErrorInvalidState;
}
if(nPort == CLOCK_PORT_OUT_VIDEO){
pPort = &pClockDataType->sOutPortDef[CLOCK_PORT_OUT_VIDEO];
pTunneledInfo = &pClockDataType->sOutPortTunneledInfo[CLOCK_PORT_OUT_VIDEO];
pBufSupplier = &pClockDataType->sOutBufSupplier[CLOCK_PORT_OUT_VIDEO];
}else if(nPort == CLOCK_PORT_OUT_AUDIO){
pPort = &pClockDataType->sOutPortDef[CLOCK_PORT_OUT_AUDIO];
pTunneledInfo = &pClockDataType->sOutPortTunneledInfo[CLOCK_PORT_OUT_AUDIO];
pBufSupplier = &pClockDataType->sOutBufSupplier[CLOCK_PORT_OUT_AUDIO];
}else{
loge("component can not find \n");
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_ClockEmptyThisBuffer(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
return eError;
}
static OMX_ERRORTYPE OMX_ClockFillThisBuffer(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
return eError;
}
static OMX_ERRORTYPE OMX_ClockSetCallbacks(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
OMX_IN OMX_PTR pAppData)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
CLOCK_DATA_TYPE* pClockDataType;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
pClockDataType->pCallbacks = pCallbacks;
pClockDataType->pAppData = pAppData;
return eError;
}
OMX_ERRORTYPE OMX_ClockComponentDeInit(
OMX_IN OMX_HANDLETYPE hComponent) {
OMX_ERRORTYPE eError = OMX_ErrorNone;
OMX_COMPONENTTYPE *pComp;
CLOCK_DATA_TYPE *pClockDataType;
pComp = (OMX_COMPONENTTYPE *)hComponent;
pClockDataType = (CLOCK_DATA_TYPE *)pComp->pComponentPrivate;
pthread_mutex_lock(&pClockDataType->stateLock);
if(pClockDataType->state != OMX_StateLoaded){
loge("compoent is in %d,but not in OMX_StateLoaded(1),can ont FreeHandle.\n",pClockDataType->state);
pthread_mutex_unlock(&pClockDataType->stateLock);
return OMX_ErrorIncorrectStateOperation;
}
pthread_mutex_unlock(&pClockDataType->stateLock);
pthread_mutex_destroy(&pClockDataType->stateLock);
aic_msg_destroy(&pClockDataType->sMsgQue);
mpp_free(pClockDataType);
pClockDataType = NULL;
logi("OMX_ClockComponentDeInit\n");
return eError;
}
OMX_ERRORTYPE OMX_ClockComponentInit(
OMX_IN OMX_HANDLETYPE hComponent)
{
OMX_COMPONENTTYPE *pComp;
CLOCK_DATA_TYPE *pClockDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
//OMX_U32 err;
OMX_U32 i;
//OMX_U32 cnt;
logi("OMX_ClockComponentInit....\n");
pComp = (OMX_COMPONENTTYPE *)hComponent;
pClockDataType = (CLOCK_DATA_TYPE *)mpp_alloc(sizeof(CLOCK_DATA_TYPE));
if (NULL == pClockDataType) {
loge("mpp_alloc(sizeof(CLOCK_DATA_TYPE) fail!");
eError = OMX_ErrorInsufficientResources;
goto _EXIT1;
}
memset(pClockDataType, 0x0, sizeof(CLOCK_DATA_TYPE));
pComp->pComponentPrivate = (void*) pClockDataType;
pClockDataType->state = OMX_StateLoaded;
pClockDataType->hSelf = pComp;
pComp->SetCallbacks = OMX_ClockSetCallbacks;
pComp->SendCommand = OMX_ClockSendCommand;
pComp->GetState = OMX_ClockGetState;
pComp->GetParameter = OMX_ClockGetParameter;
pComp->SetParameter = OMX_ClockSetParameter;
pComp->GetConfig = OMX_ClockGetConfig;
pComp->SetConfig = OMX_ClockSetConfig;
pComp->ComponentTunnelRequest = OMX_ClockComponentTunnelRequest;
pComp->ComponentDeInit = OMX_ClockComponentDeInit;
pComp->FillThisBuffer = OMX_ClockFillThisBuffer;
pComp->EmptyThisBuffer = OMX_ClockEmptyThisBuffer;
pClockDataType->sPortParam.nPorts = 2;
pClockDataType->sPortParam.nStartPortNumber = 0x0;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_VIDEO].nPortIndex = CLOCK_PORT_OUT_VIDEO;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_VIDEO].bPopulated = OMX_TRUE;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_VIDEO].bEnabled = OMX_TRUE;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_VIDEO].eDomain = OMX_PortDomainOther;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_VIDEO].eDir = OMX_DirOutput;
pClockDataType->sOutBufSupplier[CLOCK_PORT_OUT_VIDEO].nPortIndex = CLOCK_PORT_OUT_VIDEO;
pClockDataType->sOutBufSupplier[CLOCK_PORT_OUT_VIDEO].eBufferSupplier = OMX_BufferSupplyOutput;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_AUDIO].nPortIndex = CLOCK_PORT_OUT_AUDIO;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_AUDIO].bPopulated = OMX_TRUE;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_AUDIO].bEnabled = OMX_TRUE;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_AUDIO].eDomain = OMX_PortDomainOther;
pClockDataType->sOutPortDef[CLOCK_PORT_OUT_AUDIO].eDir = OMX_DirOutput;
pClockDataType->sOutBufSupplier[CLOCK_PORT_OUT_AUDIO].nPortIndex = CLOCK_PORT_OUT_AUDIO;
pClockDataType->sOutBufSupplier[CLOCK_PORT_OUT_AUDIO].eBufferSupplier = OMX_BufferSupplyOutput;
pClockDataType->sClockState.eState = OMX_TIME_ClockStateStopped;
pClockDataType->sClockState.nStartTime = -1;
for(i=0; i<CLOCK_PORT_NUM_MAX; i++){
pClockDataType->sPortStartTime[i] = -1;
}
pClockDataType->sActiveRefClock.eClock = OMX_TIME_RefClockAudio;
pClockDataType->sPauseTimeDurtion = 0;
if(aic_msg_create(&pClockDataType->sMsgQue)<0)
{
loge("aic_msg_create fail!");
eError = OMX_ErrorInsufficientResources;
goto _EXIT2;
}
pthread_mutex_init(&pClockDataType->stateLock, NULL);
return eError;
_EXIT2:
if(pClockDataType){
mpp_free(pClockDataType);
pClockDataType = NULL;
}
_EXIT1:
return eError;
}
static void OMX_ClockEventNotify(
CLOCK_DATA_TYPE * pClockDataType,
OMX_EVENTTYPE event,
OMX_U32 nData1,
OMX_U32 nData2,
OMX_PTR pEventData)
{
if(pClockDataType && pClockDataType->pCallbacks && pClockDataType->pCallbacks->EventHandler) {
pClockDataType->pCallbacks->EventHandler(
pClockDataType->hSelf,
pClockDataType->pAppData,event,
nData1, nData2, pEventData);
}
}
static void OMX_ClockStateChangeToInvalid(CLOCK_DATA_TYPE * pClockDataType)
{
pClockDataType->state = OMX_StateInvalid;
OMX_ClockEventNotify(pClockDataType
,OMX_EventError
,OMX_ErrorInvalidState,0,NULL);
OMX_ClockEventNotify(pClockDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
,pClockDataType->state,NULL);
}
static void OMX_ClockStateChangeToLoaded(CLOCK_DATA_TYPE * pClockDataType)
{
//int ret;
if(pClockDataType->state == OMX_StateIdle){
}else if(pClockDataType->state == OMX_StateExecuting){
}else if(pClockDataType->state == OMX_StatePause){
}else {
OMX_ClockEventNotify(pClockDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
, pClockDataType->state,NULL);
loge("OMX_ErrorIncorrectStateTransition\n");
return;
}
pClockDataType->state = OMX_StateLoaded;
OMX_ClockEventNotify(pClockDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
, pClockDataType->state,NULL);
}
static void OMXClockStateChangeToIdle(CLOCK_DATA_TYPE * pClockDataType)
{
//int ret;
if(pClockDataType->state == OMX_StateLoaded){
}else if(pClockDataType->state == OMX_StatePause){
}else if(pClockDataType->state == OMX_StateExecuting){
}else{
OMX_ClockEventNotify(pClockDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
, pClockDataType->state,NULL);
loge("OMX_ErrorIncorrectStateTransition\n");
return;
}
pClockDataType->state = OMX_StateIdle;
OMX_ClockEventNotify(pClockDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
, pClockDataType->state,NULL);
}
static void OMX_ClockStateChangeToExcuting(CLOCK_DATA_TYPE * pClockDataType)
{
if(pClockDataType->state == OMX_StateLoaded){
OMX_ClockEventNotify(pClockDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
, pClockDataType->state,NULL);
loge("OMX_ErrorIncorrectStateTransition\n");
return;
}else if(pClockDataType->state == OMX_StateIdle){
}else if(pClockDataType->state == OMX_StatePause){
OMX_S64 nCurMeidaTime;
pClockDataType->sPauseTimeDurtion += (OMX_ClockGetSystemTime() - pClockDataType->sPauseTimePoint);
printf("[%s:%d]OMX_ClockGetSystemTime:%ld,sPauseTimePoint:%ld,sPauseTimeDurtion:%ld,sWallTimeBase:%ld,sRefClockTimeBase:%ld\n"
,__FUNCTION__,__LINE__
,OMX_ClockGetSystemTime()
,pClockDataType->sPauseTimePoint
,pClockDataType->sPauseTimeDurtion
,pClockDataType->sWallTimeBase
,pClockDataType->sRefClockTimeBase);
nCurMeidaTime = (OMX_ClockGetSystemTime() - pClockDataType->sWallTimeBase - pClockDataType->sPauseTimeDurtion) + pClockDataType->sRefClockTimeBase;
printf("[%s:%d]pClockDataType->sPauseTimeDurtion:%ld,nCurMeidaTime:%ld\n" ,__FUNCTION__,__LINE__,pClockDataType->sPauseTimeDurtion,nCurMeidaTime);
}else{
OMX_ClockEventNotify(pClockDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
, pClockDataType->state,NULL);
loge("OMX_ErrorIncorrectStateTransition\n");
return;
}
pClockDataType->state = OMX_StateExecuting;
OMX_ClockEventNotify(pClockDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
, pClockDataType->state,NULL);
}
static void OMX_ClockStateChangeToPause(CLOCK_DATA_TYPE * pClockDataType)
{
if(pClockDataType->state == OMX_StateLoaded){
OMX_ClockEventNotify(pClockDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
, pClockDataType->state,NULL);
loge("OMX_ErrorIncorrectStateTransition\n");
return;
}else if(pClockDataType->state == OMX_StateIdle){
}else if(pClockDataType->state == OMX_StateExecuting){
OMX_S64 nCurMeidaTime;
printf("[%s:%d]OMX_ClockGetSystemTime:%ld,sPauseTimePoint:%ld,sPauseTimeDurtion:%ld,sWallTimeBase:%ld,sRefClockTimeBase:%ld\n"
,__FUNCTION__,__LINE__
,OMX_ClockGetSystemTime()
,pClockDataType->sPauseTimePoint
,pClockDataType->sPauseTimeDurtion
,pClockDataType->sWallTimeBase
,pClockDataType->sRefClockTimeBase);
nCurMeidaTime = (OMX_ClockGetSystemTime() - pClockDataType->sWallTimeBase - pClockDataType->sPauseTimeDurtion) + pClockDataType->sRefClockTimeBase;
printf("[%s:%d]OMX_ClockGetSystemTime:%ld,sPauseTimePoint:%ld,sPauseTimeDurtion:%ld,sWallTimeBase:%ld,sRefClockTimeBase:%ld,nCurMeidaTime:%ld\n"
,__FUNCTION__,__LINE__
,OMX_ClockGetSystemTime()
,pClockDataType->sPauseTimePoint
,pClockDataType->sPauseTimeDurtion
,pClockDataType->sWallTimeBase
,pClockDataType->sRefClockTimeBase
,nCurMeidaTime);
pClockDataType->sPauseTimePoint = OMX_ClockGetSystemTime();
}else{
OMX_ClockEventNotify(pClockDataType
,OMX_EventError
,OMX_ErrorIncorrectStateTransition
, pClockDataType->state,NULL);
loge("OMX_ErrorIncorrectStateTransition\n");
return;
}
pClockDataType->state = OMX_StatePause;
OMX_ClockEventNotify(pClockDataType
,OMX_EventCmdComplete
,OMX_CommandStateSet
, pClockDataType->state,NULL);
}
/*
there is on need to create a pthread to run this component.
processing cmd directly in OMX_ClockSendCommand.
*/
static OMX_ERRORTYPE OMX_ClockSendCommand(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_COMMANDTYPE Cmd,
OMX_IN OMX_U32 nParam1,
OMX_IN OMX_PTR pCmdData)
{
CLOCK_DATA_TYPE *pClockDataType;
OMX_ERRORTYPE eError = OMX_ErrorNone;
//struct aic_message sMsg;
pClockDataType = (CLOCK_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
if(OMX_CommandStateSet == Cmd){
pthread_mutex_lock(&pClockDataType->stateLock);
if(pClockDataType->state == (OMX_STATETYPE)(nParam1)){
logi("OMX_ErrorSameState\n");
OMX_ClockEventNotify(pClockDataType
,OMX_EventError
,OMX_ErrorSameState,0,NULL);
pthread_mutex_unlock(&pClockDataType->stateLock);
return OMX_ErrorSameState;
}
switch(nParam1){
case OMX_StateInvalid:
OMX_ClockStateChangeToInvalid(pClockDataType);
break;
case OMX_StateLoaded:
OMX_ClockStateChangeToLoaded(pClockDataType);
break;
case OMX_StateIdle:
OMXClockStateChangeToIdle(pClockDataType);
break;
case OMX_StateExecuting:
OMX_ClockStateChangeToExcuting(pClockDataType);
break;
case OMX_StatePause:
OMX_ClockStateChangeToPause(pClockDataType);
break;
default:
break;
}
pthread_mutex_unlock(&pClockDataType->stateLock);
}else if(OMX_CommandFlush == Cmd){
}else if(OMX_CommandPortDisable == Cmd){
}else if(OMX_CommandPortEnable == Cmd){
}else if(OMX_CommandMarkBuffer == (OMX_S32)Cmd){
}else if(OMX_CommandStop == (OMX_S32)Cmd){
}else{
}
return eError;
}