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

📄 decoder.c

📁 mpeg4视频解码源码.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
		uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];		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 (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 */	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, 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, pMB);}static voiddecoder_iframe(DECODER * dec,				Bitstream * bs,				int quant,				int intra_dc_threshold){	uint32_t bound;	uint32_t x, y;	const uint32_t mb_width = dec->mb_width;	const uint32_t mb_height = dec->mb_height;	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);		}		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 quant,				int fcode,				int intra_dc_threshold,				const WARPPOINTS *const gmc_warp){	uint32_t x, y;	uint32_t bound;	int cp_mb, st_mb;	const uint32_t mb_width = dec->mb_width;	const uint32_t mb_height = dec->mb_height;	if (!dec->is_edged[0]) {		start_timer();		image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,						dec->width, dec->height, dec->bs_version);		dec->is_edged[0] = 1;		stop_edges_timer();		}	if (gmc_warp) {		/* accuracy: 0==1/2, 1=1/4, 2=1/8, 3=1/16 */		generate_GMCparameters(	dec->sprite_warping_points,				dec->sprite_warping_accuracy, gmc_warp,				dec->width, dec->height, &dec->new_gmc_data);		/* image warping is done block-based in decoder_mbgmc(), now */	}	bound = 0;	for (y = 0; y < mb_height; y++) {		cp_mb = st_mb = 0;		for (x = 0; x < mb_width; x++) {			MACROBLOCK *mb;			/* skip stuffing */			while (BitstreamShowBits(bs, 10) == 1)				BitstreamSkip(bs, 10);			if (check_resync_marker(bs, fcode - 1)) {				bound = read_video_packet_header(bs, dec, fcode - 1,					&quant, &fcode, 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));			if (!(BitstreamGetBit(bs)))	{ /* block _is_ coded */				uint32_t mcbpc, cbpc, cbpy, cbp;				uint32_t intra, acpred_flag = 0;				int mcsel = 0;		/* mcsel: '0'=local motion, '1'=GMC */				cp_mb++;				mcbpc = get_mcbpc_inter(bs);				mb->mode = mcbpc & 7;				cbpc = (mcbpc >> 4);				DPRINTF(XVID_DEBUG_MB, "mode %i\n", mb->mode);				DPRINTF(XVID_DEBUG_MB, "cbpc %i\n", cbpc);				intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q);				if (gmc_warp && (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q))					mcsel = BitstreamGetBit(bs);				else if (intra)					acpred_flag = BitstreamGetBit(bs);				cbpy = get_cbpy(bs, intra);				DPRINTF(XVID_DEBUG_MB, "cbpy %i mcsel %i \n", cbpy,mcsel);				cbp = (cbpy << 2) | cbpc;				if (mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q) {					int dquant = dquant_table[BitstreamGetBits(bs, 2)];					DPRINTF(XVID_DEBUG_MB, "dquant %i\n", dquant);					quant += dquant;					if (quant > 31) {						quant = 31;					} else if (quant < 1) {						quant = 1;					}					DPRINTF(XVID_DEBUG_MB, "quant %i\n", quant);				}				mb->quant = quant;				if (dec->interlacing) {					if (cbp || intra) {						mb->field_dct = BitstreamGetBit(bs);						DPRINTF(XVID_DEBUG_MB,"decp: field_dct: %i\n", mb->field_dct);					}					if ((mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) && !mcsel) {						mb->field_pred = BitstreamGetBit(bs);						DPRINTF(XVID_DEBUG_MB, "decp: field_pred: %i\n", mb->field_pred);						if (mb->field_pred) {							mb->field_for_top = BitstreamGetBit(bs);							DPRINTF(XVID_DEBUG_MB,"decp: field_for_top: %i\n", mb->field_for_top);							mb->field_for_bot = BitstreamGetBit(bs);							DPRINTF(XVID_DEBUG_MB,"decp: field_for_bot: %i\n", mb->field_for_bot);						}					}				}				if (mcsel) {					decoder_mbgmc(dec, mb, x, y, fcode, cbp, bs, rounding);					continue;				} else if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {					if (dec->interlacing && mb->field_pred) {						get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound);						get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1], fcode, bound);					} else {						get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound);						mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];					}				} else if (mb->mode == MODE_INTER4V ) {					get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound);					get_motion_vector(dec, bs, x, y, 1, &mb->mvs[1], fcode, bound);					get_motion_vector(dec, bs, x, y, 2, &mb->mvs[2], fcode, bound);					get_motion_vector(dec, bs, x, y, 3, &mb->mvs[3], fcode, bound);				} else {		/* MODE_INTRA, MODE_INTRA_Q */					mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;					mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =	0;					decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,									intra_dc_threshold, bound);					continue;				}				decoder_mbinter(dec, mb, x, y, cbp, bs, rounding, 0);			} else if (gmc_warp) {	/* a not coded S(GMC)-VOP macroblock */				mb->mode = MODE_NOT_CODED_GMC;				mb->quant = quant;				decoder_mbgmc(dec, mb, x, y, fcode, 0x00, bs, rounding);				if(dec->out_frm && cp_mb > 0) {					output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);					cp_mb = 0;				}				st_mb = x+1;			} else {	/* not coded P_VOP macroblock */				mb->mode = MODE_NOT_CODED;				mb->quant = quant;				mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;				mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;				decoder_mbinter(dec, mb, x, y, 0, bs,								rounding, 0);				if(dec->out_frm && cp_mb > 0) {					output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);					cp_mb = 0;				}				st_mb = x+1;			}		}		if(dec->out_frm && cp_mb > 0)			output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);	}}/* decode B-frame motion vector */static voidget_b_motion_vector(Bitstream * bs,					VECTOR * mv,					int fcode,					const VECTOR pmv,					const DECODER * const dec,					const int x, const int y){	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);	int mv_x = get_mv(bs, fcode);	int mv_y = get_mv(bs, fcode);	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;	mv->x = mv_x;	mv->y = mv_y;}/* decode an B-frame direct & interpolate macroblock */static voiddecoder_bf_interpolate_mbinter(DECODER * dec,								IMAGE forward,								IMAGE backward,								MACROBLOCK * pMB,								const uint32_t x_pos,								const uint32_t y_pos,								Bitstream * bs,								const int direct){	uint32_t stride = dec->edged_width;	uint32_t stride2 = stride / 2;	int uv_dx, uv_dy;	int b_uv_dx, b_uv_dy;	uint8_t *pY_Cur, *pU_Cur, *pV_Cur;	const uint32_t cbp = pMB->cbp;	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);	validate_vector(pMB->mvs, x_pos, y_pos, dec);	validate_vector(pMB->b_mvs, x_pos, y_pos, dec);	if (!direct) {		uv_dx = pMB->mvs[0].x;		uv_dy = pMB->mvs[0].y;		b_uv_dx = pMB->b_mvs[0].x;		b_uv_dy = pMB->b_mvs[0].y;		if (dec->quarterpel) {			uv_dx /= 2;			uv_dy /= 2;			b_uv_dx /= 2;			b_uv_dy /= 2;		}		uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];		uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];		b_uv_dx = (b_uv_dx >> 1) + roundtab_79[b_uv_dx & 0x3];		b_uv_dy = (b_uv_dy >> 1) + roundtab_79[b_uv_dy & 0x3];	} else {		uv_dx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;		uv_dy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;		b_uv_dx = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x;		b_uv_dy = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;		if (dec->quarterpel) {			uv_dx /= 2;			uv_dy /= 2;			b_uv_dx /= 2;			b_uv_dy /= 2;		}		uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];		uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf];		b_uv_dx = (b_uv_dx >> 3) + roundtab_76[b_uv_dx & 0xf];		b_uv_dy = (b_uv_dy >> 3) + roundtab_76[b_uv_dy & 0xf];	}	start_timer();	if(dec->quarterpel) {		if(!direct) {			interpolate16x16_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64, 										dec->qtmp.y + 128, 16*x_pos, 16*y_pos,										pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);		} else {			interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64, 										dec->qtmp.y + 128, 16*x_pos, 16*y_pos,										pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);			interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64, 										dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,										pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);			interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64, 										dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,										pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);			interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64, 										dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,										pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);		}

⌨️ 快捷键说明

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