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

📄 motion_est.c

📁 mpeg4代码,比较具体
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * *  XVID MPEG-4 VIDEO CODEC *  - Motion Estimation module - * *  Copyright(C) 2002 Christoph Lampert <gruel@web.de> *               2002 Michael Militzer <michael@xvid.org> * *  This file is part of XviD, a free MPEG-4 video encoder/decoder * *  XviD 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 * *  Under section 8 of the GNU General Public License, the copyright *  holders of XVID explicitly forbid distribution in the following *  countries: * *    - Japan *    - United States of America * *  Linking XviD statically or dynamically with other modules is making a *  combined work based on XviD.  Thus, the terms and conditions of the *  GNU General Public License cover the whole combination. * *  As a special exception, the copyright holders of XviD give you *  permission to link XviD with independent modules that communicate with *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the *  license terms of these independent modules, and to copy and distribute *  the resulting combined work under terms of your choice, provided that *  every copy of the combined work is accompanied by a complete copy of *  the source code of XviD (the version of XviD used to produce the *  combined work), being distributed under the terms of the GNU General *  Public License plus this exception.  An independent module is a module *  which is not derived from or based on XviD. * *  Note that people who make modified versions of XviD are not obligated *  to grant this special exception for their modified versions; it is *  their choice whether to do so.  The GNU General Public License gives *  permission to release a modified version without this exception; this *  exception also makes it possible to release a modified version which *  carries forward this exception. * * $Id: motion_est.c,v 1.54 2002/11/26 23:44:10 edgomez Exp $ * *************************************************************************/#include <assert.h>#include <stdio.h>#include <stdlib.h>#include "../encoder.h"#include "../utils/mbfunctions.h"#include "../prediction/mbprediction.h"#include "../global.h"#include "../utils/timer.h"#include "motion.h"#include "sad.h"static int32_t lambda_vec16[32] =	/* rounded values for lambda param for weight of motion bits as in modified H.26L */{ 0, (int) (1.00235 + 0.5), (int) (1.15582 + 0.5), (int) (1.31976 + 0.5),		(int) (1.49591 + 0.5), (int) (1.68601 + 0.5),	(int) (1.89187 + 0.5), (int) (2.11542 + 0.5), (int) (2.35878 + 0.5),		(int) (2.62429 + 0.5), (int) (2.91455 + 0.5),	(int) (3.23253 + 0.5), (int) (3.58158 + 0.5), (int) (3.96555 + 0.5),		(int) (4.38887 + 0.5), (int) (4.85673 + 0.5),	(int) (5.37519 + 0.5), (int) (5.95144 + 0.5), (int) (6.59408 + 0.5),		(int) (7.31349 + 0.5), (int) (8.12242 + 0.5),	(int) (9.03669 + 0.5), (int) (10.0763 + 0.5), (int) (11.2669 + 0.5),		(int) (12.6426 + 0.5), (int) (14.2493 + 0.5),	(int) (16.1512 + 0.5), (int) (18.442 + 0.5), (int) (21.2656 + 0.5),		(int) (24.8580 + 0.5), (int) (29.6436 + 0.5),	(int) (36.4949 + 0.5)};static int32_t *lambda_vec8 = lambda_vec16;	/* same table for INTER and INTER4V for now *//* mv.length table */static const uint32_t mvtab[33] = {	1, 2, 3, 4, 6, 7, 7, 7,	9, 9, 9, 10, 10, 10, 10, 10,	10, 10, 10, 10, 10, 10, 10, 10,	10, 11, 11, 11, 11, 11, 11, 12, 12};static __inline uint32_tmv_bits(int32_t component,		const uint32_t iFcode){	if (component == 0)		return 1;	if (component < 0)		component = -component;	if (iFcode == 1) {		if (component > 32)			component = 32;		return mvtab[component] + 1;	}	component += (1 << (iFcode - 1)) - 1;	component >>= (iFcode - 1);	if (component > 32)		component = 32;	return mvtab[component] + 1 + iFcode - 1;}static __inline uint32_tcalc_delta_16(const int32_t dx,			  const int32_t dy,			  const uint32_t iFcode,			  const uint32_t iQuant){	return NEIGH_TEND_16X16 * lambda_vec16[iQuant] * (mv_bits(dx, iFcode) +													  mv_bits(dy, iFcode));}static __inline uint32_tcalc_delta_8(const int32_t dx,			 const int32_t dy,			 const uint32_t iFcode,			 const uint32_t iQuant){	return NEIGH_TEND_8X8 * lambda_vec8[iQuant] * (mv_bits(dx, iFcode) +												   mv_bits(dy, iFcode));} boolMotionEstimation(MBParam * const pParam,				 FRAMEINFO * const current,				 FRAMEINFO * const reference,				 const IMAGE * const pRefH,				 const IMAGE * const pRefV,				 const IMAGE * const pRefHV,				 const uint32_t iLimit){	const uint32_t iWcount = pParam->mb_width;	const uint32_t iHcount = pParam->mb_height;	MACROBLOCK *const pMBs = current->mbs;	MACROBLOCK *const prevMBs = reference->mbs;	const IMAGE *const pCurrent = &current->image;	const IMAGE *const pRef = &reference->image;	static const VECTOR zeroMV = { 0, 0 };	VECTOR predMV;	uint32_t x, y;	uint32_t iIntra = 0;	VECTOR pmv;	if (sadInit)		(*sadInit) ();	for (y = 0; y < iHcount; y++)	{		for (x = 0; x < iWcount; x ++)	{				MACROBLOCK *const pMB = &pMBs[x + y * iWcount];			predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);    			pMB->sad16 =				SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, 						 x, y, predMV.x, predMV.y, predMV.x, predMV.y, 						 current->motion_flags, current->quant,						 current->fcode, pParam, pMBs, prevMBs, &pMB->mv16,						 &pMB->pmvs[0]);			if (0 < (pMB->sad16 - MV16_INTER_BIAS)) {				int32_t deviation;				deviation =					dev16(pCurrent->y + x * 16 + y * 16 * pParam->edged_width,						  pParam->edged_width);				if (deviation < (pMB->sad16 - MV16_INTER_BIAS)) {					pMB->mode = MODE_INTRA;					pMB->mv16 = pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] =						pMB->mvs[3] = zeroMV;					pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] =						pMB->sad8[3] = 0;					iIntra++;					if (iIntra >= iLimit)						return 1;					continue;				}			}			pmv = pMB->pmvs[0];			if (current->global_flags & XVID_INTER4V)				if ((!(current->global_flags & XVID_LUMIMASKING) ||					 pMB->dquant == NO_CHANGE)) {					int32_t sad8 = IMV16X16 * current->quant;					if (sad8 < pMB->sad16) {						sad8 += pMB->sad8[0] =							SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,									pCurrent, 2 * x, 2 * y, 									pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y, 									current->motion_flags,									current->quant, current->fcode, pParam,									pMBs, prevMBs, &pMB->mvs[0],									&pMB->pmvs[0]);					}					if (sad8 < pMB->sad16) {						predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 1);    						sad8 += pMB->sad8[1] =							SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,									pCurrent, 2 * x + 1, 2 * y,									pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y, 									current->motion_flags,									current->quant, current->fcode, pParam,									pMBs, prevMBs, &pMB->mvs[1],									&pMB->pmvs[1]);					}					if (sad8 < pMB->sad16) {						predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 2);    						sad8 += pMB->sad8[2] =							SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,									pCurrent, 2 * x, 2 * y + 1, 									pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y, 									current->motion_flags,									current->quant, current->fcode, pParam,									pMBs, prevMBs, &pMB->mvs[2],									&pMB->pmvs[2]);					}					if (sad8 < pMB->sad16) {						predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 3);  						sad8 += pMB->sad8[3] =							SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,									pCurrent, 2 * x + 1, 2 * y + 1,									pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y, 									current->motion_flags, 									current->quant, current->fcode, pParam, 									pMBs, prevMBs,									&pMB->mvs[3], 									&pMB->pmvs[3]);					}										/* decide: MODE_INTER or MODE_INTER4V					   mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v					 */					if (sad8 < pMB->sad16) {						pMB->mode = MODE_INTER4V;						pMB->sad8[0] *= 4;						pMB->sad8[1] *= 4;						pMB->sad8[2] *= 4;						pMB->sad8[3] *= 4;						continue;					}				}			pMB->mode = MODE_INTER;			pMB->pmvs[0] = pmv;	/* pMB->pmvs[1] = pMB->pmvs[2] = pMB->pmvs[3]  are not needed for INTER */			pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;			pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] =				pMB->sad16;			}			}	return 0;}#define CHECK_MV16_ZERO {\  if ( (0 <= max_dx) && (0 >= min_dx) \    && (0 <= max_dy) && (0 >= min_dy) ) \  { \    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \    iSAD += calc_delta_16(-center_x, -center_y, (uint8_t)iFcode, iQuant);\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }	\}#define NOCHECK_MV16_CANDIDATE(X,Y) { \    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \}#define CHECK_MV16_CANDIDATE(X,Y) { \  if ( ((X) <= max_dx) && ((X) >= min_dx) \    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  { \    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \}#define CHECK_MV16_CANDIDATE_DIR(X,Y,D) { \  if ( ((X) <= max_dx) && ((X) >= min_dx) \    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  { \    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \}#define CHECK_MV16_CANDIDATE_FOUND(X,Y,D) { \  if ( ((X) <= max_dx) && ((X) >= min_dx) \    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  { \    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \}#define CHECK_MV8_ZERO {\  iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \  iSAD += calc_delta_8(-center_x, -center_y, (uint8_t)iFcode, iQuant);\  if (iSAD < iMinSAD) \  { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \}#define NOCHECK_MV8_CANDIDATE(X,Y) \  { \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \    iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \}#define CHECK_MV8_CANDIDATE(X,Y) { \  if ( ((X) <= max_dx) && ((X) >= min_dx) \    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  { \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \    iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \}#define CHECK_MV8_CANDIDATE_DIR(X,Y,D) { \  if ( ((X) <= max_dx) && ((X) >= min_dx) \    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  { \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \    iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \}#define CHECK_MV8_CANDIDATE_FOUND(X,Y,D) { \  if ( ((X) <= max_dx) && ((X) >= min_dx) \    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  { \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \    iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \}#if 0/* too slow and not fully functional at the moment */int32_t ZeroSearch16(					const uint8_t * const pRef,					const uint8_t * const pRefH,					const uint8_t * const pRefV,					const uint8_t * const pRefHV,					const IMAGE * const pCur,					const int x, const int y,					const uint32_t MotionFlags, 									const uint32_t iQuant,					const uint32_t iFcode,					MBParam * const pParam,					const MACROBLOCK * const pMBs,									const MACROBLOCK * const prevMBs,					VECTOR * const currMV,					VECTOR * const currPMV){	const int32_t iEdgedWidth = pParam->edged_width; 	const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;	int32_t iSAD;	VECTOR pred;		pred = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);    	iSAD = sad16( cur, 		get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0,0, iEdgedWidth),		iEdgedWidth, MV_MAX_ERROR);	if (iSAD <= iQuant * 96)		   	iSAD -= MV16_00_BIAS; 	currMV->x = 0;	currMV->y = 0;	currPMV->x = -pred.x;	currPMV->y = -pred.y;	return iSAD;}#endif /* 0 */int32_tDiamond16_MainSearch(const uint8_t * const pRef,					 const uint8_t * const pRefH,					 const uint8_t * const pRefV,					 const uint8_t * const pRefHV,					 const uint8_t * const cur,					 const int x,					 const int y,					 const int start_x,					 const int start_y,					 int iMinSAD,					 VECTOR * const currMV,

⌨️ 快捷键说明

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