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

📄 motion_est.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
static inline int snake_search(MpegEncContext * s, int *best, int dmin,                                       UINT8 *new_pic, UINT8 *old_pic, int pic_stride,                                       int pred_x, int pred_y, UINT16 *mv_penalty, int quant,                                       int xmin, int ymin, int xmax, int ymax, int shift,                                       uint32_t *map, uint16_t *score_map,int map_generation,                                       op_pixels_abs_func pix_abs){    int dir=0;    int c=1;    static int x_dir[8]= {1,1,0,-1,-1,-1, 0, 1};    static int y_dir[8]= {0,1,1, 1, 0,-1,-1,-1};    int fails=0;    int last_d[2]={dmin, dmin};/*static int good=0;static int bad=0;static int point=0;point++;if(256*256*256*64%point==0){    printf("%d %d %d\n", good, bad, point);}*/    for(;;){        int x= best[0];        int y= best[1];        int d;        x+=x_dir[dir];        y+=y_dir[dir];        if(x>=xmin && x<=xmax && y>=ymin && y<=ymax){            const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;            const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);            if(map[index]!=key){                d = pix_abs(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride);                d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;                map[index]=key;                score_map[index]=d;            }else                d= dmin+1;        }else{            d = dmin + 10000; //FIXME smarter boundary handling        }        if(d<dmin){            best[0]=x;            best[1]=y;            dmin=d;            if(last_d[1] - last_d[0] > last_d[0] - d) c= -c;            dir+=c;            fails=0;//good++;            last_d[1]=last_d[0];            last_d[0]=d;        }else{//bad++;            if(fails){                if(fails>=SNAKE_1+1) return dmin;            }else{                if(dir&1) dir-= c*3;                else      c= -c;//                c= -c;            }            dir+=c*SNAKE_2;            fails++;        }        dir&=7;    }}static inline int cross_search(MpegEncContext * s, int *best, int dmin,                                       UINT8 *new_pic, UINT8 *old_pic, int pic_stride,                                       int pred_x, int pred_y, UINT16 *mv_penalty, int quant,                                       int xmin, int ymin, int xmax, int ymax, int shift,                                       uint32_t *map, uint16_t *score_map,int map_generation,                                       op_pixels_abs_func pix_abs){    static int x_dir[4]= {-1, 0, 1, 0};    static int y_dir[4]= { 0,-1, 0, 1};    int improvement[2]={100000, 100000};    int dirs[2]={2, 3};    int dir;    int last_dir= -1;        for(;;){        dir= dirs[ improvement[0] > improvement[1] ? 0 : 1 ];        if(improvement[dir&1]==-1) return dmin;                {            const int x= best[0] + x_dir[dir];            const int y= best[1] + y_dir[dir];            const int key= (y<<ME_MAP_MV_BITS) + x + map_generation;            const int index= ((y<<ME_MAP_SHIFT) + x)&(ME_MAP_SIZE-1);            int d;            if(x>=xmin && x<=xmax && y>=ymin && y<=ymax){                if(map[index]!=key){                    d = pix_abs(new_pic, old_pic + x + y*pic_stride, pic_stride);                    d += (mv_penalty[(x<<shift)-pred_x] + mv_penalty[(y<<shift)-pred_y])*quant;                    map[index]=key;                    score_map[index]=d;                    if(d<dmin){                        improvement[dir&1]= dmin-d;                        improvement[(dir&1)^1]++;                        dmin=d;                        best[0]= x;                        best[1]= y;                        last_dir=dir;                        continue;                    }                }else{                    d= score_map[index];                }            }else{                d= dmin + 1000; //FIXME is this a good idea?            }            /* evaluated point was cached or checked and worse */            if(last_dir==dir){                improvement[dir&1]= -1;            }else{                improvement[dir&1]= d-dmin;                last_dir= dirs[dir&1]= dir^2;            }        }    }}static inline int update_map_generation(MpegEncContext * s){    s->me_map_generation+= 1<<(ME_MAP_MV_BITS*2);    if(s->me_map_generation==0){        s->me_map_generation= 1<<(ME_MAP_MV_BITS*2);        memset(s->me_map, 0, sizeof(uint32_t)*ME_MAP_SIZE);    }    return s->me_map_generation;}static int epzs_motion_search(MpegEncContext * s,                             int *mx_ptr, int *my_ptr,                             int P[10][2], int pred_x, int pred_y,                             int xmin, int ymin, int xmax, int ymax, uint8_t * ref_picture){    int best[2]={0, 0};    int d, dmin;     UINT8 *new_pic, *old_pic;    const int pic_stride= s->linesize;    const int pic_xy= (s->mb_y*pic_stride + s->mb_x)*16;    UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame    int quant= s->qscale; // qscale of the prev frame    const int shift= 1+s->quarter_sample;    uint32_t *map= s->me_map;    uint16_t *score_map= s->me_score_map;    int map_generation;    new_pic = s->new_picture[0] + pic_xy;    old_pic = ref_picture + pic_xy;        map_generation= update_map_generation(s);    dmin = s->dsp.pix_abs16x16(new_pic, old_pic, pic_stride);    map[0]= map_generation;    score_map[0]= dmin;    /* first line */    if ((s->mb_y == 0 || s->first_slice_line)) {        CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)        CHECK_MV(P_LAST[0]>>shift, P_LAST[1]>>shift)    }else{        if(dmin<256 && ( P_LEFT[0]    |P_LEFT[1]                        |P_TOP[0]     |P_TOP[1]                        |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){            *mx_ptr= 0;            *my_ptr= 0;            s->skip_me=1;            return dmin;        }        CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift)        if(dmin>256*2){            CHECK_MV(P_LAST[0]    >>shift, P_LAST[1]    >>shift)            CHECK_MV(P_LEFT[0]    >>shift, P_LEFT[1]    >>shift)            CHECK_MV(P_TOP[0]     >>shift, P_TOP[1]     >>shift)            CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift)        }    }    if(dmin>256*4){        CHECK_MV(P_LAST_RIGHT[0] >>shift, P_LAST_RIGHT[1] >>shift)        CHECK_MV(P_LAST_BOTTOM[0]>>shift, P_LAST_BOTTOM[1]>>shift)    }#if 0 //doest only slow things down    if(dmin>512*3){        int step;        dmin= score_map[0];        best[0]= best[1]=0;        for(step=128; step>0; step>>=1){            const int step2= step;            int y;            for(y=-step2+best[1]; y<=step2+best[1]; y+=step){                int x;                if(y<ymin || y>ymax) continue;                for(x=-step2+best[0]; x<=step2+best[0]; x+=step){                    if(x<xmin || x>xmax) continue;                    if(x==best[0] && y==best[1]) continue;                    CHECK_MV(x,y)                }            }        }    }#endif//check(best[0],best[1],0, b0)    if(s->me_method==ME_EPZS)        dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride,                                    pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, 				   shift, map, score_map, map_generation, s->dsp.pix_abs16x16);    else        dmin=         cross_search(s, best, dmin, new_pic, old_pic, pic_stride,                                    pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax,                                    shift, map, score_map, map_generation, s->dsp.pix_abs16x16);//check(best[0],best[1],0, b1)    *mx_ptr= best[0];    *my_ptr= best[1];    //    printf("%d %d %d \n", best[0], best[1], dmin);    return dmin;}static int epzs_motion_search4(MpegEncContext * s, int block,                             int *mx_ptr, int *my_ptr,                             int P[10][2], int pred_x, int pred_y,                             int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture){    int best[2]={0, 0};    int d, dmin;     UINT8 *new_pic, *old_pic;    const int pic_stride= s->linesize;    const int pic_xy= ((s->mb_y*2 + (block>>1))*pic_stride + s->mb_x*2 + (block&1))*8;    UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame    int quant= s->qscale; // qscale of the prev frame    const int shift= 1+s->quarter_sample;    uint32_t *map= s->me_map;    uint16_t *score_map= s->me_score_map;    int map_generation;    new_pic = s->new_picture[0] + pic_xy;    old_pic = ref_picture + pic_xy;    map_generation= update_map_generation(s);    dmin = 1000000;//printf("%d %d %d %d //",xmin, ymin, xmax, ymax);     /* first line */    if ((s->mb_y == 0 || s->first_slice_line) && block<2) {	CHECK_MV4(P_LEFT[0]>>shift, P_LEFT[1]>>shift)        CHECK_MV4(P_LAST[0]>>shift, P_LAST[1]>>shift)        CHECK_MV4(P_MV1[0]>>shift, P_MV1[1]>>shift)    }else{        CHECK_MV4(P_MV1[0]>>shift, P_MV1[1]>>shift)        //FIXME try some early stop        if(dmin>64*2){            CHECK_MV4(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift)            CHECK_MV4(P_LEFT[0]>>shift, P_LEFT[1]>>shift)            CHECK_MV4(P_TOP[0]>>shift, P_TOP[1]>>shift)            CHECK_MV4(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift)            CHECK_MV4(P_LAST[0]>>shift, P_LAST[1]>>shift)        }    }    if(dmin>64*4){        CHECK_MV4(P_LAST_RIGHT[0]>>shift, P_LAST_RIGHT[1]>>shift)        CHECK_MV4(P_LAST_BOTTOM[0]>>shift, P_LAST_BOTTOM[1]>>shift)    }    if(s->me_method==ME_EPZS)        dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride,                                    pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, 				   shift, map, score_map, map_generation, s->dsp.pix_abs8x8);    else        dmin=         cross_search(s, best, dmin, new_pic, old_pic, pic_stride,                                    pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax,                                    shift, map, score_map, map_generation, s->dsp.pix_abs8x8);    *mx_ptr= best[0];    *my_ptr= best[1];    //    printf("%d %d %d \n", best[0], best[1], dmin);    return dmin;}#define CHECK_HALF_MV(suffix, x, y) \{\    d= pix_abs_ ## suffix(pix, ptr+((x)>>1), s->linesize);\    d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*quant;\    COPY3_IF_LT(dminh, d, dx, x, dy, y)\}    /* The idea would be to make half pel ME after Inter/Intra decision to    save time. */static inline int halfpel_motion_search(MpegEncContext * s,				  int *mx_ptr, int *my_ptr, int dmin,				  int xmin, int ymin, int xmax, int ymax,                                  int pred_x, int pred_y, uint8_t *ref_picture,                                  op_pixels_abs_func pix_abs_x2,                                   op_pixels_abs_func pix_abs_y2, op_pixels_abs_func pix_abs_xy2, int n){    UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame    const int quant= s->qscale;    int mx, my, xx, yy, dminh;    UINT8 *pix, *ptr;    if(s->skip_me){        *mx_ptr = 0;        *my_ptr = 0;        return dmin;    }    xx = 16 * s->mb_x + 8*(n&1);    yy = 16 * s->mb_y + 8*(n>>1);    pix =  s->new_picture[0] + (yy * s->linesize) + xx;    mx = *mx_ptr;    my = *my_ptr;    ptr = ref_picture + ((yy + my) * s->linesize) + (xx + mx);        dminh = dmin;    if (mx > xmin && mx < xmax &&         my > ymin && my < ymax) {        int dx=0, dy=0;        int d, pen_x, pen_y;         mx<<=1;        my<<=1;                pen_x= pred_x + mx;        pen_y= pred_y + my;        ptr-= s->linesize;        CHECK_HALF_MV(xy2, -1, -1)        CHECK_HALF_MV(y2 ,  0, -1)        CHECK_HALF_MV(xy2, +1, -1)                ptr+= s->linesize;        CHECK_HALF_MV(x2 , -1,  0)        CHECK_HALF_MV(x2 , +1,  0)        CHECK_HALF_MV(xy2, -1, +1)        CHECK_HALF_MV(y2 ,  0, +1)        CHECK_HALF_MV(xy2, +1, +1)        mx+=dx;        my+=dy;    }else{        mx<<=1;        my<<=1;    }    *mx_ptr = mx;    *my_ptr = my;    return dminh;}static inline int fast_halfpel_motion_search(MpegEncContext * s,				  int *mx_ptr, int *my_ptr, int dmin,				  int xmin, int ymin, int xmax, int ymax,                                  int pred_x, int pred_y, uint8_t *ref_picture,                                  op_pixels_abs_func pix_abs_x2,                                   op_pixels_abs_func pix_abs_y2, op_pixels_abs_func pix_abs_xy2, int n){    UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame    uint16_t *score_map= s->me_score_map;    const int quant= s->qscale;    int mx, my, xx, yy, dminh;    UINT8 *pix, *ptr;    if(s->skip_me){//    printf("S");        *mx_ptr = 0;        *my_ptr = 0;        return dmin;    }//    printf("N");            xx = 16 * s->mb_x + 8*(n&1);    yy = 16 * s->mb_y + 8*(n>>1);    pix =  s->new_picture[0] + (yy * s->linesize) + xx;    mx = *mx_ptr;    my = *my_ptr;    ptr = ref_picture + ((yy + my) * s->linesize) + (xx + mx);        dminh = dmin;    if (mx > xmin && mx < xmax &&         my > ymin && my < ymax) {        int dx=0, dy=0;        int d, pen_x, pen_y;         const int index= (my<<ME_MAP_SHIFT) + mx;        const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)];        const int l= score_map[(index- 1               )&(ME_MAP_SIZE-1)];        const int r= score_map[(index+ 1               )&(ME_MAP_SIZE-1)];        const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)];        mx<<=1;        my<<=1;                pen_x= pred_x + mx;        pen_y= pred_y + my;        ptr-= s->linesize;        if(t<=b){            CHECK_HALF_MV(y2 ,  0, -1)            if(l<=r){                CHECK_HALF_MV(xy2, -1, -1)                if(t+r<=b+l){                    CHECK_HALF_MV(xy2, +1, -1)                    ptr+= s->linesize;                }else{                    ptr+= s->linesize;                    CHECK_HALF_MV(xy2, -1, +1)                }                CHECK_HALF_MV(x2 , -1,  0)            }else{                CHECK_HALF_MV(xy2, +1, -1)                if(t+l<=b+r){                    CHECK_HALF_MV(xy2, -1, -1)                    ptr+= s->linesize;                }else{                    ptr+= s->linesize;                    CHECK_HALF_MV(xy2, +1, +1)                }                CHECK_HALF_MV(x2 , +1,  0)            }

⌨️ 快捷键说明

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