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

📄 main.cpp

📁 H.264运动搜索算法代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"
#include "string.h"
#include "sys/timeb.h"
#include "math.h"
#include "inf.h"
#define MIN(a,b) ((a)<(b))?(a):(b);
#define MAX(a,b) ((a)>(b))?(a):(b);
int SAD(const int ox,const int oy,const int dx,const int dy,const int height,const int width,uint32 &best_sad)
{
	const int rx=ox+dx,ry=oy+dy;
	if( abs(dx)>MAX_MOTION || abs(dy)>MAX_MOTION || flag_search[dx][dy]>0 )
		return 0;
	if( rx<0 || ry<0 || rx+height>XX || ry+width>YY )
		return 0;
	uint32 sad=0;
	frame_info.frame_pot++;
	const uint8 *p1=&current_frame[ox][oy],*p2=&ref_frame[rx][ry];
	for(int i=0;i<height;i++)
	{
		for(int j=0;j<width;j++)
		{
			sad+=abs(*(p1++)-*(p2++));
		}
		p1+=(YY-width);p2+=(YY-width);
	}
	flag_search[dx][dy]=1+sad;
	if(sad>=best_sad)
		return 0;
	best_sad=sad;
	return 1;
}
void rebuilt(const int x,const int y,const int height,const int width)
{
	const int dx=frame_info.mv[x][y].dx,dy=frame_info.mv[x][y].dy;
	const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
	const int rx=ox+dx,ry=oy+dy;
	int tmp;
	const uint8 *p1=&current_frame[ox][oy],*p2=&ref_frame[rx][ry];
	if( abs(dx)>MAX_MOTION || abs(dy)>MAX_MOTION )
		exit(0);
	if( rx<0 || ry<0 || rx+height>XX || ry+width>YY )
		exit(0);
	for(int i=0;i<height;i++)
	{
		for(int j=0;j<width;j++)
		{
			tmp=*(p1++)-*(p2++);
			frame_info.frame_sse+=tmp*tmp;
		}
		p1+=(YY-width);p2+=(YY-width);	
	}
}
void search_FS(const int x,const int y,const int heigth,const int width)
{
	const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
	uint32 sad=0xffffff;
	MV mv;
	for(int i=-MAX_MOTION;i<=MAX_MOTION;i++)
	{
		for(int j=-MAX_MOTION;j<=MAX_MOTION;j++)
		{
			if(SAD(ox,oy,i,j,heigth,width,sad)==1)
			{
				mv.dx=i;mv.dy=j;
			}
		}
	}
	frame_info.mv[x][y]=mv;
	frame_info.sad[x][y]=sad;
	frame_info.frame_sad+=sad;
}
#define PATTERN_SEARCH(pattern,num,flag) \
	do\
	{\
		mvx=mv.dx;mvy=mv.dy;\
		for(int i=0;i<num;i++)\
		{\
			if(SAD(ox,oy,mvx+pattern[i][0],mvy+pattern[i][1],heigth,width,sad)==1)\
			{\
				mv.dx=mvx+pattern[i][0];mv.dy=mvy+pattern[i][1];\
			}\
		}\
	}while ( (mv.dx!=mvx || mv.dy!=mvy) && flag==1 );
void search_4SS(const int x,const int y,const int heigth,const int width)
{
	const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
	const int L4SS[9][2]={{0,0},{0,2},{-2,2},{-2,0},{-2,-2},{0,-2},{2,-2},{2,0},{2,2}};
	const int S4SS[9][2]={{0,0},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};
	uint32 sad=0xffffff;
	MV mv={0,0};int mvx,mvy;

	PATTERN_SEARCH(L4SS,9,1)
	PATTERN_SEARCH(S4SS,9,0)

	frame_info.mv[x][y]=mv;
	frame_info.sad[x][y]=sad;
	frame_info.frame_sad+=sad;
}
void search_BBGDS(const int x,const int y,const int heigth,const int width)
{
	const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
	const int BBGDS[9][2]={{0,0},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};
	uint32 sad=0xffffff;
	MV mv={0,0};int mvx,mvy;

	PATTERN_SEARCH(BBGDS,9,1)

	frame_info.mv[x][y]=mv;
	frame_info.sad[x][y]=sad;
	frame_info.frame_sad+=sad;
}
void search_DS(const int x,const int y,const int heigth,const int width)
{
	const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
	const int LDS[9][2]={{0,0},{0,2},{-1,1},{-2,0},{-1,-1},{0,-2},{1,-1},{2,0},{1,1}};
	const int SDS[5][2]={{0,0},{0,1},{-1,0},{0,-1},{1,0}};
	uint32 sad=0xffffff;
	MV mv={0,0};int mvx,mvy;

	PATTERN_SEARCH(LDS,9,1)
	PATTERN_SEARCH(SDS,5,0)

	frame_info.mv[x][y]=mv;
	frame_info.sad[x][y]=sad;
	frame_info.frame_sad+=sad;
}
void search_HS(const int x,const int y,const int heigth,const int width)
{
	const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
	const int LHS[7][2]={{0,0},{0,2},{-2,1},{-2,-1},{0,-2},{2,-1},{2,1}};
	const int SHS[9][2]={{0,0},{0,1},{-1,0},{0,-1},{1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
	uint32 sad=0xffffff;
	MV mv={0,0};int mvx,mvy;

	PATTERN_SEARCH(LHS,7,1)
	PATTERN_SEARCH(SHS,9,0)

	frame_info.mv[x][y]=mv;
	frame_info.sad[x][y]=sad;
	frame_info.frame_sad+=sad;
}
#define CHECK_ONE_PIXEL(i,j) \
	if(SAD(ox,oy,i,j,heigth,width,sad)==1)\
	{\
		mv.dx=i;mv.dy=j;\
	}
int x264_median( int a, int b, int c=0 )
{
    int min = a, max =a;
    if( b < min )
        min = b;
    else
        max = b;

    if( c < min )
        min = c;
    else if( c > max )
        max = c;

    return a + b + c - min - max;
}

//获取常用的预测运动矢量列表
void Get_MVp(const int x,const int y,MV *pre_mv,int &mvx,int &mvy,uint32 *sad=NULL)
{
	uint32 num[10];if(sad==NULL) sad=num;
	if(y>0)
	{
		pre_mv[0]=frame_info.mv[x][y-1];
		sad[0]=frame_info.sad[x][y-1];
	}
	else
	{
		pre_mv[0].dx=pre_mv[0].dy=0;
		sad[0]=0;
	}
	if(x>0)
	{
		pre_mv[1]=frame_info.mv[x-1][y];
		sad[1]=frame_info.sad[x-1][y];
	}
	else
	{
		pre_mv[1].dx=pre_mv[1].dy=0;
		sad[1]=0;
	}
	if(x>0 && y<Y-1)
	{
		pre_mv[2]=frame_info.mv[x-1][y+1];
		sad[2]=frame_info.sad[x-1][y+1];
	}
	else if(x>0)
	{
		pre_mv[2]=frame_info.mv[x-1][y-1];
		sad[2]=frame_info.sad[x-1][y-1];
	}
	else
	{
		pre_mv[2].dx=pre_mv[2].dy=0;
		sad[2]=0;
	}
	if(x>0&&y>0)
	{
		pre_mv[3]=frame_info.mv[x-1][y-1];
		sad[3]=frame_info.sad[x-1][y-1];
	}
	else
	{
		pre_mv[3].dx=pre_mv[3].dy=0;
		sad[3]=0;
	}

	pre_mv[4]=frame_info.prev_mv[x][y];
	sad[4]=frame_info.prev_sad[x][y];

	pre_mv[5].dx=2*frame_info.prev_mv[x][y].dx-frame_info.mv[x][y].dx;
	pre_mv[5].dy=2*frame_info.prev_mv[x][y].dy-frame_info.mv[x][y].dy;

	if(x==0)
	{
		mvx=pre_mv[0].dx;
		mvy=pre_mv[0].dy;
		return;
	}
	mvx=x264_median(pre_mv[0].dx,pre_mv[1].dx,pre_mv[2].dx);
	mvy=x264_median(pre_mv[0].dy,pre_mv[1].dy,pre_mv[2].dy);
}
void search_ARPS(const int x,const int y,const int heigth,const int width)
{
	const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
	const int SCS[5][2]={{0,0},{0,1},{-1,0},{0,-1},{1,0}};
	uint32 sad=0xffffff;
	MV mv={0,0},pre_mv[10];int mvx,mvy;
	const uint32 T=512;
	
	CHECK_ONE_PIXEL(0,0)
	if(sad<T)	goto END;
	{
		Get_MVp(x,y,pre_mv,mvx,mvy);
		int Length=abs(pre_mv[0].dx)>abs(pre_mv[0].dy)?abs(pre_mv[0].dx):abs(pre_mv[0].dy);
		CHECK_ONE_PIXEL(mvx,mvy)
		CHECK_ONE_PIXEL( Length,0)
		CHECK_ONE_PIXEL(-Length,0)
		CHECK_ONE_PIXEL(0, Length)
		CHECK_ONE_PIXEL(0,-Length)
	}
	PATTERN_SEARCH(SCS,5,1)
END:
	frame_info.mv[x][y]=mv;
	frame_info.sad[x][y]=sad;
	frame_info.frame_sad+=sad;
}
void search_ARPS3(const int x,const int y,const int heigth,const int width)
{
	const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
	const int SCS[5][2]={{0,0},{0,1},{-1,0},{0,-1},{1,0}};
	uint32 sad=0xffffff;
	MV mv={0,0},pre_mv[10];int mvx,mvy;
	const uint32 T=512;
	
	CHECK_ONE_PIXEL(0,0)
	if(sad<T)	goto END;
	{
		Get_MVp(x,y,pre_mv,mvx,mvy);
		int max_x=MAX(pre_mv[0].dx,pre_mv[1].dx);max_x=MAX(max_x,pre_mv[2].dx)max_x=MAX(max_x,pre_mv[3].dx);
		int max_y=MAX(pre_mv[0].dy,pre_mv[1].dy);max_y=MAX(max_y,pre_mv[2].dy)max_y=MAX(max_y,pre_mv[3].dy);
		int min_x=MIN(pre_mv[0].dx,pre_mv[1].dx);min_x=MIN(min_x,pre_mv[2].dx)min_x=MIN(min_x,pre_mv[3].dx);
		int min_y=MIN(pre_mv[0].dy,pre_mv[1].dy);min_y=MIN(min_y,pre_mv[2].dy)min_y=MIN(min_y,pre_mv[3].dy);
		CHECK_ONE_PIXEL(mvx,mvy)
		CHECK_ONE_PIXEL( max_x,mvy)
		CHECK_ONE_PIXEL( min_x,mvy)
		CHECK_ONE_PIXEL( mvx,max_y)
		CHECK_ONE_PIXEL( mvx,min_y)
	}
	PATTERN_SEARCH(SCS,5,1)
END:
	frame_info.mv[x][y]=mv;
	frame_info.sad[x][y]=sad;
	frame_info.frame_sad+=sad;
}
int Get_Mv_Length(int x,int y,MV *pre_mv,int mvx=0,int mvy=0)
{
	if(x==0&&y==0)
		return 2;
	int L=0,num;
	num=abs(pre_mv[0].dx-mvx)+abs(pre_mv[0].dy-mvy);
	if(L<num)L=num;
	num=abs(pre_mv[1].dx-mvx)+abs(pre_mv[1].dy-mvy);
	if(L<num)L=num;
	num=abs(pre_mv[2].dx-mvx)+abs(pre_mv[2].dy-mvy);
	if(L<num)L=num;
	return L;
}
void search_MVFAST(const int x,const int y,const int heigth,const int width)
{
	const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
	const int LDS[9][2]={{0,0},{0,2},{-1,1},{-2,0},{-1,-1},{0,-2},{1,-1},{2,0},{1,1}};
	const int SDS[5][2]={{0,0},{0,1},{-1,0},{0,-1},{1,0}};
	uint32 sad=0xffffff;
	MV mv={0,0},pre_mv[10];int mvx,mvy;
	const uint32 T=512,L1=1,L2=2;
	
	CHECK_ONE_PIXEL(0,0)
	if(sad<T)	goto END;
	{
		Get_MVp(x,y,pre_mv,mvx,mvy);
		int L=Get_Mv_Length(x,y,pre_mv);
		if(L<=L1)goto SMALL_SEARCH;
		if(L>L2)
		{
//			CHECK_ONE_PIXEL(mvx,mvy)
			CHECK_ONE_PIXEL(pre_mv[0].dx,pre_mv[0].dy)
			CHECK_ONE_PIXEL(pre_mv[1].dx,pre_mv[1].dy)
			CHECK_ONE_PIXEL(pre_mv[2].dx,pre_mv[2].dy)
			goto SMALL_SEARCH;
		}
	}
	PATTERN_SEARCH(LDS,9,1)
SMALL_SEARCH:
	PATTERN_SEARCH(SDS,5,1)
END:
	frame_info.mv[x][y]=mv;
	frame_info.sad[x][y]=sad;
	frame_info.frame_sad+=sad;
}
int equal_mv(MV mv1,MV mv2)
{

⌨️ 快捷键说明

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