📄 maimpeg4dec.c
字号:
MAIStatus_e eStatus = MAI_STATUS_OK; int szY, szUV; DPRINTF((M_TEXT("MPV4:_newformat() %dx%d\n"), pPInfo->m_iImageWidth, pPInfo->m_iImageHeight)); szY = (pPInfo->m_iImageWidth * pPInfo->m_iImageHeight); szUV = szY>>2; /* 420 format */ /* Register output setup (needed for Read/WriteBuffer) */ MAICompBase_RegisterOutput(hComp, 0, M_NULL /* pfOutputGetBuffer */, M_NULL /* pfOutputPutBuffer */, hComp, szY+szUV+szUV, 2); MAICompBase_SetFormatState(hComp, FORMAT_STATE_KNOWN); MAICompBase_SendFormat(hComp, 0); return eStatus;}MAIStatus_e _startprocessing(MAICompHandle_t hComp){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus = MAI_STATUS_OK; APIPRINTF((M_TEXT("MPV4: _startprocessing() enter\n"))); if (!MAICompBase_IsState(hComp, MAI_RUNSTATE_NONE)) { APIPRINTF((M_TEXT("MPV4: _startprocessing() state(%d)!=NONE\n"))); eStatus=MAI_STATUS_WRONGSTATE; } else { DPRINTF((M_TEXT("MPV4: _startprocessing() Init codec\n"))); /* create a decoder object */ if (!g_pDecoder) { DPRINTF( (M_TEXT("MPV4: _startprocessing() mpeg4_init\n")) ); /* Initialize libmpeg2 for using reference code, with no file dumps */ g_nMP4VPTS = 0; g_bEOFReached = 0; /* Open MPEG4library - Start */#ifdef MAE_HW DPRINTF((M_TEXT("MPV4: Opening the MAE Driver\n"))); open_mae_driver();#endif /* Open MPEG4 library - End */ pPInfo->m_uiFrameCount=0; pPInfo->m_uiErrorCount=0; pPInfo->m_bFirstInput=0; pPInfo->m_bNeedReset=M_FALSE; pPInfo->m_tDecodePTS=0; pPInfo->m_tInputPTS=0; pPInfo->m_CurrentSpeed=MAI_SPEED_NORMAL; pPInfo->m_NextSpeed=MAI_SPEED_NORMAL; pPInfo->m_uiCurrentDecodeMode=DECODE_NORMAL; pPInfo->m_uiNextDecodeMode=DECODE_NORMAL; } } if (eStatus==MAI_STATUS_OK) { MAICompBase_StartProcessing(hComp); /* initilize global that the decoder will use to pull data (see bitstrm.c) */ g_hInBufferPool=MAICompBase_InputGetPool(hComp, 0); g_hComp=hComp; } APIPRINTF((M_TEXT("MPV4: _startprocessing() exit: status=0x%X\n"), eStatus)); return eStatus;}MAIStatus_e _endprocessing(MAICompHandle_t hComp){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus = MAI_STATUS_OK; APIPRINTF((M_TEXT("MPV4: _endprocessing() enter\n"))); if (MAICompBase_IsState(hComp, MAI_RUNSTATE_NONE)) eStatus=MAI_STATUS_WRONGSTATE; else { /* Close the decoder library */ if (g_pDecoder) { APIPRINTF((M_TEXT("MPV4: MAICompEnd( ) Close decoder\n"))); //mae_indicate_state(M_FALSE); MP4V_Decoder_CleanUp (); // Reset to init state pPInfo->m_bDecoderInit = M_FALSE; if (g_pDecoder) g_pDecoder=(CVideoObjectDecoder *)0; } } MAICompBase_EndProcessing(hComp); APIPRINTF((M_TEXT("MPV4: _endprocessing() exit: status=0x%X\n"), eStatus)); return eStatus;}MAIStatus_e _processbuffer(MAICompHandle_t hComp, MAICompBuffer_t *pInBufferInfo){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus=MAI_STATUS_OK; static m_bool bFirstTime=M_TRUE; unsigned int uiBufsFilled=0; unsigned int uiDataFilled=0; APIPRINTF((M_TEXT("MPV4: _processbuffer(%p) enter: EOS=%d\n"),pInBufferInfo, g_bEOFReached)); if (!pInBufferInfo) { /* Since we're pulling our own buffers from input queue, we must control some of the state transitions that compbase normally would do */ if (MAICompBase_IsState(hComp, MAI_RUNSTATE_STOPPED|MAI_RUNSTATE_STOPPING)) { MAICompBase_ChangeState(hComp, MAI_RUNSTATE_STOPPED); APIPRINTF((M_TEXT("MPV4: _processbuffer(%p) enter: STOPPED\n"),pInBufferInfo)); /* clear EOS to prepare for restarting */ MP4V_ResetBitStream(); //mpeg4_setmode(DECODE_WAITFORI); g_uiWaitForIFrame = M_TRUE; return MAI_STATUS_STOPPED; } if (MAICompBase_IsState(hComp, MAI_RUNSTATE_PAUSING)) { MAICompBase_ChangeState(hComp, MAI_RUNSTATE_PAUSED); APIPRINTF((M_TEXT("MPV4: _processbuffer(%p) enter: PAUSED\n"),pInBufferInfo)); return MAI_STATUS_OK; } /* get current PTS from decoder */ pPInfo->m_tDecodePTS=g_nMP4VPTS; MAICompBase_UpdateTime(hComp, 0, g_nMP4VPTS); if (!MAICompBase_IsStreaming(hComp)) { /* HWG050722 hack - when using Synchronous Read/WriteBuffer make sure we always have at least 2 buffers ** before calling decode. We can't allow decoder to run out of data, or we'll see corrupted frames. */ MAIStatus_e ePoolResult=MAICompBufferPoolGetStatus(g_hInBufferPool, M_NULL, M_NULL, &uiBufsFilled, &uiDataFilled); APIPRINTF((M_TEXT("MPV4: _processbuffer() NotStreaming: BufsFilled=%d DataFilled=%d\n"), uiBufsFilled, uiDataFilled)); if (ePoolResult!=MAI_STATUS_OK || !uiBufsFilled || (pPInfo->m_bDecoderInit && uiBufsFilled<DECODE_MAX_BUFFERS && (uiBufsFilled<=DECODE_MIN_BUFFERS || uiDataFilled<=DECODE_MIN_DATA)) ) { APIPRINTF((M_TEXT("MPV4: _processbuffer() BUFNEEDED\n"), uiBufsFilled, uiDataFilled)); return MAI_STATUS_BUFNEEDED; } } } // Do a one time setup/initialization call. if (!pPInfo->m_bDecoderInit) /* (pInBufferInfo->dwFlags&MAICOMPBUF_FLAG_NEWFORMAT)!=0) */ { MAICompBuffer_t *pBuf=NULL; m_bool bSpatialScalable = M_FALSE; pPInfo->m_iImageWidth = 0; pPInfo->m_iImageHeight = 0; pPInfo->m_uiFrameCount = 0; pPInfo->m_uiFramesOutInMode = 0; MAICompBase_SetEOS(hComp, EOS_NONE); APIPRINTF((M_TEXT("MPV4: _processbuffer() Init: Waiting for buffer\n"))); eStatus=MAICompBufferPoolPeek(g_hInBufferPool,&pBuf,MAI_TIMEOUT_INFINITE); if (eStatus==MAI_STATUS_OK) { MAIMediaTypeVideo_t *pMPEG4_MT=(MAIMediaTypeVideo_t *)pBuf->pBuffer; // Initialize the MPEG-4 video decoder APIPRINTF((M_TEXT("MPV4: _processbuffer() MP4V_Decoder_Init\n"))); if (pMPEG4_MT) { // Check if we are getting called from AVIDemux. If so, its a XviD clip if ((pMPEG4_MT->uiFlags & MAI_VIDEOMTFLAG_AVIDEMUX) != 0) {#ifdef ENABLE_PRINTS printf("MPV4: _processbuffer() Init: Handling XviD clip\n");#endif g_iClipType = CLIP_XVID; } else {#ifdef ENABLE_PRINTS printf("MPV4: _processbuffer() Init: Handling MPEG-4 clip\n");#endif g_iClipType = CLIP_MPEG4; } } if(MP4V_Decoder_Init (NULL, &pPInfo->m_iImageWidth, &pPInfo->m_iImageHeight) != 0) { DPRINTF((M_TEXT("MPV4: _processbuffer() MP4V_Decoder_Init error with init - returning unsupported format\n"))); return MAI_STATUS_UNSUPPORTEDFORMAT; } _newformat(hComp); APIPRINTF((M_TEXT("MPV4: _processbuffer() MP4V_Decoder_Init done: Width=%d Height=%d\n"), pPInfo->m_iImageWidth, pPInfo->m_iImageHeight)); pPInfo->m_bDecoderInit = M_TRUE; } return eStatus; } // If no decoder is found, then return an error if (!g_pDecoder) return MAI_STATUS_OPENERROR;#if 0 else if ((pInBufferInfo->dwFlags&MAICOMPBUF_FLAG_PTS)!=0) { m_u32 tLo=(m_u32)(pInBufferInfo->tTimeStamp); g_tLastPTS=pInBufferInfo->tTimeStamp; /* save timestamp so we can keep Engine informed */ /* pass timestamp to decoder */ mpeg4_settimestamp (g_pDecoder, tLo, 0); }#endif // Call the appropriate decoder if(!main_short_video_header) { int eDecodeStatus; DPRINTF((M_TEXT("MPV4: _processbuffer() decode()\n")));#ifdef ENABLE_PRINTS // To match up when comparing against the StandAlone app printf("Processing Frame %d ", pPInfo->m_uiFrameCount); #endif if (pPInfo->m_bNeedReset) { /* there is a buffer queued on input */ MP4V_ResetBitStream(); g_uiWaitForIFrame = M_TRUE; pPInfo->m_bNeedReset=M_FALSE; } eDecodeStatus=decode(); // Check for End-Of-Stream condition if (eDecodeStatus == EOF) { MAICompBuffer_t *pBuf=NULL; DPRINTF((M_TEXT("MPV4: _processbuffer() decode() EOS\n"))); if (MAICompBase_GetEOS(hComp)==EOS_NONE) /* check state so we send only once */ MAICompBase_SendEOS(hComp, 0); MAICompBase_SetEOS(hComp, EOS_ON_INPUT); MAICompBase_CheckState(hComp); eStatus=MAI_STATUS_BUFNEEDED; pPInfo->m_bNeedReset=M_TRUE; /* need to reset stream when next piece of data comes in */ MAIOSSleep(200); /* prevent infinite spinning at EOS */ } // Check for any supported coding param that we can't handle currently else if (eDecodeStatus == MP4V_UNSUPPORTED_CODING_TYPE) { eStatus = MAI_STATUS_UNSUPPORTEDFORMAT; } DPRINTF((M_TEXT("MPV4: _processbuffer() decode() result=%d\n"), eDecodeStatus)); } else { DPRINTF((M_TEXT("MPV4: _processbuffer() h263_decode()\n"))); h263_decode(); } if (eStatus==MAI_STATUS_OK) { //MAICompBufferPool_t hOutputPool=MAICompBase_OutputGetPool(hComp, 0); //if (hOutputPool!=M_HANDLE_INVALID) /* output empty buffer to notify frame decode to video renderer */ { MAICompBuffer_t *pBufferInfo=M_NULL; if (MAI_STATUS_OK==MAICompBase_OutputGetBuf(hComp, 0, &pBufferInfo)) //if (MAI_STATUS_OK==MAICompBufferPoolGet(hOutputPool, MAI_BUFSTATE_EMPTY, &pBufferInfo, MAI_TIMEOUT_NONE)) { DPRINTF((M_TEXT("MPV4: _processbuffer() OutputPutBuf(datasize=0) pts=%d\n"), MAITIME_LO32(pPInfo->m_tDecodePTS))); pBufferInfo->dwFlags = MAICOMPBUF_FLAG_PTS; /* default - no special flags */ pBufferInfo->tTimeStamp = pPInfo->m_tDecodePTS; pBufferInfo->uiDataSize = 0; MAICompBase_OutputPutBuf(hComp, 0, pBufferInfo); //MAICompBufferPoolPut(hOutputPool, MAI_BUFSTATE_FILLED, pBufferInfo, MAI_TIMEOUT_INFINITE); } } MAICompBase_NewFrame(hComp, 0, MAI_FRAMETYPE_VIDEO, COMPBASE_NEWFRAME_FLAG_PROCESSED|COMPBASE_NEWFRAME_FLAG_RENDERED); MAICompBase_ReportTime(hComp, 0); pPInfo->m_uiFrameCount++; pPInfo->m_uiFramesOutInMode++; } // All done, return success APIPRINTF((M_TEXT("MPV4: _processbuffer() done: result=0x%08X\n"), eStatus)); return eStatus;}static MAIStatus_e MAICompInitInput(MAICompHandle_t hComp, unsigned int uiPinID, pfMAICompGetBufferCB_t *ppfInputGetBuffer, pfMAICompPutBufferCB_t *ppfInputPutBuffer){ return MAICompBase_InitInput(hComp, uiPinID, ppfInputGetBuffer, ppfInputPutBuffer, DEFAULT_INBUFSIZE, DEFAULT_INBUFCOUNT);}static MAIStatus_e MAICompInitOutput(MAICompHandle_t hComp, unsigned int uiPinID, pfMAICompGetBufferCB_t pfOutputGetBuf, pfMAICompPutBufferCB_t pfOutputPutBuf,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -