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

📄 estimation_pvop.c

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * *  XVID MPEG-4 VIDEO CODEC *  - Motion Estimation for P- and S- VOPs  - * *  Copyright(C) 2002 Christoph Lampert <gruel@web.de> *               2002 Michael Militzer <michael@xvid.org> *               2002-2003 Radoslaw Czyz <xvid@syskin.cjb.net> * *  This program is free software ; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation ; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY ; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program ; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * * $Id: estimation_pvop.c,v 1.17 2005/03/31 22:14:20 Isibaar Exp $ * ****************************************************************************/#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>	/* memcpy */#include "../encoder.h"#include "../prediction/mbprediction.h"#include "../global.h"#include "../utils/timer.h"#include "../image/interpolate8x8.h"#include "estimation.h"#include "motion.h"#include "sad.h"#include "motion_inlines.h"static const int xvid_me_lambda_vec8[32] =	{     0    ,(int)(1.0 * NEIGH_TEND_8X8 + 0.5),	(int)(2.0*NEIGH_TEND_8X8 + 0.5), (int)(3.0*NEIGH_TEND_8X8 + 0.5),	(int)(4.0*NEIGH_TEND_8X8 + 0.5), (int)(5.0*NEIGH_TEND_8X8 + 0.5),	(int)(6.0*NEIGH_TEND_8X8 + 0.5), (int)(7.0*NEIGH_TEND_8X8 + 0.5),	(int)(8.0*NEIGH_TEND_8X8 + 0.5), (int)(9.0*NEIGH_TEND_8X8 + 0.5),	(int)(10.0*NEIGH_TEND_8X8 + 0.5), (int)(11.0*NEIGH_TEND_8X8 + 0.5),	(int)(12.0*NEIGH_TEND_8X8 + 0.5), (int)(13.0*NEIGH_TEND_8X8 + 0.5),	(int)(14.0*NEIGH_TEND_8X8 + 0.5), (int)(15.0*NEIGH_TEND_8X8 + 0.5),	(int)(16.0*NEIGH_TEND_8X8 + 0.5), (int)(17.0*NEIGH_TEND_8X8 + 0.5),	(int)(18.0*NEIGH_TEND_8X8 + 0.5), (int)(19.0*NEIGH_TEND_8X8 + 0.5),	(int)(20.0*NEIGH_TEND_8X8 + 0.5), (int)(21.0*NEIGH_TEND_8X8 + 0.5),	(int)(22.0*NEIGH_TEND_8X8 + 0.5), (int)(23.0*NEIGH_TEND_8X8 + 0.5),	(int)(24.0*NEIGH_TEND_8X8 + 0.5), (int)(25.0*NEIGH_TEND_8X8 + 0.5),	(int)(26.0*NEIGH_TEND_8X8 + 0.5), (int)(27.0*NEIGH_TEND_8X8 + 0.5),	(int)(28.0*NEIGH_TEND_8X8 + 0.5), (int)(29.0*NEIGH_TEND_8X8 + 0.5),	(int)(30.0*NEIGH_TEND_8X8 + 0.5), (int)(31.0*NEIGH_TEND_8X8 + 0.5)};static voidCheckCandidate16(const int x, const int y, SearchData * const data, const unsigned int Direction){	const uint8_t * Reference;	int32_t sad, xc, yc; uint32_t t;	VECTOR * current;	if ( (x > data->max_dx) || (x < data->min_dx)		|| (y > data->max_dy) || (y < data->min_dy) ) return;	if (data->qpel_precision) { /* x and y are in 1/4 precision */		Reference = xvid_me_interpolate16x16qpel(x, y, 0, data);		current = data->currentQMV;		xc = x/2; yc = y/2;	} else {		Reference = GetReference(x, y, data);		current = data->currentMV;		xc = x; yc = y;	}	sad = sad16v(data->Cur, Reference, data->iEdgedWidth, data->temp);	t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision);	sad += (data->lambda16 * t);	data->temp[0] += (data->lambda8 * t);	if (data->chroma) {		if (sad >= data->iMinSAD[0]) goto no16;		sad += xvid_me_ChromaSAD((xc >> 1) + roundtab_79[xc & 0x3],								(yc >> 1) + roundtab_79[yc & 0x3], data);	}	if (sad < data->iMinSAD[0]) {		data->iMinSAD[0] = sad;		current[0].x = x; current[0].y = y;		data->dir = Direction;	}no16:	if (data->temp[0] < data->iMinSAD[1]) {		data->iMinSAD[1] = data->temp[0]; current[1].x = x; current[1].y = y; }	if (data->temp[1] < data->iMinSAD[2]) {		data->iMinSAD[2] = data->temp[1]; current[2].x = x; current[2].y = y; }	if (data->temp[2] < data->iMinSAD[3]) {		data->iMinSAD[3] = data->temp[2]; current[3].x = x; current[3].y = y; }	if (data->temp[3] < data->iMinSAD[4]) {		data->iMinSAD[4] = data->temp[3]; current[4].x = x; current[4].y = y; }}static voidCheckCandidate8(const int x, const int y, SearchData * const data, const unsigned int Direction){	int32_t sad; uint32_t t;	const uint8_t * Reference;	VECTOR * current;	if ( (x > data->max_dx) || (x < data->min_dx)		|| (y > data->max_dy) || (y < data->min_dy) ) return;	if (!data->qpel_precision) {		Reference = GetReference(x, y, data);		current = data->currentMV;	} else { /* x and y are in 1/4 precision */		Reference = xvid_me_interpolate8x8qpel(x, y, 0, 0, data);		current = data->currentQMV;	}	sad = sad8(data->Cur, Reference, data->iEdgedWidth);	t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision);	sad += (data->lambda8 * t);	if (sad < *(data->iMinSAD)) {		*(data->iMinSAD) = sad;		current->x = x; current->y = y;		data->dir = Direction;	}}intxvid_me_SkipDecisionP(const IMAGE * current, const IMAGE * reference,							const int x, const int y,							const uint32_t stride, const uint32_t iQuant){	int offset = (x + y*stride)*8;	uint32_t sadC = sad8(current->u + offset,					reference->u + offset, stride);	if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP) return 0;	sadC += sad8(current->v + offset,					reference->v + offset, stride);	if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP) return 0;	return 1;}	/*	 * pmv are filled with:	 *  [0]: Median (or whatever is correct in a special case)	 *  [1]: left neighbour	 *  [2]: top neighbour	 *  [3]: topright neighbour	 * psad are filled with:	 *  [0]: minimum of [1] to [3]	 *  [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed)	 *  [2]: top neighbour's SAD	 *  [3]: topright neighbour's SAD	 */static __inline voidget_pmvdata2(const MACROBLOCK * const mbs,		const int mb_width,		const int bound,		const int x,		const int y,		VECTOR * const pmv,		int32_t * const psad){	int lx, ly, lz;		/* left */	int tx, ty, tz;		/* top */	int rx, ry, rz;		/* top-right */	int lpos, tpos, rpos;	int num_cand = 0, last_cand = 1;	lx = x - 1;	ly = y;		lz = 1;	tx = x;		ty = y - 1;	tz = 2;	rx = x + 1;	ry = y - 1;	rz = 2;	lpos = lx + ly * mb_width;	rpos = rx + ry * mb_width;	tpos = tx + ty * mb_width;	if (lpos >= bound && lx >= 0) {		num_cand++;		last_cand = 1;		pmv[1] = mbs[lpos].mvs[lz];		psad[1] = mbs[lpos].sad8[lz];	} else {		pmv[1] = zeroMV;		psad[1] = MV_MAX_ERROR;	}	if (tpos >= bound) {		num_cand++;		last_cand = 2;		pmv[2]= mbs[tpos].mvs[tz];		psad[2] = mbs[tpos].sad8[tz];	} else {		pmv[2] = zeroMV;		psad[2] = MV_MAX_ERROR;	}	if (rpos >= bound && rx < mb_width) {		num_cand++;		last_cand = 3;		pmv[3] = mbs[rpos].mvs[rz];		psad[3] = mbs[rpos].sad8[rz];	} else {		pmv[3] = zeroMV;		psad[3] = MV_MAX_ERROR;	}	/* original pmvdata() compatibility hack */	if (x == 0 && y == 0) {		pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;		psad[0] = 0;		psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;		return;	}	/* if only one valid candidate preictor, the invalid candiates are set to the canidate */	if (num_cand == 1) {		pmv[0] = pmv[last_cand];		psad[0] = psad[last_cand];		return;	}	if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {		pmv[0] = pmv[1];		psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);		return;	}	/* set median, minimum */	pmv[0].x =		MIN(MAX(pmv[1].x, pmv[2].x),			MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));	pmv[0].y =		MIN(MAX(pmv[1].y, pmv[2].y),			MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));	psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);}static voidModeDecision_SAD(SearchData * const Data,				MACROBLOCK * const pMB,				const MACROBLOCK * const pMBs,				const int x, const int y,				const MBParam * const pParam,				const uint32_t MotionFlags,				const uint32_t VopFlags,				const uint32_t VolFlags,				const IMAGE * const pCurrent,				const IMAGE * const pRef,				const IMAGE * const vGMC,				const int coding_type,				const int skip_sad){	int mode = MODE_INTER;	int mcsel = 0;	int inter4v = (VopFlags & XVID_VOP_INTER4V) && (pMB->dquant == 0);	const uint32_t iQuant = pMB->quant;	const int skip_possible = (coding_type == P_VOP) && (pMB->dquant == 0);	int sad;	int InterBias = MV16_INTER_BIAS;	pMB->mcsel = 0;	if (inter4v == 0 || Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] +		Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant) {		mode = MODE_INTER;		sad = Data->iMinSAD[0];	} else {		mode = MODE_INTER4V;		sad = Data->iMinSAD[1] + Data->iMinSAD[2] +					Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant;		Data->iMinSAD[0] = sad;	}	/* final skip decision, a.k.a. "the vector you found, really that good?" */	if (skip_possible && (skip_sad < (int)iQuant * MAX_SAD00_FOR_SKIP))		if ( (100*skip_sad)/(pMB->sad16+1) > FINAL_SKIP_THRESH)			if (Data->chroma || xvid_me_SkipDecisionP(pCurrent, pRef, x, y, Data->iEdgedWidth/2, iQuant)) {				mode = MODE_NOT_CODED;				sad = 0;			}	/* mcsel */	if (coding_type == S_VOP) {		int32_t iSAD = sad16(Data->Cur,			vGMC->y + 16*y*Data->iEdgedWidth + 16*x, Data->iEdgedWidth, 65536);		if (Data->chroma) {			iSAD += sad8(Data->CurU, vGMC->u + 8*y*(Data->iEdgedWidth/2) + 8*x, Data->iEdgedWidth/2);			iSAD += sad8(Data->CurV, vGMC->v + 8*y*(Data->iEdgedWidth/2) + 8*x, Data->iEdgedWidth/2);		}		if (iSAD <= sad) {		/* mode decision GMC */			mode = MODE_INTER;			mcsel = 1;			sad = iSAD;		}	}

⌨️ 快捷键说明

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