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

📄 decoder.c

📁 mpeg4代码,比较具体
💻 C
📖 第 1 页 / 共 2 页
字号:
	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();}voiddecoder_iframe(DECODER * dec,			   Bitstream * bs,			   int quant,			   int intra_dc_threshold){	uint32_t bound;	uint32_t x, y;	bound = 0;	for (y = 0; y < dec->mb_height; y++) {		for (x = 0; x < dec->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, 0, &quant);				x = bound % dec->mb_width;				y = bound / dec->mb_width;			}			mb = &dec->mbs[y * dec->mb_width + x];			DPRINTF(DPRINTF_MB, "macroblock (%i,%i) %08x", 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(DPRINTF_DEBUG, "deci: field_dct: %d", 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,dec->mb_width);	}}voidget_motion_vector(DECODER * dec,				  Bitstream * bs,				  int x,				  int y,				  int k,				  VECTOR * mv,				  int fcode,				  const int bound){	int scale_fac = 1 << (fcode - 1);	int high = (32 * scale_fac) - 1;	int low = ((-32) * scale_fac);	int range = (64 * scale_fac);	VECTOR pmv;	int mv_x, mv_y;	pmv = get_pmv2(dec->mbs, dec->mb_width, bound, x, y, k);	mv_x = get_mv(bs, fcode);	mv_y = get_mv(bs, fcode);	DPRINTF(DPRINTF_MV,"mv_diff (%i,%i) pred (%i,%i)", mv_x, mv_y, pmv.x, 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;	}	mv->x = mv_x;	mv->y = mv_y;}voiddecoder_pframe(DECODER * dec,			   Bitstream * bs,			   int rounding,			   int quant,			   int fcode,			   int intra_dc_threshold){	uint32_t x, y;	uint32_t bound;	int cp_mb, st_mb;	start_timer();	image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,				   dec->width, dec->height);	stop_edges_timer();	bound = 0;	for (y = 0; y < dec->mb_height; y++) {		cp_mb = st_mb = 0;		for (x = 0; x < dec->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, fcode - 1, &quant);				x = bound % dec->mb_width;				y = bound / dec->mb_width;			}			mb = &dec->mbs[y * dec->mb_width + x];			DPRINTF(DPRINTF_MB, "macroblock (%i,%i) %08x", x, y, BitstreamShowBits(bs, 32));			/*if (!(dec->mb_skip[y*dec->mb_width + x]=BitstreamGetBit(bs)))          not_coded */			if (!(BitstreamGetBit(bs)))	/* not_coded */			{				uint32_t mcbpc;				uint32_t cbpc;				uint32_t acpred_flag;				uint32_t cbpy;				uint32_t cbp;				uint32_t intra;				cp_mb++;				mcbpc = get_mcbpc_inter(bs);				mb->mode = mcbpc & 7;				cbpc = (mcbpc >> 4);								DPRINTF(DPRINTF_MB, "mode %i", mb->mode);				DPRINTF(DPRINTF_MB, "cbpc %i", cbpc);				acpred_flag = 0;				intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q);				if (intra) {					acpred_flag = BitstreamGetBit(bs);				}				cbpy = get_cbpy(bs, intra);				DPRINTF(DPRINTF_MB, "cbpy %i", cbpy);				cbp = (cbpy << 2) | cbpc;				if (mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q) {					int dquant = dquant_table[BitstreamGetBits(bs, 2)];					DPRINTF(DPRINTF_MB, "dquant %i", dquant);					quant += dquant;					if (quant > 31) {						quant = 31;					} else if (quant < 1) {						quant = 1;					}					DPRINTF(DPRINTF_MB, "quant %i", quant);				}				mb->quant = quant;				if (dec->interlacing) {					if (cbp || intra) {						mb->field_dct = BitstreamGetBit(bs);						DPRINTF(DPRINTF_DEBUG, "decp: field_dct: %d", mb->field_dct);					}					if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {						mb->field_pred = BitstreamGetBit(bs);						DPRINTF(DPRINTF_DEBUG, "decp: field_pred: %d", mb->field_pred);						if (mb->field_pred) {							mb->field_for_top = BitstreamGetBit(bs);							DPRINTF(DPRINTF_DEBUG, "decp: field_for_top: %d", mb->field_for_top);							mb->field_for_bot = BitstreamGetBit(bs);							DPRINTF(DPRINTF_DEBUG, "decp: field_for_bot: %d", mb->field_for_bot);						}					}				}				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].x = mb->mvs[2].x = mb->mvs[3].x =							mb->mvs[0].x;						mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =							mb->mvs[0].y;					}				} 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, acpred_flag, cbp, bs, quant,								rounding);			} else				/* not coded */			{				DPRINTF(DPRINTF_DEBUG, "P-frame MB at (X,Y)=(%d,%d)", x, y);				mb->mode = MODE_NOT_CODED;				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;				/* copy macroblock directly from ref to cur */				start_timer();				transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +								 (16 * x),								 dec->refn[0].y + (16 * y) * dec->edged_width +								 (16 * x), dec->edged_width);				transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +								 (16 * x + 8),								 dec->refn[0].y + (16 * y) * dec->edged_width +								 (16 * x + 8), dec->edged_width);				transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +								 (16 * x),								 dec->refn[0].y + (16 * y +												   8) * dec->edged_width +								 (16 * x), dec->edged_width);				transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +								 (16 * x + 8),								 dec->refn[0].y + (16 * y +												   8) * dec->edged_width +								 (16 * x + 8), dec->edged_width);				transfer8x8_copy(dec->cur.u + (8 * y) * dec->edged_width / 2 +								 (8 * x),								 dec->refn[0].u +								 (8 * y) * dec->edged_width / 2 + (8 * x),								 dec->edged_width / 2);				transfer8x8_copy(dec->cur.v + (8 * y) * dec->edged_width / 2 +								 (8 * x),								 dec->refn[0].v +								 (8 * y) * dec->edged_width / 2 + (8 * x),								 dec->edged_width / 2);				stop_transfer_timer();				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);	}}/* swap two MACROBLOCK array */voidmb_swap(MACROBLOCK ** mb1,		MACROBLOCK ** mb2){	MACROBLOCK *temp = *mb1;	*mb1 = *mb2;	*mb2 = temp;}intdecoder_decode(DECODER * dec,			   XVID_DEC_FRAME * frame){	Bitstream bs;	uint32_t rounding;	uint32_t quant;	uint32_t fcode_forward;	uint32_t fcode_backward;	uint32_t intra_dc_threshold;	uint32_t vop_type;	start_global_timer();	dec->out_frm = (frame->colorspace == XVID_CSP_EXTERN) ? frame->image : NULL;	BitstreamInit(&bs, frame->bitstream, frame->length);	/* add by chenm001 <chenm001@163.com> */	/* for support B-frame to reference last 2 frame */	dec->frames++;	vop_type =		BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode_forward,							 &fcode_backward, &intra_dc_threshold);	dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.y = dec->p_fmv.y = 0;	/* init pred vector to 0 */	switch (vop_type) {	case P_VOP:		decoder_pframe(dec, &bs, rounding, quant, fcode_forward,					   intra_dc_threshold);		break;	case I_VOP:		decoder_iframe(dec, &bs, quant, intra_dc_threshold);		break;	case B_VOP:		image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);		break;	case N_VOP:		/* when low_delay==0, N_VOP's should interpolate between the past and future frames */		image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);		break;	default:		return XVID_ERR_FAIL;	}	frame->length = BitstreamPos(&bs) / 8;	image_output(&dec->cur, dec->width, dec->height, dec->edged_width,					 frame->image, frame->stride, frame->colorspace);	if (vop_type == I_VOP || vop_type == P_VOP) {		image_swap(&dec->refn[0], &dec->refn[1]);		image_swap(&dec->cur, &dec->refn[0]);		/* swap MACROBLOCK */                /* the Divx will not set the low_delay flage some times */                /* so follow code will wrong to not swap at that time */                /* this will broken bitstream! so I'm change it, */                /* But that is not the best way! can anyone tell me how */                /* to do another way? */                /* 18-07-2002   MinChen<chenm001@163.com> */                /*if (!dec->low_delay && vop_type == P_VOP) */                if (vop_type == P_VOP)			mb_swap(&dec->mbs, &dec->last_mbs);	}	emms();	stop_global_timer();	return XVID_ERR_OK;}

⌨️ 快捷键说明

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