mirror of
https://gitee.com/Vancouver2017/luban-lite.git
synced 2025-12-23 12:38:54 +00:00
1412 lines
46 KiB
C
Executable File
1412 lines
46 KiB
C
Executable File
/*
|
|
* Copyright (C) 2020-2023 ArtInChip Technology Co. Ltd
|
|
*
|
|
* author: <jun.ma@artinchip.com>
|
|
* Desc: OMX_AdecComponent
|
|
*/
|
|
|
|
#include "OMX_AdecComponent.h"
|
|
|
|
#define aic_pthread_mutex_lock(mutex)\
|
|
{\
|
|
/*loge("before lock\n");*/\
|
|
pthread_mutex_lock(mutex);\
|
|
/*loge("after lock\n");*/\
|
|
}
|
|
|
|
#define aic_pthread_mutex_unlock(mutex)\
|
|
{\
|
|
/*loge("before unlock\n");*/\
|
|
pthread_mutex_unlock(mutex);\
|
|
/*loge("after unlock\n");*/\
|
|
}
|
|
|
|
#define OMX_AdecListEmpty(list,mutex)\
|
|
({\
|
|
int ret = 0;\
|
|
aic_pthread_mutex_lock(&mutex);\
|
|
ret = mpp_list_empty(list);\
|
|
aic_pthread_mutex_unlock(&mutex);\
|
|
(ret);\
|
|
})
|
|
|
|
static OMX_ERRORTYPE OMX_AdecSendCommand(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_COMMANDTYPE Cmd,
|
|
OMX_IN OMX_U32 nParam1,
|
|
OMX_IN OMX_PTR pCmdData);
|
|
|
|
static OMX_ERRORTYPE OMX_AdecGetParameter(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_INDEXTYPE nParamIndex,
|
|
OMX_INOUT OMX_PTR pComponentParameterStructure);
|
|
|
|
static OMX_ERRORTYPE OMX_AdecSetParameter(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_INDEXTYPE nIndex,
|
|
OMX_IN OMX_PTR pComponentParameterStructure);
|
|
|
|
static OMX_ERRORTYPE OMX_AdecGetConfig(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_INDEXTYPE nIndex,
|
|
OMX_INOUT OMX_PTR pComponentConfigStructure);
|
|
|
|
static OMX_ERRORTYPE OMX_AdecSetConfig(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_INDEXTYPE nIndex,
|
|
OMX_IN OMX_PTR pComponentConfigStructure);
|
|
|
|
static OMX_ERRORTYPE OMX_AdecGetState(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_OUT OMX_STATETYPE* pState);
|
|
|
|
static OMX_ERRORTYPE OMX_AdecComponentTunnelRequest(
|
|
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_AdecEmptyThisBuffer(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
|
|
|
|
|
|
static OMX_ERRORTYPE OMX_AdecFillThisBuffer(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
|
|
|
|
static OMX_ERRORTYPE OMX_AdecSetCallbacks(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
|
|
OMX_IN OMX_PTR pAppData);
|
|
|
|
|
|
|
|
static OMX_ERRORTYPE OMX_AdecSendCommand(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_COMMANDTYPE Cmd,
|
|
OMX_IN OMX_U32 nParam1,
|
|
OMX_IN OMX_PTR pCmdData)
|
|
{
|
|
ADEC_DATA_TYPE *pAdecDataType;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
struct aic_message sMsg;
|
|
pAdecDataType = (ADEC_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(&pAdecDataType->sMsgQue, &sMsg);
|
|
return eError;
|
|
}
|
|
|
|
|
|
static void* OMX_AdecComponentThread(void* pThreadData);
|
|
|
|
static OMX_ERRORTYPE OMX_AdecGetParameter(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_INDEXTYPE nParamIndex,
|
|
OMX_INOUT OMX_PTR pComponentParameterStructure)
|
|
{
|
|
ADEC_DATA_TYPE *pAdecDataType;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
//OMX_U32 tmp1,tmp2;
|
|
|
|
pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
|
|
|
|
switch (nParamIndex){
|
|
case OMX_IndexParamPortDefinition:{
|
|
OMX_PARAM_PORTDEFINITIONTYPE *port = (OMX_PARAM_PORTDEFINITIONTYPE*)pComponentParameterStructure;
|
|
if(port->nPortIndex == ADEC_PORT_IN_INDEX){
|
|
memcpy(port,&pAdecDataType->sInPortDef,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
|
|
}else if(port->nPortIndex == ADEC_PORT_OUT_INDEX){
|
|
memcpy(port,&pAdecDataType->sOutPortDef,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
|
|
}else{
|
|
eError = OMX_ErrorBadParameter;
|
|
}
|
|
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 == 0){
|
|
sBufferSupplier->eBufferSupplier = pAdecDataType->sInBufSupplier.eBufferSupplier;
|
|
}else if(sBufferSupplier->nPortIndex == 1){
|
|
sBufferSupplier->eBufferSupplier = pAdecDataType->sOutBufSupplier.eBufferSupplier;
|
|
}else{
|
|
loge("error nPortIndex\n");
|
|
eError = OMX_ErrorBadPortIndex;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
eError = OMX_ErrorNotImplemented;
|
|
break;
|
|
}
|
|
|
|
return eError;
|
|
}
|
|
|
|
static OMX_S32 OMX_AdecAudioFormatTrans(enum aic_audio_codec_type *eDesType,OMX_AUDIO_CODINGTYPE *eSrcType)
|
|
{
|
|
OMX_S32 ret = 0;
|
|
if( eDesType== NULL || eSrcType == NULL){
|
|
loge("bad params!!!!\n");
|
|
return -1;
|
|
}
|
|
if(*eSrcType == OMX_AUDIO_CodingMP3){
|
|
*eDesType = MPP_CODEC_AUDIO_DECODER_MP3;
|
|
}else{
|
|
*eDesType = MPP_CODEC_AUDIO_DECODER_MP3;
|
|
loge("unsupport codec!!!!\n");
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static OMX_ERRORTYPE OMX_AdecSetParameter(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_INDEXTYPE nParamIndex,
|
|
OMX_IN OMX_PTR pComponentParameterStructure)
|
|
{
|
|
ADEC_DATA_TYPE *pAdecDataType;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
//OMX_S32 tmp1,tmp2;
|
|
OMX_U32 index;
|
|
enum aic_audio_codec_type eCodecType;
|
|
OMX_PARAM_FRAMEEND *sFrameEnd;
|
|
pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
|
|
switch ((OMX_S32)nParamIndex){
|
|
case OMX_IndexParamAudioPortFormat:{
|
|
OMX_AUDIO_PARAM_PORTFORMATTYPE *sPortFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE*)pComponentParameterStructure;
|
|
index = sPortFormat->nPortIndex;
|
|
if(index == ADEC_PORT_IN_INDEX){
|
|
pAdecDataType->sInPortDef.format.audio.eEncoding = sPortFormat->eEncoding;
|
|
logw("eEncoding:%d\n",pAdecDataType->sInPortDef.format.audio.eEncoding );
|
|
if(OMX_AdecAudioFormatTrans(&eCodecType,&sPortFormat->eEncoding) != 0){
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
loge("OMX_ErrorUnsupportedSetting\n");
|
|
break;
|
|
}
|
|
pAdecDataType->eCodeType = eCodecType;
|
|
logw("eCodeType:%d\n",pAdecDataType->eCodeType);
|
|
/*need to define extened OMX_Index or decide by inner*/
|
|
pAdecDataType->sDecoderConfig.packet_buffer_size = 16*1024;
|
|
pAdecDataType->sDecoderConfig.packet_count = 8;
|
|
pAdecDataType->sDecoderConfig.frame_count = 16;
|
|
|
|
}else if(index == ADEC_PORT_OUT_INDEX){
|
|
logw("now no need to set out port param\n");
|
|
}else{
|
|
loge("OMX_ErrorBadParameter\n");
|
|
}
|
|
break;
|
|
}
|
|
case OMX_IndexParamPortDefinition:{
|
|
OMX_PARAM_PORTDEFINITIONTYPE *port = (OMX_PARAM_PORTDEFINITIONTYPE*)pComponentParameterStructure;
|
|
index = port->nPortIndex;
|
|
if(index == ADEC_PORT_IN_INDEX){
|
|
pAdecDataType->sInPortDef.format.audio.eEncoding = port->format.audio.eEncoding;
|
|
logw("eEncoding:%d\n",pAdecDataType->sInPortDef.format.audio.eEncoding );
|
|
if(OMX_AdecAudioFormatTrans(&eCodecType,&port->format.audio.eEncoding) != 0){
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
loge("OMX_ErrorUnsupportedSetting\n");
|
|
break;
|
|
}
|
|
|
|
/*need to convert */
|
|
pAdecDataType->eCodeType = eCodecType;
|
|
logw("eCompressionFormat:%d\n",pAdecDataType->eCodeType);
|
|
/*need to define extened OMX_Index or decide by inner*/
|
|
pAdecDataType->sDecoderConfig.packet_buffer_size = 16*1024;
|
|
pAdecDataType->sDecoderConfig.packet_count = 8;
|
|
pAdecDataType->sDecoderConfig.frame_count = 16;
|
|
|
|
}else if(index == ADEC_PORT_OUT_INDEX){
|
|
logw("now no need to set out port param\n");
|
|
}else{
|
|
loge("OMX_ErrorBadParameter\n");
|
|
eError = OMX_ErrorBadParameter;
|
|
}
|
|
}
|
|
break;
|
|
case OMX_IndexParamVideoAvc:
|
|
break;
|
|
case OMX_IndexParamVideoProfileLevelQuerySupported:
|
|
break;
|
|
case OMX_IndexParamVideoProfileLevelCurrent:
|
|
break;
|
|
case OMX_IndexParamVideoMpeg4:
|
|
break;
|
|
case OMX_IndexVendorStreamFrameEnd:
|
|
sFrameEnd = (OMX_PARAM_FRAMEEND*)pComponentParameterStructure;
|
|
if(sFrameEnd->bFrameEnd == OMX_TRUE){
|
|
pAdecDataType->nStreamEndFlag = OMX_TRUE;
|
|
logi("setup nStreamEndFlag\n");
|
|
}else{
|
|
pAdecDataType->nStreamEndFlag = OMX_FALSE;
|
|
pAdecDataType->nDecodeEndFlag = OMX_FALSE;
|
|
pAdecDataType->nFrameEndFlag = OMX_FALSE;
|
|
logi("cancel nStreamEndFlag\n");
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return eError;
|
|
}
|
|
|
|
static OMX_ERRORTYPE OMX_AdecGetConfig(
|
|
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_AdecSetConfig(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_INDEXTYPE nIndex,
|
|
OMX_IN OMX_PTR pComponentConfigStructure)
|
|
{
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
//ADEC_DATA_TYPE* pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
|
|
|
|
switch (nIndex){
|
|
case OMX_IndexConfigTimePosition:
|
|
// 1 clear input buffer
|
|
// 2 clear output buffer
|
|
//
|
|
|
|
break;
|
|
case OMX_IndexConfigTimeSeekMode:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return eError;
|
|
|
|
}
|
|
|
|
|
|
|
|
static OMX_ERRORTYPE OMX_AdecGetState(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_OUT OMX_STATETYPE* pState)
|
|
{
|
|
ADEC_DATA_TYPE* pAdecDataType;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
|
|
|
|
aic_pthread_mutex_lock(&pAdecDataType->stateLock);
|
|
*pState = pAdecDataType->state;
|
|
aic_pthread_mutex_unlock(&pAdecDataType->stateLock);
|
|
|
|
return eError;
|
|
|
|
}
|
|
|
|
static OMX_ERRORTYPE OMX_AdecComponentTunnelRequest(
|
|
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;
|
|
ADEC_DATA_TYPE* pAdecDataType;
|
|
pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComp)->pComponentPrivate);
|
|
if(pAdecDataType->state != OMX_StateLoaded)
|
|
{
|
|
loge("Component is not in OMX_StateLoaded,it is in%d,it can not tunnel\n",pAdecDataType->state);
|
|
return OMX_ErrorInvalidState;
|
|
}
|
|
if(nPort == ADEC_PORT_IN_INDEX){
|
|
pPort = &pAdecDataType->sInPortDef;
|
|
pTunneledInfo = &pAdecDataType->sInPortTunneledInfo;
|
|
pBufSupplier = &pAdecDataType->sInBufSupplier;
|
|
}else if(nPort == ADEC_PORT_OUT_INDEX){
|
|
pPort = &pAdecDataType->sOutPortDef;
|
|
pTunneledInfo = &pAdecDataType->sOutPortTunneledInfo;
|
|
pBufSupplier = &pAdecDataType->sOutBufSupplier;
|
|
}else{
|
|
loge("component can not find port :%d\n",nPort);
|
|
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_AdecEmptyThisBuffer(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
|
|
{
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
ADEC_DATA_TYPE* pAdecDataType;
|
|
ADEC_IN_PACKET *pktNode;
|
|
int ret = 0;
|
|
struct aic_message sMsg;
|
|
pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
|
|
|
|
aic_pthread_mutex_lock(&pAdecDataType->stateLock);
|
|
if(pAdecDataType->state != OMX_StateExecuting){
|
|
loge("component is not in OMX_StateExecuting,it is in [%d]!!!\n",pAdecDataType->state);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->stateLock);
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
}
|
|
aic_pthread_mutex_unlock(&pAdecDataType->stateLock);
|
|
|
|
|
|
if(pAdecDataType->sInPortTunneledInfo.nTunneledFlag){
|
|
if(pAdecDataType->sInBufSupplier.eBufferSupplier == OMX_BufferSupplyOutput){
|
|
if(OMX_AdecListEmpty(&pAdecDataType->sInEmptyPkt,pAdecDataType->sInPktLock)){
|
|
if(pAdecDataType->nInPktNodeNum + 1> ADEC_PACKET_NUM_MAX){
|
|
loge("empty node has aready increase to max [%d]!!!\n",pAdecDataType->nInPktNodeNum);
|
|
eError = OMX_ErrorInsufficientResources;
|
|
pAdecDataType->nReceivePacktFailNum++;
|
|
return eError;
|
|
}else{
|
|
int i;
|
|
logw("no empty node,need to extend!!!\n");
|
|
for(i =0 ; i < ADEC_PACKET_ONE_TIME_CREATE_NUM; i++ ){
|
|
ADEC_IN_PACKET *pPktNode = (ADEC_IN_PACKET*)mpp_alloc(sizeof(ADEC_IN_PACKET));
|
|
if(NULL == pPktNode){
|
|
break;
|
|
}
|
|
memset(pPktNode,0x00,sizeof(ADEC_IN_PACKET));
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
mpp_list_add_tail(&pPktNode->sList, &pAdecDataType->sInEmptyPkt);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
pAdecDataType->nInPktNodeNum++;
|
|
}
|
|
if(i == 0){
|
|
loge("mpp_alloc empty video node fail\n");
|
|
eError = OMX_ErrorInsufficientResources;
|
|
pAdecDataType->nReceivePacktFailNum++;
|
|
return eError;
|
|
}
|
|
}
|
|
}
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
pktNode = mpp_list_first_entry(&pAdecDataType->sInEmptyPkt, ADEC_IN_PACKET, sList);
|
|
pktNode->sBuff.nOutputPortIndex = pBuffer->nOutputPortIndex;
|
|
pktNode->sBuff.pBuffer = pBuffer->pBuffer;
|
|
pktNode->sBuff.nFilledLen = pBuffer->nFilledLen;
|
|
pktNode->sBuff.nTimeStamp = pBuffer->nTimeStamp;
|
|
pktNode->sBuff.nFlags = pBuffer->nFlags;
|
|
if(pktNode->sBuff.nFlags & PACKET_FLAG_EOS){
|
|
pAdecDataType->nFlags |= ADEC_INPORT_STREAM_END_FLAG;
|
|
//pAdecDataType->nStreamEndFlag = OMX_TRUE;
|
|
logw("nStreamEndFlag");
|
|
}
|
|
mpp_list_del(&pktNode->sList);
|
|
mpp_list_add_tail(&pktNode->sList, &pAdecDataType->sInReadyPkt);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
|
|
sMsg.message_id = OMX_CommandNops;
|
|
sMsg.data_size = 0;
|
|
aic_msg_put(&pAdecDataType->sMsgQue, &sMsg);
|
|
|
|
pAdecDataType->nReceivePacktOkNum++;
|
|
logi("pAdecDataType->nReceivePacktOkNum:%d\n",pAdecDataType->nReceivePacktOkNum);
|
|
}else if(pAdecDataType->sInBufSupplier.eBufferSupplier == OMX_BufferSupplyInput){
|
|
eError = OMX_ErrorNotImplemented;
|
|
logw("OMX_ErrorNotImplemented\n");
|
|
}else{
|
|
eError = OMX_ErrorNotImplemented;
|
|
logw("OMX_ErrorNotImplemented\n");
|
|
}
|
|
}else{
|
|
struct mpp_packet pkt;
|
|
pkt.size = pBuffer->nFilledLen;
|
|
ret = aic_audio_decoder_get_packet(pAdecDataType->pDecoder, &pkt, pkt.size);
|
|
if(ret != 0){
|
|
//loge("get pkt from decoder error ret:%d!!!\n",ret);
|
|
if(ret == DEC_NO_EMPTY_PACKET){
|
|
pAdecDataType->nReceivePacktFailNum++;
|
|
return OMX_ErrorOverflow;
|
|
}else{
|
|
pAdecDataType->nReceivePacktFailNum++;
|
|
return OMX_ErrorInsufficientResources;
|
|
}
|
|
}else{
|
|
//logw("get pkt from decoder ok!!!\n");
|
|
}
|
|
memcpy(pkt.data,pBuffer->pBuffer,pkt.size);
|
|
pkt.flag =pBuffer->nFlags;
|
|
pkt.pts = pBuffer->nTimeStamp;
|
|
//mpp_decoder_get_packet is ok then mpp_decoder_put_packet is also ok
|
|
aic_audio_decoder_put_packet(pAdecDataType->pDecoder, &pkt);
|
|
if(pkt.flag & PACKET_FLAG_EOS){
|
|
pAdecDataType->nFlags |= ADEC_INPORT_STREAM_END_FLAG;
|
|
//pAdecDataType->nStreamEndFlag = OMX_TRUE;
|
|
logi("StreamEndFlag!!!\n");
|
|
}
|
|
pAdecDataType->nReceivePacktOkNum++;
|
|
pAdecDataType->nGiveBackPacktOkNum++;
|
|
}
|
|
return eError;
|
|
}
|
|
|
|
static OMX_ERRORTYPE OMX_AdecFillThisBuffer(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
|
|
{
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
ADEC_DATA_TYPE* pAdecDataType;
|
|
struct aic_audio_frame *pFrame;
|
|
ADEC_OUT_FRAME *pFrameNode1 = NULL,*pFrameNode2 = NULL;
|
|
OMX_BOOL bMatch = OMX_FALSE;
|
|
OMX_S32 ret;
|
|
pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
|
|
if(pBuffer->nOutputPortIndex != ADEC_PORT_OUT_INDEX){
|
|
loge("port not match\n");
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
if(!OMX_AdecListEmpty(&pAdecDataType->sOutProcessingFrame,pAdecDataType->sOutFrameLock)){
|
|
pFrame = (struct aic_audio_frame *)pBuffer->pBuffer;
|
|
aic_pthread_mutex_lock(&pAdecDataType->sOutFrameLock);
|
|
mpp_list_for_each_entry_safe(pFrameNode1,pFrameNode2,&pAdecDataType->sOutProcessingFrame,sList){
|
|
if(pFrameNode1->sFrameInfo.data == pFrame->data){
|
|
bMatch = OMX_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if(bMatch){//give frame back to decoder
|
|
ret = aic_audio_decoder_put_frame(pAdecDataType->pDecoder, &pFrameNode1->sFrameInfo);
|
|
if(ret != 0){// how to do
|
|
loge("mpp_decoder_put_frame error!!!!\n");
|
|
}
|
|
// now, no matter whether is back to decoder ok,move pFrameNode1 to sOutEmptyFrame
|
|
pAdecDataType->nSendBackFrameOkNum++;
|
|
mpp_list_del(&pFrameNode1->sList);
|
|
mpp_list_add_tail(&pFrameNode1->sList, &pAdecDataType->sOutEmptyFrame);
|
|
|
|
}else{
|
|
pAdecDataType->nSendBackFrameErrorNum++;
|
|
loge("frame not match!!!\n");
|
|
eError = OMX_ErrorBadParameter;
|
|
}
|
|
logi("pAdecDataType->nSendBackFrameOkNum:%d,pAdecDataType->nSendBackFrameErrorNum:%d\n"
|
|
,pAdecDataType->nSendBackFrameOkNum
|
|
,pAdecDataType->nSendBackFrameErrorNum);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
}else{
|
|
logw("no frame need to back \n");
|
|
eError = OMX_ErrorBadParameter;
|
|
}
|
|
return eError;
|
|
}
|
|
|
|
|
|
|
|
static OMX_ERRORTYPE OMX_AdecSetCallbacks(
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
|
|
OMX_IN OMX_PTR pAppData)
|
|
{
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
ADEC_DATA_TYPE* pAdecDataType;
|
|
pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
|
|
pAdecDataType->pCallbacks = pCallbacks;
|
|
pAdecDataType->pAppData = pAppData;
|
|
return eError;
|
|
}
|
|
|
|
OMX_ERRORTYPE OMX_AdecComponentDeInit(
|
|
OMX_IN OMX_HANDLETYPE hComponent)
|
|
{
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_COMPONENTTYPE *pComp;
|
|
ADEC_DATA_TYPE *pAdecDataType;
|
|
ADEC_IN_PACKET *pPktNode = NULL,*pPktNode1 = NULL;
|
|
ADEC_OUT_FRAME *pFrameNode = NULL,*pFrameNode1 = NULL;
|
|
pComp = (OMX_COMPONENTTYPE *)hComponent;
|
|
struct aic_message sMsg;
|
|
pAdecDataType = (ADEC_DATA_TYPE *)pComp->pComponentPrivate;
|
|
|
|
aic_pthread_mutex_lock(&pAdecDataType->stateLock);
|
|
if(pAdecDataType->state != OMX_StateLoaded){
|
|
loge("compoent is in %d,but not in OMX_StateLoaded(1),can not FreeHandle.\n",pAdecDataType->state);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->stateLock);
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
}
|
|
aic_pthread_mutex_unlock(&pAdecDataType->stateLock);
|
|
|
|
sMsg.message_id = OMX_CommandStop;
|
|
sMsg.data_size = 0;
|
|
aic_msg_put(&pAdecDataType->sMsgQue, &sMsg);
|
|
pthread_join(pAdecDataType->threadId, (void*)&eError);
|
|
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
if(!mpp_list_empty(&pAdecDataType->sInEmptyPkt)){
|
|
mpp_list_for_each_entry_safe(pPktNode, pPktNode1, &pAdecDataType->sInEmptyPkt, sList){
|
|
mpp_list_del(&pPktNode->sList);
|
|
mpp_free(pPktNode);
|
|
}
|
|
}
|
|
|
|
if(!mpp_list_empty(&pAdecDataType->sInReadyPkt)){
|
|
mpp_list_for_each_entry_safe(pPktNode, pPktNode1, &pAdecDataType->sInReadyPkt, sList){
|
|
mpp_list_del(&pPktNode->sList);
|
|
mpp_free(pPktNode);
|
|
}
|
|
}
|
|
|
|
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
|
|
|
|
aic_pthread_mutex_lock(&pAdecDataType->sOutFrameLock);
|
|
if(!mpp_list_empty(&pAdecDataType->sOutEmptyFrame)){
|
|
mpp_list_for_each_entry_safe(pFrameNode, pFrameNode1, &pAdecDataType->sOutEmptyFrame, sList){
|
|
mpp_list_del(&pFrameNode->sList);
|
|
mpp_free(pFrameNode);
|
|
}
|
|
}
|
|
if(!mpp_list_empty(&pAdecDataType->sOutReadyFrame)){
|
|
mpp_list_for_each_entry_safe(pFrameNode, pFrameNode1, &pAdecDataType->sOutReadyFrame, sList){
|
|
mpp_list_del(&pFrameNode->sList);
|
|
mpp_free(pFrameNode);
|
|
}
|
|
}
|
|
|
|
if(!mpp_list_empty(&pAdecDataType->sOutProcessingFrame)){
|
|
mpp_list_for_each_entry_safe(pFrameNode, pFrameNode1, &pAdecDataType->sOutProcessingFrame, sList){
|
|
mpp_list_del(&pFrameNode->sList);
|
|
mpp_free(pFrameNode);
|
|
}
|
|
}
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
|
|
pthread_mutex_destroy(&pAdecDataType->sInPktLock);
|
|
pthread_mutex_destroy(&pAdecDataType->sOutFrameLock);
|
|
pthread_mutex_destroy(&pAdecDataType->stateLock);
|
|
|
|
aic_msg_destroy(&pAdecDataType->sMsgQue);
|
|
|
|
if (pAdecDataType->pDecoder) {
|
|
aic_audio_decoder_destroy(pAdecDataType->pDecoder);
|
|
pAdecDataType->pDecoder = NULL;
|
|
}
|
|
|
|
mpp_free(pAdecDataType);
|
|
pAdecDataType = NULL;
|
|
|
|
logi("OMX_VideoRenderComponentDeInit\n");
|
|
return eError;
|
|
}
|
|
|
|
OMX_ERRORTYPE OMX_AdecComponentInit(
|
|
OMX_IN OMX_HANDLETYPE hComponent)
|
|
{
|
|
OMX_COMPONENTTYPE *pComp;
|
|
ADEC_DATA_TYPE *pAdecDataType;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_U32 err;
|
|
OMX_U32 i;
|
|
//OMX_U32 cnt;
|
|
|
|
logi("OMX_AdecComponentInit....\n");
|
|
|
|
pComp = (OMX_COMPONENTTYPE *)hComponent;
|
|
|
|
pAdecDataType = (ADEC_DATA_TYPE *)mpp_alloc(sizeof(ADEC_DATA_TYPE));
|
|
|
|
if (NULL == pAdecDataType) {
|
|
loge("mpp_alloc(sizeof(ADEC_DATA_TYPE) fail!\n");
|
|
eError = OMX_ErrorInsufficientResources;
|
|
goto _EXIT1;
|
|
}
|
|
|
|
memset(pAdecDataType, 0x0, sizeof(ADEC_DATA_TYPE));
|
|
pComp->pComponentPrivate = (void*) pAdecDataType;
|
|
pAdecDataType->state = OMX_StateLoaded;
|
|
pAdecDataType->hSelf = pComp;
|
|
|
|
pComp->SetCallbacks = OMX_AdecSetCallbacks;
|
|
pComp->SendCommand = OMX_AdecSendCommand;
|
|
pComp->GetState = OMX_AdecGetState;
|
|
pComp->GetParameter = OMX_AdecGetParameter;
|
|
pComp->SetParameter = OMX_AdecSetParameter;
|
|
pComp->GetConfig = OMX_AdecGetConfig;
|
|
pComp->SetConfig = OMX_AdecSetConfig;
|
|
pComp->ComponentTunnelRequest = OMX_AdecComponentTunnelRequest;
|
|
pComp->ComponentDeInit = OMX_AdecComponentDeInit;
|
|
pComp->FillThisBuffer = OMX_AdecFillThisBuffer;
|
|
pComp->EmptyThisBuffer = OMX_AdecEmptyThisBuffer;
|
|
|
|
pAdecDataType->sPortParam.nPorts = 2;
|
|
pAdecDataType->sPortParam.nStartPortNumber = 0x0;
|
|
|
|
pAdecDataType->sInPortDef.nPortIndex = ADEC_PORT_IN_INDEX;
|
|
pAdecDataType->sInPortDef.bPopulated = OMX_TRUE;
|
|
pAdecDataType->sInPortDef.bEnabled = OMX_TRUE;
|
|
pAdecDataType->sInPortDef.eDomain = OMX_PortDomainAudio;
|
|
pAdecDataType->sInPortDef.eDir = OMX_DirInput;
|
|
|
|
|
|
pAdecDataType->sOutPortDef.nPortIndex = ADEC_PORT_OUT_INDEX;
|
|
pAdecDataType->sOutPortDef.bPopulated = OMX_TRUE;
|
|
pAdecDataType->sOutPortDef.bEnabled = OMX_TRUE;
|
|
pAdecDataType->sOutPortDef.eDomain = OMX_PortDomainAudio;
|
|
pAdecDataType->sOutPortDef.eDir = OMX_DirOutput;
|
|
|
|
pAdecDataType->sInPortTunneledInfo.nPortIndex = ADEC_PORT_IN_INDEX;
|
|
pAdecDataType->sInPortTunneledInfo.pSelfComp = hComponent;
|
|
pAdecDataType->sOutPortTunneledInfo.nPortIndex = ADEC_PORT_OUT_INDEX;
|
|
pAdecDataType->sOutPortTunneledInfo.pSelfComp = hComponent;
|
|
|
|
|
|
//now demux support buffers ,later modify
|
|
pAdecDataType->sInBufSupplier.nPortIndex = ADEC_PORT_IN_INDEX;
|
|
pAdecDataType->sInBufSupplier.eBufferSupplier = OMX_BufferSupplyOutput;
|
|
pAdecDataType->nInPktNodeNum = 0;
|
|
mpp_list_init(&pAdecDataType->sInEmptyPkt);
|
|
mpp_list_init(&pAdecDataType->sInReadyPkt);
|
|
mpp_list_init(&pAdecDataType->sInProcessedPkt);
|
|
pthread_mutex_init(&pAdecDataType->sInPktLock, NULL);
|
|
for(i =0 ; i < ADEC_PACKET_ONE_TIME_CREATE_NUM; i++ ){
|
|
ADEC_IN_PACKET *pPktNode = (ADEC_IN_PACKET*)mpp_alloc(sizeof(ADEC_IN_PACKET));
|
|
if(NULL == pPktNode){
|
|
break;
|
|
}
|
|
memset(pPktNode,0x00,sizeof(ADEC_IN_PACKET));
|
|
mpp_list_add_tail(&pPktNode->sList, &pAdecDataType->sInEmptyPkt);
|
|
pAdecDataType->nInPktNodeNum++;
|
|
}
|
|
if(pAdecDataType->nInPktNodeNum == 0){
|
|
loge("mpp_alloc empty video node fail\n");
|
|
eError = OMX_ErrorInsufficientResources;
|
|
goto _EXIT2;
|
|
}
|
|
|
|
|
|
// vdec support out pot buffer
|
|
pAdecDataType->sOutBufSupplier.nPortIndex = ADEC_PORT_OUT_INDEX;
|
|
pAdecDataType->sOutBufSupplier.eBufferSupplier = OMX_BufferSupplyOutput;
|
|
pAdecDataType->nOutFrameNodeNum = 0;
|
|
mpp_list_init(&pAdecDataType->sOutEmptyFrame);
|
|
mpp_list_init(&pAdecDataType->sOutReadyFrame);
|
|
mpp_list_init(&pAdecDataType->sOutProcessingFrame);
|
|
pthread_mutex_init(&pAdecDataType->sOutFrameLock, NULL);
|
|
for(i =0 ; i < ADEC_FRAME_ONE_TIME_CREATE_NUM; i++ ){
|
|
ADEC_OUT_FRAME *pFrameNode = (ADEC_OUT_FRAME*)mpp_alloc(sizeof(ADEC_OUT_FRAME));
|
|
if(NULL == pFrameNode){
|
|
break;
|
|
}
|
|
memset(pFrameNode,0x00,sizeof(ADEC_OUT_FRAME));
|
|
mpp_list_add_tail(&pFrameNode->sList, &pAdecDataType->sOutEmptyFrame);
|
|
pAdecDataType->nOutFrameNodeNum++;
|
|
}
|
|
if(pAdecDataType->nOutFrameNodeNum == 0){
|
|
loge("mpp_alloc empty video node fail\n");
|
|
eError = OMX_ErrorInsufficientResources;
|
|
goto _EXIT3;
|
|
}
|
|
|
|
|
|
if(aic_msg_create(&pAdecDataType->sMsgQue)<0)
|
|
{
|
|
loge("aic_msg_create fail!\n");
|
|
eError = OMX_ErrorInsufficientResources;
|
|
goto _EXIT4;
|
|
}
|
|
|
|
pthread_mutex_init(&pAdecDataType->stateLock, NULL);
|
|
// Create the component thread
|
|
err = pthread_create(&pAdecDataType->threadId, NULL, OMX_AdecComponentThread, pAdecDataType);
|
|
if (err || !pAdecDataType->threadId)
|
|
{
|
|
loge("pthread_create fail!\n");
|
|
eError = OMX_ErrorInsufficientResources;
|
|
goto _EXIT5;
|
|
}
|
|
|
|
logi("OMX_AdecComponentInit OK \n");
|
|
return eError;
|
|
|
|
_EXIT5:
|
|
aic_msg_destroy(&pAdecDataType->sMsgQue);
|
|
pthread_mutex_destroy(&pAdecDataType->stateLock);
|
|
|
|
_EXIT4:
|
|
if(!mpp_list_empty(&pAdecDataType->sInEmptyPkt)){
|
|
ADEC_IN_PACKET *pPktNode = NULL,*pPktNode1 = NULL;
|
|
mpp_list_for_each_entry_safe(pPktNode, pPktNode1, &pAdecDataType->sInEmptyPkt, sList){
|
|
mpp_list_del(&pPktNode->sList);
|
|
mpp_free(pPktNode);
|
|
}
|
|
}
|
|
|
|
_EXIT3:
|
|
if(!mpp_list_empty(&pAdecDataType->sOutEmptyFrame)){
|
|
ADEC_OUT_FRAME *pFrameNode = NULL,*pFrameNode1 = NULL;
|
|
mpp_list_for_each_entry_safe(pFrameNode, pFrameNode1, &pAdecDataType->sOutEmptyFrame, sList){
|
|
mpp_list_del(&pFrameNode->sList);
|
|
mpp_free(pFrameNode);
|
|
}
|
|
}
|
|
|
|
_EXIT2:
|
|
if(pAdecDataType){
|
|
mpp_free(pAdecDataType);
|
|
pAdecDataType = NULL;
|
|
}
|
|
|
|
_EXIT1:
|
|
return eError;
|
|
}
|
|
|
|
|
|
/*
|
|
static void* OMX_DecodeThread(void *pThreadData)
|
|
{
|
|
ADEC_DATA_TYPE* pAdecDataType = (ADEC_DATA_TYPE*)pThreadData;
|
|
logi("decode_thread start!!!!!\n");
|
|
aic_audio_decoder_decode(pAdecDataType->pDecoder);
|
|
pAdecDataType->nFlags |= ADEC_DECODER_CONSUME_ALL_INPORT_STREAM_FLAG;
|
|
//pAdecDataType->nDecodeEndFlag = 1;
|
|
logi("decode_thread exit!!!!!\n");
|
|
return NULL;
|
|
}
|
|
*/
|
|
|
|
static void OMX_AdecEventNotify(
|
|
ADEC_DATA_TYPE * pAdecDataType,
|
|
OMX_EVENTTYPE event,
|
|
OMX_U32 nData1,
|
|
OMX_U32 nData2,
|
|
OMX_PTR pEventData)
|
|
{
|
|
if(pAdecDataType && pAdecDataType->pCallbacks && pAdecDataType->pCallbacks->EventHandler) {
|
|
pAdecDataType->pCallbacks->EventHandler(
|
|
pAdecDataType->hSelf,
|
|
pAdecDataType->pAppData,event,
|
|
nData1, nData2, pEventData);
|
|
}
|
|
}
|
|
|
|
static void OMX_AdecStateChangeToInvalid(ADEC_DATA_TYPE * pAdecDataType)
|
|
{
|
|
pAdecDataType->state = OMX_StateInvalid;
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventError
|
|
,OMX_ErrorInvalidState,0,NULL);
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventCmdComplete
|
|
,OMX_CommandStateSet
|
|
,pAdecDataType->state,NULL);
|
|
|
|
}
|
|
|
|
static void OMX_AdecStateChangeLoaded(ADEC_DATA_TYPE * pAdecDataType)
|
|
{
|
|
int ret;
|
|
if(pAdecDataType->state == OMX_StateIdle){
|
|
logi("Before OMX_AdecComponentThread exit,move node in sInReadyFrame to sInProcessedFrmae\n");
|
|
if(!OMX_AdecListEmpty(&pAdecDataType->sInReadyPkt,pAdecDataType->sInPktLock)){
|
|
logi("sInReadyFrame is not empty\n");
|
|
ADEC_IN_PACKET *pktNode1,*pktNode2;
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
mpp_list_for_each_entry_safe(pktNode1, pktNode2, &pAdecDataType->sInReadyPkt, sList){
|
|
pAdecDataType->nLeftReadyFrameWhenCompoentExitNum++;
|
|
mpp_list_del(&pktNode1->sList);
|
|
mpp_list_add_tail(&pktNode1->sList, &pAdecDataType->sInProcessedPkt);
|
|
}
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
}
|
|
/*
|
|
1 give back all in port pkts,
|
|
pAdecDataType->sInBufSupplier.eBufferSupplier = OMX_BufferSupplyOutput
|
|
*/
|
|
logi("Before OMX_AdecComponentThread exit,it must give back all in port pkts\n");
|
|
if(!OMX_AdecListEmpty(&pAdecDataType->sInProcessedPkt,pAdecDataType->sInPktLock)){
|
|
logi("sInProcessedPkt is not empty\n");
|
|
//ADEC_IN_PACKET *pktNode1,*pktNode2;
|
|
ADEC_IN_PACKET *pktNode1 = NULL;
|
|
//struct mpp_packet pkt;
|
|
while(!OMX_AdecListEmpty(&pAdecDataType->sInProcessedPkt,pAdecDataType->sInPktLock)){
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
pktNode1 = mpp_list_first_entry(&pAdecDataType->sInProcessedPkt, ADEC_IN_PACKET, sList);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
ret = 0;
|
|
if(pAdecDataType->sInPortTunneledInfo.nTunneledFlag){
|
|
ret = OMX_FillThisBuffer(pAdecDataType->sInPortTunneledInfo.pTunneledComp,&pktNode1->sBuff);
|
|
if(ret != 0){ // how to do ,deal with problem by TunneledComp, do nothing here
|
|
logw("OMX_FillThisBuffer error \n");
|
|
}
|
|
}else{
|
|
if(pAdecDataType->pCallbacks != NULL && pAdecDataType->pCallbacks->EmptyBufferDone!= NULL){
|
|
ret = pAdecDataType->pCallbacks->EmptyBufferDone(pAdecDataType->hSelf,pAdecDataType->pAppData,&pktNode1->sBuff);
|
|
if(ret != 0){// how to do ,deal with problem by app, do nothing here
|
|
logw("EmptyBufferDone error \n");
|
|
}
|
|
}
|
|
}
|
|
if(ret == 0){
|
|
pAdecDataType->nGiveBackPacktOkNum++;
|
|
}else{
|
|
pAdecDataType->nGiveBackPacktFailNum++;
|
|
}
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
mpp_list_del(&pktNode1->sList);
|
|
mpp_list_add_tail(&pktNode1->sList, &pAdecDataType->sInEmptyPkt);
|
|
logi("pAdecDataType->nGiveBackPacktOkNum:%d,pAdecDataType->nGiveBackPacktFailNum:%d\n"
|
|
,pAdecDataType->nGiveBackPacktOkNum
|
|
,pAdecDataType->nGiveBackPacktFailNum);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
}
|
|
}
|
|
|
|
/*
|
|
2 wait for all out port frames from other component or app to back.
|
|
pAdecDataType->sOutBufSupplier.eBufferSupplier = OMX_BufferSupplyOutput;
|
|
*/
|
|
logi("Before OMX_AdecComponentThread exit,it must wait for sOutProcessingFrame empty\n");
|
|
while(!OMX_AdecListEmpty(&pAdecDataType->sOutProcessingFrame,pAdecDataType->sOutFrameLock)){
|
|
usleep(1000);
|
|
}
|
|
/*
|
|
3 give back all frames in sOutReadyFrame to decoder
|
|
*/
|
|
logi("Before OMX_AdecComponentThread exit,it must give back all frames in sOutReadyFrame to decoder\n");
|
|
|
|
if(!OMX_AdecListEmpty(&pAdecDataType->sOutReadyFrame,pAdecDataType->sOutFrameLock)){
|
|
logi("sOutReadyFrame is not empty\n");
|
|
ADEC_OUT_FRAME *pFrameNode1,*pFrameNode2;
|
|
aic_pthread_mutex_lock(&pAdecDataType->sOutFrameLock);
|
|
mpp_list_for_each_entry_safe(pFrameNode1,pFrameNode2,&pAdecDataType->sOutReadyFrame,sList){
|
|
ret = aic_audio_decoder_put_frame(pAdecDataType->pDecoder, &pFrameNode1->sFrameInfo);
|
|
pAdecDataType->nLeftReadyFrameWhenCompoentExitNum++;
|
|
if(ret != 0){// how to do
|
|
logw("mpp_decoder_put_frame error!!!!\n");
|
|
}else{
|
|
|
|
}
|
|
// now, no matter whether is back to decoder ok,move pFrameNode1 to sOutEmptyFrame
|
|
mpp_list_del(&pFrameNode1->sList);
|
|
mpp_list_add_tail(&pFrameNode1->sList, &pAdecDataType->sOutEmptyFrame);
|
|
}
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
}
|
|
logi("OMX_AdecComponentThread ready to exit\n");
|
|
}else if(pAdecDataType->state == OMX_StateExecuting){
|
|
|
|
}else if(pAdecDataType->state == OMX_StatePause){
|
|
|
|
}else {
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventError
|
|
,OMX_ErrorIncorrectStateTransition
|
|
,pAdecDataType->state,NULL);
|
|
loge("OMX_ErrorIncorrectStateTransition\n");
|
|
return;
|
|
}
|
|
pAdecDataType->state = OMX_StateLoaded;
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventCmdComplete
|
|
,OMX_CommandStateSet
|
|
,pAdecDataType->state,NULL);
|
|
|
|
}
|
|
static void OMX_AdecStateChangeToIdle(ADEC_DATA_TYPE * pAdecDataType)
|
|
{
|
|
int ret;
|
|
if(pAdecDataType->state == OMX_StateLoaded){
|
|
//create decoder
|
|
if(pAdecDataType->pDecoder == NULL){
|
|
pAdecDataType->pDecoder = aic_audio_decoder_create(pAdecDataType->eCodeType);
|
|
if(pAdecDataType->pDecoder == NULL){
|
|
loge("mpp_decoder_create fail!!!!\n ");
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventError
|
|
,OMX_ErrorIncorrectStateTransition
|
|
,pAdecDataType->state,NULL);
|
|
loge("OMX_ErrorIncorrectStateTransition\n");
|
|
return;
|
|
}
|
|
logi("aic_audio_decoder_create ok!\n ");
|
|
|
|
ret = aic_audio_decoder_init(pAdecDataType->pDecoder, &pAdecDataType->sDecoderConfig);
|
|
if (ret) {
|
|
loge("mpp_decoder_init %d failed\n", pAdecDataType->eCodeType);
|
|
aic_audio_decoder_destroy(pAdecDataType->pDecoder);
|
|
pAdecDataType->pDecoder = NULL;
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventError
|
|
,OMX_ErrorIncorrectStateTransition
|
|
,pAdecDataType->state,NULL);
|
|
loge("OMX_ErrorIncorrectStateTransition\n");
|
|
return;
|
|
}
|
|
logi("aic_audio_decoder_init ok!\n ");
|
|
}
|
|
}else if(pAdecDataType->state == OMX_StatePause){
|
|
|
|
}else if(pAdecDataType->state == OMX_StateExecuting){
|
|
|
|
}else{
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventError
|
|
,OMX_ErrorIncorrectStateTransition
|
|
,pAdecDataType->state,NULL);
|
|
loge("OMX_ErrorIncorrectStateTransition\n");
|
|
return;
|
|
}
|
|
pAdecDataType->state = OMX_StateIdle;
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventCmdComplete
|
|
,OMX_CommandStateSet
|
|
,pAdecDataType->state,NULL);
|
|
|
|
}
|
|
static void OMX_AdecStateChangeToExcuting(ADEC_DATA_TYPE * pAdecDataType)
|
|
{
|
|
if(pAdecDataType->state == OMX_StateLoaded){
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventError
|
|
,OMX_ErrorIncorrectStateTransition
|
|
,pAdecDataType->state,NULL);
|
|
loge("OMX_ErrorIncorrectStateTransition\n");
|
|
return;
|
|
|
|
}else if(pAdecDataType->state == OMX_StateIdle){
|
|
|
|
}else if(pAdecDataType->state == OMX_StatePause){
|
|
|
|
}else{
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventError
|
|
,OMX_ErrorIncorrectStateTransition
|
|
,pAdecDataType->state,NULL);
|
|
loge("OMX_ErrorIncorrectStateTransition\n");
|
|
return;
|
|
}
|
|
pAdecDataType->state = OMX_StateExecuting;
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventCmdComplete
|
|
,OMX_CommandStateSet
|
|
,pAdecDataType->state,NULL);
|
|
|
|
}
|
|
static void OMX_AdecStateChangeToPause(ADEC_DATA_TYPE * pAdecDataType)
|
|
{
|
|
if(pAdecDataType->state == OMX_StateLoaded){
|
|
|
|
}else if(pAdecDataType->state == OMX_StateIdle){
|
|
|
|
}else if(pAdecDataType->state == OMX_StateExecuting){
|
|
|
|
}else{
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventError
|
|
,OMX_ErrorIncorrectStateTransition
|
|
,pAdecDataType->state,NULL);
|
|
loge("OMX_ErrorIncorrectStateTransition\n");
|
|
return ;
|
|
|
|
}
|
|
pAdecDataType->state = OMX_StatePause;
|
|
OMX_AdecEventNotify(pAdecDataType
|
|
,OMX_EventCmdComplete
|
|
,OMX_CommandStateSet
|
|
,pAdecDataType->state,NULL);
|
|
|
|
}
|
|
|
|
static void* OMX_AdecComponentThread(void* pThreadData)
|
|
{
|
|
struct aic_message message;
|
|
OMX_S32 nCmd; //OMX_COMMANDTYPE
|
|
OMX_S32 nCmdData; //OMX_STATETYPE
|
|
ADEC_DATA_TYPE* pAdecDataType = (ADEC_DATA_TYPE*)pThreadData;
|
|
OMX_S32 ret;
|
|
//OMX_S32 i;
|
|
ADEC_OUT_FRAME *pFrameNode;
|
|
struct aic_audio_frame sFrame;
|
|
OMX_S32 bNotifyFrameEnd = 0;
|
|
//prctl(PR_SET_NAME,(u32)"Adec");
|
|
|
|
while(1){
|
|
if (aic_msg_get(&pAdecDataType->sMsgQue, &message) == 0){
|
|
nCmd = message.message_id;
|
|
nCmdData = message.param;
|
|
logw("nCmd:%d, nCmdData:%d\n",nCmd,nCmdData);
|
|
if(OMX_CommandStateSet == nCmd){
|
|
aic_pthread_mutex_lock(&pAdecDataType->stateLock);
|
|
if(pAdecDataType->state == (OMX_STATETYPE)(nCmdData)){
|
|
OMX_AdecEventNotify(pAdecDataType,OMX_EventError,OMX_ErrorSameState,0,NULL);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->stateLock);
|
|
continue;
|
|
}
|
|
switch(nCmdData){
|
|
case OMX_StateInvalid:
|
|
OMX_AdecStateChangeToInvalid(pAdecDataType);
|
|
break;
|
|
case OMX_StateLoaded:
|
|
OMX_AdecStateChangeLoaded(pAdecDataType);
|
|
break;
|
|
case OMX_StateIdle:
|
|
OMX_AdecStateChangeToIdle(pAdecDataType);
|
|
break;
|
|
case OMX_StateExecuting:
|
|
OMX_AdecStateChangeToExcuting(pAdecDataType);
|
|
break;
|
|
case OMX_StatePause:
|
|
OMX_AdecStateChangeToPause(pAdecDataType);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
aic_pthread_mutex_unlock(&pAdecDataType->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_AdecComponentThread ready to exit!!!\n");
|
|
goto _EXIT;
|
|
}else{
|
|
|
|
}
|
|
}
|
|
|
|
if(pAdecDataType->state != OMX_StateExecuting){
|
|
//usleep(1000);
|
|
aic_msg_wait_new_msg(&pAdecDataType->sMsgQue, 0);
|
|
continue;
|
|
}
|
|
|
|
if(pAdecDataType->nFlags & ADEC_OUTPORT_SEND_ALL_FRAME_FLAG){
|
|
if(!bNotifyFrameEnd){
|
|
//notify app decoder end
|
|
OMX_AdecEventNotify(pAdecDataType,OMX_EventBufferFlag,0,0,NULL);
|
|
/*
|
|
//notify tunneld component decoder end
|
|
if(pAdecDataType->sOutPortTunneledInfo.nTunneledFlag){
|
|
OMX_PARAM_FRAMEEND sFrameEnd;
|
|
sFrameEnd.bFrameEnd = OMX_TRUE;
|
|
OMX_SetParameter(pAdecDataType->sOutPortTunneledInfo.pTunneledComp, OMX_IndexVendorStreamFrameEnd,&sFrameEnd);
|
|
}
|
|
*/
|
|
bNotifyFrameEnd = 1;
|
|
}
|
|
//usleep(1000);
|
|
aic_msg_wait_new_msg(&pAdecDataType->sMsgQue, 0);
|
|
continue;
|
|
}
|
|
bNotifyFrameEnd = 0;
|
|
|
|
// send packet to decoder
|
|
if(pAdecDataType->sInPortTunneledInfo.nTunneledFlag){
|
|
if(!OMX_AdecListEmpty(&pAdecDataType->sInReadyPkt,pAdecDataType->sInPktLock)){
|
|
ADEC_IN_PACKET *pktNode1 = NULL;
|
|
struct mpp_packet pkt;
|
|
while(!OMX_AdecListEmpty(&pAdecDataType->sInReadyPkt,pAdecDataType->sInPktLock)){
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
pktNode1 = mpp_list_first_entry(&pAdecDataType->sInReadyPkt, ADEC_IN_PACKET, sList);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
pkt.size = pktNode1->sBuff.nFilledLen;
|
|
ret = aic_audio_decoder_get_packet(pAdecDataType->pDecoder, &pkt, pkt.size);
|
|
logi("aic_audio_decoder_get_packet:%d\n",ret);
|
|
if(ret != 0){
|
|
//loge("get pkt from decoder error,ret:%d!!!\n",ret);
|
|
usleep(10*1000);
|
|
break;
|
|
}
|
|
memcpy(pkt.data,pktNode1->sBuff.pBuffer,pkt.size);
|
|
pkt.flag = pktNode1->sBuff.nFlags;
|
|
pkt.pts = pktNode1->sBuff.nTimeStamp;
|
|
/*if aic_audio_decoder_get_packet ok ,aic_audio_decoder_put_packet must be ok,so do need to justify*/
|
|
ret = aic_audio_decoder_put_packet(pAdecDataType->pDecoder, &pkt);
|
|
logi("aic_audio_decoder_put_packet ret:%d,pkt.data:%p,pkt.size:%d,pkt.flag:%d\n",ret,pkt.data,pkt.size,pkt.flag);
|
|
pAdecDataType->nPutPacktToDecoderOkNum++;
|
|
logi("pAdecDataType->nPutPacktToDecoderOkNum:%d\n",pAdecDataType->nPutPacktToDecoderOkNum);
|
|
|
|
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
mpp_list_del(&pktNode1->sList);
|
|
mpp_list_add_tail(&pktNode1->sList, &pAdecDataType->sInProcessedPkt);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
|
|
/*
|
|
ret = OMX_FillThisBuffer(pAdecDataType->sInPortTunneledInfo.pTunneledComp,&pktNode1->sBuff);
|
|
if(ret != 0){ // how to do
|
|
logw("OMX_FillThisBuffer error \n");
|
|
pAdecDataType->nGiveBackPacktFailNum++;
|
|
}else{
|
|
pAdecDataType->nGiveBackPacktOkNum++;
|
|
}
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
mpp_list_del(&pktNode1->sList);
|
|
mpp_list_add_tail(&pktNode1->sList, &pAdecDataType->sInEmptyPkt);
|
|
logi("pAdecDataType->nGiveBackPacktOkNum:%d,pAdecDataType->nGiveBackPacktFailNum:%d\n"
|
|
,pAdecDataType->nGiveBackPacktOkNum
|
|
,pAdecDataType->nGiveBackPacktFailNum);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
*/
|
|
|
|
}
|
|
|
|
}else{
|
|
aic_msg_wait_new_msg(&pAdecDataType->sMsgQue, 100*1000);
|
|
}
|
|
}
|
|
|
|
//give back packet to demux
|
|
if((pAdecDataType->sInPortTunneledInfo.nTunneledFlag)
|
|
&& (!OMX_AdecListEmpty(&pAdecDataType->sInProcessedPkt,pAdecDataType->sInPktLock))){
|
|
ADEC_IN_PACKET *pktNode1 = NULL;
|
|
//struct mpp_packet pkt;
|
|
while(!OMX_AdecListEmpty(&pAdecDataType->sInProcessedPkt,pAdecDataType->sInPktLock)){
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
pktNode1 = mpp_list_first_entry(&pAdecDataType->sInProcessedPkt, ADEC_IN_PACKET, sList);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
ret = OMX_FillThisBuffer(pAdecDataType->sInPortTunneledInfo.pTunneledComp,&pktNode1->sBuff);
|
|
if(ret == 0){
|
|
aic_pthread_mutex_lock(&pAdecDataType->sInPktLock);
|
|
mpp_list_del(&pktNode1->sList);
|
|
mpp_list_add_tail(&pktNode1->sList, &pAdecDataType->sInEmptyPkt);
|
|
pAdecDataType->nGiveBackPacktOkNum++;
|
|
logi("pAdecDataType->nGiveBackPacktOkNum:%d,pAdecDataType->nGiveBackPacktFailNum:%d\n"
|
|
,pAdecDataType->nGiveBackPacktOkNum
|
|
,pAdecDataType->nGiveBackPacktFailNum);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
}else{
|
|
//loge("OMX_FillThisBuffer error \n");
|
|
pAdecDataType->nGiveBackPacktFailNum++;
|
|
logi("pAdecDataType->nGiveBackPacktOkNum:%d,pAdecDataType->nGiveBackPacktFailNum:%d\n"
|
|
,pAdecDataType->nGiveBackPacktOkNum
|
|
,pAdecDataType->nGiveBackPacktFailNum);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// decode
|
|
/*mp3 using libmad */
|
|
if(!(pAdecDataType->nFlags & ADEC_DECODER_CONSUME_ALL_INPORT_STREAM_FLAG)){
|
|
ret = aic_audio_decoder_decode(pAdecDataType->pDecoder);
|
|
if(ret == DEC_OK){
|
|
logd("mpp_decoder_decode ok!!!\n");
|
|
}else if(ret == DEC_NO_READY_PACKET){
|
|
logw("mpp_decoder_decode error DEC_NO_READY_PACKET !!!\n");
|
|
if(pAdecDataType->nFlags & ADEC_INPORT_STREAM_END_FLAG){
|
|
//pAdecDataType->nDecodeEndFlag = OMX_TRUE;
|
|
pAdecDataType->nFlags |= ADEC_DECODER_CONSUME_ALL_INPORT_STREAM_FLAG;
|
|
logw("mpp_decoder_decode notify stream end !!!\n");
|
|
}else{
|
|
// wait some time
|
|
usleep(10*1000);
|
|
}
|
|
}else if(ret == DEC_NO_EMPTY_FRAME){// no decode on time wait sometime
|
|
logw("mpp_decoder_decode error DEC_NO_EMPTY_FRAME !!!\n");
|
|
usleep(10*1000);
|
|
}else if(ret == DEC_ERR_FM_NOT_CREATE){
|
|
|
|
}else{
|
|
loge("mpp_decoder_decode error serious,do not keep decoding !!!\n");
|
|
}
|
|
}
|
|
|
|
// get frame from decoder
|
|
if(!(pAdecDataType->nFlags & ADEC_GET_ALL_FRAME_FREOM_DECODER_FLAG)){
|
|
if(!OMX_AdecListEmpty(&pAdecDataType->sOutEmptyFrame,pAdecDataType->sOutFrameLock)){
|
|
ret = aic_audio_decoder_get_frame(pAdecDataType->pDecoder, &sFrame);
|
|
if(ret == DEC_OK){
|
|
logd("mpp_decoder_get_frame ok\n");
|
|
aic_pthread_mutex_lock(&pAdecDataType->sOutFrameLock);
|
|
pFrameNode = mpp_list_first_entry(&pAdecDataType->sOutEmptyFrame, ADEC_OUT_FRAME, sList);
|
|
pFrameNode->sFrameInfo = sFrame;
|
|
mpp_list_del(&pFrameNode->sList);
|
|
mpp_list_add_tail(&pFrameNode->sList, &pAdecDataType->sOutReadyFrame);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
pAdecDataType->nGetFrameFromDecoderNum++;
|
|
}else if(ret == DEC_NO_RENDER_FRAME){
|
|
if(pAdecDataType->nFlags & ADEC_DECODER_CONSUME_ALL_INPORT_STREAM_FLAG){
|
|
pAdecDataType->nFlags |= ADEC_GET_ALL_FRAME_FREOM_DECODER_FLAG;
|
|
//pAdecDataType->nFrameEndFlag = OMX_TRUE;
|
|
logi("nFrameEndFlag");
|
|
}
|
|
logw("mpp_decoder_get_frame error DEC_NO_RENDER_FRAME !!!\n");
|
|
usleep(10*1000);
|
|
}else if(ret == DEC_ERR_FM_NOT_CREATE){
|
|
logw("mpp_decoder_get_frame error DEC_ERR_FM_NOT_CREATE !!!\n");
|
|
usleep(10*1000);
|
|
}else if(ret == DEC_NO_EMPTY_FRAME){
|
|
logw("mpp_decoder_get_frame error DEC_NO_EMPTY_FRAME !!!\n");
|
|
usleep(10*1000);
|
|
}else{
|
|
loge("mpp_decoder_get_frame other error \n");
|
|
}
|
|
}else{
|
|
usleep(10*1000);
|
|
}
|
|
}
|
|
|
|
// send frame to other compoent or app
|
|
if(!OMX_AdecListEmpty(&pAdecDataType->sOutReadyFrame,pAdecDataType->sOutFrameLock)){
|
|
ret = 0;
|
|
OMX_BUFFERHEADERTYPE sBuffHead;
|
|
while(!OMX_AdecListEmpty(&pAdecDataType->sOutReadyFrame,pAdecDataType->sOutFrameLock)){
|
|
aic_pthread_mutex_lock(&pAdecDataType->sOutFrameLock);
|
|
pFrameNode = mpp_list_first_entry(&pAdecDataType->sOutReadyFrame, ADEC_OUT_FRAME, sList);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
sBuffHead.nOutputPortIndex = ADEC_PORT_OUT_INDEX;
|
|
sBuffHead.pBuffer = (OMX_U8 *)&pFrameNode->sFrameInfo;
|
|
if(pAdecDataType->sOutPortTunneledInfo.nTunneledFlag){
|
|
sBuffHead.nInputPortIndex = pAdecDataType->sOutPortTunneledInfo.nTunnelPortIndex;
|
|
ret = OMX_EmptyThisBuffer(pAdecDataType->sOutPortTunneledInfo.pTunneledComp,&sBuffHead);
|
|
if(ret != 0){ // how to do,deal with by TunneledComp
|
|
logw("OMX_EmptyThisBuffer error \n");
|
|
}
|
|
}else{
|
|
if(pAdecDataType->pCallbacks != NULL && pAdecDataType->pCallbacks->FillBufferDone != NULL){
|
|
ret = pAdecDataType->pCallbacks->FillBufferDone(pAdecDataType->hSelf,pAdecDataType->pAppData,&sBuffHead);
|
|
if(ret != 0){// how to do,deal with by usr
|
|
logw("EmptyBufferDone error \n");
|
|
}
|
|
}
|
|
}
|
|
if(ret == 0){
|
|
logd("OMX_EmptyThisBuffer or FillBufferDone ok! move node to using list\n");
|
|
aic_pthread_mutex_lock(&pAdecDataType->sOutFrameLock);
|
|
mpp_list_del(&pFrameNode->sList);
|
|
mpp_list_add_tail(&pFrameNode->sList, &pAdecDataType->sOutProcessingFrame);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
pAdecDataType->nSendFrameOkNum++;
|
|
}else{ // how to do ,// just only noitfy error,do not move empty list
|
|
if(pAdecDataType->pCallbacks && pAdecDataType->pCallbacks->EventHandler) {
|
|
pAdecDataType->pCallbacks->EventHandler(pAdecDataType->hSelf,
|
|
pAdecDataType->pAppData,OMX_EventError,
|
|
OMX_ErrorUndefined, pAdecDataType->state,NULL);
|
|
}
|
|
logw("OMX_EmptyThisBuffer or FillBufferDone fail!\n");
|
|
pAdecDataType->nSendFrameErrorNum++;
|
|
usleep(10*1000);
|
|
break;//fail, do not keep send frame to other compoent or app
|
|
}
|
|
}
|
|
}else{
|
|
if(pAdecDataType->nFlags & ADEC_GET_ALL_FRAME_FREOM_DECODER_FLAG){
|
|
pAdecDataType->nFlags |= ADEC_OUTPORT_SEND_ALL_FRAME_FLAG;
|
|
logi("ADEC_OUTPORT_SEND_ALL_FRAME_FLAG\n");
|
|
}
|
|
usleep(10*1000);
|
|
}
|
|
|
|
// send frame back to decoder in OMX_AdecFillThisBuffer
|
|
|
|
}
|
|
_EXIT:
|
|
|
|
loge("in port:nReceivePacktOkNum:%d,"\
|
|
"nReceivePacktFailNum:%d,"\
|
|
"nPutPacktToDecoderOkNum:%d,"\
|
|
"nPutPacktToDecoderFailNum:%d,"\
|
|
"nGiveBackPacktOkNum:%d"\
|
|
"nGiveBackPacktFailNum:%d\n"
|
|
,pAdecDataType->nReceivePacktOkNum
|
|
,pAdecDataType->nReceivePacktFailNum
|
|
,pAdecDataType->nPutPacktToDecoderOkNum
|
|
,pAdecDataType->nPutPacktToDecoderFailNum
|
|
,pAdecDataType->nGiveBackPacktOkNum
|
|
,pAdecDataType->nGiveBackPacktFailNum);
|
|
|
|
loge("out port:nGetFrameFromDecoderNum:%d,"\
|
|
"nDropFrameFromDecoderNum:%d,"\
|
|
"nSendFrameOkNum:%d,"\
|
|
"nSendFrameErrorNum:%d,"\
|
|
"nLeftReadyFrameWhenCompoentExitNum:%d\n"
|
|
,pAdecDataType->nGetFrameFromDecoderNum
|
|
,pAdecDataType->nDropFrameFromDecoderNum
|
|
,pAdecDataType->nSendFrameOkNum
|
|
,pAdecDataType->nSendFrameErrorNum
|
|
,pAdecDataType->nLeftReadyFrameWhenCompoentExitNum);
|
|
loge("OMX_AdecComponentThread EXIT\n");
|
|
return (void*)OMX_ErrorNone;
|
|
}
|
|
|