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

📄 motion_est.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
                P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);            }            pred_x= P_LEFT[0];            pred_y= P_LEFT[1];        }        dmin = epzs_motion_search(s, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax, ref_picture);         break;    }        dmin= fast_halfpel_motion_search(s, &mx, &my, dmin, rel_xmin, rel_ymin, rel_xmax, rel_ymax,                                pred_x, pred_y, ref_picture, s->dsp.pix_abs16x16_x2, s->dsp.pix_abs16x16_y2,                                s->dsp.pix_abs16x16_xy2, 0);//printf("%d %d %d %d//", s->mb_x, s->mb_y, mx, my);//    s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;    mv_table[mot_xy][0]= mx;    mv_table[mot_xy][1]= my;    return dmin;}static inline int check_bidir_mv(MpegEncContext * s,                   int mb_x, int mb_y,                   int motion_fx, int motion_fy,                   int motion_bx, int motion_by,                   int pred_fx, int pred_fy,                   int pred_bx, int pred_by){    //FIXME optimize?    //FIXME direct mode penalty    UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame    uint8_t *dest_y = s->me_scratchpad;    uint8_t *ptr;    int dxy;    int src_x, src_y;    int fbmin;    fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*s->qscale;    dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);    src_x = mb_x * 16 + (motion_fx >> 1);    src_y = mb_y * 16 + (motion_fy >> 1);    src_x = clip(src_x, -16, s->width);    if (src_x == s->width)        dxy&= 2;    src_y = clip(src_y, -16, s->height);    if (src_y == s->height)        dxy&= 1;    ptr = s->last_picture[0] + (src_y * s->linesize) + src_x;    s->dsp.put_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);    fbmin += (mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->qscale;    dxy = ((motion_by & 1) << 1) | (motion_bx & 1);    src_x = mb_x * 16 + (motion_bx >> 1);    src_y = mb_y * 16 + (motion_by >> 1);    src_x = clip(src_x, -16, s->width);    if (src_x == s->width)        dxy&= 2;    src_y = clip(src_y, -16, s->height);    if (src_y == s->height)        dxy&= 1;    ptr = s->next_picture[0] + (src_y * s->linesize) + src_x;    s->dsp.avg_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);    fbmin += s->dsp.pix_abs16x16(s->new_picture[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize);    return fbmin;}/* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/static inline int bidir_refine(MpegEncContext * s,                                  int mb_x, int mb_y){    const int mot_stride = s->mb_width + 2;    const int xy = (mb_y + 1)*mot_stride + mb_x + 1;    int fbmin;    int pred_fx= s->b_bidir_forw_mv_table[xy-1][0];    int pred_fy= s->b_bidir_forw_mv_table[xy-1][1];    int pred_bx= s->b_bidir_back_mv_table[xy-1][0];    int pred_by= s->b_bidir_back_mv_table[xy-1][1];    int motion_fx= s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0];    int motion_fy= s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1];    int motion_bx= s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0];    int motion_by= s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1];    //FIXME do refinement and add flag        fbmin= check_bidir_mv(s, mb_x, mb_y,                           motion_fx, motion_fy,                          motion_bx, motion_by,                          pred_fx, pred_fy,                          pred_bx, pred_by);   return fbmin;}static inline int direct_search(MpegEncContext * s,                                int mb_x, int mb_y){    int P[10][2];    const int mot_stride = s->mb_width + 2;    const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1;    int dmin, dmin2;    int motion_fx, motion_fy, motion_bx, motion_by, motion_bx0, motion_by0;    int motion_dx, motion_dy;    const int motion_px= s->p_mv_table[mot_xy][0];    const int motion_py= s->p_mv_table[mot_xy][1];    const int time_pp= s->pp_time;    const int time_pb= s->pb_time;    const int time_bp= time_pp - time_pb;    int bx, by;    int mx, my, mx2, my2;    uint8_t *ref_picture= s->me_scratchpad - (mb_x - 1 + (mb_y - 1)*s->linesize)*16;    int16_t (*mv_table)[2]= s->b_direct_mv_table;/*    uint16_t *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; */ // f_code of the prev frame    /* thanks to iso-mpeg the rounding is different for the zero vector, so we need to handle that ... */    motion_fx= (motion_px*time_pb)/time_pp;    motion_fy= (motion_py*time_pb)/time_pp;    motion_bx0= (-motion_px*time_bp)/time_pp;    motion_by0= (-motion_py*time_bp)/time_pp;    motion_dx= motion_dy=0;    dmin2= check_bidir_mv(s, mb_x, mb_y,                           motion_fx, motion_fy,                          motion_bx0, motion_by0,                          motion_fx, motion_fy,                          motion_bx0, motion_by0) - s->qscale;    motion_bx= motion_fx - motion_px;    motion_by= motion_fy - motion_py;    for(by=-1; by<2; by++){        for(bx=-1; bx<2; bx++){            uint8_t *dest_y = s->me_scratchpad + (by+1)*s->linesize*16 + (bx+1)*16;            uint8_t *ptr;            int dxy;            int src_x, src_y;            const int width= s->width;            const int height= s->height;            dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);            src_x = (mb_x + bx) * 16 + (motion_fx >> 1);            src_y = (mb_y + by) * 16 + (motion_fy >> 1);            src_x = clip(src_x, -16, width);            if (src_x == width) dxy &= ~1;            src_y = clip(src_y, -16, height);            if (src_y == height) dxy &= ~2;            ptr = s->last_picture[0] + (src_y * s->linesize) + src_x;            s->dsp.put_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);            dxy = ((motion_by & 1) << 1) | (motion_bx & 1);            src_x = (mb_x + bx) * 16 + (motion_bx >> 1);            src_y = (mb_y + by) * 16 + (motion_by >> 1);            src_x = clip(src_x, -16, width);            if (src_x == width) dxy &= ~1;            src_y = clip(src_y, -16, height);            if (src_y == height) dxy &= ~2;	    s->dsp.avg_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);        }    }    P_LAST[0]        = mv_table[mot_xy    ][0];    P_LAST[1]        = mv_table[mot_xy    ][1];    P_LEFT[0]        = mv_table[mot_xy - 1][0];    P_LEFT[1]        = mv_table[mot_xy - 1][1];    P_LAST_RIGHT[0]  = mv_table[mot_xy + 1][0];    P_LAST_RIGHT[1]  = mv_table[mot_xy + 1][1];    P_LAST_BOTTOM[0] = mv_table[mot_xy + mot_stride][0];    P_LAST_BOTTOM[1] = mv_table[mot_xy + mot_stride][1];/*    if(P_LEFT[0]       > (rel_xmax<<shift)) P_LEFT[0]       = (rel_xmax<<shift);    if(P_LAST_RIGHT[0] < (rel_xmin<<shift)) P_LAST_RIGHT[0] = (rel_xmin<<shift);    if(P_LAST_BOTTOM[1]< (rel_ymin<<shift)) P_LAST_BOTTOM[1]= (rel_ymin<<shift);*/    /* special case for first line */    if ((mb_y == 0 || s->first_slice_line)) {    } else {        P_TOP[0] = mv_table[mot_xy - mot_stride             ][0];        P_TOP[1] = mv_table[mot_xy - mot_stride             ][1];        P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1         ][0];        P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1         ][1];            P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);        P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);    }    dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, -16, -16, 15, 15, ref_picture);    if(mx==0 && my==0) dmin=99999999; // not representable, due to rounding stuff    if(dmin2<dmin){         dmin= dmin2;        mx=0;        my=0;    }#if 1    mx2= mx= mx*2;     my2= my= my*2;    for(by=-1; by<2; by++){        if(my2+by < -32) continue;        for(bx=-1; bx<2; bx++){            if(bx==0 && by==0) continue;            if(mx2+bx < -32) continue;            dmin2= check_bidir_mv(s, mb_x, mb_y,                           mx2+bx+motion_fx, my2+by+motion_fy,                          mx2+bx+motion_bx, my2+by+motion_by,                          mx2+bx+motion_fx, my2+by+motion_fy,                          motion_bx, motion_by) - s->qscale;                        if(dmin2<dmin){                dmin=dmin2;                mx= mx2 + bx;                my= my2 + by;            }        }    }#else    mx*=2; my*=2;#endif    if(mx==0 && my==0){        motion_bx= motion_bx0;        motion_by= motion_by0;    }    s->b_direct_mv_table[mot_xy][0]= mx;    s->b_direct_mv_table[mot_xy][1]= my;    s->b_direct_forw_mv_table[mot_xy][0]= motion_fx + mx;    s->b_direct_forw_mv_table[mot_xy][1]= motion_fy + my;    s->b_direct_back_mv_table[mot_xy][0]= motion_bx + mx;    s->b_direct_back_mv_table[mot_xy][1]= motion_by + my;    return dmin;}void ff_estimate_b_frame_motion(MpegEncContext * s,                             int mb_x, int mb_y){    const int quant= s->qscale;    int fmin, bmin, dmin, fbmin;    int type=0;        dmin= direct_search(s, mb_x, mb_y);    fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture[0], s->f_code);    bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture[0], s->b_code) - quant;//printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);    fbmin= bidir_refine(s, mb_x, mb_y);    {        int score= dmin;        type=MB_TYPE_DIRECT;                if(fmin<score){            score=fmin;            type= MB_TYPE_FORWARD;         }        if(bmin<score){            score=bmin;            type= MB_TYPE_BACKWARD;         }        if(fbmin<score){            score=fbmin;            type= MB_TYPE_BIDIR;        }        score= ((unsigned)(score*score + 128*256))>>16;        s->mc_mb_var_sum += score;        s->mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD    }    if(s->flags&CODEC_FLAG_HQ){        type= MB_TYPE_FORWARD | MB_TYPE_BACKWARD | MB_TYPE_BIDIR | MB_TYPE_DIRECT; //FIXME something smarter    }/*{static int count=0;static int sum=0;if(type==MB_TYPE_DIRECT){  int diff= ABS(s->b_forw_mv_table)}}*/    s->mb_type[mb_y*s->mb_width + mb_x]= type;/*    if(mb_y==0 && mb_x==0) printf("\n");    if(mb_x==0) printf("\n");    printf("%d", av_log2(type));*/}/* find best f_code for ME which do unlimited searches */int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type){    if(s->me_method>=ME_EPZS){        int score[8];        int i, y;        UINT8 * fcode_tab= s->fcode_tab;        int best_fcode=-1;        int best_score=-10000000;        for(i=0; i<8; i++) score[i]= s->mb_num*(8-i); //FIXME *2 and all other too so its the same but nicer        for(y=0; y<s->mb_height; y++){            int x;            int xy= (y+1)* (s->mb_width+2) + 1;            i= y*s->mb_width;            for(x=0; x<s->mb_width; x++){                if(s->mb_type[i] & type){                    int fcode= FFMAX(fcode_tab[mv_table[xy][0] + MAX_MV],                                     fcode_tab[mv_table[xy][1] + MAX_MV]);                    int j;                                        for(j=0; j<fcode && j<8; j++){                        if(s->pict_type==B_TYPE || s->mc_mb_var[i] < s->mb_var[i])                            score[j]-= 170;                    }                }                i++;                xy++;            }        }                for(i=1; i<8; i++){            if(score[i] > best_score){                best_score= score[i];                best_fcode= i;            }//            printf("%d %d\n", i, score[i]);        }//    printf("fcode: %d type: %d\n", i, s->pict_type);        return best_fcode;/*        for(i=0; i<=MAX_FCODE; i++){            printf("%d ", mv_num[i]);        }        printf("\n");*/    }else{        return 1;    }}void ff_fix_long_p_mvs(MpegEncContext * s){    const int f_code= s->f_code;    int y;    UINT8 * fcode_tab= s->fcode_tab;//int clip=0;//int noclip=0;    /* clip / convert to intra 16x16 type MVs */    for(y=0; y<s->mb_height; y++){        int x;        int xy= (y+1)* (s->mb_width+2)+1;        int i= y*s->mb_width;        for(x=0; x<s->mb_width; x++){            if(s->mb_type[i]&MB_TYPE_INTER){                if(   fcode_tab[s->p_mv_table[xy][0] + MAX_MV] > f_code                   || fcode_tab[s->p_mv_table[xy][0] + MAX_MV] == 0                   || fcode_tab[s->p_mv_table[xy][1] + MAX_MV] > f_code                   || fcode_tab[s->p_mv_table[xy][1] + MAX_MV] == 0 ){                    s->mb_type[i] &= ~MB_TYPE_INTER;                    s->mb_type[i] |= MB_TYPE_INTRA;                    s->p_mv_table[xy][0] = 0;                    s->p_mv_table[xy][1] = 0;//clip++;                }//else//  noclip++;            }            xy++;            i++;        }    }//printf("%d no:%d %d//\n", clip, noclip, f_code);    if(s->flags&CODEC_FLAG_4MV){        const int wrap= 2+ s->mb_width*2;        /* clip / convert to intra 8x8 type MVs */        for(y=0; y<s->mb_height; y++){            int xy= (y*2 + 1)*wrap + 1;            int i= y*s->mb_width;            int x;            for(x=0; x<s->mb_width; x++){                if(s->mb_type[i]&MB_TYPE_INTER4V){                    int block;                    for(block=0; block<4; block++){                        int off= (block& 1) + (block>>1)*wrap;                        int mx= s->motion_val[ xy + off ][0];                        int my= s->motion_val[ xy + off ][1];                        if(   fcode_tab[mx + MAX_MV] > f_code                           || fcode_tab[mx + MAX_MV] == 0                           || fcode_tab[my + MAX_MV] > f_code                           || fcode_tab[my + MAX_MV] == 0 ){                            s->mb_type[i] &= ~MB_TYPE_INTER4V;                            s->mb_type[i] |= MB_TYPE_INTRA;                        }                    }                }                xy+=2;                i++;            }        }    }}void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, int type){    int y;    UINT8 * fcode_tab= s->fcode_tab;    /* clip / convert to intra 16x16 type MVs */    for(y=0; y<s->mb_height; y++){        int x;        int xy= (y+1)* (s->mb_width+2)+1;        int i= y*s->mb_width;        for(x=0; x<s->mb_width; x++){            if(   fcode_tab[mv_table[xy][0] + MAX_MV] > f_code               || fcode_tab[mv_table[xy][0] + MAX_MV] == 0){                if(mv_table[xy][0]>0) mv_table[xy][0]=  (16<<f_code)-1;                else                  mv_table[xy][0]= -(16<<f_code);            }            if(   fcode_tab[mv_table[xy][1] + MAX_MV] > f_code               || fcode_tab[mv_table[xy][1] + MAX_MV] == 0){                if(mv_table[xy][1]>0) mv_table[xy][1]=  (16<<f_code)-1;                else                  mv_table[xy][1]= -(16<<f_code);            }            xy++;            i++;        }    }}

⌨️ 快捷键说明

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