mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-15 19:08:54 +00:00
1433 lines
56 KiB
C
1433 lines
56 KiB
C
/*
|
|
* 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 int OMX_AdecGiveBackAllPackets(ADEC_DATA_TYPE *pAdecDataType);
|
|
static int OMX_AdecGiveBackAllFramesToDecoder(ADEC_DATA_TYPE *pAdecDataType);
|
|
|
|
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;
|
|
#ifdef AAC_DECODER
|
|
} else if (*eSrcType == OMX_AUDIO_CodingAAC) {
|
|
*eDesType = MPP_CODEC_AUDIO_DECODER_AAC;
|
|
#endif
|
|
} else {
|
|
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;
|
|
OMX_S32 nParamIndex = (OMX_S32)nIndex;
|
|
ADEC_DATA_TYPE* pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
|
|
switch (nParamIndex) {
|
|
case OMX_IndexConfigTimePosition:
|
|
// 1 clear input buffer
|
|
OMX_AdecGiveBackAllPackets(pAdecDataType);
|
|
// 2 clear output buffer
|
|
OMX_AdecGiveBackAllFramesToDecoder(pAdecDataType);
|
|
// 3 clear flag
|
|
pAdecDataType->nFlags = 0;
|
|
pAdecDataType->nPutPacktToDecoderOkNum = 0;
|
|
pAdecDataType->nGetFrameFromDecoderNum = 0;
|
|
// 4 clear decoder buff
|
|
aic_audio_decoder_reset(pAdecDataType->pDecoder);
|
|
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;
|
|
static int rate = 0;
|
|
static struct timespec pev = {0,0},cur = {0,0};
|
|
pAdecDataType = (ADEC_DATA_TYPE *)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
|
|
|
|
aic_pthread_mutex_lock(&pAdecDataType->stateLock);
|
|
if (pAdecDataType->state != OMX_StateExecuting) {
|
|
logw("component is not in OMX_StateExecuting,it is in [%d]!!!\n",pAdecDataType->state);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->stateLock);
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
}
|
|
|
|
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) {
|
|
logw("empty node has aready increase to max [%d]!!!\n",pAdecDataType->nInPktNodeNum);
|
|
eError = OMX_ErrorInsufficientResources;
|
|
pAdecDataType->nReceivePacktFailNum++;
|
|
goto _EXIT;
|
|
} 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) {
|
|
logw("mpp_alloc empty video node fail\n");
|
|
eError = OMX_ErrorInsufficientResources;
|
|
pAdecDataType->nReceivePacktFailNum++;
|
|
goto _EXIT;
|
|
}
|
|
}
|
|
}
|
|
|
|
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++;
|
|
eError = OMX_ErrorOverflow;
|
|
goto _EXIT;
|
|
} else {
|
|
pAdecDataType->nReceivePacktFailNum++;
|
|
eError = OMX_ErrorInsufficientResources;
|
|
goto _EXIT;
|
|
}
|
|
}
|
|
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;
|
|
printf("[%s:%d]StreamEndFlag!!!\n",__FUNCTION__,__LINE__);
|
|
}
|
|
|
|
rate += pkt.size;
|
|
if (pev.tv_sec == 0) {
|
|
clock_gettime(CLOCK_REALTIME,&pev);
|
|
} else {
|
|
long diff;
|
|
clock_gettime(CLOCK_REALTIME,&cur);
|
|
diff = (cur.tv_sec - pev.tv_sec)*1000*1000 + (cur.tv_nsec - pev.tv_nsec)/1000;
|
|
if (diff > 1*1000*1000) {
|
|
//loge(" vbv rate:%d,diff:%ld \n",rate*8,diff);
|
|
rate = 0;
|
|
pev = cur;
|
|
}
|
|
}
|
|
|
|
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;
|
|
mpp_list_del(&pktNode->sList);
|
|
mpp_list_add_tail(&pktNode->sList, &pAdecDataType->sInProcessedPkt);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sInPktLock);
|
|
|
|
sMsg.message_id = OMX_CommandNops;
|
|
sMsg.data_size = 0;
|
|
aic_msg_put(&pAdecDataType->sMsgQue, &sMsg);
|
|
pAdecDataType->nReceivePacktOkNum++;
|
|
logd("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++;
|
|
eError = OMX_ErrorOverflow;
|
|
goto _EXIT;
|
|
} else {
|
|
pAdecDataType->nReceivePacktFailNum++;
|
|
eError = OMX_ErrorInsufficientResources;
|
|
goto _EXIT;
|
|
}
|
|
} 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++;
|
|
}
|
|
_EXIT:
|
|
aic_pthread_mutex_unlock(&pAdecDataType->stateLock);
|
|
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
|
|
//loge(" bMatch\n");
|
|
struct aic_message sMsg;
|
|
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);
|
|
|
|
sMsg.message_id = OMX_CommandNops;
|
|
sMsg.data_size = 0;
|
|
aic_msg_put(&pAdecDataType->sMsgQue, &sMsg);
|
|
logd("pAdecDataType->nReceivePacktOkNum:%d\n",pAdecDataType->nReceivePacktOkNum);
|
|
|
|
} else {
|
|
pAdecDataType->nSendBackFrameErrorNum++;
|
|
loge("frame not match!!!\n");
|
|
eError = OMX_ErrorBadParameter;
|
|
}
|
|
logd("pAdecDataType->nSendBackFrameOkNum:%d,pAdecDataType->nSendBackFrameErrorNum:%d\n"
|
|
,pAdecDataType->nSendBackFrameOkNum
|
|
,pAdecDataType->nSendBackFrameErrorNum);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
} else {
|
|
loge("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;
|
|
}
|
|
|
|
static int adc_thread_attr_init(pthread_attr_t *attr)
|
|
{
|
|
// default stack size is 2K, it is not enough for decode thread
|
|
if (attr == NULL) {
|
|
return EINVAL;
|
|
}
|
|
pthread_attr_init(attr);
|
|
attr->stacksize = 16*1024;
|
|
//attr->schedparam.sched_priority = 23;
|
|
attr->schedparam.sched_priority = 22;
|
|
return 0;
|
|
}
|
|
|
|
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;
|
|
|
|
pthread_attr_t *attr = NULL;
|
|
attr = (pthread_attr_t*)mpp_alloc(sizeof(pthread_attr_t));
|
|
adc_thread_attr_init(attr);
|
|
|
|
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, attr, 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 int OMX_AdecGiveBackAllPackets(ADEC_DATA_TYPE *pAdecDataType)
|
|
{
|
|
int ret = 0;
|
|
//move sInReadyPkt to sInProcessedPkt
|
|
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);
|
|
}
|
|
|
|
// give back all in port pkts
|
|
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 = NULL;
|
|
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++;
|
|
continue;// must give back ok ,so retry to give back
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int OMX_AdecGiveBackAllFramesToDecoder(ADEC_DATA_TYPE *pAdecDataType)
|
|
{
|
|
int ret = 0;
|
|
//wait for all out port frames from other component or app to back
|
|
logi("Before OMX_AdecComponentThread exit,it must wait for sOutProcessingFrame empty\n");
|
|
while(!OMX_AdecListEmpty(&pAdecDataType->sOutProcessingFrame,pAdecDataType->sOutFrameLock)) {
|
|
usleep(1000);
|
|
}
|
|
|
|
//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
|
|
loge("mpp_decoder_put_frame error!!!!\n");
|
|
} else {
|
|
|
|
}
|
|
// logd("pts:%ld:\n",pFrameNode1->sFrameInfo.pts);
|
|
// 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);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (pAdecDataType->state == OMX_StateIdle) {
|
|
OMX_AdecGiveBackAllPackets(pAdecDataType);
|
|
OMX_AdecGiveBackAllFramesToDecoder(pAdecDataType);
|
|
} 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) {
|
|
_AIC_MSG_GET_:
|
|
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;
|
|
|
|
//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_OUTPORT_SEND_ALL_FRAME_FLAG)) {
|
|
ret = aic_audio_decoder_decode(pAdecDataType->pDecoder);
|
|
if (ret == DEC_OK) {
|
|
//loge("mpp_decoder_decode ok!!!\n");
|
|
if (OMX_AdecListEmpty(&pAdecDataType->sOutEmptyFrame,pAdecDataType->sOutFrameLock)) {
|
|
ADEC_OUT_FRAME *pFrameNode = (ADEC_OUT_FRAME*)mpp_alloc(sizeof(ADEC_OUT_FRAME));
|
|
if (NULL == pFrameNode) {
|
|
loge("mpp_alloc error \n");
|
|
goto _AIC_MSG_GET_;
|
|
}
|
|
memset(pFrameNode,0x00,sizeof(ADEC_OUT_FRAME));
|
|
aic_pthread_mutex_lock(&pAdecDataType->sOutFrameLock);
|
|
mpp_list_add_tail(&pFrameNode->sList, &pAdecDataType->sOutEmptyFrame);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
pAdecDataType->nOutFrameNodeNum++;
|
|
}
|
|
ret = aic_audio_decoder_get_frame(pAdecDataType->pDecoder, &sFrame);
|
|
//loge("**********ret = %d************\n",ret);
|
|
|
|
if (ret == DEC_OK) {
|
|
//loge("mpp_decoder_decode ok!!!\n");
|
|
OMX_S32 result = 0;
|
|
OMX_BUFFERHEADERTYPE sBuffHead;
|
|
sBuffHead.nOutputPortIndex = ADEC_PORT_OUT_INDEX;
|
|
sBuffHead.pBuffer = (OMX_U8 *)&sFrame;
|
|
if (pAdecDataType->sOutPortTunneledInfo.nTunneledFlag) {
|
|
sBuffHead.nInputPortIndex = pAdecDataType->sOutPortTunneledInfo.nTunnelPortIndex;
|
|
result = OMX_EmptyThisBuffer(pAdecDataType->sOutPortTunneledInfo.pTunneledComp,&sBuffHead);
|
|
} else {
|
|
if (pAdecDataType->pCallbacks != NULL && pAdecDataType->pCallbacks->FillBufferDone != NULL) {
|
|
result = pAdecDataType->pCallbacks->FillBufferDone(pAdecDataType->hSelf,pAdecDataType->pAppData,&sBuffHead);
|
|
}
|
|
}
|
|
if (result == 0) {
|
|
static struct timespec pev = {0,0},cur = {0,0};
|
|
static int frame_rate = 0;
|
|
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->sOutProcessingFrame);
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
if (pFrameNode->sFrameInfo.flag & FRAME_FLAG_EOS) {
|
|
pAdecDataType->nFlags |= ADEC_OUTPORT_SEND_ALL_FRAME_FLAG;
|
|
printf("[%s:%d] nFrameEndFlag",__FUNCTION__,__LINE__);
|
|
}
|
|
pAdecDataType->nSendFrameOkNum++;
|
|
|
|
frame_rate++;
|
|
if (pev.tv_sec == 0) {
|
|
clock_gettime(CLOCK_REALTIME,&pev);
|
|
} else {
|
|
long diff;
|
|
clock_gettime(CLOCK_REALTIME,&cur);
|
|
diff = (cur.tv_sec - pev.tv_sec)*1000*1000 + (cur.tv_nsec - pev.tv_nsec)/1000;
|
|
if (diff > 1*1000*1000) {
|
|
//loge("a_fr:%d,diff:%ld \n",frame_rate,diff);
|
|
frame_rate = 0;
|
|
pev = cur;
|
|
}
|
|
}
|
|
//loge("pAdecDataType->nSendFrameOkNum:%d\n",pAdecDataType->nSendFrameOkNum);
|
|
} else {
|
|
//this may drop last frame,so it must deal with this case
|
|
if (sFrame.flag & FRAME_FLAG_EOS) {
|
|
printf("[%s:%d]frame end!!!\n",__FUNCTION__,__LINE__);
|
|
}
|
|
|
|
ret = aic_audio_decoder_put_frame(pAdecDataType->pDecoder, &sFrame);
|
|
if (ret != 0) {// how to do
|
|
loge("mpp_decoder_put_frame error!!!!\n");
|
|
//ASSERT();
|
|
}
|
|
logw("OMX_EmptyThisBuffer or FillBufferDone fail!\n");
|
|
pAdecDataType->nSendFrameErrorNum++;
|
|
}
|
|
|
|
} else if (ret == DEC_NO_RENDER_FRAME) {
|
|
logw("mpp_decoder_get_frame error DEC_NO_RENDER_FRAME !!!\n");
|
|
aic_msg_wait_new_msg(&pAdecDataType->sMsgQue, 1*1000);
|
|
} else if (ret == DEC_ERR_FM_NOT_CREATE) {
|
|
logw("mpp_decoder_get_frame error DEC_ERR_FM_NOT_CREATE !!!\n");
|
|
aic_msg_wait_new_msg(&pAdecDataType->sMsgQue, 1*1000);
|
|
} else if (ret == DEC_NO_EMPTY_FRAME) {
|
|
int nCnt = 0;
|
|
aic_pthread_mutex_lock(&pAdecDataType->sOutFrameLock);
|
|
mpp_list_for_each_entry(pFrameNode, &pAdecDataType->sOutProcessingFrame, sList) {
|
|
nCnt++;
|
|
}
|
|
aic_pthread_mutex_unlock(&pAdecDataType->sOutFrameLock);
|
|
loge("mpp_decoder_get_frame error DEC_NO_EMPTY_FRAME sOutProcessingFrame:%d ,nSendFrameOkNum:%d!!!\n",nCnt,pAdecDataType->nSendFrameOkNum);
|
|
aic_msg_wait_new_msg(&pAdecDataType->sMsgQue, 1*1000);
|
|
} else {
|
|
logw("mpp_decoder_get_frame other error \n");
|
|
}
|
|
} else if (ret == DEC_NO_READY_PACKET) {
|
|
aic_msg_wait_new_msg(&pAdecDataType->sMsgQue, 10*1000);
|
|
} else if (ret == DEC_NO_EMPTY_FRAME) {// no decode on time wait sometime
|
|
aic_msg_wait_new_msg(&pAdecDataType->sMsgQue, 0);
|
|
} else if (ret == DEC_ERR_FM_NOT_CREATE) {
|
|
aic_msg_wait_new_msg(&pAdecDataType->sMsgQue, 1*1000);
|
|
} else if (ret == DEC_NO_RENDER_FRAME) {
|
|
usleep(5*1000);
|
|
} else {
|
|
//ASSERT();
|
|
loge("mpp_decoder_decode error serious,do not keep decoding !!!\n");
|
|
}
|
|
}
|
|
// send frame back to decoder in OMX_AdecFillThisBuffer
|
|
|
|
}
|
|
_EXIT:
|
|
|
|
printf("[%s:%d]in port:nReceivePacktOkNum:%d,"\
|
|
"nReceivePacktFailNum:%d,"\
|
|
"nPutPacktToDecoderOkNum:%d,"\
|
|
"nPutPacktToDecoderFailNum:%d,"\
|
|
"nGiveBackPacktOkNum:%d"\
|
|
"nGiveBackPacktFailNum:%d\n"
|
|
,__FUNCTION__
|
|
,__LINE__
|
|
,pAdecDataType->nReceivePacktOkNum
|
|
,pAdecDataType->nReceivePacktFailNum
|
|
,pAdecDataType->nPutPacktToDecoderOkNum
|
|
,pAdecDataType->nPutPacktToDecoderFailNum
|
|
,pAdecDataType->nGiveBackPacktOkNum
|
|
,pAdecDataType->nGiveBackPacktFailNum);
|
|
|
|
printf("[%s:%d]out port:nGetFrameFromDecoderNum:%d,"\
|
|
"nDropFrameFromDecoderNum:%d,"\
|
|
"nSendFrameOkNum:%d,"\
|
|
"nSendFrameErrorNum:%d,"\
|
|
"nLeftReadyFrameWhenCompoentExitNum:%d\n"
|
|
,__FUNCTION__
|
|
,__LINE__
|
|
,pAdecDataType->nGetFrameFromDecoderNum
|
|
,pAdecDataType->nDropFrameFromDecoderNum
|
|
,pAdecDataType->nSendFrameOkNum
|
|
,pAdecDataType->nSendFrameErrorNum
|
|
,pAdecDataType->nLeftReadyFrameWhenCompoentExitNum);
|
|
printf("OMX_AdecComponentThread EXIT\n");
|
|
return (void*)OMX_ErrorNone;
|
|
}
|
|
|