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

📄 motion_est.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    const int size=0;    const int h=8;    int block;    int P[10][2];    uint8_t * const mv_penalty= c->current_mv_penalty;    int same=1;    const int stride= 2*s->linesize;    int dmin_sum= 0;    const int mot_stride= s->mb_stride;    const int xy= s->mb_x + s->mb_y*mot_stride;    c->ymin>>=1;    c->ymax>>=1;    c->stride<<=1;    c->uvstride<<=1;    init_interlaced_ref(s, ref_index);    for(block=0; block<2; block++){        int field_select;        int best_dmin= INT_MAX;        int best_field= -1;        for(field_select=0; field_select<2; field_select++){            int dmin, mx_i, my_i;            int16_t (*mv_table)[2]= mv_tables[block][field_select];            if(user_field_select){                assert(field_select==0 || field_select==1);                assert(field_select_tables[block][xy]==0 || field_select_tables[block][xy]==1);                if(field_select_tables[block][xy] != field_select)                    continue;            }            P_LEFT[0] = mv_table[xy - 1][0];            P_LEFT[1] = mv_table[xy - 1][1];            if(P_LEFT[0]       > (c->xmax<<1)) P_LEFT[0]       = (c->xmax<<1);            c->pred_x= P_LEFT[0];            c->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]      > (c->ymax<<1)) P_TOP[1]     = (c->ymax<<1);                if(P_TOPRIGHT[0] < (c->xmin<<1)) P_TOPRIGHT[0]= (c->xmin<<1);                if(P_TOPRIGHT[0] > (c->xmax<<1)) P_TOPRIGHT[0]= (c->xmax<<1);                if(P_TOPRIGHT[1] > (c->ymax<<1)) P_TOPRIGHT[1]= (c->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 = epzs_motion_search2(s, &mx_i, &my_i, P, block, field_select+ref_index, mv_table, (1<<16)>>1);            dmin= c->sub_motion_search(s, &mx_i, &my_i, dmin, block, field_select+ref_index, size, h);            mv_table[xy][0]= mx_i;            mv_table[xy][1]= my_i;            if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){                int dxy;                //FIXME chroma ME                uint8_t *ref= c->ref[field_select+ref_index][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](c->scratchpad, ref    , stride, h);                }else{                    s->dsp.put_pixels_tab       [size][dxy](c->scratchpad, ref    , stride, h);                }                dmin= s->dsp.mb_cmp[size](s, c->src[block][0], c->scratchpad, stride, h);                dmin+= (mv_penalty[mx_i-c->pred_x] + mv_penalty[my_i-c->pred_y] + 1)*c->mb_penalty_factor;            }else                dmin+= c->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;    }    c->ymin<<=1;    c->ymax<<=1;    c->stride>>=1;    c->uvstride>>=1;    if(same)        return INT_MAX;    switch(c->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*c->mb_penalty_factor;    }}static void clip_input_mv(MpegEncContext * s, int16_t *mv, int interlaced){    int ymax= s->me.ymax>>interlaced;    int ymin= s->me.ymin>>interlaced;    if(mv[0] < s->me.xmin) mv[0] = s->me.xmin;    if(mv[0] > s->me.xmax) mv[0] = s->me.xmax;    if(mv[1] <       ymin) mv[1] =       ymin;    if(mv[1] >       ymax) mv[1] =       ymax;}static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int p_type){    MotionEstContext * const c= &s->me;    Picture *p= s->current_picture_ptr;    int mb_xy= mb_x + mb_y*s->mb_stride;    int xy= 2*mb_x + 2*mb_y*s->b8_stride;    int mb_type= s->current_picture.mb_type[mb_xy];    int flags= c->flags;    int shift= (flags&FLAG_QPEL) + 1;    int mask= (1<<shift)-1;    int x, y, i;    int d=0;    me_cmp_func cmpf= s->dsp.sse[0];    me_cmp_func chroma_cmpf= s->dsp.sse[1];    if(p_type && USES_LIST(mb_type, 1)){        av_log(c->avctx, AV_LOG_ERROR, "backward motion vector in P frame\n");        return INT_MAX/2;    }    assert(IS_INTRA(mb_type) || USES_LIST(mb_type,0) || USES_LIST(mb_type,1));    for(i=0; i<4; i++){        int xy= s->block_index[i];        clip_input_mv(s, p->motion_val[0][xy], !!IS_INTERLACED(mb_type));        clip_input_mv(s, p->motion_val[1][xy], !!IS_INTERLACED(mb_type));    }    if(IS_INTERLACED(mb_type)){        int xy2= xy  + s->b8_stride;        s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA;        c->stride<<=1;        c->uvstride<<=1;        if(!(s->flags & CODEC_FLAG_INTERLACED_ME)){            av_log(c->avctx, AV_LOG_ERROR, "Interlaced macroblock selected but interlaced motion estimation disabled\n");            return INT_MAX/2;        }        if(USES_LIST(mb_type, 0)){            int field_select0= p->ref_index[0][xy ];            int field_select1= p->ref_index[0][xy2];            assert(field_select0==0 ||field_select0==1);            assert(field_select1==0 ||field_select1==1);            init_interlaced_ref(s, 0);            if(p_type){                s->p_field_select_table[0][mb_xy]= field_select0;                s->p_field_select_table[1][mb_xy]= field_select1;                *(uint32_t*)s->p_field_mv_table[0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ];                *(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2];                s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER_I;            }else{                s->b_field_select_table[0][0][mb_xy]= field_select0;                s->b_field_select_table[0][1][mb_xy]= field_select1;                *(uint32_t*)s->b_field_mv_table[0][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ];                *(uint32_t*)s->b_field_mv_table[0][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2];                s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_FORWARD_I;            }            x= p->motion_val[0][xy ][0];            y= p->motion_val[0][xy ][1];            d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0, 0, cmpf, chroma_cmpf, flags);            x= p->motion_val[0][xy2][0];            y= p->motion_val[0][xy2][1];            d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1, 1, cmpf, chroma_cmpf, flags);        }        if(USES_LIST(mb_type, 1)){            int field_select0= p->ref_index[1][xy ];            int field_select1= p->ref_index[1][xy2];            assert(field_select0==0 ||field_select0==1);            assert(field_select1==0 ||field_select1==1);            init_interlaced_ref(s, 2);            s->b_field_select_table[1][0][mb_xy]= field_select0;            s->b_field_select_table[1][1][mb_xy]= field_select1;            *(uint32_t*)s->b_field_mv_table[1][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[1][xy ];            *(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[1][xy2];            if(USES_LIST(mb_type, 0)){                s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BIDIR_I;            }else{                s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BACKWARD_I;            }            x= p->motion_val[1][xy ][0];            y= p->motion_val[1][xy ][1];            d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0+2, 0, cmpf, chroma_cmpf, flags);            x= p->motion_val[1][xy2][0];            y= p->motion_val[1][xy2][1];            d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1+2, 1, cmpf, chroma_cmpf, flags);            //FIXME bidir scores        }        c->stride>>=1;        c->uvstride>>=1;    }else if(IS_8X8(mb_type)){        if(!(s->flags & CODEC_FLAG_4MV)){            av_log(c->avctx, AV_LOG_ERROR, "4MV macroblock selected but 4MV encoding disabled\n");            return INT_MAX/2;        }        cmpf= s->dsp.sse[1];        chroma_cmpf= s->dsp.sse[1];        init_mv4_ref(c);        for(i=0; i<4; i++){            xy= s->block_index[i];            x= p->motion_val[0][xy][0];            y= p->motion_val[0][xy][1];            d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 1, 8, i, i, cmpf, chroma_cmpf, flags);        }        s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER4V;    }else{        if(USES_LIST(mb_type, 0)){            if(p_type){                *(uint32_t*)s->p_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy];                s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER;            }else if(USES_LIST(mb_type, 1)){                *(uint32_t*)s->b_bidir_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy];                *(uint32_t*)s->b_bidir_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy];                s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BIDIR;            }else{                *(uint32_t*)s->b_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy];                s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_FORWARD;            }            x= p->motion_val[0][xy][0];            y= p->motion_val[0][xy][1];            d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 0, 0, cmpf, chroma_cmpf, flags);        }else if(USES_LIST(mb_type, 1)){            *(uint32_t*)s->b_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy];            s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BACKWARD;            x= p->motion_val[1][xy][0];            y= p->motion_val[1][xy][1];            d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 2, 0, cmpf, chroma_cmpf, flags);        }else            s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA;    }    return d;}void ff_estimate_p_frame_motion(MpegEncContext * s,                                int mb_x, int mb_y){    MotionEstContext * const c= &s->me;    uint8_t *pix, *ppix;    int sum, mx, my, dmin;    int varc;            ///< the variance of the block (sum of squared (p[y][x]-average))    int vard;            ///< sum of squared differences with the estimated motion vector    int P[10][2];    const int shift= 1+s->quarter_sample;    int mb_type=0;    Picture * const pic= &s->current_picture;    init_ref(c, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0);    assert(s->quarter_sample==0 || s->quarter_sample==1);    assert(s->linesize == c->stride);    assert(s->uvlinesize == c->uvstride);    c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);    c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;    get_limits(s, 16*mb_x, 16*mb_y);    c->skip=0;    /* intra / predictive decision */    pix = c->src[0][0];    sum = s->dsp.pix_sum(pix, s->linesize);    varc = s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500;    pic->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;    pic->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8;    c->mb_var_sum_temp += (varc+128)>>8;    if(c->avctx->me_threshold){        vard= check_input_motion(s, mb_x, mb_y, 1);        if((vard+128)>>8 < c->avctx->me_threshold){            int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);            int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;            pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;            c->mc_mb_var_sum_temp += (vard+128)>>8;            c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);            return;        }        if((vard+128)>>8 < c->avctx->mb_threshold)            mb_type= s->mb_type[mb_x + mb_y*s->mb_stride];    }    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;    case ME_X1:    case ME_EPZS:       {            const int mot_stride = s->b8_stride;            const int mot_xy = s->block_index[0];            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]       > (c->xmax<<shift)) P_LEFT[0]       = (c->xmax<<shift);            if(!s->first_slice_line) {                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 + 2][0];                P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1];                if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);                if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);                if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->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]);

⌨️ 快捷键说明

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