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

📄 estimation_bvop.c

📁 TMS320C6713Xvid视频压缩算法源代码.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
		data->iMinSAD[0] = sad;		data->currentQMV[0].x = x; data->currentQMV[0].y = y;	} else if (sad < data->iMinSAD2) {		data->iMinSAD2 = sad;		data->currentQMV2.x = x; data->currentQMV2.y = y;	}}static __inline VECTORChoosePred(const MACROBLOCK * const pMB, const uint32_t mode){/* the stupidiest function ever */	return (mode == MODE_FORWARD ? pMB->mvs[0] : pMB->b_mvs[0]);}static void __inlinePreparePredictionsBF(VECTOR * const pmv, const int x, const int y,							const uint32_t iWcount,							const MACROBLOCK * const pMB,							const uint32_t mode_curr){	/* [0] is prediction */	pmv[0].x = EVEN(pmv[0].x); pmv[0].y = EVEN(pmv[0].y);	pmv[1].x = pmv[1].y = 0; /* [1] is zero */	pmv[2] = ChoosePred(pMB, mode_curr);	pmv[2].x = EVEN(pmv[2].x); pmv[2].y = EVEN(pmv[2].y);	if ((y != 0)&&(x != (int)(iWcount+1))) {			/* [3] top-right neighbour */		pmv[3] = ChoosePred(pMB+1-iWcount, mode_curr);		pmv[3].x = EVEN(pmv[3].x); pmv[3].y = EVEN(pmv[3].y);	} else pmv[3].x = pmv[3].y = 0;	if (y != 0) {		pmv[4] = ChoosePred(pMB-iWcount, mode_curr);		pmv[4].x = EVEN(pmv[4].x); pmv[4].y = EVEN(pmv[4].y);	} else pmv[4].x = pmv[4].y = 0;	if (x != 0) {		pmv[5] = ChoosePred(pMB-1, mode_curr);		pmv[5].x = EVEN(pmv[5].x); pmv[5].y = EVEN(pmv[5].y);	} else pmv[5].x = pmv[5].y = 0;	if (x != 0 && y != 0) {		pmv[6] = ChoosePred(pMB-1-iWcount, mode_curr);		pmv[6].x = EVEN(pmv[6].x); pmv[6].y = EVEN(pmv[6].y);	} else pmv[6].x = pmv[6].y = 0;}/* search backward or forward */static voidSearchBF(	const IMAGE * const pRef,			const uint8_t * const pRefH,			const uint8_t * const pRefV,			const uint8_t * const pRefHV,			const int x, const int y,			const uint32_t MotionFlags,			const uint32_t iFcode,			const MBParam * const pParam,			MACROBLOCK * const pMB,			const VECTOR * const predMV,			int32_t * const best_sad,			const int32_t mode_current,			SearchData * const Data){	int i;	VECTOR pmv[7];	int threshA = (MotionFlags & XVID_ME_FASTREFINE16) ? 150 : 300;	*Data->iMinSAD = MV_MAX_ERROR;	Data->iFcode = iFcode;	Data->qpel_precision = 0;	Data->chromaX = Data->chromaY = Data->chromaSAD = 256*4096; /* reset chroma-sad cache */	Data->RefP[0] = pRef->y + (x + Data->iEdgedWidth*y) * 16;	Data->RefP[2] = pRefH + (x + Data->iEdgedWidth*y) * 16;	Data->RefP[1] = pRefV + (x + Data->iEdgedWidth*y) * 16;	Data->RefP[3] = pRefHV + (x + Data->iEdgedWidth*y) * 16;	Data->RefP[4] = pRef->u + (x + y * (Data->iEdgedWidth/2)) * 8;	Data->RefP[5] = pRef->v + (x + y * (Data->iEdgedWidth/2)) * 8;	Data->predMV = *predMV;	get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,				pParam->width, pParam->height, iFcode - Data->qpel, 1, 0);	pmv[0] = Data->predMV;	if (Data->qpel) { pmv[0].x /= 2; pmv[0].y /= 2; }	PreparePredictionsBF(pmv, x, y, pParam->mb_width, pMB, mode_current);	Data->currentMV->x = Data->currentMV->y = 0;	/* main loop. checking all predictions */	for (i = 0; i < 7; i++)		if (!vector_repeats(pmv, i) )			CheckCandidate16no4v(pmv[i].x, pmv[i].y, Data, i);	if (*Data->iMinSAD > 512) {		unsigned int mask = make_mask(pmv, 7, Data->dir);		MainSearchFunc *MainSearchPtr;		if (MotionFlags & XVID_ME_USESQUARES16) MainSearchPtr = xvid_me_SquareSearch;		else if (MotionFlags & XVID_ME_ADVANCEDDIAMOND16) MainSearchPtr = xvid_me_AdvDiamondSearch;		else MainSearchPtr = xvid_me_DiamondSearch;				MainSearchPtr(Data->currentMV->x, Data->currentMV->y, Data, mask, CheckCandidate16no4v);	}	xvid_me_SubpelRefine(Data, CheckCandidate16no4v);	if (Data->qpel && (*Data->iMinSAD < *best_sad + threshA)) {		Data->currentQMV->x = 2*Data->currentMV->x;		Data->currentQMV->y = 2*Data->currentMV->y;		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, iFcode, 2, 0);		if (MotionFlags & XVID_ME_QUARTERPELREFINE16) { 			if (MotionFlags & XVID_ME_FASTREFINE16)				SubpelRefine_Fast(Data, CheckCandidate16no4v_qpel);			else				xvid_me_SubpelRefine(Data, CheckCandidate16no4v);		}	}	/* three bits are needed to code backward mode. four for forward */	if (mode_current == MODE_FORWARD) *Data->iMinSAD += 4 * Data->lambda16;	else *Data->iMinSAD += 3 * Data->lambda16;	if (*Data->iMinSAD < *best_sad) {		*best_sad = *Data->iMinSAD;		pMB->mode = mode_current;		if (Data->qpel) {			pMB->pmvs[0].x = Data->currentQMV->x - predMV->x;			pMB->pmvs[0].y = Data->currentQMV->y - predMV->y;			if (mode_current == MODE_FORWARD)				pMB->qmvs[0] = *Data->currentQMV;			else				pMB->b_qmvs[0] = *Data->currentQMV;		} else {			pMB->pmvs[0].x = Data->currentMV->x - predMV->x;			pMB->pmvs[0].y = Data->currentMV->y - predMV->y;		}		if (mode_current == MODE_FORWARD) pMB->mvs[0] = *Data->currentMV;		else pMB->b_mvs[0] = *Data->currentMV;	}	if (mode_current == MODE_FORWARD) *(Data->currentMV+2) = *Data->currentMV;	else *(Data->currentMV+1) = *Data->currentMV; /* we store currmv for interpolate search */}static voidSkipDecisionB(const IMAGE * const pCur,				const IMAGE * const f_Ref,				const IMAGE * const b_Ref,				MACROBLOCK * const pMB,				const uint32_t x, const uint32_t y,				const SearchData * const Data){	int k;	if (!Data->chroma) {		int dx = 0, dy = 0, b_dx = 0, b_dy = 0;		int32_t sum;		const uint32_t stride = Data->iEdgedWidth/2;		/* this is not full chroma compensation, only it's fullpel approximation. should work though */		for (k = 0; k < 4; k++) {			dy += Data->directmvF[k].y >> Data->qpel;			dx += Data->directmvF[k].x >> Data->qpel;			b_dy += Data->directmvB[k].y >> Data->qpel;			b_dx += Data->directmvB[k].x >> Data->qpel;		}		dy = (dy >> 3) + roundtab_76[dy & 0xf];		dx = (dx >> 3) + roundtab_76[dx & 0xf];		b_dy = (b_dy >> 3) + roundtab_76[b_dy & 0xf];		b_dx = (b_dx >> 3) + roundtab_76[b_dx & 0xf];		sum = sad8bi(pCur->u + 8 * x + 8 * y * stride,						f_Ref->u + (y*8 + dy/2) * stride + x*8 + dx/2,						b_Ref->u + (y*8 + b_dy/2) * stride + x*8 + b_dx/2,						stride);		if (sum >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) return; /* no skip */		sum += sad8bi(pCur->v + 8*x + 8 * y * stride,						f_Ref->v + (y*8 + dy/2) * stride + x*8 + dx/2,						b_Ref->v + (y*8 + b_dy/2) * stride + x*8 + b_dx/2,						stride);				if (sum >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) return; /* no skip */	}	/* skip */	pMB->mode = MODE_DIRECT_NONE_MV; /* skipped */	for (k = 0; k < 4; k++) {		pMB->qmvs[k] = pMB->mvs[k] = Data->directmvF[k];		pMB->b_qmvs[k] = pMB->b_mvs[k] =  Data->directmvB[k];	}}static uint32_tSearchDirect(const IMAGE * const f_Ref,				const uint8_t * const f_RefH,				const uint8_t * const f_RefV,				const uint8_t * const f_RefHV,				const IMAGE * const b_Ref,				const uint8_t * const b_RefH,				const uint8_t * const b_RefV,				const uint8_t * const b_RefHV,				const IMAGE * const pCur,				const int x, const int y,				const uint32_t MotionFlags,				const int32_t TRB, const int32_t TRD,				const MBParam * const pParam,				MACROBLOCK * const pMB,				const MACROBLOCK * const b_mb,				int32_t * const best_sad,				SearchData * const Data){	int32_t skip_sad;	int k = (x + Data->iEdgedWidth*y) * 16;	MainSearchFunc *MainSearchPtr;	CheckFunc * CheckCandidate;	*Data->iMinSAD = 256*4096;	Data->RefP[0] = f_Ref->y + k;	Data->RefP[2] = f_RefH + k;	Data->RefP[1] = f_RefV + k;	Data->RefP[3] = f_RefHV + k;	Data->b_RefP[0] = b_Ref->y + k;	Data->b_RefP[2] = b_RefH + k;	Data->b_RefP[1] = b_RefV + k;	Data->b_RefP[3] = b_RefHV + k;	Data->RefP[4] = f_Ref->u + (x + (Data->iEdgedWidth/2) * y) * 8;	Data->RefP[5] = f_Ref->v + (x + (Data->iEdgedWidth/2) * y) * 8;	Data->b_RefP[4] = b_Ref->u + (x + (Data->iEdgedWidth/2) * y) * 8;	Data->b_RefP[5] = b_Ref->v + (x + (Data->iEdgedWidth/2) * y) * 8;	k = Data->qpel ? 4 : 2;	Data->max_dx = k * (pParam->width - x * 16);	Data->max_dy = k * (pParam->height - y * 16);	Data->min_dx = -k * (16 + x * 16);	Data->min_dy = -k * (16 + y * 16);	Data->referencemv = Data->qpel ? b_mb->qmvs : b_mb->mvs;	Data->qpel_precision = 0;	for (k = 0; k < 4; k++) {		pMB->mvs[k].x = Data->directmvF[k].x = ((TRB * Data->referencemv[k].x) / TRD);		pMB->b_mvs[k].x = Data->directmvB[k].x = ((TRB - TRD) * Data->referencemv[k].x) / TRD;		pMB->mvs[k].y = Data->directmvF[k].y = ((TRB * Data->referencemv[k].y) / TRD);		pMB->b_mvs[k].y = Data->directmvB[k].y = ((TRB - TRD) * Data->referencemv[k].y) / TRD;		if ( (pMB->b_mvs[k].x > Data->max_dx) | (pMB->b_mvs[k].x < Data->min_dx)			| (pMB->b_mvs[k].y > Data->max_dy) | (pMB->b_mvs[k].y < Data->min_dy) ) {			*best_sad = 256*4096; /* in that case, we won't use direct mode */			pMB->mode = MODE_DIRECT; /* just to make sure it doesn't say "MODE_DIRECT_NONE_MV" */			pMB->b_mvs[0].x = pMB->b_mvs[0].y = 0;			return 256*4096;		}		if (b_mb->mode != MODE_INTER4V) {			pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mvs[0];			pMB->b_mvs[1] = pMB->b_mvs[2] = pMB->b_mvs[3] = pMB->b_mvs[0];			Data->directmvF[1] = Data->directmvF[2] = Data->directmvF[3] = Data->directmvF[0];			Data->directmvB[1] = Data->directmvB[2] = Data->directmvB[3] = Data->directmvB[0];			break;		}	}	CheckCandidate = b_mb->mode == MODE_INTER4V ? CheckCandidateDirect : CheckCandidateDirectno4v;	CheckCandidate(0, 0, Data, 255);	/* initial (fast) skip decision */	if (*Data->iMinSAD < (int)Data->iQuant * INITIAL_SKIP_THRESH) {		/* possible skip */		SkipDecisionB(pCur, f_Ref, b_Ref, pMB, x, y, Data);		if (pMB->mode == MODE_DIRECT_NONE_MV) return *Data->iMinSAD; /* skipped */	}	skip_sad = *Data->iMinSAD;	if (!(MotionFlags & XVID_ME_SKIP_DELTASEARCH)) {		if (MotionFlags & XVID_ME_USESQUARES16) MainSearchPtr = xvid_me_SquareSearch;			else if (MotionFlags & XVID_ME_ADVANCEDDIAMOND16) MainSearchPtr = xvid_me_AdvDiamondSearch;				else MainSearchPtr = xvid_me_DiamondSearch;		MainSearchPtr(0, 0, Data, 255, CheckCandidate);		xvid_me_SubpelRefine(Data, CheckCandidate);	}	*Data->iMinSAD += Data->lambda16;	*best_sad = *Data->iMinSAD;	if (Data->qpel || b_mb->mode == MODE_INTER4V) pMB->mode = MODE_DIRECT;	else pMB->mode = MODE_DIRECT_NO4V; /* for faster compensation */	pMB->pmvs[3] = *Data->currentMV;	for (k = 0; k < 4; k++) {		pMB->mvs[k].x = Data->directmvF[k].x + Data->currentMV->x;		pMB->b_mvs[k].x = (	(Data->currentMV->x == 0)							? Data->directmvB[k].x							:pMB->mvs[k].x - Data->referencemv[k].x);		pMB->mvs[k].y = (Data->directmvF[k].y + Data->currentMV->y);		pMB->b_mvs[k].y = ((Data->currentMV->y == 0)							? Data->directmvB[k].y							: pMB->mvs[k].y - Data->referencemv[k].y);		if (Data->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;		}	}	return skip_sad;}static void set_range(int * range, SearchData * Data){	Data->min_dx = range[0];	Data->max_dx = range[1];	Data->min_dy = range[2];	Data->max_dy = range[3];}static voidSubpelRefine_dir(SearchData * const data, CheckFunc * const CheckCandidate, const int dir){/* Do a half-pel or q-pel refinement */	const VECTOR centerMV = data->qpel_precision ? 		data->currentQMV[dir-1] : data->currentMV[dir-1];	CHECK_CANDIDATE(centerMV.x, centerMV.y - 1, dir);	CHECK_CANDIDATE(centerMV.x + 1, centerMV.y - 1, dir);	CHECK_CANDIDATE(centerMV.x + 1, centerMV.y, dir);	CHECK_CANDIDATE(centerMV.x + 1, centerMV.y + 1, dir);	CHECK_CANDIDATE(centerMV.x, centerMV.y + 1, dir);	CHECK_CANDIDATE(centerMV.x - 1, centerMV.y + 1, dir);	CHECK_CANDIDATE(centerMV.x - 1, centerMV.y, dir);	CHECK_CANDIDATE(centerMV.x - 1, centerMV.y - 1, dir);}/* Pretty much redundant code, just as SubpelRefine_dir above too * * TODO: Get rid off all the redundancy (SubpelRefine_Fast_dir,  *       CheckCandidate16no4v_qpel etc.)                          */voidSubpelRefine_Fast_dir(SearchData * data, CheckFunc * CheckCandidate, const int dir){/* Do a fast q-pel refinement */	VECTOR centerMV;	VECTOR second_best;	int best_sad = *data->iMinSAD;	int xo, yo, xo2, yo2;	int size = 2;	data->iMinSAD2 = 0;	/* check all halfpixel positions near our best halfpel position */	centerMV = data->currentQMV[dir-1];	*data->iMinSAD = 256 * 4096;	CHECK_CANDIDATE(centerMV.x, centerMV.y - size, dir);	CHECK_CANDIDATE(centerMV.x + size, centerMV.y - size, dir);	CHECK_CANDIDATE(centerMV.x + size, centerMV.y, dir);	CHECK_CANDIDATE(centerMV.x + size, centerMV.y + size, dir);	CHECK_CANDIDATE(centerMV.x, centerMV.y + size, dir);	CHECK_CANDIDATE(centerMV.x - size, centerMV.y + size, dir);

⌨️ 快捷键说明

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