#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)
{
if(mv1.dx==mv2.dx && mv1.dy==mv2.dy)
   return 1;
else
   return 0;
}
void search_PMVFAST(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;

int thresa=512,thresb=1024,Found=0,PredEq=0;
if(x>0 && y>0)
{
   thresa=MIN(frame_info.sad[x-1][y],frame_info.sad[x][y-1]);
   thresa=MIN(thresa,frame_info.sad[x-1][y+1]);
   thresb=thresa+256;
   if(thresa<512) thresa=512;
   if(thresa>1024)thresa=1024;
   if(thresb>1792)thresb=1792;
}
Get_MVp(x,y,pre_mv,mvx,mvy);
if(x>0 && equal_mv(pre_mv[0],pre_mv[1]) && equal_mv(pre_mv[0],pre_mv[2]) )
   PredEq=1;

int Distance=abs(mvx)+abs(mvy);
if( PredEq==1 && mvx==pre_mv[4].dx && mvy==pre_mv[4].dy )
   Found=2;

CHECK_ONE_PIXEL(mvx,mvy)
if( equal_mv(mv,pre_mv[4]) && sad<frame_info.prev_sad[x][y] )
   goto END;
if(sad<256) 
   goto END;
CHECK_ONE_PIXEL(0,0)
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)
CHECK_ONE_PIXEL(pre_mv[4].dx,pre_mv[4].dy)
if(sad<thresa)
   goto END;
if( equal_mv(mv,pre_mv[4]) && sad<frame_info.prev_sad[x][y] )
   goto END;
if( Distance>0 || thresb<1536 || PredEq==1 )
   goto SMALL_SEARCH;
PATTERN_SEARCH(LDS,9,Found!=2)
SMALL_SEARCH:
PATTERN_SEARCH(SDS,5,Found!=2)
END:
frame_info.mv[x][y]=mv;
frame_info.sad[x][y]=sad;
frame_info.frame_sad+=sad;
}
void search_CDHS(const int x,const int y,const int heigth,const int width)
{
const int ox=x*BLOCK_HEIGTH,oy=y*BLOCK_WIDTH;
const int LCS[9][2]={{0,0},{0,1},{-1,0},{0,-1},{1,0},{0,2},{-2,0},{0,-2},{2,0}};
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}};
const int HHS[7][2]={{0,0},{0,2},{0,-2},{1,1},{1,-1},{-1,1},{-1,-1}};
const int VHS[7][2]={{0,0},{2,0},{-2,0},{1,1},{1,-1},{-1,1},{-1,-1}};
uint32 sad=0xffffff;
MV mv={0,0},mv_tmp;int mvx,mvy,flag;

PATTERN_SEARCH(SDS,5,0)
if(mv.dx==0&&mv.dy==0)goto END;
PATTERN_SEARCH(SDS,5,0)
if(abs(mv.dx)+abs(mv.dy)==1)goto END;
mv_tmp=mv;mv.dx=mv.dy=0;
PATTERN_SEARCH(LCS,9,0)
if(mv.dx==0&&mv.dy==0) mv=mv_tmp;
if(abs(mv.dx)==1 && abs(mv.dy)==1)
   flag=0;
else if(abs(mv.dx)==0 && abs(mv.dy)==2)
   flag=1;
else if(abs(mv.dx)==2 && abs(mv.dy)==0)
   flag=2;
else
   printf("error/n");
do
{
   mvx=mv.dx;mvy=mv.dy;
   if(flag==0)
   {
    for(int i=0;i<9;i++)
    {
     if(SAD(ox,oy,mvx+LDS[i][0],mvy+LDS[i][1],heigth,width,sad)==1)
     {
      mv.dx=mvx+LDS[i][0];mv.dy=mvy+LDS[i][1];
      if   (abs(LDS[i][1])==2) flag=1;
      else if (abs(LDS[i][0])==2) flag=2;
      else       flag=0;
     }
    }
   }
   else if(flag==1)
   {
    for(int i=0;i<7;i++)
    {
     if(SAD(ox,oy,mvx+HHS[i][0],mvy+HHS[i][1],heigth,width,sad)==1)
     {
      mv.dx=mvx+HHS[i][0];mv.dy=mvy+HHS[i][1];
      flag = abs(HHS[i][1])==2 ? 1 : 0;
     }
    }
   }
   else
   {
    for(int i=0;i<7;i++)
    {
     if(SAD(ox,oy,mvx+VHS[i][0],mvy+VHS[i][1],heigth,width,sad)==1)
     {
      mv.dx=mvx+VHS[i][0];mv.dy=mvy+VHS[i][1];
      flag = abs(VHS[i][0])==2 ? 2 : 0;
     }
    }
   }
}while ( mv.dx!=mvx || mv.dy!=mvy );
PATTERN_SEARCH(SDS,5,0)
END:
frame_info.mv[x][y]=mv;
frame_info.sad[x][y]=sad;
frame_info.frame_sad+=sad;
}
void search_AVPS(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}};
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}};
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},pre_mv[10];uint32 pre_sad[10];int mvx,mvy;

int thresa=512,thresb=1024,PredEq=0;
Get_MVp(x,y,pre_mv,mvx,mvy,pre_sad);
int sad_max=0xffffff,sad_min=0;
if(x>0 && y>0)
{
   if(equal_mv(mv,pre_mv[0]))   
    sad_min=MAX(sad_min,pre_sad[0])
   else
    sad_max=MIN(sad_max,pre_sad[0]);
   if(equal_mv(mv,pre_mv[1]))   
    sad_min=MAX(sad_min,pre_sad[1])
   else
    sad_max=MIN(sad_max,pre_sad[1]);                                                                                                                                                                                                                       
   if(equal_mv(mv,pre_mv[2]))   
    sad_min=MAX(sad_min,pre_sad[2])
   else
    sad_max=MIN(sad_max,pre_sad[2]);
//   if(equal_mv(mv,pre_mv[3]))   
//    sad_min=MAX(sad_min,pre_sad[3])
//   else
//    sad_max=MIN(sad_max,pre_sad[3]);
   if(sad_min==0)sad_min=512;
   if(sad_max==0xffffff)sad_max=512;
   thresa=MAX(sad_max,sad_min);
    
   sad_max=MAX(pre_sad[0],pre_sad[1]);
   sad_max=MAX(sad_max,pre_sad[2]);
   sad_max=MAX(sad_max,pre_sad[3]);
   sad_min=MIN(pre_sad[0],pre_sad[1]);
   sad_min=MIN(sad_min,pre_sad[2]);
   sad_min=MIN(sad_min,pre_sad[3]);

thresb=MAX(sad_max,thresa+256);
   if(thresa<512) thresa=512;
   if(thresa>1024)thresa=1024;
   if(thresb>1792)thresb=1792;
}
else
{
   sad_min=0;
   sad_max=2048;
}
if(x>0 && equal_mv(pre_mv[0],pre_mv[1]) && equal_mv(pre_mv[0],pre_mv[2]) )
   PredEq=1;

CHECK_ONE_PIXEL(mvx,mvy)
if(sad<256)
   goto END;
CHECK_ONE_PIXEL(0,0)
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)
CHECK_ONE_PIXEL(pre_mv[4].dx,pre_mv[4].dy)
if(sad<thresa)
   goto END;
if(sad<thresb||sad_max-sad_min<256||(x>0&&y>0&&Get_Mv_Length(x,y,pre_mv,mvx,mvy)<2))
   goto SMALL_SEARCH2;
else
{
   CHECK_ONE_PIXEL(pre_mv[5].dx,pre_mv[5].dy)
   goto LARGE_SEARCH0;
}
// {
// CHECK_ONE_PIXEL(pre_mv[5].dx,pre_mv[5].dy)
// PATTERN_SEARCH(LHS,7,1)
// int sad_sub=0xffffff;mvx=mvy=0;
// for(int i=1;i<7;i++)
// {
//   int dx=mv.dx+LHS[i][0],dy=mv.dy+LHS[i][1];
//   const int rx=ox+dx,ry=oy+dy;
//   if( abs(dx)>MAX_MOTION || abs(dy)>MAX_MOTION)
//    continue;
//   if( rx<0 || ry<0 || rx+heigth>XX || ry+width>YY )
//    continue;
//   if( flag_search[dx][dy]<sad_sub )
//   {
//    sad_sub=flag_search[dx][dy];
//    mvx=LHS[i][0];mvy=LHS[i][1];
//   }
// }
// int shsxy[3][2];
// if(mvx==0)
// {
//   shsxy[0][0]=-1;shsxy[1][0]=0;shsxy[2][0]=1;shsxy[0][1]=shsxy[1][1]=shsxy[2][1]=mvy/2;
// }
// else
// {
//   shsxy[0][0]=mvx/2;shsxy[0][1]=mvy;
//   shsxy[1][0]=mvx/2;shsxy[1][1]=0;
//   shsxy[2][0]=    0;shsxy[2][1]=mvy;
// }
// PATTERN_SEARCH(shsxy,3,0);
// PATTERN_SEARCH(SDS,5,0);
// goto END;
// }
LARGE_SEARCH0:
PATTERN_SEARCH(LDS,9,1)
PATTERN_SEARCH(SDS,5,0)
goto END;
LARGE_SEARCH1:
PATTERN_SEARCH(LHS,7,1)
PATTERN_SEARCH(SHS,9,0)
goto END;
LARGE_SEARCH2:
PATTERN_SEARCH(L4SS,9,1)
PATTERN_SEARCH(S4SS,9,0)
goto END;
SMALL_SEARCH0:
PATTERN_SEARCH(SHS,9,1)
   goto END;
SMALL_SEARCH1:
PATTERN_SEARCH(SDS,5,1)
   goto END;
SMALL_SEARCH2:
do
{
   MV tmp_mv=mv;uint32 tmp_sad=sad;
   mvx=mv.dx;mvy=mv.dy;sad=0xffffff;
   for(int i=1;i<5;i++)
   {
    if(SAD(ox,oy,mvx+SDS[i][0],mvy+SDS[i][1],heigth,width,sad)==1)
    {
     mv.dx=mvx+SDS[i][0];mv.dy=mvy+SDS[i][1];
    }
   }
   if(sad<tmp_sad)
    continue;
   if(sad/(float)tmp_sad>1.15)
   {
    mv=tmp_mv;sad=tmp_sad;
    break;
   }
   if(mv.dy!=mvy)
   {
    CHECK_ONE_PIXEL(mv.dx-1,mv.dy)
    CHECK_ONE_PIXEL(mv.dx+1,mv.dy)
   }
   if(mv.dx!=mvx)
   {
    CHECK_ONE_PIXEL(mv.dx,mv.dy-1)
    CHECK_ONE_PIXEL(mv.dx,mv.dy+1)
   }
   if(sad>=tmp_sad)
   {
    mv=tmp_mv;sad=tmp_sad;
    break;
   }
}while ( 1 );
goto END;
END:
frame_info.mv[x][y]=mv;
frame_info.sad[x][y]=sad;
frame_info.frame_sad+=sad;
}

http://blog.csdn.net/china_video_expert/article/details/5936332#comments

多媒体开发之---h264快速运动估计算法的更多相关文章

  1. 多媒体开发之---h264 高度和宽度获取

    ( School of Computer Science & Technology, Soochow University,SuZhou 215006:) Abstract: H.264 is ...

  2. 多媒体开发之---h264格式slice_header

    从Slice_Header学习H.264 写在前面: $     H.264我是结合标准和毕厚杰的书一块学的.看句法语义时最是头疼,一大堆的元素,很需要耐心.标准中在介绍某个元素的语义时,经常会突然冒 ...

  3. 多媒体开发之---h264 NALU 语法结构

    补充笔记: 关于VCL:VCL层是指视频编码层,VCL NAL 单元是指那些nal_unit_type 值等于 1 到 5(包括 1 和 5)的 NAL 单元,这些单元都包含了视频数据.所有其他的 N ...

  4. 多媒体开发之--- h264 图像、帧、片、NALU

    图像.帧.片.NALU 是学习 H.264的人常常感到困惑的一些概念,我在这里对自己的理解做一些阐述,欢迎大家讨论: H.264 是一次概念的革新,它打破常规,完全没有 I 帧.P帧.B 帧的概念,也 ...

  5. 多媒体开发之---H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流

    一.MP4格式基本概念 MP4格式对应标准MPEG-4标准(ISO/IEC14496) 二.MP4封装格式核心概念 1  MP4封装格式对应标准为 ISO/IEC 14496-12(信息技术 视听对象 ...

  6. 多媒体开发之---H264 RTSP交互过程

    OPTIONS rtsp://192.168.1.154:8557/h264 RTSP/1.0 CSeq: 1 User-Agent: VLC media player (LIVE555 Stream ...

  7. 多媒体开发之---h264 rtp打包

    http://blog.csdn.net/newthinker_wei/article/details/8997440 http://blog.csdn.net/dengzikun/article/d ...

  8. 多媒体开发之---h264中 的RTP PAYLOAD 格式

    H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +---------------+      |0|1|2|3|4|5|6|7 ...

  9. 多媒体开发之---h264 图像参数级语义

    (四)图像参数集语义 pic_parameter_set_rbsp( ) {       // pic_parameter_set_id 用以指定本参数集的序号,该序号在各片的片头被引用.    pi ...

随机推荐

  1. 学习笔记5——wp主题开发

    我觉得学习wordpress插件开发之前还是得先理解一下wp的主题开发,循序渐进才能学好wordpress开发,话不多说,接下来整理一下这两天学习的wordpress主题开发的一些心得和体会,与大家一 ...

  2. C++ char数组和string类简单使用总结

    使用char数组,进行字符串的操作,是c风格的操作方式. string是C++的风格,感觉string本质上就是一个vector<char> 以下代码详细展示了字符串的常见操作 #incl ...

  3. 【工具】Homebrew的安装及使用

    Homebrew官网:http://brew.sh/index_zh-cn.html Homebrew是Mac OSX上的软件包管理工具,能在Mac中方便的安装软件或者卸载软件,相当于linux下的a ...

  4. 【LeetCode】Valid Parentheses(有效的括号)

    这道题是LeetCode里的第20道题. 题目要求: 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭 ...

  5. Luogu【P3609】蹄子剪刀布(DP+滚动数组)

    题目链接 (突然高兴 又一次瞬间想出转移方程并一遍A掉!!233333(虽然从二叉苹果树那题开始我就发现我的方程好像跟别人不大一样 (所以这样就可以名正言顺的水题解了 设f[i][j][k]表示考虑F ...

  6. HDU 3949 XOR ——线形基 高斯消元

    [题目分析] 异或空间的K小值. 高斯消元和动态维护线形基两种方法都试了试. 动态维护更好些,也更快(QAQ,我要高斯消元有何用) 高斯消元可以用来开拓视野. 注意0和-1的情况 [代码] 高斯消元 ...

  7. FZU 2186 小明的迷宫 【压状dp】

    Problem Description 小明误入迷宫,塞翁失马焉知非福,原来在迷宫中还藏着一些财宝,小明想获得所有的财宝并离开迷宫.因为小明还是学生,还有家庭作业要做,所以他想尽快获得所有财宝并离开迷 ...

  8. 常州模拟赛d2t1 小X的质数

    题目背景 小 X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的 情感.小 X 认为,质数是一切自然数起源的地方. 题目描述 在小 X 的认知里,质数是除了本身和 1 以外,没有其他因 ...

  9. Java:Session详解

    以下情况,Session结束生命周期,Servlet容器将Session所占资源释放:1.客户端关闭浏览器2.Session过期3.服务器端调用了HttpSession的invalidate()方法. ...

  10. HTML 文档之 Head 最佳实践--摘抄

    HTML 文档之 Head 最佳实践 story 01-10 阅读 353 收藏 0 收藏 这篇文章整理了作者认可的一些最佳实践,写在这里与各位分享 阅读原文折叠收起 HTML 文档之 Head 最佳 ...