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

1056 lines
31 KiB
C
Executable File

/******************************************************************************
Copyright (C), 2001-2016, Allwinner Tech. Co., Ltd.
******************************************************************************
File Name : mpi_demux.c
Version : Initial Draft
Author : Allwinner BU3-PD2 Team
Created : 2016/08/09
Last Modified :
Description : mpi functions implement for demux module.
Function List :
History :
******************************************************************************/
//#define LOG_NDEBUG 0
#define LOG_TAG "mpi_demux"
#include <utils/plat_log.h>
//ref platform headers
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "plat_type.h"
#include "plat_errno.h"
#include "plat_defines.h"
#include "plat_math.h"
#include "cdx_list.h"
//media api headers to app
#include "mm_common.h"
#include "mm_comm_demux.h"
#include "mpi_demux.h"
//media internal common headers.
#include <tsemaphore.h>
#include <media_common.h>
#include <media_common_vcodec.h>
#include <media_common_acodec.h>
#include <mm_component.h>
//#include <mpi_mux_common.h>
#include <CdxParser.h>
typedef struct DEMUX_CHN_MAP_S
{
DEMUX_CHN mDemuxChn; // demux channel index, [0, DEMUX_MAX_CHN_NUM)
MM_COMPONENTTYPE *mDemuxComp; // demux component instance
cdx_sem_t mSemCompCmd;
MPPCallbackInfo mCallbackInfo;
struct list_head mList;
}DEMUX_CHN_MAP_S;
typedef struct DemuxChnManager
{
struct list_head mList; //element type: DEMUX_CHN_MAP_S
pthread_mutex_t mLock;
}DemuxChnManager;
static DemuxChnManager *gpDemuxChnMap = NULL;
ERRORTYPE DEMUX_Construct(void)
{
int ret;
if (gpDemuxChnMap != NULL) {
return SUCCESS;
}
gpDemuxChnMap = (DemuxChnManager*)malloc(sizeof(DemuxChnManager));
if (NULL == gpDemuxChnMap) {
aloge("alloc DemuxChnManager error(%s)!", strerror(errno));
return FAILURE;
}
ret = pthread_mutex_init(&gpDemuxChnMap->mLock, NULL);
if (ret != 0) {
aloge("fatal error! mutex init fail");
free(gpDemuxChnMap);
gpDemuxChnMap = NULL;
return FAILURE;
}
INIT_LIST_HEAD(&gpDemuxChnMap->mList);
return SUCCESS;
}
ERRORTYPE DEMUX_Destruct(void)
{
if (gpDemuxChnMap != NULL) {
if (!list_empty(&gpDemuxChnMap->mList)) {
aloge("fatal error! some demux channel still running when destroy demux device!");
}
pthread_mutex_destroy(&gpDemuxChnMap->mLock);
free(gpDemuxChnMap);
gpDemuxChnMap = NULL;
}
return SUCCESS;
}
static ERRORTYPE DEMUX_searchExistChannel_l(DEMUX_CHN DemuxChn, DEMUX_CHN_MAP_S** ppChn)
{
ERRORTYPE ret = FAILURE;
DEMUX_CHN_MAP_S* pEntry;
if (gpDemuxChnMap == NULL) {
return FAILURE;
}
list_for_each_entry(pEntry, &gpDemuxChnMap->mList, mList)
{
if(pEntry->mDemuxChn == DemuxChn)
{
if(ppChn)
{
*ppChn = pEntry;
}
ret = SUCCESS;
break;
}
}
return ret;
}
static ERRORTYPE DEMUX_searchExistChannel(DEMUX_CHN DemuxChn, DEMUX_CHN_MAP_S** ppChn)
{
ERRORTYPE ret = FAILURE;
DEMUX_CHN_MAP_S* pEntry;
if (gpDemuxChnMap == NULL) {
return FAILURE;
}
pthread_mutex_lock(&gpDemuxChnMap->mLock);
ret = DEMUX_searchExistChannel_l(DemuxChn, ppChn);
pthread_mutex_unlock(&gpDemuxChnMap->mLock);
return ret;
}
static ERRORTYPE DEMUX_addChannel_l(DEMUX_CHN_MAP_S *pChn)
{
if (gpDemuxChnMap == NULL) {
return FAILURE;
}
list_add_tail(&pChn->mList, &gpDemuxChnMap->mList);
return SUCCESS;
}
static ERRORTYPE DEMUX_addChannel(DEMUX_CHN_MAP_S *pChn)
{
if (gpDemuxChnMap == NULL) {
return FAILURE;
}
pthread_mutex_lock(&gpDemuxChnMap->mLock);
ERRORTYPE ret = DEMUX_addChannel_l(pChn);
pthread_mutex_unlock(&gpDemuxChnMap->mLock);
return SUCCESS;
}
static ERRORTYPE DEMUX_removeChannel(DEMUX_CHN_MAP_S *pChn)
{
if (gpDemuxChnMap == NULL) {
return FAILURE;
}
pthread_mutex_lock(&gpDemuxChnMap->mLock);
list_del(&pChn->mList);
pthread_mutex_unlock(&gpDemuxChnMap->mLock);
return SUCCESS;
}
MM_COMPONENTTYPE *DEMUX_GetChnComp(MPP_CHN_S *pMppChn)
{
DEMUX_CHN_MAP_S* pChn;
if (DEMUX_searchExistChannel(pMppChn->mChnId, &pChn) != SUCCESS) {
return NULL;
}
return pChn->mDemuxComp;
}
static DEMUX_CHN_MAP_S* DEMUX_CHN_MAP_S_Construct()
{
DEMUX_CHN_MAP_S *pChannel = (DEMUX_CHN_MAP_S*)malloc(sizeof(DEMUX_CHN_MAP_S));
if(NULL == pChannel)
{
aloge("fatal error! malloc fail[%s]!", strerror(errno));
return NULL;
}
memset(pChannel, 0, sizeof(DEMUX_CHN_MAP_S));
cdx_sem_init(&pChannel->mSemCompCmd, 0);
return pChannel;
}
static void DEMUX_CHN_MAP_S_Destruct(DEMUX_CHN_MAP_S *pChannel)
{
if(pChannel->mDemuxComp)
{
aloge("fatal error! Demux component need free before!");
COMP_FreeHandle(pChannel->mDemuxComp);
pChannel->mDemuxComp = NULL;
}
cdx_sem_deinit(&pChannel->mSemCompCmd);
free(pChannel);
}
static ERRORTYPE DemuxEventHandler(
COMP_HANDLETYPE hComponent,
void* pAppData,
COMP_EVENTTYPE eEvent,
unsigned int nData1,
unsigned int nData2,
void* pEventData)
{
ERRORTYPE ret;
MPP_CHN_S DemuxChnInfo;
ret = ((MM_COMPONENTTYPE*)hComponent)->GetConfig(hComponent, COMP_IndexVendorMPPChannelInfo, &DemuxChnInfo);
if(ret == SUCCESS)
{
alogv("demux event, MppChannel[%d][%d][%d]", DemuxChnInfo.mModId, DemuxChnInfo.mDevId, DemuxChnInfo.mChnId);
}
DEMUX_CHN_MAP_S *pChn = (DEMUX_CHN_MAP_S*)pAppData;
switch(eEvent)
{
case COMP_EventCmdComplete:
{
if(COMP_CommandStateSet == nData1)
{
alogv("Demux EventCmdComplete, current StateSet[%d]", nData2);
cdx_sem_up(&pChn->mSemCompCmd);
break;
}
else
{
alogw("Low probability! What command[0x%x]?", nData1);
break;
}
}
case COMP_EventError:
{
if(ERR_DEMUX_SAMESTATE == nData1)
{
alogw("Demux set same StateSet[%d]", nData2);
cdx_sem_up(&pChn->mSemCompCmd);
break;
}
else if(ERR_DEMUX_INCORRECT_STATE_TRANSITION == nData1)
{
aloge("Why invalid state transition?! CurState[%#x]", nData2);
cdx_sem_up(&pChn->mSemCompCmd);
break;
}
else
{
aloge("Fatal error! What command[%#x]?!", nData1);
break;
}
}
case COMP_EventBufferFlag:
{
alogw("EOF found!");
MPP_CHN_S ChannelInfo;
ChannelInfo.mModId = MOD_ID_DEMUX;
ChannelInfo.mDevId = 0;
ChannelInfo.mChnId = pChn->mDemuxChn;
CHECK_MPP_CALLBACK(pChn->mCallbackInfo.callback);
pChn->mCallbackInfo.callback(pChn->mCallbackInfo.cookie, &ChannelInfo, MPP_EVENT_NOTIFY_EOF, NULL);
break;
}
default:
{
aloge("fatal error! unknown event[0x%x]", eEvent);
break;
}
}
return SUCCESS;
}
COMP_CALLBACKTYPE DemuxCallback = {
.EventHandler = DemuxEventHandler,
.EmptyBufferDone = NULL,
.FillBufferDone = NULL,
};
ERRORTYPE AW_MPI_DEMUX_CreateChn(DEMUX_CHN dmxChn, const DEMUX_CHN_ATTR_S *pAttr)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
if(NULL == pAttr)
{
aloge("fatal error! illagal DemuxAttr!");
return ERR_DEMUX_ILLEGAL_PARAM;
}
pthread_mutex_lock(&gpDemuxChnMap->mLock);
if(SUCCESS == DEMUX_searchExistChannel_l(dmxChn, NULL))
{
pthread_mutex_unlock(&gpDemuxChnMap->mLock);
return ERR_DEMUX_EXIST;
}
DEMUX_CHN_MAP_S *pNode = DEMUX_CHN_MAP_S_Construct();
pNode->mDemuxChn = dmxChn;
//create Demux Component here...
ERRORTYPE eRet = SUCCESS;
eRet = COMP_GetHandle((COMP_HANDLETYPE*)&pNode->mDemuxComp, CDX_ComponentNameDemux, (void*)pNode, &DemuxCallback);
if(eRet != SUCCESS)
{
aloge("fatal error! get comp handle fail!");
}
MPP_CHN_S ChannelInfo;
ChannelInfo.mModId = MOD_ID_DEMUX;
ChannelInfo.mDevId = 0;
ChannelInfo.mChnId = pNode->mDemuxChn;
eRet = pNode->mDemuxComp->SetConfig(pNode->mDemuxComp, COMP_IndexVendorMPPChannelInfo, (void*)&ChannelInfo);
eRet = pNode->mDemuxComp->SetConfig(pNode->mDemuxComp, COMP_IndexVendorDemuxChnAttr, (void*)pAttr);
eRet = pNode->mDemuxComp->SetConfig(pNode->mDemuxComp, COMP_IndexVendorDemuxSetDataSource, NULL);
eRet = pNode->mDemuxComp->SetConfig(pNode->mDemuxComp, COMP_IndexVendorDemuxPreparePorts, NULL);
if (SUCCESS != eRet)
{
COMP_FreeHandle(pNode->mDemuxComp);
pNode->mDemuxComp = NULL;
DEMUX_CHN_MAP_S_Destruct(pNode);
pthread_mutex_unlock(&gpDemuxChnMap->mLock);
return ERR_DEMUX_FILE_EXCEPTION;
}
eRet = pNode->mDemuxComp->SendCommand(pNode->mDemuxComp, COMP_CommandStateSet, COMP_StateIdle, NULL);
cdx_sem_down(&pNode->mSemCompCmd);
//create Demux Component done!
DEMUX_addChannel_l(pNode);
pthread_mutex_unlock(&gpDemuxChnMap->mLock);
return SUCCESS;
}
ERRORTYPE AW_MPI_DEMUX_DestroyChn(DEMUX_CHN dmxChn)
{
ERRORTYPE ret;
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
ERRORTYPE eRet;
if(pChn->mDemuxComp)
{
COMP_STATETYPE nCompState;
if(SUCCESS == pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState))
{
if(nCompState == COMP_StateIdle)
{
eRet = pChn->mDemuxComp->SendCommand(pChn->mDemuxComp, COMP_CommandStateSet, COMP_StateLoaded, NULL);
cdx_sem_down(&pChn->mSemCompCmd);
eRet = SUCCESS;
}
else if(nCompState == COMP_StateLoaded)
{
eRet = SUCCESS;
}
else if(nCompState == COMP_StateInvalid)
{
alogw("Low probability! Component StateInvalid?");
eRet = SUCCESS;
}
else
{
aloge("fatal error! invalid DemuxChn[%d] state[0x%x]!", dmxChn, nCompState);
eRet = FAILURE;
}
if(eRet == SUCCESS)
{
DEMUX_removeChannel(pChn);
COMP_FreeHandle(pChn->mDemuxComp);
pChn->mDemuxComp = NULL;
DEMUX_CHN_MAP_S_Destruct(pChn);
ret = SUCCESS;
}
else
{
ret = ERR_DEMUX_BUSY;
}
}
else
{
aloge("fatal error! GetState fail!");
ret = ERR_DEMUX_BUSY;
}
}
else
{
aloge("fatal error! no Demux component!");
list_del(&pChn->mList);
DEMUX_CHN_MAP_S_Destruct(pChn);
ret = SUCCESS;
}
return ret;
}
ERRORTYPE AW_MPI_DEMUX_RegisterCallback(DEMUX_CHN dmxChn, MPPCallbackInfo *pCallback)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DmxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
pChn->mCallbackInfo.callback = pCallback->callback;
pChn->mCallbackInfo.cookie = pCallback->cookie;
return SUCCESS;
}
ERRORTYPE AW_MPI_DEMUX_SetChnAttr(DEMUX_CHN dmxChn, DEMUX_CHN_ATTR_S *pAttr)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid dmxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
ERRORTYPE ret;
COMP_STATETYPE nState;
ret = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nState);
if(COMP_StateExecuting != nState && COMP_StateIdle != nState)
{
aloge("wrong state[0x%x], return!", nState);
return ERR_DEMUX_NOT_PERM;
}
ret = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorDemuxChnAttr, (void*)pAttr);
return ret;
}
ERRORTYPE AW_MPI_DEMUX_GetChnAttr(DEMUX_CHN dmxChn, DEMUX_CHN_ATTR_S *pAttr)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
ERRORTYPE ret;
COMP_STATETYPE nState;
ret = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nState);
if(COMP_StateExecuting != nState && COMP_StateIdle != nState)
{
aloge("wrong state[0x%x], return!", nState);
return ERR_DEMUX_NOT_PERM;
}
ret = pChn->mDemuxComp->GetConfig(pChn->mDemuxComp, COMP_IndexVendorDemuxChnAttr, (void*)pAttr);
return ret;
}
static ERRORTYPE convert_CdxMediaInfoT_to_DEMUX_MEDIA_INFO_S(DEMUX_MEDIA_INFO_S *pDemuxMediaInfo, CdxMediaInfoT *pCdxMediaInfo)
{
memset(pDemuxMediaInfo, 0, sizeof(DEMUX_MEDIA_INFO_S));
struct CdxProgramS *pProgram = &pCdxMediaInfo->program[0];
int i;
pDemuxMediaInfo->mFileSize = pCdxMediaInfo->fileSize;
pDemuxMediaInfo->mDuration = pProgram->duration;
if(pProgram->videoNum > 0)
{
pDemuxMediaInfo->mVideoNum = pProgram->videoNum;
if(pDemuxMediaInfo->mVideoNum > DEMUX_MAX_VIDEO_STREAM_NUM)
{
aloge("fatal error! videoNum[%d]>max[%d]", pDemuxMediaInfo->mVideoNum, DEMUX_MAX_VIDEO_STREAM_NUM);
pDemuxMediaInfo->mVideoNum = DEMUX_MAX_VIDEO_STREAM_NUM;
}
pDemuxMediaInfo->mVideoIndex = pProgram->videoIndex;
if(pDemuxMediaInfo->mVideoIndex >= pDemuxMediaInfo->mVideoNum)
{
aloge("fatal error! videoIndex[%d]>num[%d]", pDemuxMediaInfo->mVideoIndex, pDemuxMediaInfo->mVideoNum);
}
for(i=0; i<pDemuxMediaInfo->mVideoNum; i++)
{
pDemuxMediaInfo->mVideoStreamInfo[i].mCodecType = map_EVIDEOCODECFORMAT_to_PAYLOAD_TYPE_E(pProgram->video[i].eCodecFormat);
pDemuxMediaInfo->mVideoStreamInfo[i].mWidth = pProgram->video[i].nWidth;
pDemuxMediaInfo->mVideoStreamInfo[i].mHeight = pProgram->video[i].nHeight;
pDemuxMediaInfo->mVideoStreamInfo[i].mFrameRate = pProgram->video[i].nFrameRate;
pDemuxMediaInfo->mVideoStreamInfo[i].mAvgBitsRate = pCdxMediaInfo->bitrate;
pDemuxMediaInfo->mVideoStreamInfo[i].mMaxBitsRate = pCdxMediaInfo->bitrate;
VideoStreamInfo *pVideoStreamInfo = (void*)&pProgram->video[i];
pDemuxMediaInfo->mVideoStreamInfo[i].nCodecSpecificDataLen = pVideoStreamInfo->nCodecSpecificDataLen;
pDemuxMediaInfo->mVideoStreamInfo[i].pCodecSpecificData = pVideoStreamInfo->pCodecSpecificData;
}
}
if(pProgram->audioNum > 0)
{
pDemuxMediaInfo->mAudioNum = pProgram->audioNum;
if(pDemuxMediaInfo->mAudioNum > DEMUX_MAX_AUDIO_STREAM_NUM)
{
aloge("fatal error! audioNum[%d]>max[%d]", pDemuxMediaInfo->mAudioNum, DEMUX_MAX_AUDIO_STREAM_NUM);
pDemuxMediaInfo->mAudioNum = DEMUX_MAX_AUDIO_STREAM_NUM;
}
pDemuxMediaInfo->mAudioIndex = pProgram->audioIndex;
if(pDemuxMediaInfo->mAudioIndex >= pDemuxMediaInfo->mAudioNum)
{
aloge("fatal error! audioIndex[%d]>num[%d]", pDemuxMediaInfo->mAudioIndex, pDemuxMediaInfo->mAudioNum);
}
for(i=0; i<pDemuxMediaInfo->mAudioNum; i++)
{
pDemuxMediaInfo->mAudioStreamInfo[i].mCodecType = map_EAUDIOCODECFORMAT_to_PAYLOAD_TYPE_E(pProgram->audio[i].eCodecFormat, pProgram->audio[i].eSubCodecFormat);
pDemuxMediaInfo->mAudioStreamInfo[i].mChannelNum = pProgram->audio[i].nChannelNum;
pDemuxMediaInfo->mAudioStreamInfo[i].mBitsPerSample = pProgram->audio[i].nBitsPerSample;
pDemuxMediaInfo->mAudioStreamInfo[i].mSampleRate = pProgram->audio[i].nSampleRate;
pDemuxMediaInfo->mAudioStreamInfo[i].mAvgBitsRate = pProgram->audio[i].nAvgBitrate;
pDemuxMediaInfo->mAudioStreamInfo[i].mMaxBitsRate = pProgram->audio[i].nMaxBitRate;
}
}
//subtitle
if (pProgram->subtitleNum > 0)
{
pDemuxMediaInfo->mSubtitleNum = pProgram->subtitleNum;
if (pDemuxMediaInfo->mSubtitleNum > DEMUX_MAX_SUBTITLE_STREAM_NUM)
{
aloge("fatal error! subtitleNum[%d]>max[%d]", \
pDemuxMediaInfo->mSubtitleNum, DEMUX_MAX_SUBTITLE_STREAM_NUM);
pDemuxMediaInfo->mSubtitleNum = DEMUX_MAX_SUBTITLE_STREAM_NUM;
}
pDemuxMediaInfo->mSubtitleIndex = pProgram->subtitleIndex;
if (pDemuxMediaInfo->mSubtitleIndex >= pDemuxMediaInfo->mSubtitleNum)
{
aloge("fatal error! subtitleIndex[%d]>num[%d]", \
pDemuxMediaInfo->mSubtitleIndex, pDemuxMediaInfo->mSubtitleNum);
}
}
return SUCCESS;
}
ERRORTYPE AW_MPI_DEMUX_GetMediaInfo(DEMUX_CHN dmxChn, DEMUX_MEDIA_INFO_S *pDemuxMediaInfo)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
ERRORTYPE ret;
COMP_STATETYPE nState;
ret = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nState);
if(COMP_StateIdle != nState && COMP_StateExecuting!= nState && COMP_StatePause!= nState)
{
aloge("wrong state[0x%x], return!", nState);
return ERR_DEMUX_NOT_PERM;
}
CdxMediaInfoT stMediaInfo;
ret = pChn->mDemuxComp->GetConfig(pChn->mDemuxComp, COMP_IndexVendorDemuxMediaInfo, (void*)&stMediaInfo);
convert_CdxMediaInfoT_to_DEMUX_MEDIA_INFO_S(pDemuxMediaInfo, &stMediaInfo);
return ret;
}
ERRORTYPE AW_MPI_DEMUX_Start(DEMUX_CHN dmxChn)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if(COMP_StateIdle == nCompState || COMP_StatePause == nCompState)
{
eRet = pChn->mDemuxComp->SendCommand(pChn->mDemuxComp, COMP_CommandStateSet, COMP_StateExecuting, NULL);
if(eRet != SUCCESS)
{
aloge("fatal error! send command stateExecuting fail");
}
cdx_sem_down(&pChn->mSemCompCmd);
ret = SUCCESS;
}
else
{
alogd("DemuxChannelState[0x%x], do nothing!", nCompState);
ret = SUCCESS;
}
return ret;
}
ERRORTYPE AW_MPI_DEMUX_Stop(DEMUX_CHN dmxChn)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
alogd("chn not exist");
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if(COMP_StateExecuting == nCompState || COMP_StatePause == nCompState)
{
eRet = pChn->mDemuxComp->SendCommand(pChn->mDemuxComp, COMP_CommandStateSet, COMP_StateIdle, NULL);
if(eRet != SUCCESS)
{
aloge("fatal error! send command stateExecuting fail");
}
cdx_sem_down(&pChn->mSemCompCmd);
ret = SUCCESS;
}
else if(COMP_StateIdle == nCompState)
{
alogv("DemuxChannelState[0x%x], do nothing!", nCompState);
ret = SUCCESS;
}
else
{
aloge("fatal error! check DemuxChannelState[0x%x]!", nCompState);
ret = FAILURE;
}
return ret;
}
ERRORTYPE AW_MPI_DEMUX_Pause(DEMUX_CHN dmxChn)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if(COMP_StateExecuting == nCompState)
{
eRet = pChn->mDemuxComp->SendCommand(pChn->mDemuxComp, COMP_CommandStateSet, COMP_StatePause, NULL);
if(eRet != SUCCESS)
{
aloge("fatal error! send command stateExecuting fail");
}
cdx_sem_down(&pChn->mSemCompCmd);
ret = SUCCESS;
}
else if(COMP_StateIdle == nCompState)
{
alogv("DemuxChannelState[%#x], do nothing!", nCompState);
ret = SUCCESS;
}
else
{
aloge("Fatal error! Check DemuxChannelState[%#x]!", nCompState);
ret = FAILURE;
}
return ret;
}
//ERRORTYPE AW_MPI_DEMUX_ResetChn(DEMUX_CHN dmxChn)
//{
// if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
// {
// aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
// return ERR_DEMUX_INVALID_CHNID;
// }
// DEMUX_CHN_MAP_S *pChn;
// if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
// {
// return ERR_DEMUX_UNEXIST;
// }
// COMP_STATETYPE nCompState = COMP_StateInvalid;
// ERRORTYPE eRet, eRet2;
// eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
// if(eRet == SUCCESS && COMP_StateIdle == nCompState)
// {
// eRet2 = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorDemuxResetChannel, NULL);
// if(eRet2 != SUCCESS)
// {
// aloge("fatal error! reset channel fail[0x%x]!", eRet2);
// }
// return eRet2;
// }
// else
// {
// aloge("wrong status[0x%x], can't reset demux channel!", nCompState);
// return ERR_DEMUX_NOT_PERM;
// }
//}
ERRORTYPE AW_MPI_DEMUX_Seek(DEMUX_CHN dmxChn, int msec)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if(COMP_StateIdle == nCompState || COMP_StatePause == nCompState)
{
CedarXSeekPara seekPara;
memset(&seekPara, 0, sizeof(CedarXSeekPara));
seekPara.seek_time = msec;
eRet = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorSeekToPosition, (void*)&seekPara);
if(eRet != SUCCESS)
{
aloge("fatal error! demux seek fail!");
}
ret = eRet;
}
else
{
alogd("seek in wrong DemuxChannelState[0x%x], do nothing!", nCompState);
ret = ERR_DEMUX_INCORRECT_STATE_OPERATION;
}
return ret;
}
//ERRORTYPE AW_MPI_DEMUX_DisableTrack(DEMUX_CHN dmxChn, int nDisableTrack)
//{
// if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
// {
// aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
// return ERR_DEMUX_INVALID_CHNID;
// }
// DEMUX_CHN_MAP_S *pChn;
// if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
// {
// return ERR_DEMUX_UNEXIST;
// }
// int ret;
// int eRet;
// COMP_STATETYPE nCompState;
// eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
// if(COMP_StateIdle == nCompState)
// {
// eRet = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorDemuxDisableTrack, (void*)&nDisableTrack);
// if(eRet != SUCCESS)
// {
// aloge("fatal error! send command stateExecuting fail");
// }
// ret = SUCCESS;
// }
// else
// {
// aloge("DisableTrack in WRONG State[%#x]!", nCompState);
// ret = FAILURE;
// }
// return ret;
//}
//ERRORTYPE AW_MPI_DEMUX_DisableMediaType(DEMUX_CHN dmxChn, int nDisableMediaType)
//{
// if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
// {
// aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
// return ERR_DEMUX_INVALID_CHNID;
// }
// DEMUX_CHN_MAP_S *pChn;
// if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
// {
// return ERR_DEMUX_UNEXIST;
// }
// int ret;
// int eRet;
// COMP_STATETYPE nCompState;
// eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
// if(COMP_StateIdle == nCompState)
// {
// eRet = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorDemuxDisableMediaType, (void*)&nDisableMediaType);
// if(eRet != SUCCESS)
// {
// aloge("fatal error! send command stateExecuting fail");
// }
// ret = SUCCESS;
// }
// else
// {
// alogw("DisableMediaType in WRONG State[%#x]!", nCompState);
// ret = FAILURE;
// }
// return ret;
//}
ERRORTYPE AW_MPI_DEMUX_getDmxOutPutBuf(DEMUX_CHN dmxChn, EncodedStream *pDmxOutBuf, int nMilliSec)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if(COMP_StateExecuting == nCompState)
{
DemuxStream stDmxStream;
stDmxStream.pEncodedStream = pDmxOutBuf;
stDmxStream.nMilliSec = nMilliSec;
eRet = pChn->mDemuxComp->GetConfig(pChn->mDemuxComp, COMP_IndexVendorDemuxOutBuffer, (void *)&stDmxStream);
if(eRet != SUCCESS)
{
/*aloge("get buf fail[0x%x]", eRet);*/
ret = eRet;
}
else
{
ret = SUCCESS;
}
}
else
{
alogw("DisableMediaTrack in WRONG State[%#x]!", nCompState);
ret = ERR_DEMUX_INCORRECT_STATE_OPERATION;
}
return ret;
}
ERRORTYPE AW_MPI_DEMUX_releaseDmxBuf(DEMUX_CHN dmxChn, EncodedStream *pDmxOutBuf)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if(COMP_StateExecuting == nCompState || COMP_StateIdle == nCompState)
{
eRet = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorDemuxOutBuffer, (void *)pDmxOutBuf);
if(eRet != SUCCESS)
{
aloge("get buf fail");
ret = FAILURE;
}
else
{
ret = SUCCESS;
}
}
else
{
//alogw("DisableMediaTrack in WRONG State[%#x]!", nCompState);
ret = ERR_DEMUX_INCORRECT_STATE_OPERATION;
}
return ret;
}
ERRORTYPE AW_MPI_DEMUX_SelectVideoStream(DEMUX_CHN dmxChn, int nVideoIndex)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if (COMP_StateIdle == nCompState)
{
eRet = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorSwitchVideo, (void *)&nVideoIndex);
if (eRet != SUCCESS)
{
aloge("select video stream fail");
return FAILURE;
}
else
{
ret = SUCCESS;
}
}
else
{
alogw("Select video stream in WRONG State[%#x]!", nCompState);
ret = FAILURE;
}
return ret;
}
ERRORTYPE AW_MPI_DEMUX_SelectAudioStream(DEMUX_CHN dmxChn, int nAudioIndex)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if (COMP_StateIdle == nCompState)
{
eRet = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorSwitchAudio, (void *)&nAudioIndex);
if (eRet != SUCCESS)
{
aloge("select audio stream fail");
return FAILURE;
}
else
{
ret = SUCCESS;
}
}
else
{
alogw("Select audio stream in WRONG State[%#x]!", nCompState);
ret = FAILURE;
}
return ret;
}
ERRORTYPE AW_MPI_DEMUX_SelectSubtitleStream(DEMUX_CHN dmxChn, int nSubtitlrIndex)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if (COMP_StateIdle == nCompState)
{
eRet = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorSwitchSubtitle, (void *)&nSubtitlrIndex);
if (eRet != SUCCESS)
{
aloge("select subtitle stream fail");
return FAILURE;
}
else
{
ret = SUCCESS;
}
}
else
{
alogw("Select subtitle stream in WRONG State[%#x]!", nCompState);
ret = FAILURE;
}
return ret;
}
ERRORTYPE AW_MPI_DEMUX_SwitchDateSource(DEMUX_CHN dmxChn, DEMUX_CHN_ATTR_S *pChnAttr)
{
if(!(dmxChn>=0 && dmxChn <DEMUX_MAX_CHN_NUM))
{
aloge("fatal error! invalid DemuxChn[%d]!", dmxChn);
return ERR_DEMUX_INVALID_CHNID;
}
DEMUX_CHN_MAP_S *pChn;
if(SUCCESS != DEMUX_searchExistChannel(dmxChn, &pChn))
{
return ERR_DEMUX_UNEXIST;
}
int ret;
int eRet;
COMP_STATETYPE nCompState;
eRet = pChn->mDemuxComp->GetState(pChn->mDemuxComp, &nCompState);
if ((COMP_StatePause == nCompState) || (COMP_StateIdle == nCompState))
{
eRet = pChn->mDemuxComp->SetConfig(pChn->mDemuxComp, COMP_IndexVendorDemuxSwitchDateSource, (void *)pChnAttr);
if (eRet != SUCCESS)
{
aloge("select subtitle stream fail");
return FAILURE;
}
else
{
ret = SUCCESS;
}
}
else
{
alogw("set next file now in WRONG State[%#x]!", nCompState);
ret = FAILURE;
}
return ret;
}