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

📄 decoder.c

📁 TMS320C6713Xvid视频压缩算法源代码.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (cbp & (1 << (5 - i))) {	/* coded */			memset(block, 0, 64 * sizeof(int16_t));	/* clear */			start_timer();			get_inter_block(bs, block, direction);			stop_coding_timer();			start_timer();			dequant(&data[i * 64], block, iQuant, dec->mpeg_quant_matrices);			stop_iquant_timer();			start_timer();			idct(&data[i * 64]);			stop_idct_timer();		}	}	if (dec->interlacing && pMB->field_dct) {		next_block = stride;		stride *= 2;	}	start_timer();	if (reduced_resolution) {		if (cbp & 32)			add_upsampled_8x8_16to8(pY_Cur, &data[0 * 64], stride);		if (cbp & 16)			add_upsampled_8x8_16to8(pY_Cur + 16, &data[1 * 64], stride);		if (cbp & 8)			add_upsampled_8x8_16to8(pY_Cur + next_block, &data[2 * 64], stride);		if (cbp & 4)			add_upsampled_8x8_16to8(pY_Cur + 16 + next_block, &data[3 * 64], stride);		if (cbp & 2)			add_upsampled_8x8_16to8(pU_Cur, &data[4 * 64], stride2);		if (cbp & 1)			add_upsampled_8x8_16to8(pV_Cur, &data[5 * 64], stride2);	} else {		if (cbp & 32)			transfer_16to8add(pY_Cur, &data[0 * 64], stride);		if (cbp & 16)			transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);		if (cbp & 8)			transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);		if (cbp & 4)			transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);		if (cbp & 2)			transfer_16to8add(pU_Cur, &data[4 * 64], stride2);		if (cbp & 1)			transfer_16to8add(pV_Cur, &data[5 * 64], stride2);	}	stop_transfer_timer();}static void __inlinevalidate_vector(VECTOR * mv, unsigned int x_pos, unsigned int y_pos, const DECODER * dec){	/* clip a vector to valid range 	   prevents crashes if bitstream is broken 	*/	int shift = 5 + dec->quarterpel;	int xborder_high = (int)(dec->mb_width - x_pos) << shift;	int xborder_low = (-(int)x_pos-1) << shift;	int yborder_high = (int)(dec->mb_height - y_pos) << shift;	int yborder_low = (-(int)y_pos-1) << shift;#define CHECK_MV(mv) \	do { \	if ((mv).x > xborder_high) { \		DPRINTF(XVID_DEBUG_MV, "mv.x > max -- %d > %d, MB %d, %d", (mv).x, xborder_high, x_pos, y_pos); \		(mv).x = xborder_high; \	} else if ((mv).x < xborder_low) { \		DPRINTF(XVID_DEBUG_MV, "mv.x < min -- %d < %d, MB %d, %d", (mv).x, xborder_low, x_pos, y_pos); \		(mv).x = xborder_low; \	} \	if ((mv).y > yborder_high) { \		DPRINTF(XVID_DEBUG_MV, "mv.y > max -- %d > %d, MB %d, %d", (mv).y, yborder_high, x_pos, y_pos); \		(mv).y = yborder_high; \	} else if ((mv).y < yborder_low) { \		DPRINTF(XVID_DEBUG_MV, "mv.y < min -- %d < %d, MB %d, %d", (mv).y, yborder_low, x_pos, y_pos); \		(mv).y = yborder_low; \	} \	} while (0)	CHECK_MV(mv[0]);	CHECK_MV(mv[1]);	CHECK_MV(mv[2]);	CHECK_MV(mv[3]);}/* decode an inter macroblock */static voiddecoder_mbinter(DECODER * dec,				const MACROBLOCK * pMB,				const uint32_t x_pos,				const uint32_t y_pos,				const uint32_t cbp,				Bitstream * bs,				const uint32_t rounding,				const int reduced_resolution,				const int ref){	uint32_t stride = dec->edged_width;	uint32_t stride2 = stride / 2;	uint32_t i;	uint8_t *pY_Cur, *pU_Cur, *pV_Cur;	int uv_dx, uv_dy;	VECTOR mv[4];	/* local copy of mvs */	if (reduced_resolution) {		pY_Cur = dec->cur.y + (y_pos << 5) * stride + (x_pos << 5);		pU_Cur = dec->cur.u + (y_pos << 4) * stride2 + (x_pos << 4);		pV_Cur = dec->cur.v + (y_pos << 4) * stride2 + (x_pos << 4);		for (i = 0; i < 4; i++)	{			mv[i].x = RRV_MV_SCALEUP(pMB->mvs[i].x);			mv[i].y = RRV_MV_SCALEUP(pMB->mvs[i].y);		}	} else {		pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);		pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);		pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);		for (i = 0; i < 4; i++)			mv[i] = pMB->mvs[i];	}	validate_vector(mv, x_pos, y_pos, dec);	start_timer();	if (pMB->mode != MODE_INTER4V) { /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */		uv_dx = mv[0].x;		uv_dy = mv[0].y;		if (dec->quarterpel) {			uv_dx /= 2;			uv_dy /= 2;		}		uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];		uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];		if (reduced_resolution)			interpolate32x32_switch(dec->cur.y, dec->refn[0].y, 32*x_pos, 32*y_pos,									mv[0].x, mv[0].y, stride, rounding);		else if (dec->quarterpel)			interpolate16x16_quarterpel(dec->cur.y, dec->refn[ref].y, dec->qtmp.y, dec->qtmp.y + 64,	 								dec->qtmp.y + 128, 16*x_pos, 16*y_pos,											mv[0].x, mv[0].y, stride, rounding);		else			interpolate16x16_switch(dec->cur.y, dec->refn[ref].y, 16*x_pos, 16*y_pos,									mv[0].x, mv[0].y, stride, rounding);	} else {	/* MODE_INTER4V */		if(dec->quarterpel) {			uv_dx = (mv[0].x / 2) + (mv[1].x / 2) + (mv[2].x / 2) + (mv[3].x / 2);			uv_dy = (mv[0].y / 2) + (mv[1].y / 2) + (mv[2].y / 2) + (mv[3].y / 2);		} else {			uv_dx = mv[0].x + mv[1].x + mv[2].x + mv[3].x;			uv_dy = mv[0].y + mv[1].y + mv[2].y + mv[3].y;		}		uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];		uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf];		if (reduced_resolution) {			interpolate16x16_switch(dec->cur.y, dec->refn[0].y, 32*x_pos, 32*y_pos,								mv[0].x, mv[0].y, stride, rounding);			interpolate16x16_switch(dec->cur.y, dec->refn[0].y , 32*x_pos + 16, 32*y_pos,								mv[1].x, mv[1].y, stride, rounding);			interpolate16x16_switch(dec->cur.y, dec->refn[0].y , 32*x_pos, 32*y_pos + 16,								mv[2].x, mv[2].y, stride, rounding);			interpolate16x16_switch(dec->cur.y, dec->refn[0].y , 32*x_pos + 16, 32*y_pos + 16,								mv[3].x, mv[3].y, stride, rounding);			interpolate16x16_switch(dec->cur.u, dec->refn[0].u , 16 * x_pos, 16 * y_pos,								uv_dx, uv_dy, stride2, rounding);			interpolate16x16_switch(dec->cur.v, dec->refn[0].v , 16 * x_pos, 16 * y_pos,								uv_dx, uv_dy, stride2, rounding);		} else if (dec->quarterpel) {			interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,									dec->qtmp.y + 128, 16*x_pos, 16*y_pos,									mv[0].x, mv[0].y, stride, rounding);			interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,									dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,									mv[1].x, mv[1].y, stride, rounding);			interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,									dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,									mv[2].x, mv[2].y, stride, rounding);			interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,									dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,									mv[3].x, mv[3].y, stride, rounding);		} else {			interpolate8x8_switch(dec->cur.y, dec->refn[0].y , 16*x_pos, 16*y_pos,								mv[0].x, mv[0].y, stride, rounding);			interpolate8x8_switch(dec->cur.y, dec->refn[0].y , 16*x_pos + 8, 16*y_pos,								mv[1].x, mv[1].y, stride, rounding);			interpolate8x8_switch(dec->cur.y, dec->refn[0].y , 16*x_pos, 16*y_pos + 8,								mv[2].x, mv[2].y, stride, rounding);			interpolate8x8_switch(dec->cur.y, dec->refn[0].y , 16*x_pos + 8, 16*y_pos + 8,								mv[3].x, mv[3].y, stride, rounding);		}	}	/* chroma */	if (reduced_resolution) {		interpolate16x16_switch(dec->cur.u, dec->refn[0].u, 16 * x_pos, 16 * y_pos,								uv_dx, uv_dy, stride2, rounding);		interpolate16x16_switch(dec->cur.v, dec->refn[0].v, 16 * x_pos, 16 * y_pos,								uv_dx, uv_dy, stride2, rounding);	} else {		interpolate8x8_switch(dec->cur.u, dec->refn[ref].u, 8 * x_pos, 8 * y_pos,								uv_dx, uv_dy, stride2, rounding);		interpolate8x8_switch(dec->cur.v, dec->refn[ref].v, 8 * x_pos, 8 * y_pos,								uv_dx, uv_dy, stride2, rounding);	}	stop_comp_timer();	if (cbp)		decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur,							reduced_resolution, pMB);}static voiddecoder_mbgmc(DECODER * dec,				MACROBLOCK * const pMB,				const uint32_t x_pos,				const uint32_t y_pos,				const uint32_t fcode,				const uint32_t cbp,				Bitstream * bs,				const uint32_t rounding){	const uint32_t stride = dec->edged_width;	const uint32_t stride2 = stride / 2;	uint8_t *const pY_Cur=dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);	uint8_t *const pU_Cur=dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);	uint8_t *const pV_Cur=dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);	NEW_GMC_DATA * gmc_data = &dec->new_gmc_data;	pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;	start_timer();/* this is where the calculations are done */	gmc_data->predict_16x16(gmc_data,			dec->cur.y + y_pos*16*stride + x_pos*16, dec->refn[0].y,			stride, stride, x_pos, y_pos, rounding);	gmc_data->predict_8x8(gmc_data,			dec->cur.u + y_pos*8*stride2 + x_pos*8, dec->refn[0].u,			dec->cur.v + y_pos*8*stride2 + x_pos*8, dec->refn[0].v,			stride2, stride2, x_pos, y_pos, rounding);	gmc_data->get_average_mv(gmc_data, &pMB->amv, x_pos, y_pos, dec->quarterpel);	pMB->amv.x = gmc_sanitize(pMB->amv.x, dec->quarterpel, fcode);	pMB->amv.y = gmc_sanitize(pMB->amv.y, dec->quarterpel, fcode);	pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;	stop_transfer_timer();	if (cbp)		decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, 0, pMB);}static voiddecoder_iframe(DECODER * dec,				Bitstream * bs,				int reduced_resolution,				int quant,				int intra_dc_threshold){	uint32_t bound;	uint32_t x, y;	uint32_t mb_width = dec->mb_width;	uint32_t mb_height = dec->mb_height;	if (reduced_resolution) {		mb_width = (dec->width + 31) / 32;		mb_height = (dec->height + 31) / 32;	}	bound = 0;	for (y = 0; y < mb_height; y++) {		for (x = 0; x < mb_width; x++) {			MACROBLOCK *mb;			uint32_t mcbpc;			uint32_t cbpc;			uint32_t acpred_flag;			uint32_t cbpy;			uint32_t cbp;			while (BitstreamShowBits(bs, 9) == 1)				BitstreamSkip(bs, 9);			if (check_resync_marker(bs, 0))			{				bound = read_video_packet_header(bs, dec, 0,							&quant, NULL, NULL, &intra_dc_threshold);				x = bound % mb_width;				y = bound / mb_width;			}			mb = &dec->mbs[y * dec->mb_width + x];			DPRINTF(XVID_DEBUG_MB, "macroblock (%i,%i) %08x\n", x, y, BitstreamShowBits(bs, 32));			mcbpc = get_mcbpc_intra(bs);			mb->mode = mcbpc & 7;			cbpc = (mcbpc >> 4);			acpred_flag = BitstreamGetBit(bs);			cbpy = get_cbpy(bs, 1);			cbp = (cbpy << 2) | cbpc;			if (mb->mode == MODE_INTRA_Q) {				quant += dquant_table[BitstreamGetBits(bs, 2)];				if (quant > 31) {					quant = 31;				} else if (quant < 1) {					quant = 1;				}			}			mb->quant = quant;			mb->mvs[0].x = mb->mvs[0].y =			mb->mvs[1].x = mb->mvs[1].y =			mb->mvs[2].x = mb->mvs[2].y =			mb->mvs[3].x = mb->mvs[3].y =0;			if (dec->interlacing) {				mb->field_dct = BitstreamGetBit(bs);				DPRINTF(XVID_DEBUG_MB,"deci: field_dct: %i\n", mb->field_dct);			}			decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,							intra_dc_threshold, bound, reduced_resolution);		}		if(dec->out_frm)			output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,0,y,mb_width);	}}static voidget_motion_vector(DECODER * dec,				Bitstream * bs,				int x,				int y,				int k,				VECTOR * ret_mv,				int fcode,				const int bound){	const int scale_fac = 1 << (fcode - 1);	const int high = (32 * scale_fac) - 1;	const int low = ((-32) * scale_fac);	const int range = (64 * scale_fac);	const VECTOR pmv = get_pmv2(dec->mbs, dec->mb_width, bound, x, y, k);	VECTOR mv;	mv.x = get_mv(bs, fcode);	mv.y = get_mv(bs, fcode);	DPRINTF(XVID_DEBUG_MV,"mv_diff (%i,%i) pred (%i,%i) result (%i,%i)\n", mv.x, mv.y, pmv.x, pmv.y, mv.x+pmv.x, mv.y+pmv.y);	mv.x += pmv.x;	mv.y += pmv.y;	if (mv.x < low) {		mv.x += range;	} else if (mv.x > high) {		mv.x -= range;	}	if (mv.y < low) {		mv.y += range;	} else if (mv.y > high) {		mv.y -= range;	}	ret_mv->x = mv.x;	ret_mv->y = mv.y;}/* for P_VOP set gmc_warp to NULL */static voiddecoder_pframe(DECODER * dec,				Bitstream * bs,				int rounding,				int reduced_resolution,				int quant,				int fcode,				int intra_dc_threshold,				const WARPPOINTS *const gmc_warp)

⌨️ 快捷键说明

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