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

📄 estimation_bvop.c

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 C
📖 第 1 页 / 共 3 页
字号:
static voidSearchInterpolate_final(const int x, const int y,						const uint32_t MotionFlags,						const MBParam * const pParam,						int32_t * const best_sad,						SearchData * const Data){	int i, j;	int b_range[4], f_range[4];	get_range(f_range, f_range+1, f_range+2, f_range+3, x, y, 4, pParam->width, pParam->height, Data->iFcode - Data->qpel, 1);	get_range(b_range, b_range+1, b_range+2, b_range+3, x, y, 4, pParam->width, pParam->height, Data->bFcode - Data->qpel, 1);	/* diamond */	do {		Data->dir = 0;		/* forward MV moves */		i = Data->currentMV[0].x; j = Data->currentMV[0].y;		CheckCandidateInt(i + 1, j, Data, 1);		CheckCandidateInt(i, j + 1, Data, 1);		CheckCandidateInt(i - 1, j, Data, 1);		CheckCandidateInt(i, j - 1, Data, 1);		/* backward MV moves */		set_range(b_range, Data);		i = Data->currentMV[1].x; j = Data->currentMV[1].y;		CheckCandidateInt(i + 1, j, Data, 2);		CheckCandidateInt(i, j + 1, Data, 2);		CheckCandidateInt(i - 1, j, Data, 2);		CheckCandidateInt(i, j - 1, Data, 2);		set_range(f_range, Data);	} while (Data->dir != 0);	/* qpel refinement */	if (Data->qpel) {		Data->qpel_precision = 1;		get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, 			x, y, 4, pParam->width, pParam->height, Data->iFcode, 2);				Data->currentQMV[0].x = 2 * Data->currentMV[0].x;		Data->currentQMV[0].y = 2 * Data->currentMV[0].y;		Data->currentQMV[1].x = 2 * Data->currentMV[1].x;		Data->currentQMV[1].y = 2 * Data->currentMV[1].y;		if (MotionFlags & XVID_ME_QUARTERPELREFINE16) {			xvid_me_SubpelRefine(Data->currentQMV[0], Data, CheckCandidateInt, 1);			get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, 				x, y, 4, pParam->width, pParam->height, Data->bFcode, 2);			xvid_me_SubpelRefine(Data->currentQMV[1], Data, CheckCandidateInt, 2);		}	}	if (Data->iMinSAD[0] < *best_sad) *best_sad = Data->iMinSAD[0];}static void ModeDecision_BVOP_SAD(const SearchData * const Data_d,					  const SearchData * const Data_b,					  const SearchData * const Data_f,					  const SearchData * const Data_i,					  MACROBLOCK * const pMB,					  const MACROBLOCK * const b_mb,					  VECTOR * f_predMV,					  VECTOR * b_predMV){	int mode = MODE_DIRECT, k;	int best_sad, f_sad, b_sad, i_sad;	const int qpel = Data_d->qpel;	/* evaluate cost of all modes - quite simple in SAD */	best_sad = Data_d->iMinSAD[0] + 1*Data_d->lambda16;	b_sad = Data_b->iMinSAD[0] + 3*Data_d->lambda16;	f_sad = Data_f->iMinSAD[0] + 4*Data_d->lambda16;	i_sad = Data_i->iMinSAD[0] + 2*Data_d->lambda16;	if (b_sad < best_sad) {		mode = MODE_BACKWARD;		best_sad = b_sad;	}	if (f_sad < best_sad) {		mode = MODE_FORWARD;		best_sad = f_sad;	}	if (i_sad < best_sad) {		mode = MODE_INTERPOLATE;		best_sad = i_sad;	}	pMB->sad16 = best_sad;	pMB->mode = mode;	pMB->cbp = 63;	switch (mode) {	case MODE_DIRECT:		if (!qpel && b_mb->mode != MODE_INTER4V) pMB->mode = MODE_DIRECT_NO4V; /* for faster compensation */		pMB->pmvs[3] = Data_d->currentMV[0];		for (k = 0; k < 4; k++) {			pMB->mvs[k].x = Data_d->directmvF[k].x + Data_d->currentMV->x;			pMB->b_mvs[k].x = (	(Data_d->currentMV->x == 0)								? Data_d->directmvB[k].x								:pMB->mvs[k].x - Data_d->referencemv[k].x);			pMB->mvs[k].y = (Data_d->directmvF[k].y + Data_d->currentMV->y);			pMB->b_mvs[k].y = ((Data_d->currentMV->y == 0)								? Data_d->directmvB[k].y								: pMB->mvs[k].y - Data_d->referencemv[k].y);			if (qpel) {				pMB->qmvs[k].x = pMB->mvs[k].x; pMB->mvs[k].x /= 2;				pMB->b_qmvs[k].x = pMB->b_mvs[k].x; pMB->b_mvs[k].x /= 2;				pMB->qmvs[k].y = pMB->mvs[k].y; pMB->mvs[k].y /= 2;				pMB->b_qmvs[k].y = pMB->b_mvs[k].y; pMB->b_mvs[k].y /= 2;			}			if (b_mb->mode != MODE_INTER4V) {				pMB->mvs[3] = pMB->mvs[2] = pMB->mvs[1] = pMB->mvs[0];				pMB->b_mvs[3] = pMB->b_mvs[2] = pMB->b_mvs[1] = pMB->b_mvs[0];				pMB->qmvs[3] = pMB->qmvs[2] = pMB->qmvs[1] = pMB->qmvs[0];				pMB->b_qmvs[3] = pMB->b_qmvs[2] = pMB->b_qmvs[1] = pMB->b_qmvs[0];				break;			}					}		break;	case MODE_FORWARD:		if (qpel) {			pMB->pmvs[0].x = Data_f->currentQMV->x - f_predMV->x;			pMB->pmvs[0].y = Data_f->currentQMV->y - f_predMV->y;			pMB->qmvs[0] = *Data_f->currentQMV;			*f_predMV = Data_f->currentQMV[0];		} else {			pMB->pmvs[0].x = Data_f->currentMV->x - f_predMV->x;			pMB->pmvs[0].y = Data_f->currentMV->y - f_predMV->y;			*f_predMV = Data_f->currentMV[0];		}		pMB->mvs[0] = *Data_f->currentMV;		pMB->b_mvs[0] = *Data_b->currentMV; /* hint for future searches */		break;	case MODE_BACKWARD:		if (qpel) {			pMB->pmvs[0].x = Data_b->currentQMV->x - b_predMV->x;			pMB->pmvs[0].y = Data_b->currentQMV->y - b_predMV->y;			pMB->b_qmvs[0] = *Data_b->currentQMV;			*b_predMV = Data_b->currentQMV[0];		} else {			pMB->pmvs[0].x = Data_b->currentMV->x - b_predMV->x;			pMB->pmvs[0].y = Data_b->currentMV->y - b_predMV->y;			*b_predMV = Data_b->currentMV[0];		}		pMB->b_mvs[0] = *Data_b->currentMV;		pMB->mvs[0] = *Data_f->currentMV; /* hint for future searches */		break;	case MODE_INTERPOLATE:		pMB->mvs[0] = Data_i->currentMV[0];		pMB->b_mvs[0] = Data_i->currentMV[1];		if (qpel) {			pMB->qmvs[0] = Data_i->currentQMV[0];			pMB->b_qmvs[0] = Data_i->currentQMV[1];			pMB->pmvs[1].x = pMB->qmvs[0].x - f_predMV->x;			pMB->pmvs[1].y = pMB->qmvs[0].y - f_predMV->y;			pMB->pmvs[0].x = pMB->b_qmvs[0].x - b_predMV->x;			pMB->pmvs[0].y = pMB->b_qmvs[0].y - b_predMV->y;			*f_predMV = Data_i->currentQMV[0];			*b_predMV = Data_i->currentQMV[1];		} else {			pMB->pmvs[1].x = pMB->mvs[0].x - f_predMV->x;			pMB->pmvs[1].y = pMB->mvs[0].y - f_predMV->y;			pMB->pmvs[0].x = pMB->b_mvs[0].x - b_predMV->x;			pMB->pmvs[0].y = pMB->b_mvs[0].y - b_predMV->y;			*f_predMV = Data_i->currentMV[0];			*b_predMV = Data_i->currentMV[1];		}		break;	}}static __inline voidmaxMotionBVOP(int * const MVmaxF, int * const MVmaxB, const MACROBLOCK * const pMB, const int qpel){	if (pMB->mode == MODE_FORWARD || pMB->mode == MODE_INTERPOLATE) {		const VECTOR * const mv = qpel ? pMB->qmvs : pMB->mvs;		int max = *MVmaxF;		if (mv[0].x > max) max = mv[0].x;		else if (-mv[0].x - 1 > max) max = -mv[0].x - 1;		if (mv[0].y > max) max = mv[0].y;		else if (-mv[0].y - 1 > max) max = -mv[0].y - 1;		*MVmaxF = max;	}	if (pMB->mode == MODE_BACKWARD || pMB->mode == MODE_INTERPOLATE) {		const VECTOR * const mv = qpel ? pMB->b_qmvs : pMB->b_mvs;		int max = *MVmaxB;		if (mv[0].x > max) max = mv[0].x;		else if (-mv[0].x - 1 > max) max = -mv[0].x - 1;		if (mv[0].y > max) max = mv[0].y;		else if (-mv[0].y - 1 > max) max = -mv[0].y - 1;		*MVmaxB = max;	}}voidMotionEstimationBVOP(MBParam * const pParam,					 FRAMEINFO * const frame,					 const int32_t time_bp,					 const int32_t time_pp,					 /* forward (past) reference */					 const MACROBLOCK * const f_mbs,					 const IMAGE * const f_ref,					 const IMAGE * const f_refH,					 const IMAGE * const f_refV,					 const IMAGE * const f_refHV,					 /* backward (future) reference */					 const FRAMEINFO * const b_reference,					 const IMAGE * const b_ref,					 const IMAGE * const b_refH,					 const IMAGE * const b_refV,					 const IMAGE * const b_refHV){	uint32_t i, j;	int32_t best_sad = 256*4096;	uint32_t skip_sad;	int fb_thresh;	const MACROBLOCK * const b_mbs = b_reference->mbs;	VECTOR f_predMV, b_predMV;	int MVmaxF = 0, MVmaxB = 0;	const int32_t TRB = time_pp - time_bp;	const int32_t TRD = time_pp;	DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);	/* some pre-inintialized data for the rest of the search */	SearchData Data_d, Data_f, Data_b, Data_i;	memset(&Data_d, 0, sizeof(SearchData));	Data_d.iEdgedWidth = pParam->edged_width;	Data_d.qpel = pParam->vol_flags & XVID_VOL_QUARTERPEL ? 1 : 0;	Data_d.rounding = 0;	Data_d.chroma = frame->motion_flags & XVID_ME_CHROMA_BVOP;	Data_d.iQuant = frame->quant;	Data_d.quant_sq = frame->quant*frame->quant;	Data_d.dctSpace = dct_space;	Data_d.quant_type = !(pParam->vol_flags & XVID_VOL_MPEGQUANT);	Data_d.mpeg_quant_matrices = pParam->mpeg_quant_matrices;	Data_d.RefQ = f_refV->u; /* a good place, also used in MC (for similar purpose) */	memcpy(&Data_f, &Data_d, sizeof(SearchData));	memcpy(&Data_b, &Data_d, sizeof(SearchData));	memcpy(&Data_i, &Data_d, sizeof(SearchData));	Data_f.iFcode = Data_i.iFcode = frame->fcode = b_reference->fcode;	Data_b.iFcode = Data_i.bFcode = frame->bcode = b_reference->fcode;	for (j = 0; j < pParam->mb_height; j++) {		f_predMV = b_predMV = zeroMV;	/* prediction is reset at left boundary */		for (i = 0; i < pParam->mb_width; i++) {			MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width;			const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width;			pMB->mode = -1;			initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i,					  i, j, f_ref, f_refH->y, f_refV->y, f_refHV->y,					  b_ref, b_refH->y, b_refV->y, b_refHV->y,					  &frame->image, b_mb);/* special case, if collocated block is SKIPed in P-VOP: encoding is forward (0,0), cpb=0 without further ado */			if (b_reference->coding_type != S_VOP)				if (b_mb->mode == MODE_NOT_CODED) {					pMB->mode = MODE_NOT_CODED;					pMB->mvs[0] = pMB->b_mvs[0] = zeroMV;					pMB->sad16 = 0;					continue;				}/* direct search comes first, because it (1) checks for SKIP-mode	and (2) sets very good predictions for forward and backward search */			skip_sad = SearchDirect_initial(i, j, frame->motion_flags, TRB, TRD, pParam, pMB, 											b_mb, &best_sad, &Data_d);			if (pMB->mode == MODE_DIRECT_NONE_MV) {				pMB->sad16 = best_sad;				pMB->cbp = 0;				continue;			}			SearchBF_initial(i, j, frame->motion_flags, frame->fcode, pParam, pMB,						&f_predMV, &best_sad, MODE_FORWARD, &Data_f, Data_d.currentMV[1]);			SearchBF_initial(i, j, frame->motion_flags, frame->bcode, pParam, pMB,						&b_predMV, &best_sad, MODE_BACKWARD, &Data_b, Data_d.currentMV[2]);			if (frame->motion_flags&XVID_ME_BFRAME_EARLYSTOP)				fb_thresh = best_sad;			else				fb_thresh = best_sad + (best_sad>>1);			if (Data_f.iMinSAD[0] <= fb_thresh)				SearchBF_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_f);			if (Data_b.iMinSAD[0] <= fb_thresh)				SearchBF_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_b);			SearchInterpolate_initial(i, j, frame->motion_flags, pParam, &f_predMV, &b_predMV, &best_sad,								  &Data_i, Data_f.currentMV[0], Data_b.currentMV[0]);			if (((Data_i.iMinSAD[0] < best_sad +(best_sad>>3)) && !(frame->motion_flags&XVID_ME_FAST_MODEINTERPOLATE))				|| Data_i.iMinSAD[0] <= best_sad)				SearchInterpolate_final(i, j, frame->motion_flags, pParam, &best_sad, &Data_i);						if (Data_d.iMinSAD[0] <= 2*best_sad)				if ((!(frame->motion_flags&XVID_ME_SKIP_DELTASEARCH) && (best_sad > 750))					|| (best_sad > 1000))									SearchDirect_final(frame->motion_flags, b_mb, &best_sad, &Data_d);			/* final skip decision */			if ( (skip_sad < 2 * Data_d.iQuant * MAX_SAD00_FOR_SKIP )				&& ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) ) {				Data_d.chromaSAD = 0; /* green light for chroma check */				SkipDecisionB(pMB, &Data_d);								if (pMB->mode == MODE_DIRECT_NONE_MV) { /* skipped? */					pMB->sad16 = skip_sad;					pMB->cbp = 0;					continue;				}			}			if (frame->vop_flags & XVID_VOP_RD_BVOP) 				ModeDecision_BVOP_RD(&Data_d, &Data_b, &Data_f, &Data_i, 					pMB, b_mb, &f_predMV, &b_predMV, frame->motion_flags, pParam, i, j, best_sad);			else				ModeDecision_BVOP_SAD(&Data_d, &Data_b, &Data_f, &Data_i, pMB, b_mb, &f_predMV, &b_predMV);			maxMotionBVOP(&MVmaxF, &MVmaxB, pMB, Data_d.qpel);		}	}	frame->fcode = getMinFcode(MVmaxF);	frame->bcode = getMinFcode(MVmaxB);}

⌨️ 快捷键说明

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