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

📄 decoder.c

📁 mpeg4视频解码源码.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
	} else {		interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos,							pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);		interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos,							pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);		interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos + 8,							pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);		interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos + 8,							pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);	}	interpolate8x8_switch(dec->cur.u, forward.u, 8 * x_pos, 8 * y_pos, uv_dx,						uv_dy, stride2, 0);	interpolate8x8_switch(dec->cur.v, forward.v, 8 * x_pos, 8 * y_pos, uv_dx,						uv_dy, stride2, 0);	if(dec->quarterpel) {		if(!direct) {			interpolate16x16_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,					dec->qtmp.y + 128, 16*x_pos, 16*y_pos,					pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);		} else {			interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,					dec->qtmp.y + 128, 16*x_pos, 16*y_pos,					pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);			interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,					dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,					pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);			interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,					dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,					pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);			interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,					dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,					pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);		}	} else {		interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos, 16 * y_pos,				pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);		interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos + 8,				16 * y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);		interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos,				16 * y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);		interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos + 8,				16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);	}	interpolate8x8_add_switch(dec->cur.u, backward.u, 8 * x_pos, 8 * y_pos,			b_uv_dx, b_uv_dy, stride2, 0);	interpolate8x8_add_switch(dec->cur.v, backward.v, 8 * x_pos, 8 * y_pos,			b_uv_dx, b_uv_dy, stride2, 0);	stop_comp_timer();	if (cbp)		decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);}/* for decode B-frame dbquant */static __inline int32_tget_dbquant(Bitstream * bs){	if (!BitstreamGetBit(bs))		/*  '0' */		return (0);	else if (!BitstreamGetBit(bs))	/* '10' */		return (-2);	else							/* '11' */		return (2);}/* * decode B-frame mb_type * bit		ret_value * 1		0 * 01		1 * 001		2 * 0001		3 */static int32_t __inlineget_mbtype(Bitstream * bs){	int32_t mb_type;	for (mb_type = 0; mb_type <= 3; mb_type++)		if (BitstreamGetBit(bs))			return (mb_type);	return -1;}static voiddecoder_bframe(DECODER * dec,				Bitstream * bs,				int quant,				int fcode_forward,				int fcode_backward){	uint32_t x, y;	VECTOR mv;	const VECTOR zeromv = {0,0};	int i;	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 (!dec->is_edged[1]) {		start_timer();		image_setedges(&dec->refn[1], dec->edged_width, dec->edged_height,						dec->width, dec->height, dec->bs_version);		dec->is_edged[1] = 1;		stop_edges_timer();	}	for (y = 0; y < dec->mb_height; y++) {		/* Initialize Pred Motion Vector */		dec->p_fmv = dec->p_bmv = zeromv;		for (x = 0; x < dec->mb_width; x++) {			MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];			MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];			const int fcode_max = (fcode_forward>fcode_backward) ? fcode_forward : fcode_backward;			int intra_dc_threshold; /* fake variable */			if (check_resync_marker(bs, fcode_max  - 1)) {				int bound = read_video_packet_header(bs, dec, fcode_max - 1, &quant,													 &fcode_forward, &fcode_backward, &intra_dc_threshold);				x = bound % dec->mb_width;				y = bound / dec->mb_width;				/* reset predicted macroblocks */				dec->p_fmv = dec->p_bmv = zeromv;			}			mv =			mb->b_mvs[0] = mb->b_mvs[1] = mb->b_mvs[2] = mb->b_mvs[3] =			mb->mvs[0] = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = zeromv;			mb->quant = quant;			/*			 * skip if the co-located P_VOP macroblock is not coded			 * if not codec in co-located S_VOP macroblock is _not_			 * automatically skipped			 */			if (last_mb->mode == MODE_NOT_CODED) {				mb->cbp = 0;				mb->mode = MODE_FORWARD;				decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1);				continue;			}			if (!BitstreamGetBit(bs)) {	/* modb=='0' */				const uint8_t modb2 = BitstreamGetBit(bs);				mb->mode = get_mbtype(bs);				if (!modb2)		/* modb=='00' */					mb->cbp = BitstreamGetBits(bs, 6);				else					mb->cbp = 0;				if (mb->mode && mb->cbp) {					quant += get_dbquant(bs);					if (quant > 31)						quant = 31;					else if (quant < 1)						quant = 1;				}				mb->quant = quant;				if (dec->interlacing) {					if (mb->cbp) {						mb->field_dct = BitstreamGetBit(bs);						DPRINTF(XVID_DEBUG_MB,"decp: field_dct: %i\n", mb->field_dct);					}					if (mb->mode) {						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);						}					}				}			} else {				mb->mode = MODE_DIRECT_NONE_MV;				mb->cbp = 0;			}			switch (mb->mode) {			case MODE_DIRECT:				get_b_motion_vector(bs, &mv, 1, zeromv, dec, x, y);			case MODE_DIRECT_NONE_MV:				for (i = 0; i < 4; i++) {					mb->mvs[i].x = last_mb->mvs[i].x*dec->time_bp/dec->time_pp + mv.x;					mb->mvs[i].y = last_mb->mvs[i].y*dec->time_bp/dec->time_pp + mv.y;										mb->b_mvs[i].x = (mv.x)						?  mb->mvs[i].x - last_mb->mvs[i].x						: last_mb->mvs[i].x*(dec->time_bp - dec->time_pp)/dec->time_pp;					mb->b_mvs[i].y = (mv.y)						? mb->mvs[i].y - last_mb->mvs[i].y						: last_mb->mvs[i].y*(dec->time_bp - dec->time_pp)/dec->time_pp;				}				decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],												mb, x, y, bs, 1);				break;			case MODE_INTERPOLATE:				get_b_motion_vector(bs, &mb->mvs[0], fcode_forward, dec->p_fmv, dec, x, y);				dec->p_fmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] =	mb->mvs[0];				get_b_motion_vector(bs, &mb->b_mvs[0], fcode_backward, dec->p_bmv, dec, x, y);				dec->p_bmv = mb->b_mvs[1] = mb->b_mvs[2] = mb->b_mvs[3] = mb->b_mvs[0];				decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],											mb, x, y, bs, 0);				break;			case MODE_BACKWARD:				get_b_motion_vector(bs, &mb->mvs[0], fcode_backward, dec->p_bmv, dec, x, y);				dec->p_bmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] =	mb->mvs[0];				decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 0);				break;			case MODE_FORWARD:				get_b_motion_vector(bs, &mb->mvs[0], fcode_forward, dec->p_fmv, dec, x, y);				dec->p_fmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] =	mb->mvs[0];				decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1);				break;			default:				DPRINTF(XVID_DEBUG_ERROR,"Not supported B-frame mb_type = %i\n", mb->mode);			}		} /* End of for */	}}/* perform post processing if necessary, and output the image */void decoder_output(DECODER * dec, IMAGE * img, MACROBLOCK * mbs,					xvid_dec_frame_t * frame, xvid_dec_stats_t * stats,					int coding_type, int quant){	const int brightness = XVID_VERSION_MINOR(frame->version) >= 1 ? frame->brightness : 0;	if (dec->cartoon_mode)		frame->general &= ~XVID_FILMEFFECT;	if ((frame->general & (XVID_DEBLOCKY|XVID_DEBLOCKUV|XVID_FILMEFFECT) || brightness!=0) 		&& mbs != NULL)	/* post process */	{		/* note: image is stored to tmp */		image_copy(&dec->tmp, img, dec->edged_width, dec->height);		image_postproc(&dec->postproc, &dec->tmp, dec->edged_width, 					   mbs, dec->mb_width, dec->mb_height, dec->mb_width,					   frame->general, brightness, dec->frames, (coding_type == B_VOP));		img = &dec->tmp;	}	image_output(img, dec->width, dec->height,				 dec->edged_width, (uint8_t**)frame->output.plane, frame->output.stride,				 frame->output.csp, dec->interlacing);	if (stats) {		stats->type = coding2type(coding_type);		stats->data.vop.time_base = (int)dec->time_base;		stats->data.vop.time_increment = 0;	/* XXX: todo */		stats->data.vop.qscale_stride = dec->mb_width;		stats->data.vop.qscale = dec->qscale;		if (stats->data.vop.qscale != NULL && mbs != NULL) {			int i;			for (i = 0; i < dec->mb_width*dec->mb_height; i++)				stats->data.vop.qscale[i] = mbs[i].quant;		} else 			stats->data.vop.qscale = NULL;	}}intdecoder_decode(DECODER * dec,				xvid_dec_frame_t * frame, xvid_dec_stats_t * stats){	Bitstream bs;	uint32_t rounding;	uint32_t quant = 2;	uint32_t fcode_forward;	uint32_t fcode_backward;	uint32_t intra_dc_threshold;	WARPPOINTS gmc_warp;	int coding_type;	int success, output, seen_something;	if (XVID_VERSION_MAJOR(frame->version) != 1 || (stats && XVID_VERSION_MAJOR(stats->version) != 1))	/* v1.x.x */		return XVID_ERR_VERSION;	start_global_timer();	dec->low_delay_default = (frame->general & XVID_LOWDELAY);	if ((frame->general & XVID_DISCONTINUITY))		dec->frames = 0;	dec->out_frm = (frame->output.csp == XVID_CSP_SLICE) ? &frame->output : NULL;	if (frame->length < 0) {	/* decoder flush */		int ret;		/* if not decoding "low_delay/packed", and this isn't low_delay and			we have a reference frame, then outout the reference frame */		if (!(dec->low_delay_default && dec->packed_mode) && !dec->low_delay && dec->frames>0) {			decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);			dec->frames = 0;			ret = 0;		} else {			if (stats) stats->type = XVID_TYPE_NOTHING;			ret = XVID_ERR_END;		}		emms();		stop_global_timer();		return ret;	}	BitstreamInit(&bs, frame->bitstream, frame->length);	/* XXX: 0x7f is only valid whilst decoding vfw xvid/divx5 avi's */	if(dec->low_delay_default && frame->length == 1 && BitstreamShowBits(&bs, 8) == 0x7f)	{		image_output(&dec->refn[0], dec->width, dec->height, dec->edged_width,					 (uint8_t**)frame->output.plane, frame->output.stride, frame->output.csp, dec->interlacing);		if (stats) stats->type = XVID_TYPE_NOTHING;		emms();		return 1;	/* one byte consumed */	}	success = 0;	output = 0;	seen_something = 0;repeat:	coding_type = BitstreamReadHeaders(&bs, dec, &rounding,			&quant, &fcode_forward, &fcode_backward, &intra_dc_threshold, &gmc_warp);	DPRINTF(XVID_DEBUG_HEADER, "coding_type=%i,  packed=%i,  time=%"#if defined(_MSC_VER)    "I64"#else    "ll"#endif    "i,  time_pp=%i,  time_bp=%i\n",							coding_type,	dec->packed_mode, dec->time, dec->time_pp, dec->time_bp);	if (coding_type == -1) { /* nothing */		if (success) goto done;		if (stats) stats->type = XVID_TYPE_NOTHING;		emms();		return BitstreamPos(&bs)/8;	}	if (coding_type == -2 || coding_type == -3) {	/* vol and/or resize */		if (coding_type == -3)			decoder_resize(dec);		if (stats) {			stats->type = XVID_TYPE_VOL;			stats->data.vol.general = 0;			/*XXX: if (dec->interlacing)				stats->data.vol.general |= ++INTERLACING; */			stats->data.vol.width = dec->width;			stats->data.vol.height = dec->height;			stats->data.vol.par = dec->aspect_ratio;			stats->data.vol.par_width = dec->par_width;			stats->data.vol.par_height = dec->par_height;			emms();			return BitstreamPos(&bs)/8;	/* number of bytes consumed */		}		goto repeat;	}	if(dec->frames == 0 && coding_type != I_VOP) {		/* 1st frame is not an i-vop */		goto repeat;	}	dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.y = dec->p_fmv.y = 0;	/* init pred vector to 0 */	/* packed_mode: special-N_VOP treament */	if (dec->packed_mode && coding_type == N_VOP) {		if (dec->low_delay_default && dec->frames > 0) {			decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);			output = 1;		}		/* ignore otherwise */	} else if (coding_type != B_VOP) {		switch(coding_type) {		case I_VOP :			decoder_iframe(dec, &bs, quant, intra_dc_threshold);			break;		case P_VOP :			decoder_pframe(dec, &bs, rounding, quant,						fcode_forward, intra_dc_threshold, NULL);			break;		case S_VOP :			decoder_pframe(dec, &bs, rounding, quant,						fcode_forward, intra_dc_threshold, &gmc_warp);			break;		case N_VOP :			/* XXX: not_coded vops are not used for forward prediction */			/* we should not swap(last_mbs,mbs) */			image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);			SWAP(MACROBLOCK *, dec->mbs, dec->last_mbs); /* it will be swapped back */			break;		}		/* note: for packed_mode, output is performed when the special-N_VOP is decoded */		if (!(dec->low_delay_default && dec->packed_mode)) {			if (dec->low_delay) {				decoder_output(dec, &dec->cur, dec->mbs, frame, stats, coding_type, quant);				output = 1;			} else if (dec->frames > 0)	{ /* is the reference frame valid? */				/* output the reference frame */				decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);				output = 1;			}		}		image_swap(&dec->refn[0], &dec->refn[1]);		dec->is_edged[1] = dec->is_edged[0];		image_swap(&dec->cur, &dec->refn[0]);		dec->is_edged[0] = 0;		SWAP(MACROBLOCK *, dec->mbs, dec->last_mbs);		dec->last_coding_type = coding_type;		dec->frames++;		seen_something = 1;	} else {	/* B_VOP */		if (dec->low_delay) {			DPRINTF(XVID_DEBUG_ERROR, "warning: bvop found in low_delay==1 stream\n");			dec->low_delay = 0;		}		if (dec->frames < 2) {			/* attemping to decode a bvop without atleast 2 reference frames */			image_printf(&dec->cur, dec->edged_width, dec->height, 16, 16,						"broken b-frame, mising ref frames");			if (stats) stats->type = XVID_TYPE_NOTHING;		} else if (dec->time_pp <= dec->time_bp) {			/* this occurs when dx50_bvop_compatibility==0 sequences are			decoded in vfw. */			image_printf(&dec->cur, dec->edged_width, dec->height, 16, 16,						"broken b-frame, tpp=%i tbp=%i", dec->time_pp, dec->time_bp);			if (stats) stats->type = XVID_TYPE_NOTHING;		} else {			decoder_bframe(dec, &bs, quant, fcode_forward, fcode_backward);			decoder_output(dec, &dec->cur, dec->mbs, frame, stats, coding_type, quant);		}		output = 1;		dec->frames++;	}#if 0 /* Avoids to read to much data because of 32bit reads in our BS functions */	 BitstreamByteAlign(&bs);#endif	/* low_delay_default mode: repeat in packed_mode */	if (dec->low_delay_default && dec->packed_mode && output == 0 && success == 0) {		success = 1;		goto repeat;	}done :  /* if we reach here without outputing anything _and_     the calling application has specified low_delay_default,     we *must* output something.     this always occurs on the first call to decode() call     when bframes are present in the bitstream. it may also     occur if no vops  were seen in the bitstream     if packed_mode is enabled, then we output the recently     decoded frame (the very first ivop). otherwise we have     nothing to display, and therefore output a black screen.  */  if (dec->low_delay_default && output == 0) {    if (dec->packed_mode && seen_something) {			decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);    } else {			image_clear(&dec->cur, dec->width, dec->height, dec->edged_width, 0, 128, 128);			decoder_output(dec, &dec->cur, NULL, frame, stats, P_VOP, quant);			if (stats) stats->type = XVID_TYPE_NOTHING;		}	}	emms();	stop_global_timer();	return (BitstreamPos(&bs) + 7) / 8;	/* number of bytes consumed */}

⌨️ 快捷键说明

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