📄 maimp4demux.c
字号:
eStatus=MAI_STATUS_NOTOPEN;
}
else
{
m_u32 pts=(m_u32)lSeekValue;
uiNewVSamplePosition=time_to_sample(VIDEO, pts);
uiNewASamplePosition=time_to_sample(AUDIO, pts);
/* check limits */
if (uiNewVSamplePosition>g_uiVideoSampleCount)
uiNewVSamplePosition=g_uiVideoSampleCount;
if (uiNewASamplePosition>g_uiAudioSampleCount)
uiNewASamplePosition=g_uiAudioSampleCount;
g_uiVideoSampleNum=uiNewVSamplePosition;
g_uiAudioSampleNum=uiNewASamplePosition;
eStatus = MAI_STATUS_OK;
}
}
else if (eSeekType==MAI_SEEKTYPE_ABS)
{
if (!g_bInit)
{
/* stream is not open yet, allow seek to exact byte position */
if (!lSeekValue) /* seek to start allowed */
eStatus=inputseek((m_u32)lSeekValue);
else
eStatus=MAI_STATUS_NOTOPEN;
}
else if (!lSeekValue) /* seek to start */
{
g_uiVideoSampleNum=0;
g_uiAudioSampleNum=0;
}
else /* seek type not supported */
eStatus=MAI_STATUS_UNSUPPORTED;
}
else if (eSeekType==MAI_SEEKTYPE_ABSPCT || eSeekType==MAI_SEEKTYPE_ABSALIGNED)
{
if (!g_bInit)
eStatus=MAI_STATUS_NOTOPEN;
else
{
m_u32 uiPercentPos=(m_u32)lSeekValue/10; /* adjust percentage to units of 10 */
m_u32 uiTotalSamples=g_uiVideoSampleCount>g_uiAudioSampleCount?g_uiVideoSampleCount:g_uiAudioSampleCount;
if (uiPercentPos>1000)
uiPercentPos=1000;
APIPRINTF( (M_TEXT("MAIengine_Command(Seek) ABSPCT/ABSALIGNED=%d\n"), (m_u32)lSeekValue) );
eSeekType=MAI_SEEKTYPE_ABSPCT;
if (g_uiVideoSampleCount) /* we know how many samples are in the stream */
{
MAISize_t ulTempPos=0;
/* avoid division of int64 on MIPS due to library dependencies:
ulNewDataPos = (SampleCount * (MAISize_t)uiPercentPos) / (MAISize_t)1000;
*/
ulTempPos=(m_u32)g_uiVideoSampleCount * (MAISize_t)uiPercentPos;
/* approx divide by 100 (110010b) using shifts */
ulTempPos=(unsigned int)((ulTempPos>>7) + (ulTempPos>>9) + (ulTempPos>>12));
/* approx divide by 10 (1010b) using shifts */
uiNewVSamplePosition=(unsigned int)((ulTempPos>>4) + (ulTempPos>>5) + (ulTempPos>>8) + (ulTempPos>>9));
}
if (g_uiAudioSampleCount) /* we know how many samples are in the stream */
{
MAISize_t ulTempPos=0;
/* avoid division of int64 on MIPS due to library dependencies:
ulNewDataPos = (SampleCount * (MAISize_t)uiPercentPos) / (MAISize_t)100;
*/
ulTempPos=(m_u32)g_uiAudioSampleCount * (MAISize_t)uiPercentPos;
/* approx divide by 100 (110010b) using shifts */
ulTempPos=(unsigned int)((ulTempPos>>7) + (ulTempPos>>9) + (ulTempPos>>12));
/* approx divide by 10 (1010b) using shifts */
uiNewASamplePosition=(unsigned int)((ulTempPos>>4) + (ulTempPos>>5) + (ulTempPos>>8) + (ulTempPos>>9));
}
/* check limits */
if (uiNewVSamplePosition>g_uiVideoSampleCount)
uiNewVSamplePosition=g_uiVideoSampleCount;
if (uiNewASamplePosition>g_uiAudioSampleCount)
uiNewASamplePosition=g_uiAudioSampleCount;
g_uiVideoSampleNum=uiNewVSamplePosition;
g_uiAudioSampleNum=uiNewASamplePosition;
eStatus = MAI_STATUS_OK;
}
}
else /* seek type not supported */
eStatus=MAI_STATUS_UNSUPPORTED;
}
if (eStatus==MAI_STATUS_OK)
{
/* seek to new position successful, setup for first read */
if (g_bFirstRead)
{
APIPRINTF( (M_TEXT("MP4DEMUX: _streamseek() Reseting bFileRead\n")) );
g_bFirstRead=M_TRUE;
/* we must let caller know that reads at the old position have ended */
//MAICompBase_SendProgressCB(hComp, MAI_PROGRESSFLAG_EOS);
}
}
return eStatus;
}
static void _InBufferPoolStateCB(MAICompBufferPool_t hBufferPool, MAIBufState_e ePoolState, void *pUserData)
{
MAICompHandle_t hThisComp = (MAICompHandle_t)pUserData;
/* This reports to us if BufferPool becomes: MAI_BUFSTATE_FILLED or MAI_BUFSTATE_EMPTY */
PUTPRINTF((M_TEXT("MP4DEMUX: _InBufferPoolStateCB() ePoolState=%d\n"), ePoolState));
if (g_pfProgressCB && (g_uiProgressSelectFlags & MAI_PROGRESS_BUFFER)!=0)
{
MAIProgressBuffer_t ProgressInfo;
unsigned int uiMaxBufs;
unsigned int uiMaxBufSize;
unsigned int uiBufsFilled;
unsigned int uiDataFilled;
MAICompBufferPoolGetStatus(hBufferPool, &uiMaxBufs, &uiMaxBufSize, &uiBufsFilled, &uiDataFilled);
/* setup progress info fields */
memset(&ProgressInfo, 0, sizeof(MAIProgressBuffer_t));
ProgressInfo.uiFlags=0;
ProgressInfo.hComp=hThisComp;
ProgressInfo.tCurrentTime = 0;
ProgressInfo.eBufferUnitType=MAI_UNIT_BYTES;
ProgressInfo.uiBufferAvail=(uiMaxBufs-uiBufsFilled)*uiMaxBufSize;
ProgressInfo.uiBufferUsed=uiDataFilled;
ProgressInfo.uiTotalBufferCount=uiMaxBufs;
ProgressInfo.uiUsedBufferCount=uiBufsFilled;
/* make progress call */
PUTPRINTF((M_TEXT("MP4DEMUX: _InBufferPoolStateCB() making ProgressCB(MAI_PROGRESS_BUFFER)\n"), ePoolState));
g_pfProgressCB(hThisComp, MAI_PROGRESS_BUFFER, &ProgressInfo, sizeof(ProgressInfo));
}
PUTPRINTF((M_TEXT("MP4DEMUX: _InBufferPoolStateCB() exiting\n")));
}
static MAIStatus_e MAICompInitInput(MAICompHandle_t hComp, unsigned int uiPinID,
pfMAICompGetBufferCB_t *pfInputGetBuffer,
pfMAICompPutBufferCB_t *pfInputPutBuffer)
{
MAIStatus_e eStatus = MAI_STATUS_UNSUPPORTED;
#ifndef FILESOURCE
if (uiPinID==0) /* one input pin only */
{
/* return the get/set function pointers to the upstream component */
if (pfInputGetBuffer)
*pfInputGetBuffer = MAIMP4Demux_GetBuffer;
if (pfInputPutBuffer)
*pfInputPutBuffer = MAIMP4Demux_PutBuffer;
eStatus = MAI_STATUS_OK;
}
#endif
return eStatus;
}
static MAIStatus_e MAICompInitOutput(MAICompHandle_t hComp, unsigned int uiPinID,
pfMAICompGetBufferCB_t pfOutputGetBuf, pfMAICompPutBufferCB_t pfOutputPutBuf,
MAICompHandle_t hBufferOwnerComp)
{
MAIStatus_e eStatus = MAI_STATUS_UNSUPPORTED;
if (uiPinID==0) /* video pin */
{
g_pfOutputVideoGetBuf = pfOutputGetBuf; // Callback to get buffer from upstream component (video decoder)
g_pfOutputVideoPutBuf = pfOutputPutBuf; // Callback to send buffer to upstream component (video decoder)
g_hOutputVideoOwner = hBufferOwnerComp;
eStatus = MAI_STATUS_OK;
}
else if (uiPinID==1) /* audio pin */
{
g_pfOutputAudioGetBuf = pfOutputGetBuf; // Callback to get buffer from upstream component (video decoder)
g_pfOutputAudioPutBuf = pfOutputPutBuf; // Callback to send buffer to upstream component (video decoder)
g_hOutputAudioOwner = hBufferOwnerComp;
eStatus = MAI_STATUS_OK;
}
return eStatus;
}
static MAIStatus_e MAICompGetMediaType(MAICompHandle_t hComp, MAICompDirection_e eDirection, unsigned int uiPinID, MAIMediaType_t *pMediaType)
{
MAIStatus_e eStatus = MAI_STATUS_UNSUPPORTED;
if (uiPinID==0 && eDirection==MAICOMP_DIR_INPUT)
{
if (!pMediaType)
eStatus=MAI_STATUS_BADARG;
else
{
MAIMediaTypeStream_t *pStreamInfo=(MAIMediaTypeStream_t *)pMediaType;
/* clear the info structure */
if (pStreamInfo->MediaTypeInfo.uiSize<sizeof(MAIMediaTypeStream_t))
eStatus=MAI_STATUS_BADARG; /* caller didn't pass a large enough structure */
else
{
memcpy(pStreamInfo, &g_StreamInfo, sizeof(MAIMediaTypeStream_t));
eStatus = MAI_STATUS_OK;
}
}
}
else if (eDirection==MAICOMP_DIR_OUTPUT)
{
if (!pMediaType)
eStatus=MAI_STATUS_BADARG;
else
{
if (uiPinID==0)
{
MAIMediaTypeVideo_t *pVideoInfo=(MAIMediaTypeVideo_t *)pMediaType;
/* clear the info structure */
memset(pVideoInfo, 0, sizeof(MAIMediaTypeVideo_t));
/* fill in Common MediaType fields */
pVideoInfo->MediaTypeInfo.uiSize=sizeof(MAIMediaTypeVideo_t);
pVideoInfo->MediaTypeInfo.eMType=MAI_MTYPE_VIDEO;
pVideoInfo->MediaTypeInfo.eMSubtype=MAI_MSUBTYPE_WMV;
pVideoInfo->MediaTypeInfo.uiFlags=0;
/* TBD - fill in Video MediaType specific fields */
eStatus=MAI_STATUS_OK;
}
else if (uiPinID==1)
{
MAIMediaTypeAudio_t *pAudioInfo=(MAIMediaTypeAudio_t *)pMediaType;
/* clear the info structure */
memset(pAudioInfo, 0, sizeof(MAIMediaTypeAudio_t));
/* fill in Common MediaType fields */
pAudioInfo->MediaTypeInfo.uiSize=sizeof(MAIMediaTypeAudio_t);
pAudioInfo->MediaTypeInfo.eMType=MAI_MTYPE_AUDIO;
pAudioInfo->MediaTypeInfo.eMSubtype=MAI_MSUBTYPE_WMA;
pAudioInfo->MediaTypeInfo.uiFlags=0;
/* TBD - fill in Audio MediaType specific fields */
eStatus=MAI_STATUS_OK;
}
else /* unsupported pin */
{
memset(pMediaType, 0, sizeof(MAIMediaType_t));
pMediaType->uiSize=sizeof(MAIMediaType_t);
pMediaType->eMType=MAI_MTYPE_NONE;
pMediaType->eMSubtype=MAI_MSUBTYPE_NONE;
pMediaType->uiFlags=0;
}
}
}
return eStatus;
}
static MAIStatus_e MAICompSetErrorCB(MAICompHandle_t hComp, pfMAICompErrorCB_t pfCB)
{
g_pfErrorCB = pfCB;
return MAI_STATUS_OK;
}
static MAIStatus_e MAICompSetProgressCB(MAICompHandle_t hComp, pfMAICompProgressCB_t pfCB, unsigned int uiProgressSelectFlags)
{
g_pfProgressCB = pfCB;
g_uiProgressSelectFlags=uiProgressSelectFlags;
return MAI_STATUS_OK;
}
/*
** Function: MAICompGetState(hComp, peStateOut)
** Descript: Get the component's running state.
*/
static MAIStatus_e MAICompGetState(MAICompHandle_t hComp, MAIRunState_e *peStateOut)
{
if (peStateOut)
*peStateOut=g_eCompState;
return MAI_STATUS_OK;
}
static void _ChangeState(MAICompHandle_t hComp, MAIRunState_e eNewState)
{
/* State Definitions:
MAI_RUNSTATE_NONE - component not initialized
MAI_RUNSTATE_INIT - component initialized, thread not started yet
MAI_RUNSTATE_PLAYING - component initialized, thread active
MAI_RUNSTATE_PAUSED - component initialized, thread active, processing paused
MAI_RUNSTATE_STOPPED - component initialized, thread exited
MAI_RUNSTATE_DESTROYING - MAICompEnd() in progress - destroying thread
*/
if (g_eCompState!=eNewState) /* state changed */
{
MAIRunState_e eLastState=g_eCompState; /* save last state */
g_eCompState=eNewState; /* change state */
if (g_pfProgressCB &&
(g_uiProgressSelectFlags & MAI_PROGRESS_STATE)!=0) /* deliver progress call to report state change */
{
MAIProgressState_t SProgressInfo;
memset(&SProgressInfo, 0, sizeof(MAIProgressState_t));
SProgressInfo.hComp=hComp;
SProgressInfo.eCurrentState=eNewState;
SProgressInfo.eLastState=eLastState;
g_pfProgressCB(hComp, MAI_PROGRESS_STATE, &SProgressInfo, sizeof(MAIProgressState_t));
}
}
}
MAIStatus_e _ReportStart(MAICompHandle_t hComp)
{
MAIStatus_e eStatus = MAI_STATUS_OK;
/* deliver progress call to report SOS */
if (g_pfProgressCB &&
(g_uiProgressSelectFlags & MAI_PROGRESS_STREAM)!=0)
{
MAIProgressStream_t ProgressInfo;
APIPRINTF((M_TEXT("MP4DEMUX: _ReportStart() Delivering START\n")));
/* setup progress info fields */
memset(&ProgressInfo, 0, sizeof(MAIProgressState_t));
ProgressInfo.uiFlags=MAI_PROGRESSFLAG_START;
if (g_pfOutputVideoGetBuf && g_pfOutputVideoPutBuf && g_uiVideoSampleCount)
ProgressInfo.uiFlags|=MAI_PROGRESSFLAG_VIDEO;
if (g_pfOutputAudioGetBuf && g_pfOutputAudioPutBuf && g_uiAudioSampleCount)
ProgressInfo.uiFlags|=MAI_PROGRESSFLAG_AUDIO;
ProgressInfo.hComp=hComp;
ProgressInfo.eCurrentState=g_eCompState;
ProgressInfo.tCurrentTime=g_tLastPTS;
/* make progress call */
g_pfProgressCB(hComp, MAI_PROGRESS_STREAM, &ProgressInfo, sizeof(ProgressInfo));
}
return eStatus;
}
/* send output buffers with EOS flag */
MAIStatus_e _ReportEOS(MAICompHandle_t hComp)
{
MAIStatus_e eStatus = MAI_STATUS_OK;
MAICompBuffer_t *pBufferInfo;
if (g_eEOS!=EOS_DELIVERED)
{
if (g_pfOutputVideoGetBuf && g_pfOutputVideoPutBuf && g_uiVideoSampleCount &&
MAI_STATUS_OK==g_pfOutputVideoGetBuf(g_hOutputVideoOwner,&pBufferInfo))
{
APIPRINTF((M_TEXT("MP4DEMUX: _ReportEOS(Video)\n")));
pBufferInfo->dwFlags = MAICOMPBUF_FLAG_EOS;
pBufferInfo->uiDataSize = 0;
eStatus=g_pfOutputVideoPutBuf(g_hOutputVideoOwner, pBufferInfo);
}
if (g_pfOutputAudioGetBuf && g_pfOutputAudioPutBuf && g_uiAudioSampleCount &&
MAI_STATUS_OK==g_pfOutputAudioGetBuf(g_hOutputAudioOwner,&pBufferInfo))
{
APIPRINTF((M_TEXT("MP4DEMUX: _ReportEOS(Video)\n")));
pBufferInfo->dwFlags = MAICOMPBUF_FLAG_EOS;
pBufferInfo->uiDataSize = 0;
eStatus=g_pfOutputAudioPutBuf(g_hOutputAudioOwner, pBufferInfo);
}
if (g_pfProgressCB &&
(g_uiProgressSelectFlags & MAI_PROGRESS_STREAM)!=0) /* deliver progress call to report EOS */
{
MAIProgressStream_t ProgressInfo;
APIPRINTF((M_TEXT("MP4DEMUX: _ReportEOS() Delivering EOS\n")));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -