⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decoder.c

📁 基于Linux的ffmepg decoder
💻 C
📖 第 1 页 / 共 5 页
字号:
								(mbb_img->y - u32output_mb_ystart) * dec->output_stride /2) * PIXEL_V)							|mDmaSysInc3b(DMA_INCS_16);		// 2 * PIXEL_V					}				}			}		#endif		}//(19)preMoveRGB(3S-R)(D)(Conf0)//(19')(Conf1)(3S-x) 		if (u32pipe & BIT_3ST) { 			u32pipe &= ~BIT_3ST;		#if (OUTPUT_FMT < OUTPUT_FMT_YUV)			u32pipe |=  BIT_DMA_RGB_GO;			// update address of destination			// dont forget the next one after the one mb-jumpping			// mb_last is the next one after mb_rgb			if ((mb_rgb->mb_jump != 0) || (mb_last->mb_jump != 0) ||				(mbb_rgb->x == u32output_mb_start) || (mbb_rgb->x == (u32output_mb_start + 1))) {				if ((mbb_rgb->x >= u32output_mb_start)					&& (mbb_rgb->x < u32output_mb_end)					&& (mbb_rgb->y >= u32output_mb_ystart)					&& (mbb_rgb->y < u32output_mb_yend)) {					if (mbb_vld->toggle == 0)						dma_cmd_tgl0[CHNI_RGB] =							mDmaSysMemAddr29b((uint32_t) dec->output_base_phy +								(mbb_rgb->x - u32output_mb_start) * PIXEL_Y * RGB_PIXEL_SIZE +								(mbb_rgb->y - u32output_mb_ystart) * dec->output_stride * PIXEL_Y * RGB_PIXEL_SIZE)							| mDmaSysInc3b(RGB_DMA_INC);		//PIXEL_Y * 2;					else						dma_cmd_tgl1[CHNI_RGB] =							mDmaSysMemAddr29b((uint32_t) dec->output_base_phy +								(mbb_rgb->x - u32output_mb_start) * PIXEL_Y * RGB_PIXEL_SIZE +								(mbb_rgb->y - u32output_mb_ystart) * dec->output_stride * PIXEL_Y * RGB_PIXEL_SIZE)							| mDmaSysInc3b(RGB_DMA_INC);		//PIXEL_Y * 2;				}			}			u32grpc &= ~(uint32_t)(3 << (ID_CHN_RGB * 2));		// exec RGB dma	 		if ((u32pipe & BIT_PRE_DT) == 0)				u32grpc |= 1 << (ID_CHN_RGB*2);				// RGB dma: skip but inscr.		#endif 		}//(6)wait VLD(0S-1S)		if (u32pipe & BIT_0ST) {			u32pipe &= ~ BIT_0ST;			u32pipe |=  BIT_1ST;			vpe_prob_vld_start();			mFa526DrainWrBuf();			while (((u32temp = ptMP4->VLDSTS) & BIT0) == 0)				;			vpe_prob_vld_end();			// check error code			if (u32temp  & 0xF000) {				mVpe_Indicator(0x92000000 | (u32temp  & 0xF000));				mVpe_FAIL();			 	//waitDMC & waitDT				while ((ptMP4->CPSTS & (BIT14 | BIT1)) != (BIT14 | BIT1))					;				u32temp = FindRsmkOrVopS(bs, ptMP4);				break;			}			// Resync marker detected			if (u32temp & BIT1) {				if (bRead_video_packet_header(dec, NULL, NULL, &bound) == -1) {					mVpe_FAIL();					break;				}				if (bound != mbb_dmc->mbpos) {					// correct 'dmc'ed(img) jump to correct next-'dmc'ed(dmc)					mb_img->mb_jump = bound - mbb_dmc->mbpos;					// correct 'vld'ed(dmc) information					mb_dmc = &dec->mbs[bound];					mb_dmc->mb_jump = 0;					mbb_dmc->x = bound % dec->mb_width;					mbb_dmc->y = (int32_t)(bound / dec->mb_width);					mbb_dmc->mbpos = bound;					// correct store acdc pointer					// dont care about 'load preditor', it will not be used until next line is reached					if (mbb_vld->toggle == 0) {						dma_cmd_tgl0[CHNI_STORE_PREDITOR] =							mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64 * mbb_vld->x)							| mDmaSysInc3b(DMA_INCS_128);						dma_cmd_tgl1[CHNI_STORE_PREDITOR] =							mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64 * (mbb_vld->x + 1))							| mDmaSysInc3b(DMA_INCS_128);					} else {						dma_cmd_tgl1[CHNI_STORE_PREDITOR] =							mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64 * mbb_vld->x)							| mDmaSysInc3b(DMA_INCS_128);						dma_cmd_tgl0[CHNI_STORE_PREDITOR] =							mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64 * (mbb_vld->x + 1))							| mDmaSysInc3b(DMA_INCS_128);					}				}				mb_cnt_in_vp = (u32temp >> 16) - 1;				//pu32table = &Table_Output[4];				pu32table = &((uint32_t *)((uint32_t) dec->pu32BaseAddr + TABLE_OUTPUT_OFF))[4];			}			mbb_dmc->cbp = (*pu32table >> 23) & 0x3F;			mbb_dmc->quant = (ptMP4->VOP0 >> 8) & 0xFF;			if (dec->data_partitioned)				pu32table += 4;		}		mbb_vld->mbpos = mbb_dmc->mbpos + 1;		mbb_vld->x = mbb_dmc->x + 1;		mbb_vld->y = mbb_dmc->y;		if (mbb_vld->x == dec->mb_width) {			mbb_vld->x = 0;			mbb_vld->y ++;		}		// indicator		mVpe_Indicator(0x91000000 | (mbb_vld->y << 12) | mbb_vld->x);//(1)preVLD(x-0S)		if (mbb_vld->y < dec->mb_height) {			u32pipe |= BIT_0ST;			// init mb_vld			mb_vld = &dec->mbs[mbb_vld->mbpos];			mb_vld->mb_jump = 0;			// get acdcPredict command parameter			u32cmd_mc = predict_acdc_I(mbb_vld, (int32_t)dec->mb_width, bound);			u32cmd_mc |= u32cmd_mc_reload;		}		else			u32cmd_mc = u32cmd_mc_reload;//(7)preStoreACDC//(2)preLoadACDC		if ((mb_img->mb_jump != 0) || (mb_dmc->mb_jump != 0) ||(mbb_vld->x == 0)) {			if (mbb_vld->toggle == 0) {				dma_cmd_tgl0[CHNI_STORE_PREDITOR] =					mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy)					| mDmaSysInc3b(DMA_INCS_128);				dma_cmd_tgl0[CHNI_LOAD_PREDITOR] =					mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64)					| mDmaSysInc3b(DMA_INCS_128);			}else {				dma_cmd_tgl1[CHNI_STORE_PREDITOR] =					mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy)					| mDmaSysInc3b(DMA_INCS_128);				dma_cmd_tgl1[CHNI_LOAD_PREDITOR] =					mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64)					| mDmaSysInc3b(DMA_INCS_128);			}		}		else if (mbb_vld->x == 1) {			if (mbb_vld->toggle == 0)				dma_cmd_tgl0[CHNI_STORE_PREDITOR] =					mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64)					| mDmaSysInc3b(DMA_INCS_128);			else				dma_cmd_tgl1[CHNI_STORE_PREDITOR] =					mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy + 64)					| mDmaSysInc3b(DMA_INCS_128);		}		if (mbb_vld->x == (dec->mb_width - 1)) {			if (mbb_vld->toggle == 0)				dma_cmd_tgl0[CHNI_LOAD_PREDITOR] =					mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy)					| mDmaSysInc3b(DMA_INCS_128);			else				dma_cmd_tgl1[CHNI_LOAD_PREDITOR] =					mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy)					| mDmaSysInc3b(DMA_INCS_128);		}//(7)waitDMA_load--(13)waitDMA_store----------------(20)waitDMA_img-(24)waitDMA_RGB(Conf0)//										|-------(21)waitDMA_yuv(Conf1)		vpe_prob_dma_start();		mFa526DrainWrBuf();		while((ptDma->Status & BIT0) == 0)			;		vpe_prob_dma_end();//(22)waitDT(D-x)(Conf0)	#if (OUTPUT_FMT < OUTPUT_FMT_YUV) 		if (u32pipe & BIT_PRE_DT) {			u32pipe &=  ~BIT_PRE_DT;			vpe_prob_dt_start();			mFa526DrainWrBuf();			while((ptMP4->CPSTS & BIT14) == 0)				;			vpe_prob_dt_end();		}//(14)prDT(2S-D)(Conf0) 		if (u32pipe & BIT_2ST) {			if ((mbb_img->x >= u32output_mb_start)				&& (mbb_img->x < u32output_mb_end)				&& (mbb_img->y >= u32output_mb_ystart)				&& (mbb_img->y < u32output_mb_yend)) {				u32pipe |= BIT_PRE_DT;				if (mbb_img->toggle) {					ptMP4->MECADDR = INTER_Y_OFF_1;		// YUV2RGB source addr, [10: 7] valid					ptMP4->MCCADDR = BUFFER_RGB_OFF_1;// YUV2RGB dest. addr, [10: 7] valid				} else {					ptMP4->MECADDR = INTER_Y_OFF_0;		// YUV2RGB source addr, [10: 7] valid					ptMP4->MCCADDR = BUFFER_RGB_OFF_0;// YUV2RGB dest. addr, [10: 7] valid				}				u32cmd_mc |= MCCTL_DTGO;			} 		}	#endif//(15) wait DMC(2S-3S)		if (u32pipe & BIT_2ST) {			u32pipe &= ~BIT_2ST;			u32pipe |= BIT_3ST;			vpe_prob_dmc_start();			mFa526DrainWrBuf();			while ((ptMP4->CPSTS & BIT1) == 0)				;			vpe_prob_dmc_end();		}//(8)preDMC(1S)		if (u32pipe & BIT_1ST) {			if (mbb_dmc->toggle)				// dmc_input(& output) direct to INTER_Y_OFF_1				ptMP4->MCIADDR = INTER_Y_OFF_1;			else				// dmc_input(& output) direct to INTER_Y_OFF_0				ptMP4->MCIADDR = INTER_Y_OFF_0;			u32cmd_mc |= MCCTL_DMCGO;			// fill CBP in this stage			ptMP4->QCR0 = (mbb_dmc->quant << 18) | mbb_dmc->cbp;		}		if (u32pipe == 0)			break;	}	for (; (ptMP4->VLDSTS & BIT10)==0; ) ;			/// wait for autobuffer clean	// stop auto-buffering	ptMP4->VLDCTL = VLDCTL_ABFSTOP;}//R: BIT_DMA_RGB_GO/*			<-  mb_vld	-><- mb_ref      -><- mb_dmc  -><- mb_img     -><- mb_rgb    -><-    0st     -><-  1st stage	-><- 2nd stage  -><- 3nd stage -><- 4nd stage  -><- 5nd stage ->----------------------------cycle start --------------------------------------------------			(3)goMC_vld-----------------(15)goMC_dmc--(23)goMC_dt			(4)goDMA_LD_ST-(12)goDMA_ref---------------(24)goDMA_img-(30)goDMA_rgb(R-x)(Conf0)												|----(25)goDMA_yuv(Conf1)									     (16)prePXI(3S)			(5)goME_pmv----------------(17)goME_pxi************************************************************************** change to next mb *									      (18)preMoveImg(3S)									      (19)preMoveYuv(3S)(Conf1)													  (26)preMoveRGB(4S-R)(D)(Conf0)													  (26')Conf1(4S-x)			(6)waitME_PMV(0S)			(7)storeMV(0S)			(8)preMoveRef(0S-1S)(1)preVLD(x-0S)			(9)preStoreACDC(2)preLoadACDC										(20)waitDMC(3S-4S)							(13)preDMC(2S-3S) 													  (27)waitDT(D-x)(Conf0) 										(21)preDT(4S)(x-D)(Conf0)			(10)waitVLD(1S-2S)										(22)waitME_pxi(4S)			(11)waitDMA_LD_ST-(14)waitDMA_ref------------(28)waitDMA_img--(31)waitDMA_rgb(Conf0)												|-----(29)waitDMA_yuv(Conf1)----------------------------cycle end --------------------------------------------------*/#define P_FRAME_PIPE	5voiddecoder_pframe(DECODER * dec,			   Bitstream * bs,			   int rounding,			   int quant,			   int fcode){	volatile MP4_t * ptMP4 = (MP4_t *)((uint32_t)dec->pu32BaseAddr + MP4_OFF);	volatile MDMA * ptDma = (MDMA *)((uint32_t)dec->pu32BaseAddr + DMA_OFF);	uint32_t * dma_cmd_tgl0 = (uint32_t *)((uint32_t)dec->pu32BaseAddr + DMA_CMD_OFF_0);	uint32_t * dma_cmd_tgl1 = (uint32_t *)((uint32_t)dec->pu32BaseAddr + DMA_CMD_OFF_1);	uint32_t u32temp;	uint32_t u32pipe = 0;	uint32_t u32cmd_mc = 0;	uint32_t u32cmd_mc_reload = 0;	uint32_t u32cmd_me = 0;	uint32_t mb_cnt_in_vp = 0;			// MB count in video packet	uint32_t mbpos_in_vp = 0;			// MB pos in video packet//	uint32_t * pu32table = &Table_Output[4];// table pointer in video packet	uint32_t * pu32table = &((uint32_t *)((uint32_t) dec->pu32BaseAddr + TABLE_OUTPUT_OFF))[4];	int32_t i;	int32_t bound = 0;	uint32_t u32ErrorCount = 0;	uint32_t u32grpc;	MACROBLOCK_b mbb[P_FRAME_PIPE];	MACROBLOCK_b *mbb_vld = &mbb[P_FRAME_PIPE - 1];	MACROBLOCK_b *mbb_ref=0;	MACROBLOCK_b *mbb_dmc=0;	MACROBLOCK_b *mbb_img=0;	MACROBLOCK_b *mbb_rgb=0;	MACROBLOCK *mb_vld;	MACROBLOCK *mb_ref;	MACROBLOCK *mb_dmc;	MACROBLOCK *mb_img;	MACROBLOCK *mb_rgb;	MACROBLOCK *mb_last;	uint32_t u32output_mb_end=0;	uint32_t u32output_mb_start = 0;	uint32_t u32output_mb_yend=0;	uint32_t u32output_mb_ystart = 0;	if (dec->output_base_phy == NULL)			// goDT & moveRGB never start		u32output_mb_start = 0xFFFFFFFF;	else {		// width		if (dec->width >= dec->output_stride) {			u32temp = dec->mb_width - (dec->output_stride / PIXEL_Y);	// width diff between screan and VOP			u32output_mb_start = u32temp / 2;			u32output_mb_end = (dec->output_stride / PIXEL_Y) + u32output_mb_start;		} else			u32output_mb_end = dec->width / PIXEL_Y;		// height		if (dec->height >= dec->output_height) {			u32temp = dec->mb_height - (dec->height / PIXEL_Y);			// height diff between screan and VOP			u32output_mb_ystart = u32temp / 2;			u32output_mb_yend = (dec->height / PIXEL_Y) + u32output_mb_ystart;		} else			u32output_mb_yend = dec->height / PIXEL_Y;	}	///////////////////////////////////////////////////////////////////////////	// Enable auto-buffering	ptMP4->VLDCTL = VLDCTL_ABFSTART;	// reset PMV counter	ptMP4->MECTL = MECTL_VOPSTART;	// init mc & me command	if (dec->quant_type == MPEG4_QUANT)		u32cmd_mc_reload = MCCTL_MP4Q;	if (dec->h263 == 1)		u32cmd_mc_reload |= MCCTL_SVH;	dma_chain_init_p(dec);	ptDma->GRPS = 0;	// the last command in the chain never skipped.	u32grpc = (2 << (ID_CHN_1MV*2))			// disable 1mv			|(2 << (ID_CHN_4MV*2))		// disable 4mv			|(2 << (ID_CHN_IMG*2))		// disable IMG		#if (OUTPUT_FMT == OUTPUT_FMT_YUV)			|(2 << (ID_CHN_YUV*2))		// YUV dma: disable.		#else			|(2 << (ID_CHN_RGB*2))		// RGB dma: disable.		#endif			|(3 << (ID_CHN_ACDC*2));		// LdSt_ACDC sync to VLD_done										// load & store non-meaning	mb_vld = mb_ref = mb_dmc = mb_img = mb_rgb = mb_last = &dec->mbs[0];	mb_vld->mb_jump = 0;	mbb_vld->mbpos = -1;	mbb_vld->x = -1;	mbb_vld->y = 0;	mbb_vld->toggle = 1;	i = -1;	while (1)	{//(3)goMC_vld-----------------(15)goMC_dmc--(23)goMC_dt		if (u32cmd_mc & (MCCTL_DECGO | MCCTL_DMCGO | MCCTL_DTGO))			ptMP4->MCCTL = u32cmd_mc;//(4)goDMA_LD_ST-(12)goDMA_ref---------------(24)goDMA_img-(30)goDMA_rgb(Conf0)//										|--(25)goDMA_yuv(Conf1)		{			u32pipe &=  ~BIT_DMA_RGB_GO;			ptDma->GRPC = u32grpc;			if (mb_ref->mode == MODE_INTER4V) {				if (mbb_vld->toggle == 0)					ptDma->CCA = (DMA_CMD_OFF_0 + CHNP_REF_4MV_Y0 * 4) | DMA_LC_LOC;				else					ptDma->CCA = (DMA_CMD_OFF_1 + CHNP_REF_4MV_Y0 * 4) | DMA_LC_LOC;			} else {				if (mbb_vld->toggle == 0)					ptDma->CCA = (DMA_CMD_OFF_0 + CHNP_REF_1MV_Y * 4) | DMA_LC_LOC;				else					ptDma->CCA = (DMA_CMD_OFF_1 + CHNP_REF_1MV_Y * 4) | DMA_LC_LOC;			}			// dont care SMaddr

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -