sdk-hwV1.3/external/eyesee-mpp/middleware/sun8iw21/media/component/UvcVirVi_Component.c

1219 lines
47 KiB
C

/******************************************************************************
Copyright (C), 2001-2017, Allwinner Tech. Co., Ltd.
******************************************************************************
File Name : UvcVirVi_Component.c
Version :
Author : Allwinner BU3-PD2 Team
Created : 2017/12/10
Last Modified :
Description : mpp component implement
Function List :
History :
******************************************************************************/
//#define LOG_NDEBUG 0
#define LOG_TAG "UvcVirVi_Component"
#include <utils/plat_log.h>
#include <errno.h>
#include <string.h>
#include <sys/prctl.h>
#include <cdx_list.h>
#include <ComponentCommon.h>
#include <mm_component.h>
#include <cedarx_demux.h>
#include <EncodedStream.h>
#include <UvcCompStream.h>
#include "UvcVirVi_Component.h"
#define UVC_FIFO_LEVEL_INIT (30)
static void *Uvc_ComponentThread(void *pThreadData);
ERRORTYPE UvcSetCallbacks(PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN COMP_CALLBACKTYPE* pCallbacks,
PARAM_IN void* pAppData)
{
ERRORTYPE eError = SUCCESS;
if(!hComponent || !pCallbacks || !pAppData)
{
eError = ERR_UVC_ILLEGAL_PARAM;
goto COMP_CONF_CMD_FAIL;
}
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
pUvcInputData->pCallbacks = pCallbacks;
pUvcInputData->pAppData = pAppData;
COMP_CONF_CMD_FAIL:
return eError;
}
ERRORTYPE UvcGetState(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_OUT COMP_STATETYPE* pState )
{
ERRORTYPE eError = SUCCESS;
if(!hComponent || !pState)
{
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
*pState = pUvcInputData->state;
return eError;
}
ERRORTYPE UvcSendCommand(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN COMP_COMMANDTYPE Cmd,
PARAM_IN unsigned int nParam1,
PARAM_IN void* pCmdData)
{
ERRORTYPE eError = SUCCESS;
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
CompInternalMsgType eCmd;
message_t msg;
if(COMP_StateInvalid == pUvcInputData->state)
{
eError = ERR_UVC_SYS_NOTREADY;
return eError;
}
switch(Cmd)
{
case COMP_CommandStateSet:
eCmd = SetState;
break;
case COMP_CommandFlush:
eCmd = Flush;
break;
default:
alogw("impossible comp_command[0x%x]", Cmd);
break;
}
msg.command = eCmd;
msg.para0 = nParam1;
put_message(&pUvcInputData->cmd_queue, &msg);
return eError;
}
ERRORTYPE UvcSetMPPChannelInfo(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN MPP_CHN_S *pChn)
{
ERRORTYPE eError = SUCCESS;
if(!hComponent || !pChn)
{
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
pUvcInputData->mMppChnInfo = *pChn;
return eError;
}
ERRORTYPE UvcGetMPPChannelInfo(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN MPP_CHN_S *pChn)
{
ERRORTYPE eError = SUCCESS;
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
*pChn = pUvcInputData->mMppChnInfo;
return eError;
}
ERRORTYPE UvcSetDevInfo(PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN UvcChnManager *pUvcChnManager)
{
ERRORTYPE eError = SUCCESS;
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
pUvcInputData->pUvcChnManager = pUvcChnManager;
return eError;
}
ERRORTYPE UvcGetPortDefinition(PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_INOUT COMP_PARAM_PORTDEFINITIONTYPE *pPortDef)
{
ERRORTYPE eError = SUCCESS;
if(!hComponent || !pPortDef)
{
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
BOOL bFindFlag = FALSE;
int i;
for(i = 0; i < UVC_CHN_MAX_PORTS; i++)
{
if(pUvcInputData->sPortDef[i].nPortIndex == pPortDef->nPortIndex)
{
memcpy(pPortDef, &pUvcInputData->sPortDef[i], sizeof pUvcInputData->sPortDef[i]);
bFindFlag = TRUE;
}
}
if(!bFindFlag)
{
eError = ERR_UVC_ILLEGAL_PARAM;
}
return eError;
}
ERRORTYPE UvcSetPortDefinition(PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_INOUT COMP_PARAM_PORTDEFINITIONTYPE *pPortDef)
{
ERRORTYPE eError = SUCCESS;
if(!hComponent || !pPortDef)
{
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
BOOL bFindFlag = FALSE;
int i;
for(i = 0; i < UVC_CHN_MAX_PORTS; i++)
{
if(pUvcInputData->sPortDef[i].nPortIndex == pPortDef->nPortIndex)
{
memcpy(&pUvcInputData->sPortDef[i], pPortDef, sizeof pUvcInputData->sPortDef[i]);
bFindFlag = TRUE;
}
}
if(!bFindFlag)
{
eError = ERR_UVC_ILLEGAL_PARAM;
}
return eError;
}
ERRORTYPE UvcGetCompBufferSupplier(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_INOUT COMP_PARAM_BUFFERSUPPLIERTYPE *pPortBufSupplier)
{
ERRORTYPE eError = SUCCESS;
if(!hComponent || !pPortBufSupplier)
{
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
BOOL bFindFlag = FALSE;
int i;
for(i = 0; i < UVC_CHN_MAX_PORTS; i++)
{
if(pUvcInputData->sPortBufSupplier[i].nPortIndex == pPortBufSupplier->nPortIndex)
{
memcpy(pPortBufSupplier, &pUvcInputData->sPortBufSupplier[i], sizeof pUvcInputData->sPortBufSupplier[i]);
bFindFlag = TRUE;
break;
}
}
if(!bFindFlag)
{
eError = ERR_UVC_ILLEGAL_PARAM;
}
return eError;
}
ERRORTYPE UvcSetCompBufferSupplier(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN COMP_PARAM_BUFFERSUPPLIERTYPE *pPortBufSupplier)
{
ERRORTYPE eError = SUCCESS;
if(!hComponent || !pPortBufSupplier)
{
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
BOOL bFindFlag = FALSE;
int i;
for(i = 0; i < UVC_CHN_MAX_PORTS; i++)
{
if(pUvcInputData->sPortBufSupplier[i].nPortIndex == pPortBufSupplier->nPortIndex)
{
memcpy(&pUvcInputData->sPortBufSupplier[i], pPortBufSupplier, sizeof pUvcInputData->sPortBufSupplier[i]);
bFindFlag = TRUE;
break;
}
}
if(!bFindFlag)
{
eError = ERR_UVC_ILLEGAL_PARAM;
}
return eError;
}
ERRORTYPE UvcGetPortExtraDef(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_OUT COMP_PARAM_PORTEXTRADEFINITIONTYPE *pPortDef)
{
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
int portIdx = pPortDef->nPortIndex;
if(!pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_DATA_OUT].pVendorInfo)
{
VideoStreamInfo *ptr = malloc(sizeof(VideoStreamInfo));
if(!ptr)
{
aloge("can not malloc the VideoStreamInfo!!");
return ERR_UVC_NOMEM;
}
memset(ptr, 0, sizeof(VideoStreamInfo));
if(V4L2_PIX_FMT_MJPEG == pUvcInputData->pUvcChnManager->mUvcAttr.mPixelformat)
{
ptr->eCodecFormat = VIDEO_CODEC_FORMAT_MJPEG;
ptr->bIsFramePackage = 1;
}
else if(V4L2_PIX_FMT_H264 == pUvcInputData->pUvcChnManager->mUvcAttr.mPixelformat)
{
ptr->eCodecFormat = VIDEO_CODEC_FORMAT_H264;
}
else
{
ptr->eCodecFormat = VIDEO_CODEC_FORMAT_UNKNOWN;
}
ptr->nWidth = pUvcInputData->pUvcChnManager->mUvcAttr.mUvcVideo_Width;
ptr->nHeight = pUvcInputData->pUvcChnManager->mUvcAttr.mUvcVideo_Height;
ptr->nFrameRate = (pUvcInputData->pUvcChnManager->mUvcAttr.mUvcVideo_Fps)* 1000;
ptr->nFrameDuration = (1000*1000*1000) / (ptr->nFrameRate);
ptr->bIsFramePackage = 1;
pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_DATA_OUT].pVendorInfo = (void *)ptr;
}
if(portIdx == UVC_CHN_PORT_INDEX_DATA_OUT)
{
memcpy(pPortDef, &pUvcInputData->sPortExtraDef[portIdx], sizeof(COMP_PARAM_PORTEXTRADEFINITIONTYPE));
return TRUE;
}
else
{
return FAILURE;
}
}
ERRORTYPE UvcComponentTunnelRequest(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN unsigned int nPort,
PARAM_IN COMP_HANDLETYPE hTunneledComp,
PARAM_IN unsigned int nTunneledPort,
PARAM_INOUT COMP_TUNNELSETUPTYPE* pTunnelSetup)
{
ERRORTYPE eError = SUCCESS;
if(!hComponent)
{
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
if(COMP_StateExecuting == pUvcInputData->state)
{
alogw("Be careful! tunnel request may be some danger in StateExecuting");
}
else if(pUvcInputData->state != COMP_StateIdle)
{
aloge("fatal error! tunnel request process_thread_state can't be in state[0x%x]", pUvcInputData->state);
eError = ERR_UVC_INCORRECT_STATE_OPERATION;
return eError;
}
COMP_PARAM_PORTDEFINITIONTYPE *pPortDef;
COMP_INTERNAL_TUNNELINFOTYPE *pPortTunnelInfo;
COMP_PARAM_BUFFERSUPPLIERTYPE *pPortBufSupplier;
BOOL bFindFlag = FALSE;
int i;
for(i = 0; i < UVC_CHN_MAX_PORTS; i++)
{
if(pUvcInputData->sPortDef[i].nPortIndex == nPort)
{
pPortDef = &pUvcInputData->sPortDef[i];
bFindFlag = TRUE;
break;
}
}
if(!bFindFlag)
{
aloge("fatal error! portIndex[%d] wrong!", nPort);
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
bFindFlag = FALSE;
for(i = 0; i < UVC_CHN_MAX_PORTS; i++)
{
if(pUvcInputData->sPortTunnelInfo[i].nPortIndex == nPort)
{
pPortTunnelInfo = &pUvcInputData->sPortTunnelInfo[i];
bFindFlag = TRUE;
break;
}
}
if(!bFindFlag)
{
aloge("fatal error! portIndex[%d] wrong!", nPort);
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
bFindFlag = FALSE;
for(i = 0; i < UVC_CHN_MAX_PORTS; i++)
{
if(pUvcInputData->sPortBufSupplier[i].nPortIndex == nPort)
{
pPortBufSupplier = &pUvcInputData->sPortBufSupplier[i];
bFindFlag = TRUE;
break;
}
}
if(!bFindFlag)
{
aloge("fatal error! portIndex[%d] wrong!", nPort);
eError = ERR_AI_ILLEGAL_PARAM;
return eError;
}
pPortTunnelInfo->nPortIndex = nPort;
pPortTunnelInfo->hTunnel = hTunneledComp;
pPortTunnelInfo->nTunnelPortIndex = nTunneledPort;
pPortTunnelInfo->eTunnelType = (pPortDef->eDomain == COMP_PortDomainOther)?TUNNEL_TYPE_CLOCK : TUNNEL_TYPE_COMMON;
if(NULL == hTunneledComp && 0 == nTunneledPort && NULL == pTunnelSetup)
{
alogd("omx_core cancel setup tunnel on port[%d]", nPort);
eError = SUCCESS;
if(pPortDef->eDir == COMP_DirOutput)
{
pUvcInputData->mOutputPortTunnelFlag = FALSE;
}
else
{
//pVideoViData->mInputPortTunnelFlag = FALSE;
}
return eError;
}
if(COMP_DirOutput == pPortDef->eDir)
{
pTunnelSetup->nTunnelFlags = 0;
pTunnelSetup->eSupplier = pPortBufSupplier->eBufferSupplier;
pUvcInputData->mOutputPortTunnelFlag = TRUE;
}
else
{
COMP_PARAM_PORTDEFINITIONTYPE out_port_def;
out_port_def.nPortIndex = nTunneledPort;
((MM_COMPONENTTYPE *)hTunneledComp)->GetConfig(hTunneledComp, COMP_IndexParamPortDefinition, &out_port_def);
if(out_port_def.eDir != COMP_DirOutput)
{
aloge("fatal error! tunnel port index[%d] direction is not output!", nTunneledPort);
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
pPortDef->format = out_port_def.format;
if(pTunnelSetup->eSupplier != pPortBufSupplier->eBufferSupplier)
{
alogw("Low probability! use input portIndex[%d] buffer supplier[%d] as final!", nPort, pPortBufSupplier->eBufferSupplier);
pTunnelSetup->eSupplier = pPortBufSupplier->eBufferSupplier;
}
COMP_PARAM_BUFFERSUPPLIERTYPE oSupplier;
oSupplier.nPortIndex = nTunneledPort;
((MM_COMPONENTTYPE *)hTunneledComp)->GetConfig(hTunneledComp, COMP_IndexParamCompBufferSupplier, &oSupplier);
oSupplier.eBufferSupplier = pTunnelSetup->eSupplier;
((MM_COMPONENTTYPE *)hTunneledComp)->SetConfig(hTunneledComp, COMP_IndexParamCompBufferSupplier, &oSupplier);
}
return eError;
}
static VIDEO_FRAME_INFO_S *UvcGetReadyFrame(UVCDATATYPE *pUvcInputData)
{
UvcFrameInfo *pEntry = NULL;
pthread_mutex_lock(&pUvcInputData->mOutFrameLock);
if(list_empty(&pUvcInputData->mReadyOutFrameList))
{
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
return NULL;
}
pEntry = list_first_entry(&pUvcInputData->mReadyOutFrameList, UvcFrameInfo, mList);
list_move_tail(&pEntry->mList, &pUvcInputData->mUsedOutFrameList);
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
return &pEntry->VFrame;
}
static ERRORTYPE UvcReleaseFrame(UVCDATATYPE *pUvcInputData, VIDEO_FRAME_INFO_S *pFrame)
{
UvcFrameInfo *pEntry, *pTmp;
BOOL bFindFlag = FALSE;
pthread_mutex_lock(&pUvcInputData->mOutFrameLock);
list_for_each_entry_safe(pEntry, pTmp, &pUvcInputData->mUsedOutFrameList, mList)
{
if(pEntry->VFrame.mId == pFrame->mId)
{
list_del(&pEntry->mList);
bFindFlag = TRUE;
break;
}
}
if(list_empty(&pUvcInputData->mUsedOutFrameList))
{
pthread_cond_signal(&pUvcInputData->mWaiteUsedFrmeEmpty);
}
if(bFindFlag)
{
list_add_tail(&pEntry->mList, &pUvcInputData->mIdleOutFrameList);
}
else
{
aloge("Unknown video virvi frame, frame id[%d]!", pFrame->mId);
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
return FAILURE;
}
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
return SUCCESS;
}
ERRORTYPE UvcGetData(PARAM_IN COMP_HANDLETYPE hComponent, PARAM_OUT UvcStream *pstParams)
{
ERRORTYPE eError = SUCCESS;
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
if(pUvcInputData->state != COMP_StateIdle && pUvcInputData->state != COMP_StateExecuting)
{
alogw("call getStream in wrong state[0x%x]", pUvcInputData->state);
return ERR_UVC_NOT_PERM;
}
if(pUvcInputData->mOutputPortTunnelFlag)
{
return ERR_UVC_NOT_PERM;
}
VIDEO_FRAME_INFO_S *pstFrameInfo = pstParams->pStream;
int nMilliSec = pstParams->nMilliSec;
_TryToGetFrame:
if(list_empty(&pUvcInputData->mReadyOutFrameList))
{
if(0 == nMilliSec)
{
eError = FAILURE;
}
else if(nMilliSec < 0)
{
pUvcInputData->mWaitingCapDataFlag = TRUE;
cdx_sem_down(&pUvcInputData->mSemWaitInputFrame);
pUvcInputData->mWaitingCapDataFlag = FALSE;
goto _TryToGetFrame;
}
else
{
pUvcInputData->mWaitingCapDataFlag = TRUE;
int ret = cdx_sem_down_timedwait(&pUvcInputData->mSemWaitInputFrame, nMilliSec);
if(ETIMEDOUT == ret)
{
eError = FAILURE;
pUvcInputData->mWaitingCapDataFlag = FALSE;
}
else if(0 == ret)
{
pUvcInputData->mWaitingCapDataFlag = FALSE;
goto _TryToGetFrame;
}
else
{
eError = FAILURE;
pUvcInputData->mWaitingCapDataFlag = FALSE;
}
}
}
else
{
pthread_mutex_lock(&pUvcInputData->mOutFrameLock);
UvcFrameInfo *pEntry = list_first_entry(&pUvcInputData->mReadyOutFrameList, UvcFrameInfo, mList);
memcpy(pstFrameInfo, &pEntry->VFrame, sizeof(VIDEO_FRAME_INFO_S));
list_move_tail(&pEntry->mList, &pUvcInputData->mUsedOutFrameList);
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
}
return eError;
}
static ERRORTYPE UvcReleaseData(PARAM_IN COMP_HANDLETYPE hComponent, PARAM_IN UvcStream *pstParams)
{
ERRORTYPE eError = SUCCESS;
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
if(pUvcInputData->state != COMP_StateIdle && pUvcInputData->state != COMP_StateExecuting)
{
alogw("call getStream in wrong state[0x%x]", pUvcInputData->state);
return ERR_UVC_NOT_PERM;
}
if(pUvcInputData->mOutputPortTunnelFlag)
{
return ERR_UVC_NOT_PERM;
}
VIDEO_FRAME_INFO_S *pstFrameInfo = pstParams->pStream;
uvcInput_RefsReduceAndRleaseData2(pUvcInputData->pUvcChnManager, pstFrameInfo);
UvcReleaseFrame(pUvcInputData, pstFrameInfo);
return eError;
}
static ERRORTYPE UvcEmptyThisBuffer(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN COMP_BUFFERHEADERTYPE* pBuffer)
{
ERRORTYPE eError = SUCCESS;
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
pthread_mutex_lock(&pUvcInputData->mStateLock);
if(pUvcInputData->state != COMP_StateExecuting)
{
aloge("send frame when uvc state[0x%x], is not executing", pUvcInputData->state);
eError = FAILURE;
goto err_state;
}
if(pBuffer->nInputPortIndex == pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].nPortIndex)
{
VIDEO_FRAME_INFO_S *pFrm = (VIDEO_FRAME_INFO_S *) pBuffer->pOutputPortPrivate;
pthread_mutex_lock(&pUvcInputData->mOutFrameLock);
if(list_empty(&pUvcInputData->mIdleOutFrameList))
{
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
aloge("the IdleOutFrameList is empty!");
eError = FAILURE;
goto err_mem;
}
UvcFrameInfo *pEnty = list_first_entry(&pUvcInputData->mIdleOutFrameList, UvcFrameInfo, mList);
pEnty->VFrame = *pFrm;
list_move_tail(&pEnty->mList, &pUvcInputData->mReadyOutFrameList);
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
if(pUvcInputData->mWaitingCapDataFlag)
{
if(pUvcInputData->mOutputPortTunnelFlag)
{
pUvcInputData->mWaitingCapDataFlag = FALSE;
message_t msg;
msg.command = UvcComp_InputFrameAvailable;
put_message(&pUvcInputData->cmd_queue, &msg);
}
else
{
pUvcInputData->mWaitingCapDataFlag = FALSE;
cdx_sem_up(&pUvcInputData->mSemWaitInputFrame);
}
}
}
else
{
aloge("fatal error! the portindex can not fit!!");
}
err_mem:
err_state:
pthread_mutex_unlock(&pUvcInputData->mStateLock);
return eError;
}
ERRORTYPE UvcFillThisBuffer(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN COMP_BUFFERHEADERTYPE* pBuffer)
{
ERRORTYPE eError = SUCCESS;
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
VIDEO_FRAME_INFO_S *pDstFrame = NULL;
if(pBuffer->nOutputPortIndex == pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].nPortIndex)
{
if(UVC_H264 == pUvcInputData->pUvcChnManager->mUvcAttr.mPixelformat
|| UVC_MJPEG == pUvcInputData->pUvcChnManager->mUvcAttr.mPixelformat)
{
EncodedStream *pEncodedFrame = (EncodedStream*)pBuffer->pOutputPortPrivate;
UvcFrameInfo *pEntry, *pTmp;
int nFindFlag = 0;
pthread_mutex_lock(&pUvcInputData->mOutFrameLock);
list_for_each_entry_safe(pEntry, pTmp, &pUvcInputData->mUsedOutFrameList, mList)
{
if(pEntry->VFrame.mId == pEncodedFrame->nID)
{
if(0 == nFindFlag)
{
pDstFrame = &pEntry->VFrame;
}
nFindFlag++;
if(nFindFlag > 1)
{
aloge("fatal error! why find [%d]frames? frameId[%d]", nFindFlag, pEncodedFrame->nID);
}
//break;
}
}
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
if(NULL == pDstFrame)
{
aloge("fatal error! can't find frameId[%d], check code!", pEncodedFrame->nID);
}
}
else
{
pDstFrame = (VIDEO_FRAME_INFO_S*)pBuffer->pOutputPortPrivate;
}
if(pDstFrame != NULL)
{
uvcInput_RefsReduceAndRleaseData2(pUvcInputData->pUvcChnManager, pDstFrame);
UvcReleaseFrame(pUvcInputData, pDstFrame);
}
else
{
aloge("fatal error! frame is null! check code!");
}
}
else
{
aloge("fatal error! outputPortIndex[%d]!=[%d]", pBuffer->nOutputPortIndex, pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].nPortIndex);
}
return eError;
}
ERRORTYPE UvcSetConfig(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN COMP_INDEXTYPE nIndex,
PARAM_IN void* pComponentConfigStructure)
{
ERRORTYPE eError = SUCCESS;
switch(nIndex)
{
case COMP_IndexVendorMPPChannelInfo:
eError = UvcSetMPPChannelInfo(hComponent,(MPP_CHN_S *)pComponentConfigStructure);
break;
case COMP_IndexVendorUvcChnAttr:
break;
case COMP_IndexParamPortDefinition:
eError = UvcSetPortDefinition(hComponent, (COMP_PARAM_PORTDEFINITIONTYPE *)pComponentConfigStructure);
break;
case COMP_IndexParamCompBufferSupplier:
eError = UvcSetCompBufferSupplier(hComponent, (COMP_PARAM_BUFFERSUPPLIERTYPE *) pComponentConfigStructure);
break;
case COMP_IndexVendorReleaseUvcFrame:
eError = UvcReleaseData(hComponent, (UvcStream *)pComponentConfigStructure);
break;
case COMP_IndexVendorUvcSetDevInfo:
eError = UvcSetDevInfo(hComponent, (UvcChnManager *)pComponentConfigStructure);
break;
default :
eError = FAILURE;
aloge("fatal error! check the nIndex[0x%x] !", nIndex);
break;
}
return eError;
}
ERRORTYPE UvcGetConfig(
PARAM_IN COMP_HANDLETYPE hComponent,
PARAM_IN COMP_INDEXTYPE nIndex,
PARAM_IN void* pComponentConfigStructure)
{
ERRORTYPE eError = SUCCESS;
switch(nIndex)
{
case COMP_IndexVendorMPPChannelInfo:
eError = UvcGetMPPChannelInfo(hComponent, (MPP_CHN_S *)pComponentConfigStructure);
break;
case COMP_IndexParamPortDefinition:
eError = UvcGetPortDefinition(hComponent, (COMP_PARAM_PORTDEFINITIONTYPE *)pComponentConfigStructure);
break;
case COMP_IndexParamCompBufferSupplier:
eError = UvcGetCompBufferSupplier(hComponent, (COMP_PARAM_BUFFERSUPPLIERTYPE *)pComponentConfigStructure);
break;
case COMP_IndexVendorGetUvcFrame:
eError = UvcGetData(hComponent, (UvcStream *)pComponentConfigStructure);
break;
case COMP_IndexVendorParamPortExtraDefinition:
eError = UvcGetPortExtraDef(hComponent, (COMP_PARAM_PORTEXTRADEFINITIONTYPE *)pComponentConfigStructure);
break;
default :
eError = FAILURE;
aloge("fatal error! check the nIndex[0x%x] !", nIndex);
break;
}
return eError;
}
ERRORTYPE UvcComponentDeInit(void *hComponent)
{
ERRORTYPE eError = SUCCESS;
if(!hComponent)
{
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *) (((MM_COMPONENTTYPE*) hComponent)->pComponentPrivate);
CompInternalMsgType eCmd = Stop;
message_t msg;
int ret = 0,i = 0;
msg.command = eCmd;
put_message(&pUvcInputData->cmd_queue, &msg);
pthread_join(pUvcInputData->thread_id, (void *)&eError);
message_destroy(&pUvcInputData->cmd_queue);
pthread_mutex_lock(&pUvcInputData->mOutFrameLock);
if(!list_empty(&pUvcInputData->mReadyOutFrameList))
{
aloge("fatal error! why readyOutFramelist is not empty?");
}
if(!list_empty(&pUvcInputData->mIdleOutFrameList))
{
UvcFrameInfo *pEntry,*pTmp;
list_for_each_entry_safe(pEntry, pTmp, &pUvcInputData->mIdleOutFrameList, mList)
{
list_del(&pEntry->mList);
free(pEntry);
}
}
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
pthread_cond_destroy(&pUvcInputData->mWaiteUsedFrmeEmpty);
pthread_mutex_destroy(&pUvcInputData->mOutFrameLock);
cdx_sem_deinit(&pUvcInputData->mSemWaitInputFrame);
pthread_mutex_destroy(&pUvcInputData->mStateLock);
if(pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_DATA_OUT].pVendorInfo)
{
free((VideoStreamInfo *)pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_DATA_OUT].pVendorInfo);
pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_DATA_OUT].pVendorInfo = NULL;
}
free(pUvcInputData);
return eError;
}
ERRORTYPE UvcComponentInit(PARAM_IN COMP_HANDLETYPE hComponent)
{
ERRORTYPE eError = SUCCESS;
if(!hComponent)
{
eError = ERR_UVC_ILLEGAL_PARAM;
return eError;
}
int ret = 0, i = 0;
MM_COMPONENTTYPE *pComp = (MM_COMPONENTTYPE *)hComponent;
UVCDATATYPE *pUvcInputData = (UVCDATATYPE*)malloc(sizeof(UVCDATATYPE));
if(!pUvcInputData)
{
eError = ERR_UVC_NOMEM;
return eError;
}
memset(pUvcInputData, 0, sizeof *pUvcInputData);
pComp->pComponentPrivate = (void *)pUvcInputData;
pUvcInputData->hSelf = hComponent;
pUvcInputData->state = COMP_StateLoaded;
pthread_mutex_init(&pUvcInputData->mStateLock, NULL);
pUvcInputData->mWaitingCapDataFlag = FALSE;
cdx_sem_init(&pUvcInputData->mSemWaitInputFrame, 0 );
pthread_cond_init(&pUvcInputData->mWaiteUsedFrmeEmpty, NULL);
pthread_mutex_init(&pUvcInputData->mOutFrameLock, NULL);
INIT_LIST_HEAD(&pUvcInputData->mIdleOutFrameList);
INIT_LIST_HEAD(&pUvcInputData->mReadyOutFrameList);
INIT_LIST_HEAD(&pUvcInputData->mUsedOutFrameList);
for(i = 0; i < UVC_FIFO_LEVEL_INIT; i++)
{
UvcFrameInfo *pUvcFrameInfo = (UvcFrameInfo *)malloc(sizeof(UvcFrameInfo));
if(!pUvcFrameInfo)
{
aloge("fatal error! malloc fail[%s]!", strerror(errno));
eError = ERR_UVC_NOMEM;
return eError;
}
list_add_tail(&pUvcFrameInfo->mList, &pUvcInputData->mIdleOutFrameList);
}
pComp->SetCallbacks = UvcSetCallbacks;
pComp->SendCommand = UvcSendCommand;
pComp->GetConfig = UvcGetConfig;
pComp->SetConfig = UvcSetConfig;
pComp->GetState = UvcGetState;
pComp->ComponentTunnelRequest = UvcComponentTunnelRequest;
pComp->ComponentDeInit = UvcComponentDeInit;
pComp->EmptyThisBuffer = UvcEmptyThisBuffer;
pComp->FillThisBuffer = UvcFillThisBuffer;
pUvcInputData->sPortParam.nPorts = 0;
pUvcInputData->sPortParam.nStartPortNumber = 0;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].nPortIndex = pUvcInputData->sPortParam.nPorts;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].bEnabled = TRUE;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].eDomain = COMP_PortDomainVideo;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].eDir = COMP_DirInput;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].format.video.cMIMEType = "YVU420";
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].format.video.nFrameWidth = 176;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].format.video.nFrameHeight = 144;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].format.video.eCompressionFormat = PT_BUTT;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_NCOM_IN].format.video.eColorFormat = MM_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
pUvcInputData->sPortBufSupplier[UVC_CHN_PORT_INDEX_NCOM_IN].nPortIndex = pUvcInputData->sPortParam.nPorts;
pUvcInputData->sPortBufSupplier[UVC_CHN_PORT_INDEX_NCOM_IN].eBufferSupplier = COMP_BufferSupplyInput;
pUvcInputData->sPortTunnelInfo[UVC_CHN_PORT_INDEX_NCOM_IN].nPortIndex = pUvcInputData->sPortParam.nPorts;
pUvcInputData->sPortTunnelInfo[UVC_CHN_PORT_INDEX_NCOM_IN].eTunnelType = TUNNEL_TYPE_COMMON;
pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_NCOM_IN].nPortIndex = pUvcInputData->sPortParam.nPorts;
pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_NCOM_IN].pVendorInfo = NULL;
pUvcInputData->sPortParam.nPorts++;
// pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_COMP_IN].nPortIndex = pUvcInputData->sPortParam.nPorts;
// pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_COMP_IN].bEnabled = TRUE;
// pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_COMP_IN].eDomain = COMP_PortDomainVideo;
// pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_COMP_IN].eDir = COMP_DirInput;
// pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_COMP_IN].format.video.cMIMEType = "YVU420";
// pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_COMP_IN].format.video.nFrameWidth = 176;
// pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_COMP_IN].format.video.nFrameHeight = 144;
// pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_COMP_IN].format.video.eCompressionFormat = PT_BUTT;
// pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_COMP_IN].format.video.eColorFormat = MM_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
// pUvcInputData->sPortBufSupplier[UVC_CHN_PORT_INDEX_COMP_IN].nPortIndex = pUvcInputData->sPortParam.nPorts;
// pUvcInputData->sPortBufSupplier[UVC_CHN_PORT_INDEX_COMP_IN].eBufferSupplier = COMP_BufferSupplyInput;
// pUvcInputData->sPortTunnelInfo[UVC_CHN_PORT_INDEX_COMP_IN].nPortIndex = pUvcInputData->sPortParam.nPorts;
// pUvcInputData->sPortTunnelInfo[UVC_CHN_PORT_INDEX_COMP_IN].eTunnelType = TUNNEL_TYPE_COMMON;
// pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_COMP_IN].nPortIndex = pUvcInputData->sPortParam.nPorts;
// pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_COMP_IN].pVendorInfo = NULL;
// pUvcInputData->sPortParam.nPorts++;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].nPortIndex = pUvcInputData->sPortParam.nPorts;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].bEnabled = TRUE;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].eDomain = COMP_PortDomainVideo;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].eDir = COMP_DirOutput;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].format.video.cMIMEType = "YVU420";
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].format.video.nFrameWidth = 176;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].format.video.nFrameHeight = 144;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].format.video.eCompressionFormat = PT_BUTT; // YCbCr420;
pUvcInputData->sPortDef[UVC_CHN_PORT_INDEX_DATA_OUT].format.video.eColorFormat = MM_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
pUvcInputData->sPortBufSupplier[UVC_CHN_PORT_INDEX_DATA_OUT].nPortIndex = pUvcInputData->sPortParam.nPorts;
pUvcInputData->sPortBufSupplier[UVC_CHN_PORT_INDEX_DATA_OUT].eBufferSupplier = COMP_BufferSupplyOutput;
pUvcInputData->sPortTunnelInfo[UVC_CHN_PORT_INDEX_DATA_OUT].nPortIndex = pUvcInputData->sPortParam.nPorts;
pUvcInputData->sPortTunnelInfo[UVC_CHN_PORT_INDEX_DATA_OUT].eTunnelType = TUNNEL_TYPE_COMMON;
pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_DATA_OUT].nPortIndex = pUvcInputData->sPortParam.nPorts;
pUvcInputData->sPortExtraDef[UVC_CHN_PORT_INDEX_DATA_OUT].pVendorInfo = NULL;
pUvcInputData->sPortParam.nPorts++;
if(message_create(&pUvcInputData->cmd_queue) < 0)
{
aloge("message error!");
eError = ERR_UVC_NOMEM;
return eError;
}
if(pthread_create(&pUvcInputData->thread_id, NULL, Uvc_ComponentThread, pUvcInputData) || !pUvcInputData->thread_id)
{
aloge("creat Uvc_ComponentThread fail!");
eError = ERR_UVC_NOMEM;
return eError;
}
alogw("UvcVirvi_Component had Init!!!");
return eError;
}
static void *Uvc_ComponentThread(void *pThreadData)
{
unsigned int cmddaata;
CompInternalMsgType cmd;
UVCDATATYPE *pUvcInputData = (UVCDATATYPE *)pThreadData;
message_t cmd_msg;
alogd("UVC ComponentThread start run!");
prctl(PR_SET_NAME, "UvcComponentThread", 0, 0, 0);
while(1)
{
PROCESS_MESSAGE:
if(0 == get_message(&pUvcInputData->cmd_queue, &cmd_msg))
{
cmd = cmd_msg.command;
cmddaata = (unsigned int)cmd_msg.para0;
if(cmd == SetState)
{
pthread_mutex_lock(&pUvcInputData->mStateLock);
if(pUvcInputData->state == (COMP_STATETYPE)cmddaata)
{
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventError, ERR_UVC_SAMESTATE, 0, NULL);
}
else
{
switch((COMP_STATETYPE)cmddaata)
{
case COMP_StateInvalid:
pUvcInputData->state = COMP_StateInvalid;
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventError, ERR_UVC_INVALIDSTATE, 0, NULL);
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventCmdComplete, COMP_CommandStateSet,
pUvcInputData->state, NULL);
break;
case COMP_StateLoaded:
if(pUvcInputData->state != COMP_StateIdle)
{
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventError, ERR_UVC_INCORRECT_STATE_TRANSITION, 0, NULL);
}
else
{
pthread_mutex_lock(&pUvcInputData->mOutFrameLock);
if(!list_empty(&pUvcInputData->mReadyOutFrameList))
{
aloge("fatal error! ready frame list is not empty!");
}
while(!list_empty(&pUvcInputData->mUsedOutFrameList))
{
alogd("wait all Using frame return");
pthread_cond_wait(&pUvcInputData->mWaiteUsedFrmeEmpty, &pUvcInputData->mOutFrameLock);
}
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
pUvcInputData->state = COMP_StateLoaded;
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventCmdComplete, COMP_CommandStateSet,
pUvcInputData->state, NULL);
}
break;
case COMP_StateIdle:
if(COMP_StateLoaded == pUvcInputData->state)
{
pUvcInputData->state = COMP_StateIdle;
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventCmdComplete, COMP_CommandStateSet,
pUvcInputData->state, NULL);
}
else if(COMP_StatePause == pUvcInputData->state || COMP_StateExecuting == pUvcInputData->state)
{
pthread_mutex_lock(&pUvcInputData->mOutFrameLock);
if(!list_empty(&pUvcInputData->mReadyOutFrameList))
{
int num = 0;
UvcFrameInfo *pEntry, *pTmp;
list_for_each_entry_safe(pEntry, pTmp, &pUvcInputData->mReadyOutFrameList, mList)
{
uvcInput_RefsReduceAndRleaseData2(pUvcInputData->pUvcChnManager, &pEntry->VFrame);
list_move_tail(&pEntry->mList, &pUvcInputData->mIdleOutFrameList);
num++;
}
alogd("There are [%d] ready frames to be return!", num);
}
if(!list_empty(&pUvcInputData->mUsedOutFrameList))
{
int cnt = 0;
struct list_head *pList;
list_for_each(pList, &pUvcInputData->mUsedOutFrameList) { cnt++; }
alogd("Be careful! [%d]used out frame not return, need wait when in convertion to loaded", cnt);
}
pthread_mutex_unlock(&pUvcInputData->mOutFrameLock);
pUvcInputData->state = COMP_StateIdle;
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventCmdComplete, COMP_CommandStateSet,
pUvcInputData->state, NULL);
}
else
{
aloge("fatal error! current state[0x%x] can't turn to idle!", pUvcInputData->state);
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventError, ERR_UVC_INCORRECT_STATE_TRANSITION, 0, NULL);
}
break;
case COMP_StateExecuting:
if(COMP_StateIdle == pUvcInputData->state || COMP_StateExecuting == pUvcInputData->state
|| COMP_StatePause == pUvcInputData->state)
{
pUvcInputData->state = COMP_StateExecuting;
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventCmdComplete, COMP_CommandStateSet,
pUvcInputData->state, NULL);
}
else
{
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventError, ERR_UVC_INCORRECT_STATE_TRANSITION, 0, NULL);
}
break;
case COMP_StatePause:
if(COMP_StateIdle == pUvcInputData->state || COMP_StateExecuting == pUvcInputData->state)
{
pUvcInputData->state = COMP_StatePause;
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventCmdComplete, COMP_CommandStateSet,
pUvcInputData->state, NULL);
}
else
{
pUvcInputData->pCallbacks->EventHandler(pUvcInputData->hSelf, pUvcInputData->pAppData,
COMP_EventError, ERR_UVC_INCORRECT_STATE_TRANSITION, 0, NULL);
}
break;
default:
break;
}
}
pthread_mutex_unlock(&pUvcInputData->mStateLock);
}
else if(Flush == cmd)
{
}
else if(UvcComp_InputFrameAvailable == cmd)
{
}
else if(Stop == cmd)
{
goto EXIT;
}
goto PROCESS_MESSAGE;
}
int eError;
if(COMP_StateExecuting == pUvcInputData->state)
{
if(TRUE == pUvcInputData->mOutputPortTunnelFlag)
{
COMP_INTERNAL_TUNNELINFOTYPE *pPortTunnelInfo = &pUvcInputData->sPortTunnelInfo[UVC_CHN_PORT_INDEX_DATA_OUT];
MM_COMPONENTTYPE *pOutTunnelComp = (MM_COMPONENTTYPE *)pPortTunnelInfo->hTunnel;
if(pOutTunnelComp)
{
COMP_BUFFERHEADERTYPE obh;
EncodedStream stEncodedFrame;
VIDEO_FRAME_INFO_S *pFrm = UvcGetReadyFrame(pUvcInputData);
if(!pFrm)
{
pUvcInputData->mWaitingCapDataFlag = TRUE;
TMessage_WaitQueueNotEmpty(&pUvcInputData->cmd_queue, 0);
goto PROCESS_MESSAGE;
}
obh.nOutputPortIndex = pPortTunnelInfo->nPortIndex;
obh.nInputPortIndex = pPortTunnelInfo->nTunnelPortIndex;
if(UVC_H264 == pUvcInputData->pUvcChnManager->mUvcAttr.mPixelformat
|| UVC_MJPEG == pUvcInputData->pUvcChnManager->mUvcAttr.mPixelformat)
{
//h264, jpeg, etc.
memset(&stEncodedFrame, 0, sizeof(EncodedStream));
stEncodedFrame.media_type = CDX_PacketVideo;
stEncodedFrame.nID = pFrm->mId;
stEncodedFrame.nFilledLen = pFrm->VFrame.mStride[0];
stEncodedFrame.nTobeFillLen = pFrm->VFrame.mStride[0];
stEncodedFrame.nTimeStamp = pFrm->VFrame.mpts;
stEncodedFrame.nFlags = CEDARV_FLAG_PTS_VALID | CEDARV_FLAG_FIRST_PART | CEDARV_FLAG_LAST_PART;
stEncodedFrame.pBuffer = pFrm->VFrame.mpVirAddr[0];
stEncodedFrame.pBufferExtra = NULL;
stEncodedFrame.nBufferLen = pFrm->VFrame.mStride[0];
stEncodedFrame.nBufferExtraLen = 0;
stEncodedFrame.video_stream_type = VIDEO_TYPE_MAJOR;
obh.pOutputPortPrivate = (void*)&stEncodedFrame;
}
else
{
obh.pOutputPortPrivate = (void*)pFrm;
}
eError = pOutTunnelComp->EmptyThisBuffer(pOutTunnelComp, &obh);
if(eError != SUCCESS)
{
alogw("Loop UvcVirVi_ComponentThread OutTunnelComp EmptyThisBuffer failed %x, return this frame", eError);
uvcInput_RefsReduceAndRleaseData2(pUvcInputData->pUvcChnManager,pFrm);
UvcReleaseFrame(pUvcInputData, pFrm);
}
}
else
{
TMessage_WaitQueueNotEmpty(&pUvcInputData->cmd_queue, 0);
goto PROCESS_MESSAGE;
}
}
else
{
TMessage_WaitQueueNotEmpty(&pUvcInputData->cmd_queue, 0);
}
}
else
{
TMessage_WaitQueueNotEmpty(&pUvcInputData->cmd_queue, 0);
}
}
EXIT:
alogv("UVC ComponentThread stopeed!");
return (void *)SUCCESS;
}