📄 maimpeg2dec.c
字号:
DPRINTF((M_TEXT("MPV2:_newformat()\n"))); DPRINTF2((M_TEXT("MPV2:_newformat() mpeg2_info\n"))); pInfo=mpeg2_info(pPInfo->m_pDecoder); szY = (pInfo->sequence->width * pInfo->sequence->height); 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);#ifdef VREND_SUPPORT if (pPInfo->m_eOutputMode==OUTPUT_MODE_VREND && !pPInfo->m_bVideoOpen) { unsigned long g_OptionDisplayFormat=0x32315659; /* FOURCC_YV12 */ unsigned short g_OptionDisplayBPP=12; unsigned char *Y=M_NULL, *U=M_NULL, *V=M_NULL; if (util_VRendInit(pInfo->sequence->width, pInfo->sequence->height, g_OptionDisplayFormat,g_OptionDisplayBPP)) { DPRINTF((M_TEXT("MPV2:_newformat() VRend initialization failed (%dx%d)\n"), pInfo->sequence->width, pInfo->sequence->height) ); } else { pPInfo->m_bVideoOpen=M_TRUE;#if 0 if (!m_pVideoBuffer[0]) { unsigned int uiFrameSize=pInfo->sequence->width*pInfo->sequence->height; m_pVideoBuffer[0]=(unsigned char *)MAIOSMemAlloc(uiFrameSize + uiFrameSize/2); /* Y plane */ m_pVideoBuffer[1]=m_pVideoBuffer[0]+uiFrameSize; /* U plane */ m_pVideoBuffer[2]=m_pVideoBuffer[1]+uiFrameSize/4; /* V plane */ mpeg2_custom_fbuf (pPInfo->m_pDecoder, 1); mpeg2_set_buf (pPInfo->m_pDecoder, m_pVideoBuffer, 0); }#endif } }#endif /* VREND_SUPPORT */ 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("MPV2: _startprocessing() enter\n"))); if (!MAICompBase_IsState(hComp, MAI_RUNSTATE_NONE)) eStatus=MAI_STATUS_WRONGSTATE; else { DPRINTF((M_TEXT("MPV2: _startprocessing() Init codec\n"))); /* create a decoder object */ if (!pPInfo->m_pDecoder) { DPRINTF((M_TEXT("MPV2: _startprocessing() mpeg2_init\n"))); /* Initialize libmpeg2 for using reference code, with no file dumps */#ifdef MAE_HW pPInfo->m_pDecoder = mpeg2_init (/* USE_MAE */(unsigned char)1,0,0, /* VideoOn */0);#else pPInfo->m_pDecoder = mpeg2_init (/* USE_MAE */(unsigned char)0,0,0, /* VideoOn */0);#endif pPInfo->m_uiFrameCount=0; pPInfo->m_uiOutputFrameCount=0; pPInfo->m_uiErrorCount=0; pPInfo->m_bFirstInput=0; pPInfo->m_tDecodePTS=0; pPInfo->m_tInputPTS=0; pPInfo->m_CurrentSpeed=MAI_SPEED_NORMAL; pPInfo->m_NextSpeed=MAI_SPEED_NORMAL; pPInfo->m_uiCurrentDecodeMode=COMP_DECMODE_ALL; pPInfo->m_uiNextDecodeMode=COMP_DECMODE_ALL; pPInfo->m_bCheckSync = M_FALSE; pPInfo->m_uiFramesOutInMode = 0; pPInfo->m_uiFramesSinceCheckSync = 0; } } if (eStatus==MAI_STATUS_OK) { MAICompBase_StartProcessing(hComp); } APIPRINTF((M_TEXT("MPV2: _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("MPV2: _endprocessing() enter\n"))); if (MAICompBase_IsState(hComp, MAI_RUNSTATE_NONE)) eStatus=MAI_STATUS_WRONGSTATE; else {#ifdef VREND_SUPPORT if (pPInfo->m_bVideoOpen) { util_VRendClose(); pPInfo->m_bVideoOpen=0; if (pPInfo->m_pVideoBuffer[0]) { MAIOSMemFree(pPInfo->m_pVideoBuffer[0]); pPInfo->m_pVideoBuffer[0]=M_NULL; } }#endif /* Close MPEG2 library */ if (pPInfo->m_pDecoder) { APIPRINTF((M_TEXT("MPV2: MAICompEnd() mpeg2_close\n"))); mpeg2_close(pPInfo->m_pDecoder); pPInfo->m_pDecoder=(mpeg2dec_t *)0; } } MAICompBase_EndProcessing(hComp); APIPRINTF((M_TEXT("MPV2: _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; mpeg2_state_t state; m_bool bSetPTS=M_FALSE; DPRINTF((M_TEXT("MPV2: MPEG2Decode(%d bytes, pts=%d) bufflags=0x%X decmode=%d\n"), pInBufferInfo->uiDataSize, MAITIME_LO32(pInBufferInfo->tTimeStamp), pInBufferInfo->dwFlags, pPInfo->m_uiCurrentDecodeMode)); if (!pPInfo->m_pDecoder) { ERRORPRINTF((M_TEXT("MPV2: _processbuffer() Decoder not open\n"))); return MAI_STATUS_OPENERROR; /* decoder not initialized */ } if ((pInBufferInfo->dwFlags&(MAICOMPBUF_FLAG_DATADISCON|MAICOMPBUF_FLAG_SOS))!=0) /* send out DATADISCON/SOS buffer */ { MAICompBuffer_t *pOutBufferInfo=M_NULL; if (MAI_STATUS_OK==MAICompBase_OutputGetBuf(hComp, 0, &pOutBufferInfo)) { DPRINTF((M_TEXT("MPV2: _processbuffer() OutputPutBuf(DATADISCON/SOS, datasize=0) flags=0x%X pts=%d\n"), pInBufferInfo->dwFlags, MAITIME_LO32(pPInfo->m_tDecodePTS))); pOutBufferInfo->dwFlags = MAICOMPBUF_FLAG_VIDEO; pOutBufferInfo->dwFlags |= pInBufferInfo->dwFlags&(MAICOMPBUF_FLAG_DATADISCON|MAICOMPBUF_FLAG_SOS); if ((pInBufferInfo->dwFlags&MAICOMPBUF_FLAG_PTS)!=0) { pOutBufferInfo->dwFlags |= MAICOMPBUF_FLAG_PTS; MAITIME_ASSIGN(pOutBufferInfo->tTimeStamp, pInBufferInfo->tTimeStamp); } pOutBufferInfo->uiDataSize = 0; MAICompBase_OutputPutBuf(hComp, 0, pOutBufferInfo); } /* if IFrame mode, no need to flush since we are probably in a trick mode */ if (pPInfo->m_uiCurrentDecodeMode!=DECODE_I_ONLY) { DPRINTF((M_TEXT("MPV2: MPEG2Decode() mpeg2_setdiscontinuity()\n"))); mpeg2_setdiscontinuity(pPInfo->m_pDecoder, 1); pPInfo->m_uiFramesOutInMode=0; } if (pPInfo->m_uiCurrentDecodeMode==DECODE_NORMAL && pPInfo->m_CurrentSpeed==MAI_SPEED_NORMAL) { APIPRINTF((M_TEXT("MPV2: MPEG2Decode() DATADISCON: DECODE_NORMAL\n"))); SETDECODEMODE(pPInfo, DECODE_NORMAL, pPInfo->m_CurrentSpeed); } }#ifndef SETPTS_ON_GOP_ONLY if ((pInBufferInfo->dwFlags&MAICOMPBUF_FLAG_PTS)!=0) /* pass timestamp to decoder */ {#ifdef SYNC_SKIPPING_SUPPORT SYNCPRINTF((M_TEXT("MPV2: MPEG2Decode() pts=%d framessincesync=%d\n"), MAITIME_LO32(pInBufferInfo->tTimeStamp), pPInfo->m_uiFramesSinceCheckSync)); if (pPInfo->m_bCheckSync && pPInfo->m_uiFramesSinceCheckSync>40) /* we are not receiving check_sync calls frequently enough */ { /* force decoder to go back to NORMAL decode via check_sync */ MAIParamClock_t Clock; Clock.uiFlags = MAI_CLOCK_FLAG_CURRENTTIME; Clock.hComp = M_NULL; Clock.pvClock = M_NULL; Clock.eTimeUnits = MAI_UNIT_TIME_MS; MAITIME_ASSIGN(Clock.tCurrentTime, pPInfo->m_tDecodePTS); Clock.tCurrentTime-=300; SYNCPRINTF((M_TEXT("MPV2: MPEG2Decode() internal check_sync() framesellapsed=%d\n"), pPInfo->m_uiFramesSinceCheckSync)); check_sync(pPInfo, &Clock); }#endif mpeg2_settimestamp (pPInfo->m_pDecoder, (mpeg_time_t)pInBufferInfo->tTimeStamp); MAITIME_ASSIGN(pPInfo->m_tDecodePTS, pInBufferInfo->tTimeStamp); MAICompBase_UpdateTime(hComp, 0, pPInfo->m_tDecodePTS); bSetPTS=M_TRUE; }#endif mpeg2_buffer (pPInfo->m_pDecoder, pInBufferInfo->pBuffer, (unsigned char *)pInBufferInfo->pBuffer + pInBufferInfo->uiDataSize); while (1) { DPRINTF2((M_TEXT("MPV2: mpeg2_parse()\n"))); state = mpeg2_parse (pPInfo->m_pDecoder); DPRINTF2((M_TEXT("MPV2: mpeg2_parse() done\n"))); switch (state) { case STATE_BUFFER: return MAI_STATUS_OK; case STATE_SEQUENCE: pPInfo->m_uiFrameCount=0; _newformat(hComp); update_speed(pPInfo, 1); /* force decode mode update on new sequence */ break;#ifdef SETPTS_ON_GOP_ONLY case STATE_GOP: if (!bSetPTS && (pInBufferInfo->dwFlags&MAICOMPBUF_FLAG_PTS)!=0) /* pass timestamp to decoder */ { m_s32 tLo=(m_s32)(pInBufferInfo->tTimeStamp); mpeg2_settimestamp (pPInfo->m_pDecoder, tLo, 0); bSetPTS=M_TRUE; }#endif break; case STATE_PICTURE: /* decoder is starting to parse a new picture */ { const mpeg2_info_t *pInfo=mpeg2_info(pPInfo->m_pDecoder); DPRINTF((M_TEXT("MPV2: MPEG2Decode() STATE_PICTURE: type=%d pts=%d count=%d\n"), pInfo->uiFrameType, pInBufferInfo->tTimeStamp, pInfo->uiFrameCount)); MAICompBase_NewFrame(hComp, 0, MAI_FRAMETYPE_VIDEO, COMPBASE_NEWFRAME_FLAG_INPUT); } break; case STATE_SLICE: case STATE_END: case STATE_INVALID_END: { const mpeg2_info_t *pInfo=mpeg2_info(pPInfo->m_pDecoder); if (state==STATE_END) { DPRINTF((M_TEXT("MPV2: MPEG2Decode() STATE_END\n"))); }#ifdef VREND_SUPPORT if (state!=STATE_INVALID_END && pInfo->display_fbuf && pPInfo->m_bVideoOpen) { util_VRendDrawYUV420((unsigned char *)pInfo->display_fbuf->buf[0], (unsigned char *)pInfo->display_fbuf->buf[1], (unsigned char *)pInfo->display_fbuf->buf[2], pInfo->sequence->width, pInfo->sequence->height, pInfo->sequence->width); }#endif /* VREND_SUPPORT */ /* send out empty buffer marked with PTS */ { mpeg_time_t tCurrent=0; MAICompBuffer_t *pOutBufferInfo=M_NULL; m_bool bPostOutput=pInfo->uiFrameSent?M_TRUE:M_FALSE; mpeg2_gettimestamp(pPInfo->m_pDecoder, &tCurrent); if (!bPostOutput && GETDECODEMODE(pPInfo)!=DECODE_NORMAL) bPostOutput=M_TRUE; if (tCurrent>pPInfo->m_tDecodePTS) pPInfo->m_tDecodePTS=tCurrent; if(bPostOutput) { if (MAI_STATUS_OK==MAICompBase_OutputGetBuf(hComp, 0, &pOutBufferInfo)) { APIPRINTF((M_TEXT("MPV2: _processbuffer() OutputPutBuf(datasize=0) pts=%d framesout=%d\n"), MAITIME_LO32(pPInfo->m_tDecodePTS), pPInfo->m_uiFramesOutInMode)); pOutBufferInfo->dwFlags = MAICOMPBUF_FLAG_VIDEO; if ((pInBufferInfo->dwFlags&MAICOMPBUF_FLAG_PTS)!=0) { pOutBufferInfo->dwFlags |= MAICOMPBUF_FLAG_PTS; pOutBufferInfo->tTimeStamp = pPInfo->m_tDecodePTS; } pOutBufferInfo->uiDataSize = 0; MAICompBase_OutputPutBuf(hComp, 0, pOutBufferInfo); } } else { APIPRINTF((M_TEXT("MPV2: _processbuffer() OutputPutBuf(datasize=0) pts=%d (skipped)\n"), MAITIME_LO32(pPInfo->m_tDecodePTS))); } } update_speed(pPInfo, 0); /* check if decode mode change is requested */ 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++; pPInfo->m_uiFramesSinceCheckSync++; } break; default: break; } /* switch(state) */ } 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, MAICompHandle_t hBufferOwnerComp){ return MAICompBase_InitOutput(hComp, uiPinID, pfOutputGetBuf, pfOutputPutBuf, hBufferOwnerComp);}static MAIStatus_e MAICompStart(MAICompHandle_t hComp){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus = MAI_STATUS_OK; DPRINTF((M_TEXT("MPV2: MAICompStart() enter\n"))); _startprocessing(hComp); eStatus=MAICompBase_StartStreaming(hComp, MAICompBase_ProcessorThread, 0); APIPRINTF((M_TEXT("MPV2: MAICompStart() done: status=0x%X\n"), eStatus)); return eStatus;}static MAIStatus_e MAICompEnd(MAICompHandle_t hComp){ MAIStatus_e eStatus = MAI_STATUS_OK; APIPRINTF((M_TEXT("MPV2: MAICompEnd() enter\n"))); /* call base EndStreaming to close down any running threads */ eStatus=MAICompBase_EndStreaming(hComp, MAI_TIMEOUT_INFINITE); /* now call our local endprocessing logic */ if (!MAICompBase_IsState(hComp, MAI_RUNSTATE_NONE)) eStatus=_endprocessing(hComp); APIPRINTF((M_TEXT("MPV2: MAICompEnd() done: status=0x%X\n"), eStatus) ); return eStatus;}static MAIStatus_e MAICompSendCommand(MAICompHandle_t hComp, m_u32 uiCommand, m_u32 uiParam1, m_u32 uiParam2, m_u32 uiParam3, void *pUserInstance, MAITimeOut_t uiTimeOut){ MAIStatus_e eStatus = MAI_STATUS_OK; ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); switch (uiCommand) { case MAICOMP_CMD_PLAY: { MAISpeed_e NewSpeed=(MAISpeed_e)uiParam1; unsigned int uiNewPlayRate=NewSpeed&MAI_SPEED_RATEMASK; APIPRINTF((M_TEXT("MPV2: MAICompSendCommand(CMD_PLAY) speed=0x%X: DecodeMode=%d\n"),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -