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

📄 motion_est.c

📁 arm平台下的H264编码和解码源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        s->current_picture.motion_val[0][mot_xy  ][0]= mx;        s->current_picture.motion_val[0][mot_xy  ][1]= my;        s->current_picture.motion_val[0][mot_xy+1][0]= mx;        s->current_picture.motion_val[0][mot_xy+1][1]= my;    }}/** * get fullpel ME search limits. */static inline void get_limits(MpegEncContext *s, int x, int y){/*    if(s->avctx->me_range) s->me.range= s->avctx->me_range >> 1;    else                   s->me.range= 16;*/    if (s->unrestricted_mv) {        s->me.xmin = - x - 16;        s->me.ymin = - y - 16;        s->me.xmax = - x + s->mb_width *16;        s->me.ymax = - y + s->mb_height*16;    } else {        s->me.xmin = - x;        s->me.ymin = - y;        s->me.xmax = - x + s->mb_width *16 - 16;        s->me.ymax = - y + s->mb_height*16 - 16;    }}static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift){    const int size= 1;    const int h=8;    int block;    int P[10][2];    int dmin_sum=0, mx4_sum=0, my4_sum=0;    uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;    int same=1;    const int stride= s->linesize;    const int uvstride= s->uvlinesize;    for(block=0; block<4; block++){        int mx4, my4;        int pred_x4, pred_y4;        int dmin4;        static const int off[4]= {2, 1, 1, -1};        const int mot_stride = s->b8_stride;        const int mot_xy = s->block_index[block];        const int block_x= (block&1);        const int block_y= (block>>1);        uint8_t *src_data[3]= {            s->new_picture.data[0] + 8*(2*s->mb_x + block_x) + stride  *8*(2*s->mb_y + block_y), //FIXME chroma?            s->new_picture.data[1] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y),            s->new_picture.data[2] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y)        };        uint8_t *ref_data[3]= {            s->last_picture.data[0] + 8*(2*s->mb_x + block_x) + stride  *8*(2*s->mb_y + block_y), //FIXME chroma?            s->last_picture.data[1] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y),            s->last_picture.data[2] + 4*(2*s->mb_x + block_x) + uvstride*4*(2*s->mb_y + block_y)        };        P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];        P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];        if(P_LEFT[0]       > (s->me.xmax<<shift)) P_LEFT[0]       = (s->me.xmax<<shift);        /* special case for first line */        if (s->first_slice_line && block<2) {            pred_x4= P_LEFT[0];            pred_y4= P_LEFT[1];        } else {            P_TOP[0]      = s->current_picture.motion_val[0][mot_xy - mot_stride             ][0];            P_TOP[1]      = s->current_picture.motion_val[0][mot_xy - mot_stride             ][1];            P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0];            P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1];            if(P_TOP[1]      > (s->me.ymax<<shift)) P_TOP[1]     = (s->me.ymax<<shift);            if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift);            if(P_TOPRIGHT[0] > (s->me.xmax<<shift)) P_TOPRIGHT[0]= (s->me.xmax<<shift);            if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.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]);//            if(s->out_format == FMT_H263){                pred_x4 = P_MEDIAN[0];                pred_y4 = P_MEDIAN[1];#if 0            }else { /* mpeg1 at least */                pred_x4= P_LEFT[0];                pred_y4= P_LEFT[1];            }#endif        }        P_MV1[0]= mx;        P_MV1[1]= my;        dmin4 = s->me.motion_search[1](s, &mx4, &my4, P, pred_x4, pred_y4,                                        src_data, ref_data, stride, uvstride, s->p_mv_table, (1<<16)>>shift, mv_penalty);        dmin4= s->me.sub_motion_search(s, &mx4, &my4, dmin4, 					  pred_x4, pred_y4, src_data, ref_data, stride, uvstride, size, h, mv_penalty);                if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]           && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE){            int dxy;            const int offset= ((block&1) + (block>>1)*stride)*8;            uint8_t *dest_y = s->me.scratchpad + offset;            if(s->quarter_sample){                uint8_t *ref= ref_data[0] + (mx4>>2) + (my4>>2)*stride;                dxy = ((my4 & 3) << 2) | (mx4 & 3);                if(s->no_rounding)                    s->dsp.put_no_rnd_qpel_pixels_tab[1][dxy](dest_y   , ref    , stride);                else                    s->dsp.put_qpel_pixels_tab       [1][dxy](dest_y   , ref    , stride);            }else{                uint8_t *ref= ref_data[0] + (mx4>>1) + (my4>>1)*stride;                dxy = ((my4 & 1) << 1) | (mx4 & 1);                if(s->no_rounding)                    s->dsp.put_no_rnd_pixels_tab[1][dxy](dest_y    , ref    , stride, h);                else                    s->dsp.put_pixels_tab       [1][dxy](dest_y    , ref    , stride, h);            }            dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*s->me.mb_penalty_factor;        }else            dmin_sum+= dmin4;        if(s->quarter_sample){            mx4_sum+= mx4/2;            my4_sum+= my4/2;        }else{            mx4_sum+= mx4;            my4_sum+= my4;        }                    s->current_picture.motion_val[0][ s->block_index[block] ][0]= mx4;        s->current_picture.motion_val[0][ s->block_index[block] ][1]= my4;        if(mx4 != mx || my4 != my) same=0;    }        if(same)        return INT_MAX;        if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){        dmin_sum += s->dsp.mb_cmp[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*16*stride, s->me.scratchpad, stride, 16);    }        if(s->avctx->mb_cmp&FF_CMP_CHROMA){        int dxy;        int mx, my;        int offset;        mx= ff_h263_round_chroma(mx4_sum);        my= ff_h263_round_chroma(my4_sum);        dxy = ((my & 1) << 1) | (mx & 1);                offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize;               if(s->no_rounding){            s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad    , s->last_picture.data[1] + offset, s->uvlinesize, 8);            s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad+8  , s->last_picture.data[2] + offset, s->uvlinesize, 8);        }else{            s->dsp.put_pixels_tab       [1][dxy](s->me.scratchpad    , s->last_picture.data[1] + offset, s->uvlinesize, 8);            s->dsp.put_pixels_tab       [1][dxy](s->me.scratchpad+8  , s->last_picture.data[2] + offset, s->uvlinesize, 8);        }        dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, s->me.scratchpad  , s->uvlinesize, 8);        dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, s->me.scratchpad+8, s->uvlinesize, 8);    }    switch(s->avctx->mb_cmp&0xFF){    /*case FF_CMP_SSE:        return dmin_sum+ 32*s->qscale*s->qscale;*/    case FF_CMP_RD:        return dmin_sum;    default:        return dmin_sum+ 11*s->me.mb_penalty_factor;    }}static int interlaced_search(MpegEncContext *s, uint8_t *frame_src_data[3], uint8_t *frame_ref_data[3],                              int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int f_code, int mx, int my){    const int size=0;    const int h=8;    int block;    int P[10][2];    uint8_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV;    int same=1;    const int stride= 2*s->linesize;    const int uvstride= 2*s->uvlinesize;    int dmin_sum= 0;    const int mot_stride= s->mb_stride;    const int xy= s->mb_x + s->mb_y*mot_stride;        s->me.ymin>>=1;    s->me.ymax>>=1;        for(block=0; block<2; block++){        int field_select;        int best_dmin= INT_MAX;        int best_field= -1;        uint8_t *src_data[3]= {            frame_src_data[0] + s->  linesize*block,            frame_src_data[1] + s->uvlinesize*block,            frame_src_data[2] + s->uvlinesize*block        };        for(field_select=0; field_select<2; field_select++){            int dmin, mx_i, my_i, pred_x, pred_y;            uint8_t *ref_data[3]= {                frame_ref_data[0] + s->  linesize*field_select,                frame_ref_data[1] + s->uvlinesize*field_select,                frame_ref_data[2] + s->uvlinesize*field_select            };            int16_t (*mv_table)[2]= mv_tables[block][field_select];                        P_LEFT[0] = mv_table[xy - 1][0];            P_LEFT[1] = mv_table[xy - 1][1];            if(P_LEFT[0]       > (s->me.xmax<<1)) P_LEFT[0]       = (s->me.xmax<<1);                        pred_x= P_LEFT[0];            pred_y= P_LEFT[1];                        if(!s->first_slice_line){                P_TOP[0]      = mv_table[xy - mot_stride][0];                P_TOP[1]      = mv_table[xy - mot_stride][1];                P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0];                P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1];                if(P_TOP[1]      > (s->me.ymax<<1)) P_TOP[1]     = (s->me.ymax<<1);                if(P_TOPRIGHT[0] < (s->me.xmin<<1)) P_TOPRIGHT[0]= (s->me.xmin<<1);                if(P_TOPRIGHT[0] > (s->me.xmax<<1)) P_TOPRIGHT[0]= (s->me.xmax<<1);                if(P_TOPRIGHT[1] > (s->me.ymax<<1)) P_TOPRIGHT[1]= (s->me.ymax<<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]);            }            P_MV1[0]= mx; //FIXME not correct if block != field_select            P_MV1[1]= my / 2;                        dmin = s->me.motion_search[4](s, &mx_i, &my_i, P, pred_x, pred_y,                                            src_data, ref_data, stride, uvstride, mv_table, (1<<16)>>1, mv_penalty);            dmin= s->me.sub_motion_search(s, &mx_i, &my_i, dmin,                                            pred_x, pred_y, src_data, ref_data, stride, uvstride, size, h, mv_penalty);                        mv_table[xy][0]= mx_i;            mv_table[xy][1]= my_i;                        if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]               && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE){                int dxy;                //FIXME chroma ME                uint8_t *ref= ref_data[0] + (mx_i>>1) + (my_i>>1)*stride;                dxy = ((my_i & 1) << 1) | (mx_i & 1);                if(s->no_rounding){                    s->dsp.put_no_rnd_pixels_tab[size][dxy](s->me.scratchpad, ref    , stride, h);                }else{                    s->dsp.put_pixels_tab       [size][dxy](s->me.scratchpad, ref    , stride, h);                }                dmin= s->dsp.mb_cmp[size](s, src_data[0], s->me.scratchpad, stride, h);                dmin+= (mv_penalty[mx_i-pred_x] + mv_penalty[my_i-pred_y] + 1)*s->me.mb_penalty_factor;            }else                dmin+= s->me.mb_penalty_factor; //field_select bits                            dmin += field_select != block; //slightly prefer same field                        if(dmin < best_dmin){                best_dmin= dmin;                best_field= field_select;            }        }        {            int16_t (*mv_table)[2]= mv_tables[block][best_field];            if(mv_table[xy][0] != mx) same=0; //FIXME check if these checks work and are any good at all            if(mv_table[xy][1]&1) same=0;            if(mv_table[xy][1]*2 != my) same=0;             if(best_field != block) same=0;        }        field_select_tables[block][xy]= best_field;        dmin_sum += best_dmin;    }        s->me.ymin<<=1;    s->me.ymax<<=1;    if(same)        return INT_MAX;        switch(s->avctx->mb_cmp&0xFF){    /*case FF_CMP_SSE:        return dmin_sum+ 32*s->qscale*s->qscale;*/    case FF_CMP_RD:        return dmin_sum;    default:        return dmin_sum+ 11*s->me.mb_penalty_factor;    }}void ff_estimate_p_frame_motion(MpegEncContext * s,                                int mb_x, int mb_y){    uint8_t *pix, *ppix;    int sum, varc, vard, mx, my, dmin, xx, yy;    int pred_x=0, pred_y=0;    int P[10][2];    const int shift= 1+s->quarter_sample;    int mb_type=0;    uint8_t *ref_picture= s->last_picture.data[0];    Picture * const pic= &s->current_picture;    uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;    const int stride= s->linesize;    const int uvstride= s->uvlinesize;    uint8_t *src_data[3]= {        s->new_picture.data[0] + 16*(mb_x + stride*mb_y),        s->new_picture.data[1] + 8*(mb_x + uvstride*mb_y),        s->new_picture.data[2] + 8*(mb_x + uvstride*mb_y)    };    uint8_t *ref_data[3]= {        s->last_picture.data[0] + 16*(mb_x + stride*mb_y),        s->last_picture.data[1] + 8*(mb_x + uvstride*mb_y),        s->last_picture.data[2] + 8*(mb_x + uvstride*mb_y)    };    assert(s->quarter_sample==0 || s->quarter_sample==1);    s->me.penalty_factor    = get_penalty_factor(s, s->avctx->me_cmp);    s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp);    s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);    get_limits(s, 16*mb_x, 16*mb_y);    s->me.skip=0;    switch(s->me_method) {    case ME_ZERO:    default:	no_motion_search(s, &mx, &my);        mx-= mb_x*16;        my-= mb_y*16;        dmin = 0;        break;#if 0    case ME_FULL:	dmin = full_motion_search(s, &mx, &my, range, ref_picture);        mx-= mb_x*16;        my-= mb_y*16;        break;    case ME_LOG:	dmin = log_motion_search(s, &mx, &my, range / 2, ref_picture);        mx-= mb_x*16;        my-= mb_y*16;        break;    case ME_PHODS:	dmin = phods_motion_search(s, &mx, &my, range / 2, ref_picture);        mx-= mb_x*16;        my-= mb_y*16;        break;#endif    case ME_X1:    case ME_EPZS:       {

⌨️ 快捷键说明

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