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

📄 motion_est.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
                if(P_TOPRIGHT[0] < (rel_xmin<<shift)) P_TOPRIGHT[0]= (rel_xmin<<shift);                if(P_TOPRIGHT[1] > (rel_ymax<<shift)) P_TOPRIGHT[1]= (rel_ymax<<shift);                        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]);            }            pred_x= P_LEFT[0];            pred_y= P_LEFT[1];        }                if(mv_table == s->b_forw_mv_table){            mv_scale= (s->pb_time<<16) / (s->pp_time<<shift);        }else{            mv_scale= ((s->pb_time - s->pp_time)<<16) / (s->pp_time<<shift);        }                dmin = s->me.motion_search[0](s, 0, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax,                                       picture, s->p_mv_table, mv_scale, mv_penalty);         break;    }        dmin= s->me.sub_motion_search(s, &mx, &my, dmin, rel_xmin, rel_ymin, rel_xmax, rel_ymax,				   pred_x, pred_y, picture, 0, 0, mv_penalty);                                       if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)        dmin= s->me.get_mb_score(s, mx, my, pred_x, pred_y, picture, mv_penalty);//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 move into template?    //FIXME better f_code prediction (max mv & distance)    uint8_t * const mv_penalty= s->me.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;    if(s->quarter_sample){        dxy = ((motion_fy & 3) << 2) | (motion_fx & 3);        src_x = mb_x * 16 + (motion_fx >> 2);        src_y = mb_y * 16 + (motion_fy >> 2);        assert(src_x >=-16 && src_x<=s->h_edge_pos);        assert(src_y >=-16 && src_y<=s->v_edge_pos);        ptr = s->last_picture.data[0] + (src_y * s->linesize) + src_x;        s->dsp.put_qpel_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize);        dxy = ((motion_by & 3) << 2) | (motion_bx & 3);        src_x = mb_x * 16 + (motion_bx >> 2);        src_y = mb_y * 16 + (motion_by >> 2);        assert(src_x >=-16 && src_x<=s->h_edge_pos);        assert(src_y >=-16 && src_y<=s->v_edge_pos);            ptr = s->next_picture.data[0] + (src_y * s->linesize) + src_x;        s->dsp.avg_qpel_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize);    }else{        dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);        src_x = mb_x * 16 + (motion_fx >> 1);        src_y = mb_y * 16 + (motion_fy >> 1);        assert(src_x >=-16 && src_x<=s->h_edge_pos);        assert(src_y >=-16 && src_y<=s->v_edge_pos);        ptr = s->last_picture.data[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 * 16 + (motion_bx >> 1);        src_y = mb_y * 16 + (motion_by >> 1);        assert(src_x >=-16 && src_x<=s->h_edge_pos);        assert(src_y >=-16 && src_y<=s->v_edge_pos);            ptr = s->next_picture.data[0] + (src_y * s->linesize) + src_x;        s->dsp.avg_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);    }    fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*s->me.mb_penalty_factor           +(mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->me.mb_penalty_factor           + s->dsp.mb_cmp[0](s, s->new_picture.data[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize);               if(s->avctx->mb_cmp&FF_CMP_CHROMA){    }    //FIXME CHROMA !!!               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_stride;    const int xy = mb_y *mot_stride + mb_x;    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_stride;    const int mot_xy = mb_y*mot_stride + mb_x;    const int shift= 1+s->quarter_sample;    int dmin, i;    const int time_pp= s->pp_time;    const int time_pb= s->pb_time;    int mx, my, xmin, xmax, ymin, ymax;    int16_t (*mv_table)[2]= s->b_direct_mv_table;    uint8_t * const mv_penalty= s->me.mv_penalty[1] + MAX_MV;        ymin= xmin=(-32)>>shift;    ymax= xmax=   31>>shift;    if(IS_8X8(s->next_picture.mb_type[mot_xy])){        s->mv_type= MV_TYPE_8X8;    }else{        s->mv_type= MV_TYPE_16X16;    }    for(i=0; i<4; i++){        int index= s->block_index[i];        int min, max;            s->me.co_located_mv[i][0]= s->motion_val[index][0];        s->me.co_located_mv[i][1]= s->motion_val[index][1];        s->me.direct_basis_mv[i][0]= s->me.co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3));        s->me.direct_basis_mv[i][1]= s->me.co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3));//        s->me.direct_basis_mv[1][i][0]= s->me.co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3);//        s->me.direct_basis_mv[1][i][1]= s->me.co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(shift+3);        max= FFMAX(s->me.direct_basis_mv[i][0], s->me.direct_basis_mv[i][0] - s->me.co_located_mv[i][0])>>shift;        min= FFMIN(s->me.direct_basis_mv[i][0], s->me.direct_basis_mv[i][0] - s->me.co_located_mv[i][0])>>shift;        max+= (2*mb_x + (i& 1))*8 + 1; // +-1 is for the simpler rounding        min+= (2*mb_x + (i& 1))*8 - 1;        xmax= FFMIN(xmax, s->width - max);        xmin= FFMAX(xmin, - 16     - min);        max= FFMAX(s->me.direct_basis_mv[i][1], s->me.direct_basis_mv[i][1] - s->me.co_located_mv[i][1])>>shift;        min= FFMIN(s->me.direct_basis_mv[i][1], s->me.direct_basis_mv[i][1] - s->me.co_located_mv[i][1])>>shift;        max+= (2*mb_y + (i>>1))*8 + 1; // +-1 is for the simpler rounding        min+= (2*mb_y + (i>>1))*8 - 1;        ymax= FFMIN(ymax, s->height - max);        ymin= FFMAX(ymin, - 16      - min);                if(s->mv_type == MV_TYPE_16X16) break;    }        assert(xmax <= 15 && ymax <= 15 && xmin >= -16 && ymin >= -16);        if(xmax < 0 || xmin >0 || ymax < 0 || ymin > 0){        s->b_direct_mv_table[mot_xy][0]= 0;        s->b_direct_mv_table[mot_xy][1]= 0;        return 256*256*256*64;    }    P_LEFT[0]        = clip(mv_table[mot_xy - 1][0], xmin<<shift, xmax<<shift);    P_LEFT[1]        = clip(mv_table[mot_xy - 1][1], ymin<<shift, ymax<<shift);    /* special case for first line */    if (mb_y) {        P_TOP[0]      = clip(mv_table[mot_xy - mot_stride             ][0], xmin<<shift, xmax<<shift);        P_TOP[1]      = clip(mv_table[mot_xy - mot_stride             ][1], ymin<<shift, ymax<<shift);        P_TOPRIGHT[0] = clip(mv_table[mot_xy - mot_stride + 1         ][0], xmin<<shift, xmax<<shift);        P_TOPRIGHT[1] = clip(mv_table[mot_xy - mot_stride + 1         ][1], ymin<<shift, ymax<<shift);            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]);    }     //FIXME direct_search  ptr in context!!! (needed for chroma anyway or this will get messy)       if(s->flags&CODEC_FLAG_QPEL){        dmin = simple_direct_qpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax,                                                      &s->last_picture, mv_table, 1<<14, mv_penalty);        dmin = simple_direct_qpel_qpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax,                                                0, 0, &s->last_picture, 0, 0, mv_penalty);                if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)            dmin= simple_direct_qpel_qpel_get_mb_score(s, mx, my, 0, 0, &s->last_picture, mv_penalty);    }else{        dmin = simple_direct_hpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax,                                                      &s->last_picture, mv_table, 1<<15, mv_penalty);        dmin = simple_direct_hpel_hpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax,                                                0, 0, &s->last_picture, 0, 0, mv_penalty);        if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)            dmin= simple_direct_hpel_hpel_get_mb_score(s, mx, my, 0, 0, &s->last_picture, mv_penalty);    }    s->b_direct_mv_table[mot_xy][0]= mx;    s->b_direct_mv_table[mot_xy][1]= my;    return dmin;}void ff_estimate_b_frame_motion(MpegEncContext * s,                             int mb_x, int mb_y){    const int penalty_factor= s->me.mb_penalty_factor;    int fmin, bmin, dmin, fbmin;    int type=0;        s->me.skip=0;    if (s->codec_id == CODEC_ID_MPEG4)        dmin= direct_search(s, mb_x, mb_y);    else        dmin= INT_MAX;    s->me.skip=0;    fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, &s->last_picture, s->f_code) + 3*penalty_factor;        s->me.skip=0;    bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, &s->next_picture, s->b_code) + 2*penalty_factor;//printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);    s->me.skip=0;    fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor;//printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin);    {        int score= fmin;        type = MB_TYPE_FORWARD;                if (dmin <= score){            score = dmin;            type = MB_TYPE_DIRECT;        }        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->current_picture.mc_mb_var_sum += score;        s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE    }    if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){        type= MB_TYPE_FORWARD | MB_TYPE_BACKWARD | MB_TYPE_BIDIR | MB_TYPE_DIRECT; //FIXME something smarter        if(dmin>256*256*16) type&= ~MB_TYPE_DIRECT; //dont try direct mode if its invalid for this MB    }    s->mb_type[mb_y*s->mb_stride + mb_x]= 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_t * 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);        for(y=0; y<s->mb_height; y++){            int x;            int xy= y*s->mb_stride;            for(x=0; x<s->mb_width; x++){                if(s->mb_type[xy] & 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->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy])                            score[j]-= 170;                    }                }                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, range;    assert(s->pict_type==P_TYPE);    range = (((s->out_format == FMT_MPEG1) ? 8 : 16) << f_code);        if(s->msmpeg4_version) range= 16;        if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range;        /* clip / convert to intra 16x16 type MVs */    for(y=0; y<s->mb_height; y++){        int x;        int xy= y*s->mb_stride;        for(x=0; x<s->mb_width; x++){            if(s->mb_type[xy]&MB_TYPE_INTER){                if(   s->p_mv_table[xy][0] >=range || s->p_mv_table[xy][0] <-range                   || s->p_mv_table[xy][1] >=range || s->p_mv_table[xy][1] <-range){                    s->mb_type[xy] &= ~MB_TYPE_INTER;                    s->mb_type[xy] |= MB_TYPE_INTRA;                    s->p_mv_table[xy][0] = 0;                    s->p_mv_table[xy][1] = 0;                }            }            xy++;        }    }//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_stride;            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(   mx >=range || mx <-range                           || my >=range || my <-range){                            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;    // RAL: 8 in MPEG-1, 16 in MPEG-4    int range = (((s->out_format == FMT_MPEG1) ? 8 : 16) << f_code);        if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range;    /* clip / convert to intra 16x16 type MVs */    for(y=0; y<s->mb_height; y++){        int x;        int xy= y*s->mb_stride;        for(x=0; x<s->mb_width; x++){            if (s->mb_type[xy] & type){    // RAL: "type" test added...                if(   mv_table[xy][0] >=range || mv_table[xy][0] <-range                   || mv_table[xy][1] >=range || mv_table[xy][1] <-range){                    if(s->codec_id == CODEC_ID_MPEG1VIDEO && 0){                    }else{                        if     (mv_table[xy][0] > range-1) mv_table[xy][0]=  range-1;                        else if(mv_table[xy][0] < -range ) mv_table[xy][0]= -range;                        if     (mv_table[xy][1] > range-1) mv_table[xy][1]=  range-1;                        else if(mv_table[xy][1] < -range ) mv_table[xy][1]= -range;                    }                }            }            xy++;        }    }}

⌨️ 快捷键说明

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