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

📄 estimation_bvop.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
			int32_t * const best_sad,
			const int32_t mode_current,
			SearchData * const Data,
			VECTOR hint)
{

	int i;
	VECTOR pmv[7];
	*Data->iMinSAD = MV_MAX_ERROR;
	Data->qpel_precision = 0;

	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);

	pmv[0] = Data->predMV;
	if (Data->qpel) { 
		pmv[0].x /= 2; pmv[0].y /= 2; 
		hint.x /= 2; hint.y /= 2;
	}

	PreparePredictionsBF(pmv, x, y, pParam->mb_width, pMB, mode_current, hint);

	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);
	}

	if (Data->iMinSAD[0] < *best_sad) *best_sad = Data->iMinSAD[0];
}

static void
SearchBF_final(const int x, const int y,
			const uint32_t MotionFlags,
			const MBParam * const pParam,
			int32_t * const best_sad,
			SearchData * const Data)
{
	if(!Data->qpel) {
		/* halfpel mode */
		if (MotionFlags & XVID_ME_HALFPELREFINE16)
				xvid_me_SubpelRefine(Data->currentMV[0], Data, CheckCandidate16no4v, 0);
	} else {
		/* qpel mode */
		if(MotionFlags & XVID_ME_FASTREFINE16) {
			/* fast */
			get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,
						pParam->width, pParam->height, Data->iFcode, 2);
			FullRefine_Fast(Data, CheckCandidate16no4v, 0);

		} else {

			Data->currentQMV->x = 2*Data->currentMV->x;
			Data->currentQMV->y = 2*Data->currentMV->y;
			if(MotionFlags & XVID_ME_QUARTERPELREFINE16) {
				/* full */
				if (MotionFlags & XVID_ME_HALFPELREFINE16) {
					xvid_me_SubpelRefine(Data->currentMV[0], Data, CheckCandidate16no4v, 0); /* hpel part */
					Data->currentQMV->x = 2*Data->currentMV->x;
					Data->currentQMV->y = 2*Data->currentMV->y;
				}
				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->qpel_precision = 1;
				xvid_me_SubpelRefine(Data->currentQMV[0], Data, CheckCandidate16no4v, 0); /* qpel part */
			}
		}
	}
	if (Data->iMinSAD[0] < *best_sad) *best_sad = Data->iMinSAD[0];

}

static void
SkipDecisionB(MACROBLOCK * const pMB, 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(Data->CurU,
						Data->RefP[4] + (dy/2) * (int)stride + dx/2,
						Data->b_RefP[4] + (b_dy/2) * (int)stride + b_dx/2,
						stride);

		if (sum >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) return; /* no skip */

		sum += sad8bi(Data->CurV,
						Data->RefP[5] + (dy/2) * (int)stride + dx/2,
						Data->b_RefP[5] + (b_dy/2) * (int)stride + b_dx/2,
						stride);

		if (sum >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) return; /* no skip */
	} else {
		int sum = Data->chromaSAD; /* chroma-sad SAD caching keeps it there */

		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];
		if (Data->qpel) {
			pMB->mvs[k].x /= 2; pMB->mvs[k].y /= 2; /* it's a hint for future searches */
			pMB->b_mvs[k].x /= 2; pMB->b_mvs[k].y /= 2;
		}
	}
}

static uint32_t
SearchDirect_initial(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;

	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;

	for (k = 0; k < 4; k++) {
		Data->directmvF[k].x = ((TRB * Data->referencemv[k].x) / TRD);
		Data->directmvB[k].x = ((TRB - TRD) * Data->referencemv[k].x) / TRD;
		Data->directmvF[k].y = ((TRB * Data->referencemv[k].y) / TRD);
		Data->directmvB[k].y = ((TRB - TRD) * Data->referencemv[k].y) / TRD;

		if ( (Data->directmvB[k].x > Data->max_dx) | (Data->directmvB[k].x < Data->min_dx)
			| (Data->directmvB[k].y > Data->max_dy) | (Data->directmvB[k].y < Data->min_dy) ) {

			Data->iMinSAD[0] = *best_sad = 256*4096; /* in that case, we won't use direct mode */
			return 256*4096;
		}
		if (b_mb->mode != MODE_INTER4V) {
			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;
		}
	}
	Data->qpel_precision = Data->qpel; /* this initial check is done with full precision, to find real 
											SKIP sad */

	CheckCandidateDirect(0, 0, Data, 255);	/* will also fill iMinSAD[1..4] with 8x8 SADs */

	/* initial (fast) skip decision */
	if (Data->iMinSAD[1] < (int)Data->iQuant * INITIAL_SKIP_THRESH
		&& Data->iMinSAD[2] < (int)Data->iQuant * INITIAL_SKIP_THRESH
		&& Data->iMinSAD[3] < (int)Data->iQuant * INITIAL_SKIP_THRESH
		&& Data->iMinSAD[4] < (int)Data->iQuant * INITIAL_SKIP_THRESH) {
		/* possible skip */
		SkipDecisionB(pMB, Data);
		if (pMB->mode == MODE_DIRECT_NONE_MV)
			return *Data->iMinSAD; /* skipped */
	}

	if (Data->chroma && Data->chromaSAD >= MAX_CHROMA_SAD_FOR_SKIP * (int)Data->iQuant) /* chroma doesn't allow skip */
		skip_sad = 256*4096;
	else
		skip_sad = 4*MAX(MAX(Data->iMinSAD[1],Data->iMinSAD[2]), MAX(Data->iMinSAD[3],Data->iMinSAD[4]));

	Data->currentMV[1].x = Data->directmvF[0].x + Data->currentMV->x; /* hints for forward and backward searches */
	Data->currentMV[1].y = Data->directmvF[0].y + Data->currentMV->y;

	Data->currentMV[2].x = ((Data->currentMV->x == 0) ?
			Data->directmvB[0].x
			: Data->currentMV[1].x - Data->referencemv[0].x);

	Data->currentMV[2].y = ((Data->currentMV->y == 0) ?
			Data->directmvB[0].y
			: Data->currentMV[1].y - Data->referencemv[0].y);

	*best_sad = Data->iMinSAD[0];

	return skip_sad;
}

static void
SearchDirect_final( const uint32_t MotionFlags,
					const MACROBLOCK * const b_mb,
					int32_t * const best_sad,
					SearchData * const Data)

{
	CheckFunc * CheckCandidate = b_mb->mode == MODE_INTER4V ? 
									CheckCandidateDirect : CheckCandidateDirectno4v;
	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;

	Data->qpel_precision = 0;
	MainSearchPtr(0, 0, Data, 255, CheckCandidate);

	Data->qpel_precision = Data->qpel;
	if(Data->qpel) {
		*Data->iMinSAD = 256*4096; /* this old SAD was not real, it was in hpel precision */
		CheckCandidate(Data->currentMV->x, Data->currentMV->y, Data, 255);
	}

	xvid_me_SubpelRefine(Data->currentMV[0], Data, CheckCandidate, 0);

	if (Data->iMinSAD[0] < *best_sad) {
		*best_sad = Data->iMinSAD[0];
	}
		
}


static __inline 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 void
SearchInterpolate_initial(
				const int x, const int y,
				const uint32_t MotionFlags,
				const MBParam * const pParam,
				const VECTOR * const f_predMV,
				const VECTOR * const b_predMV,
				int32_t * const best_sad,
				SearchData * const Data,
				const VECTOR startF,
				const VECTOR startB)

{
	int b_range[4], f_range[4];

	Data->qpel_precision = 0;

	Data->predMV = *f_predMV;
	Data->bpredMV = *b_predMV;

	Data->currentMV[0] = startF;
	Data->currentMV[1] = startB;

	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);

	if (Data->currentMV[0].x > f_range[1]) Data->currentMV[0].x = f_range[1];
	if (Data->currentMV[0].x < f_range[0]) Data->currentMV[0].x = f_range[0];
	if (Data->currentMV[0].y > f_range[3]) Data->currentMV[0].y = f_range[3];
	if (Data->currentMV[0].y < f_range[2]) Data->currentMV[0].y = f_range[2];

	if (Data->currentMV[1].x > b_range[1]) Data->currentMV[1].x = b_range[1];
	if (Data->currentMV[1].x < b_range[0]) Data->currentMV[1].x = b_range[0];
	if (Data->currentMV[1].y > b_range[3]) Data->currentMV[1].y = b_range[3];
	if (Data->currentMV[1].y < b_range[2]) Data->currentMV[1].y = b_range[2];

	set_range(f_range, Data);

	CheckCandidateInt(Data->currentMV[0].x, Data->currentMV[0].y, Data, 1);

	if (Data->iMinSAD[0] < *best_sad) *best_sad = Data->iMinSAD[0];
}

static void
SearchInterpolate_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;

⌨️ 快捷键说明

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