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

📄 decoder.c

📁 基于Linux的ffmepg decoder
💻 C
📖 第 1 页 / 共 5 页
字号:
								refy);			}		}		refx = (x * PIXEL_U * 2 + uv_dx) / 2; 		// unit: 1 pixel		refy = (y * PIXEL_U * 2 + uv_dy) / 2;	 	// unit: 1 pixel		transfer8x8_copy_ben(dec,						mbpos * SIZE_U,						dec->cur.u_virt,						dec->refn.u_virt,						refx,						refy);		transfer8x8_copy_ben(dec,						mbpos * SIZE_U,						dec->cur.v_virt,						dec->refn.v_virt,						refx,						refy);		mbpos ++;		x ++;		if (x == dec->mb_width) {			x = 0;			y ++;		}	}}static __inline uint32_tFindRsmkOrVopS(Bitstream * const bs, volatile MP4_t * ptMP4){	uint32_t u32temp;	while (1) {		// MPEG4 search re-sync marker before decoding		u32temp = ptMP4->VLDCTL & ~0x000F;		ptMP4->VLDCTL = u32temp | mVLDCTL_CMD4b(2);		ptMP4->MCCTL |= MCCTL_DECGO;		mFa526DrainWrBuf();		while (((u32temp = ptMP4->VLDSTS) & BIT0) == 0)			;		if ((u32temp & 0xF000) == 0xE000) {			// timeout			for (; (ptMP4->VLDSTS & BIT10)==0; ) ;			/// wait for autobuffer clean			BitstreamUpdatePos_phy(bs,				(uint32_t *)(ptMP4->ASADR - 256 + (ptMP4->BITLEN & 0x3f) - 0xc),				ptMP4->VADR & 0x1f);//			BitstreamUpdatePos(bs,//				(uint32_t *)(ptMP4->ASADR - 256 + (ptMP4->BITLEN & 0x3f) - 0xc),//				ptMP4->VADR & 0x1f);			if ((BitstreamPos(bs) >> 3) >= bs->length) { // nothing found				u32temp = BIT2;				break;			}		} else			break;	}	return u32temp;}static __inline voiddma_chain_init_i(DECODER * dec){	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);	// for the 1st time dma trigger, use tgl_1 dma chain,	// fill these 2 register to avoid the dma register unknow	dma_cmd_tgl1[CHNI_STORE_PREDITOR] =	dma_cmd_tgl1[CHNI_LOAD_PREDITOR] =		mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy)		| mDmaSysInc3b(DMA_INCS_128);	// tgl 0	dma_cmd_tgl0[CHNI_IMG_U] =		mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy)		|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U	dma_cmd_tgl0[CHNI_IMG_V] =		mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy)		|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U	// tgl 1	dma_cmd_tgl1[CHNI_IMG_U] =		mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy+ 64)		|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U	dma_cmd_tgl1[CHNI_IMG_V] =		mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy+ 64)		|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U}static __inline voiddma_chain_init_p(DECODER * dec){	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);	// for the 1st time dma trigger, use tgl_1 dma chain,	// fill these 2 register to avoid the dma register unknow	dma_cmd_tgl1[CHNP_STORE_PREDITOR] =	dma_cmd_tgl1[CHNP_LOAD_PREDITOR] =		mDmaSysMemAddr29b((uint32_t)dec->pu16ACDC_ptr_phy)		| mDmaSysInc3b(DMA_INCS_128);	// tgl 0	dma_cmd_tgl0[CHNP_IMG_U] =		mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy + 64)		|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U	dma_cmd_tgl0[CHNP_IMG_V] =		mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy + 64)		|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U	// tgl 1	dma_cmd_tgl1[CHNP_IMG_U] =		mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy)		|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U	dma_cmd_tgl1[CHNP_IMG_V] =		mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy)		|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U}#define BIT_0ST		BIT0#define BIT_1ST		BIT1#define BIT_2ST		BIT2#define BIT_3ST		BIT3#define BIT_4ST		BIT4#define BIT_5ST		BIT5#define BIT_DMA_RGB_GO	BIT8#define BIT_PRE_DT			BIT9// Conf0: configure output as RGB or CbYCrY// Conf1: configure output as YUV420/*				<-  mb_vld	   -><- mb_dmc	    -><- mb_img       -><- mb_rgb    -><-00st stage	    -><-  1st stage      -><- 2nd stage	    -><-   3nd stage   -><- 4nd stage ->----------------------------cycle start -----------------------------------------------				(3)goMC_vld------(9)goMC_dmc-----(16)goMC_dt				(4)goDMA_LD-----(10)goDMA_ST-----(17)goDMA_img--(23)goDMA_ RGB(R-x)(Conf0)											|---(18)goDMA_yuv(Conf1)~~change to next mb~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~								(11)preMoveImg(1S-2S)								(12)preMoveYuv(1S-2S)(Conf1)												(19)preMoveRGB(3S-R)(D)(Conf0)												(19')(Conf1)(3S-x)				(5)wait VLD(0S-1S)(1)preVLD(x-0S)				(6)preStoreACDC(2)preLoadACDC				(7)waitDMA_LD----(13)waitDMA_ST---(20)waitDMA_img---(24)waitDMA_RGB(Conf0)											|---(21)waitDMA_yuv(Conf1)												(22)waitDT(D-x)(Conf0)								(14)prDT(2S)(x-D)(Conf0)								(15)wait DMC(2S-3S)				(8)preDMC(1S)----------------------------cycle end --------------------------------------------------*/#define I_FRAME_PIPE	4voiddecoder_iframe(DECODER * dec,			   Bitstream * bs,			   int quant){	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);	int32_t bound = 0;	int32_t i;	uint32_t u32temp;	uint32_t u32cmd_mc;	uint32_t u32pipe = 0;	uint32_t u32cmd_mc_reload;	uint32_t mb_cnt_in_vp = 0;			// MB count in video packet//	uint32_t * pu32table = &Table_Output[4];	uint32_t * pu32table = &((uint32_t *)((uint32_t) dec->pu32BaseAddr + TABLE_OUTPUT_OFF))[4];	uint32_t u32grpc;	MACROBLOCK *mb_vld;	MACROBLOCK *mb_dmc;	MACROBLOCK *mb_img;	MACROBLOCK *mb_rgb;	MACROBLOCK *mb_last;	MACROBLOCK_b mbb[I_FRAME_PIPE];	MACROBLOCK_b *mbb_vld = &mbb[I_FRAME_PIPE - 1];	MACROBLOCK_b *mbb_dmc=0;	MACROBLOCK_b *mbb_img=0;	MACROBLOCK_b *mbb_rgb=0;	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;	u32cmd_mc_reload = MCCTL_INTRA;	if (dec->quant_type == MPEG4_QUANT)		u32cmd_mc_reload = MCCTL_MP4Q | MCCTL_INTRA;	if (dec->h263 == 1)		u32cmd_mc_reload |= MCCTL_SVH;	u32cmd_mc = u32cmd_mc_reload;	dma_chain_init_i(dec);	ptDma->GRPS = 0;	// the last command in the chain never skipped.	u32grpc = (2 << (ID_CHN_1MV*2))			// 1mv dma: disable			|(2 << (ID_CHN_4MV*2))		// 4mv dma: disable			|(2 << (ID_CHN_IMG*2))		// IMG dma: disable		#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));		// St_ACDC dma: sync to VLD_done										// Ld_ACDC dma: sync to VLD_done	mb_vld = 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-------(9)goMC_dmc--(16)goMC_dt		if (u32cmd_mc & (MCCTL_DECGO | MCCTL_DMCGO | MCCTL_DTGO)) {			// swap 2 buffer			// setup Dezigzag-scan output address and dequant input address			// VLD output to DZQ[31..16]			DZQ[15..0] is input of DMC			if (i & BIT0)				ptMP4->QAR = ((QCOEFF_OFF_1 & 0xFFFF) << 16) | (QCOEFF_OFF_2 & 0xFFFF);			else				ptMP4->QAR = ((QCOEFF_OFF_2 & 0xFFFF) << 16) | (QCOEFF_OFF_1 & 0xFFFF);			ptMP4->MCCTL = u32cmd_mc;		}//(4)goDMA_LD-----(10)goDMA_ST-----(17)goDMA_img--(23)goDMA_ RGB(R-x)(Conf0)//							|-----(18)goDMA_yuv(Conf1)		{			u32pipe &=  ~BIT_DMA_RGB_GO;			ptDma->GRPC = u32grpc;			if (mbb_vld->toggle == 0)				ptDma->CCA = (DMA_CMD_OFF_0 + CHNI_IMG_Y * 4) | DMA_LC_LOC;			else				ptDma->CCA = (DMA_CMD_OFF_1 + CHNI_IMG_Y * 4) | DMA_LC_LOC;			// dont care SMaddr			// dont care LMaddr			// dont care BlkWidth			ptDma->Control =				mDmaIntChainMask1b(TRUE) |				mDmaEn1b(TRUE) |				mDmaChainEn1b(TRUE) |				mDmaDir1b(DONT_CARE) |				mDmaSType2b(DONT_CARE) |				mDmaLType2b(DONT_CARE) |				mDmaLen12b(0) |				mDmaID4b(0);		}		u32grpc = (2 << (ID_CHN_1MV*2))			// 1mv dma: disable				|(2 << (ID_CHN_4MV*2))		// 4mv dma: disable				|(2 << (ID_CHN_IMG*2))		// IMG dma: disable			#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));		// St_ACDC dma: sync to VLD_done											// Ld_ACDC dma: sync to VLD_done//~~change to next mb~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~		///////////////////////////////////////////////////////////////////////////		// update mb pointer		i ++;		mbb_rgb = mbb_img;		mbb_img = mbb_dmc;		mbb_dmc = mbb_vld;		mbb_vld = &mbb[i%I_FRAME_PIPE];		mbb_vld->toggle = i & BIT0;		mb_last = mb_rgb;		mb_rgb = mb_img;		mb_img = mb_dmc;		mb_dmc = mb_vld;//(11)preMoveImg(1S-2S)//(12)preMoveYuv(1S-2S)(Conf1) 		if (u32pipe & BIT_1ST) {			u32pipe &=  ~BIT_1ST;			u32pipe |=  BIT_2ST;			u32grpc &= ~(uint32_t)(3 << (ID_CHN_IMG * 2));		// exec IMG dma			// update address of destination			// dont forget to update the next one after the one mb-jumpping(dma ping-pong chain)			// mb_rgb is the next one after mb_img			if ((mb_img->mb_jump != 0) || (mb_rgb->mb_jump != 0)) {				if (mbb_vld->toggle == 0) {					// y					dma_cmd_tgl0[CHNI_IMG_Y] = 						mDmaSysMemAddr29b((uint32_t) dec->cur.y_phy + (uint32_t)mbb_img->x * 2 * SIZE_U +							(uint32_t)mbb_img->y * dec->mb_width * SIZE_Y)						|mDmaSysInc3b(DMA_INCS_256);		// 2 *  SIZE_U					// u					dma_cmd_tgl0[CHNI_IMG_U] =						mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy + (uint32_t)mbb_img->mbpos * SIZE_U)						|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U					// v					dma_cmd_tgl0[CHNI_IMG_V] =						mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy + (uint32_t)mbb_img->mbpos * SIZE_V)						|mDmaSysInc3b(DMA_INCS_128);		// SIZE_V				}				else {					// y					dma_cmd_tgl1[CHNI_IMG_Y] = 						mDmaSysMemAddr29b((uint32_t) dec->cur.y_phy + (uint32_t)mbb_img->x * 2 * SIZE_U +							(uint32_t)mbb_img->y * dec->mb_width * SIZE_Y)						|mDmaSysInc3b(DMA_INCS_256);		// 2 *  SIZE_U					// u					dma_cmd_tgl1[CHNI_IMG_U] =						mDmaSysMemAddr29b((uint32_t) dec->cur.u_phy + (uint32_t)mbb_img->mbpos * SIZE_U)						|mDmaSysInc3b(DMA_INCS_128);		// SIZE_U					// v					dma_cmd_tgl1[CHNI_IMG_V] =						mDmaSysMemAddr29b((uint32_t) dec->cur.v_phy + (uint32_t)mbb_img->mbpos * SIZE_V)						|mDmaSysInc3b(DMA_INCS_128);		// SIZE_V				}			}			else if ((mbb_img->x == 0) || (mbb_img->x == 1)) {				u32temp = mDmaSysMemAddr29b((uint32_t) dec->cur.y_phy	+							(uint32_t) mbb_img->mbpos * SIZE_Y -							(uint32_t) mbb_img->x * 2 * SIZE_U)						|mDmaSysInc3b(DMA_INCS_256);		// 2 *  SIZE_U				if (mbb_vld->toggle == 0)					dma_cmd_tgl0[CHNI_IMG_Y] = u32temp;				else					dma_cmd_tgl1[CHNI_IMG_Y] = u32temp;			}		#if (OUTPUT_FMT == OUTPUT_FMT_YUV)			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)) {				u32grpc &= ~(uint32_t)(3 << (ID_CHN_YUV * 2));		// exec YUV dma				if (((mb_img->mb_jump != 0) || (mb_rgb->mb_jump != 0)) ||				(mbb_img->x == u32output_mb_start) || (mbb_img->x == (u32output_mb_start + 1))) {					if (mbb_vld->toggle == 0) {						// y output						dma_cmd_tgl0[CHNI_YUV_Y] = 							mDmaSysMemAddr29b((uint32_t) dec->output_base_phy +								((mbb_img->x - u32output_mb_start)  +								(mbb_img->y - u32output_mb_ystart) * dec->output_stride) * PIXEL_Y)							|mDmaSysInc3b(DMA_INCS_32);		// 2 * PIXEL_Y						// u output						dma_cmd_tgl0[CHNI_YUV_U] =							mDmaSysMemAddr29b((uint32_t) dec->output_base_u_phy +								((mbb_img->x - u32output_mb_start)+								(mbb_img->y - u32output_mb_ystart)  * dec->output_stride /2) * PIXEL_U)							|mDmaSysInc3b(DMA_INCS_16);		// 2 * PIXEL_U						// v output						dma_cmd_tgl0[CHNI_YUV_V] =							mDmaSysMemAddr29b((uint32_t) dec->output_base_v_phy +								((mbb_img->x - u32output_mb_start) +								(mbb_img->y - u32output_mb_ystart) * dec->output_stride /2) * PIXEL_V)							|mDmaSysInc3b(DMA_INCS_16);		// 2 * PIXEL_V					}					else {						// y output						dma_cmd_tgl1[CHNI_YUV_Y] = 							mDmaSysMemAddr29b((uint32_t) dec->output_base_phy +								((mbb_img->x - u32output_mb_start)+								(mbb_img->y - u32output_mb_ystart) * dec->output_stride) * PIXEL_Y)							|mDmaSysInc3b(DMA_INCS_32);		// 2 *  PIXEL_Y						// u output						dma_cmd_tgl1[CHNI_YUV_U] =							mDmaSysMemAddr29b((uint32_t) dec->output_base_u_phy +								((mbb_img->x - u32output_mb_start)+								(mbb_img->y - u32output_mb_ystart) * dec->output_stride /2) * PIXEL_U )							|mDmaSysInc3b(DMA_INCS_16);		// 2 * PIXEL_U						// v output						dma_cmd_tgl1[CHNI_YUV_V] =							mDmaSysMemAddr29b((uint32_t) dec->output_base_v_phy +								((mbb_img->x - u32output_mb_start)+

⌨️ 快捷键说明

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