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

📄 motion_est.c

📁 arm平台下的H264编码和解码源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        ptr = ref_data[0] + (src_y * stride) + src_x;        s->dsp.put_qpel_pixels_tab[0][dxy](dest_y    , ptr    , stride);        dxy = ((motion_by & 3) << 2) | (motion_bx & 3);        src_x = motion_bx >> 2;        src_y = motion_by >> 2;            ptr = ref_data[3] + (src_y * stride) + src_x;        s->dsp.avg_qpel_pixels_tab[size][dxy](dest_y    , ptr    , stride);    }else{        dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);        src_x = motion_fx >> 1;        src_y = motion_fy >> 1;        ptr = ref_data[0] + (src_y * stride) + src_x;        s->dsp.put_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);        dxy = ((motion_by & 1) << 1) | (motion_bx & 1);        src_x = motion_bx >> 1;        src_y = motion_by >> 1;            ptr = ref_data[3] + (src_y * stride) + src_x;        s->dsp.avg_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);    }    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[size](s, src_data[0], dest_y, stride, h); //FIXME new_pic               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, uint8_t *src_data[3], uint8_t *ref_data[6],                                  int stride, int uvstride,                                  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, src_data, ref_data, stride, uvstride,                          motion_fx, motion_fy,                          motion_bx, motion_by,                          pred_fx, pred_fy,                          pred_bx, pred_by,                          0, 16);   return fbmin;}static inline int direct_search(MpegEncContext * s, uint8_t *src_data[3], uint8_t *ref_data[6],                                int stride, int uvstride,                                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->next_picture.motion_val[0][index][0];        s->me.co_located_mv[i][1]= s->next_picture.motion_val[0][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+= 16*mb_x + 1; // +-1 is for the simpler rounding        min+= 16*mb_x - 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+= 16*mb_y + 1; // +-1 is for the simpler rounding        min+= 16*mb_y - 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;    }        s->me.xmin= xmin;    s->me.ymin= ymin;    s->me.xmax= xmax;    s->me.ymax= ymax;    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 (!s->first_slice_line) { //FIXME maybe allow this over thread boundary as its cliped        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, &mx, &my, P, 0, 0,                                                      src_data, ref_data, stride, uvstride, mv_table, 1<<14, mv_penalty);        dmin = simple_direct_qpel_qpel_motion_search(s, &mx, &my, dmin,                                                0, 0, src_data, ref_data, stride, uvstride, 0, 16, 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, src_data, ref_data, stride, uvstride, mv_penalty);    }else{        dmin = simple_direct_hpel_epzs_motion_search(s, &mx, &my, P, 0, 0,                                                      src_data, ref_data, stride, uvstride, mv_table, 1<<15, mv_penalty);        dmin = simple_direct_hpel_hpel_motion_search(s, &mx, &my, dmin,                                                0, 0, src_data, ref_data, stride, uvstride, 0, 16, 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, src_data, ref_data, stride, uvstride, mv_penalty);    }        get_limits(s, 16*mb_x, 16*mb_y); //restore s->me.?min/max, maybe not needed    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, bimin, fimin;    int type=0;    const int stride= s->linesize;    const int uvstride= s->uvlinesize;    uint8_t *src_data[3]= {        s->new_picture.data[0] + 16*(s->mb_x + stride*s->mb_y),        s->new_picture.data[1] + 8*(s->mb_x + uvstride*s->mb_y),        s->new_picture.data[2] + 8*(s->mb_x + uvstride*s->mb_y)    };    uint8_t *ref_data[6]= {        s->last_picture.data[0] + 16*(s->mb_x + stride*s->mb_y),        s->last_picture.data[1] + 8*(s->mb_x + uvstride*s->mb_y),        s->last_picture.data[2] + 8*(s->mb_x + uvstride*s->mb_y),        s->next_picture.data[0] + 16*(s->mb_x + stride*s->mb_y),        s->next_picture.data[1] + 8*(s->mb_x + uvstride*s->mb_y),        s->next_picture.data[2] + 8*(s->mb_x + uvstride*s->mb_y)    };        s->me.skip=0;    if (s->codec_id == CODEC_ID_MPEG4)        dmin= direct_search(s, src_data, ref_data, stride, uvstride, mb_x, mb_y);    else        dmin= INT_MAX;//FIXME penalty stuff for non mpeg4    s->me.skip=0;    fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, src_data,                                ref_data, stride, uvstride, 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, src_data,                                ref_data+3, stride, uvstride, 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, src_data, ref_data, stride, uvstride, mb_x, mb_y) + penalty_factor;//printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin);        if(s->flags & CODEC_FLAG_INTERLACED_ME){        const int xy = mb_y*s->mb_stride + mb_x;//FIXME mb type penalty        s->me.skip=0;        fimin= interlaced_search(s, src_data, ref_data  ,                                  s->b_field_mv_table[0], s->b_field_select_table[0], s->f_code,                                 s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);        bimin= interlaced_search(s, src_data, ref_data+3,                                  s->b_field_mv_table[1], s->b_field_select_table[1], s->b_code,                                 s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1]);    }else        fimin= bimin= INT_MAX;    {        int score= fmin;        type = CANDIDATE_MB_TYPE_FORWARD;                if (dmin <= score){            score = dmin;            type = CANDIDATE_MB_TYPE_DIRECT;        }        if(bmin<score){            score=bmin;            type= CANDIDATE_MB_TYPE_BACKWARD;         }        if(fbmin<score){            score=fbmin;            type= CANDIDATE_MB_TYPE_BIDIR;        }        if(fimin<score){            score=fimin;            type= CANDIDATE_MB_TYPE_FORWARD_I;        }        if(bimin<score){            score=bimin;            type= CANDIDATE_MB_TYPE_BACKWARD_I;        }                score= ((unsigned)(score*score + 128*256))>>16;        s->mc_mb_var_sum_temp += 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= CANDIDATE_MB_TYPE_FORWARD | CANDIDATE_MB_TYPE_BACKWARD | CANDIDATE_MB_TYPE_BIDIR | CANDIDATE_MB_TYPE_DIRECT;        if(fimin < INT_MAX)            type |= CANDIDATE_MB_TYPE_FORWARD_I;        if(bimin < INT_MAX)            type |= CANDIDATE_MB_TYPE_BACKWARD_I;        if(fimin < INT_MAX && bimin < INT_MAX){            type |= CANDIDATE_MB_TYPE_BIDIR_I;        }         //FIXME something smarter        if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //dont try direct mode if its invalid for this MB#if 0                if(s->out_format == FMT_MPEG1)            type |= CANDIDATE_MB_TYPE_INTRA;#endif    }    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;    //printf("%d no:%d %d//\n", clip, noclip, f_code);    if(s->flags&CODEC_FLAG_4MV){        const int wrap= s->b8_stride;        /* clip / convert to intra 8x8 type MVs */        for(y=0; y<s->mb_height; y++){            int xy= y*2*wrap;            int i= y*s->mb_stride;            int x;            for(x=0; x<s->mb_width; x++){                if(s->mb_type[i]&CANDIDATE_MB_TYPE_INTER4V){                    int block;                    for(block=0; block<4; block++){                        int off= (block& 1) + (block>>1)*wrap;                        int mx= s->current_picture.motion_val[0][ xy + off ][0];                        int my= s->current_picture.motion_val[0][ xy + off ][1];                        if(   mx >=range || mx <-range                           || my >=range || my <-range){                            s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V;                            s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA;                            s->current_picture.mb_type[i]= CANDIDATE_MB_TYPE_INTRA;                        }                    }                }                x

⌨️ 快捷键说明

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