• 多媒体开发之---h264快速运动估计算法


    #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

  • 相关阅读:
    结构-行为-样式-有趣的函数
    结构-行为-样式-angularJs笔记
    Js-Html 前端系列--页面撑开头尾
    Java 实现下载
    Js-Html 前端系列--Ajax
    Js-Html 前端系列--checkbox
    Nutz中过滤特殊字符
    NUTZ中处理系统未捕获异常
    Thymeleaf 笔记
    Json 使用小结
  • 原文地址:https://www.cnblogs.com/pengkunfan/p/3975448.html
Copyright © 2020-2023  润新知