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

📄 motion_est.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
        }else{            if(l<=r){                if(t+l<=b+r){                    CHECK_HALF_MV(xy2, -1, -1)                    ptr+= s->linesize;                }else{                    ptr+= s->linesize;                    CHECK_HALF_MV(xy2, +1, +1)                }                CHECK_HALF_MV(x2 , -1,  0)                CHECK_HALF_MV(xy2, -1, +1)            }else{                if(t+r<=b+l){                    CHECK_HALF_MV(xy2, +1, -1)                    ptr+= s->linesize;                }else{                    ptr+= s->linesize;                    CHECK_HALF_MV(xy2, -1, +1)                }                CHECK_HALF_MV(x2 , +1,  0)                CHECK_HALF_MV(xy2, +1, +1)            }            CHECK_HALF_MV(y2 ,  0, +1)        }        mx+=dx;        my+=dy;    }else{        mx<<=1;        my<<=1;    }    *mx_ptr = mx;    *my_ptr = my;    return dminh;}static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4){    const int xy= s->mb_x + 1 + (s->mb_y + 1)*(s->mb_width + 2);        s->p_mv_table[xy][0] = mx;    s->p_mv_table[xy][1] = my;    /* has allready been set to the 4 MV if 4MV is done */    if(mv4){        int mot_xy= s->block_index[0];        s->motion_val[mot_xy  ][0]= mx;        s->motion_val[mot_xy  ][1]= my;        s->motion_val[mot_xy+1][0]= mx;        s->motion_val[mot_xy+1][1]= my;        mot_xy += s->block_wrap[0];        s->motion_val[mot_xy  ][0]= mx;        s->motion_val[mot_xy  ][1]= my;        s->motion_val[mot_xy+1][0]= mx;        s->motion_val[mot_xy+1][1]= my;    }}static inline void get_limits(MpegEncContext *s, int *range, int *xmin, int *ymin, int *xmax, int *ymax, int f_code){    *range = 8 * (1 << (f_code - 1));    /* XXX: temporary kludge to avoid overflow for msmpeg4 */    if (s->out_format == FMT_H263 && !s->h263_msmpeg4)	*range *= 2;    if (s->unrestricted_mv) {        *xmin = -16;        *ymin = -16;        if (s->h263_plus)            *range *= 2;        if(s->avctx==NULL || s->avctx->codec->id!=CODEC_ID_MPEG4){            *xmax = s->mb_width*16;            *ymax = s->mb_height*16;        }else {            /* XXX: dunno if this is correct but ffmpeg4 decoder wont like it otherwise 	            (cuz the drawn edge isnt large enough))*/            *xmax = s->width;            *ymax = s->height;        }    } else {        *xmin = 0;        *ymin = 0;        *xmax = s->mb_width*16 - 16;        *ymax = s->mb_height*16 - 16;    }}static inline int mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, int ymax, int mx, int my, int shift){    int block;    int P[10][2];    uint8_t *ref_picture= s->last_picture[0];    int dmin_sum=0;    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->block_wrap[0];        const int mot_xy = s->block_index[block];//        const int block_x= (block&1);//        const int block_y= (block>>1);#if 1 // this saves us a bit of cliping work and shouldnt affect compression in a negative way        const int rel_xmin4= xmin;        const int rel_xmax4= xmax;        const int rel_ymin4= ymin;        const int rel_ymax4= ymax;#else        const int rel_xmin4= xmin - block_x*8;        const int rel_xmax4= xmax - block_x*8 + 8;        const int rel_ymin4= ymin - block_y*8;        const int rel_ymax4= ymax - block_y*8 + 8;#endif        P_LAST[0] = s->motion_val[mot_xy    ][0];        P_LAST[1] = s->motion_val[mot_xy    ][1];        P_LEFT[0] = s->motion_val[mot_xy - 1][0];        P_LEFT[1] = s->motion_val[mot_xy - 1][1];        P_LAST_RIGHT[0] = s->motion_val[mot_xy + 1][0];        P_LAST_RIGHT[1] = s->motion_val[mot_xy + 1][1];        P_LAST_BOTTOM[0]= s->motion_val[mot_xy + 1*mot_stride][0];        P_LAST_BOTTOM[1]= s->motion_val[mot_xy + 1*mot_stride][1];        if(P_LEFT[0]       > (rel_xmax4<<shift)) P_LEFT[0]       = (rel_xmax4<<shift);        if(P_LAST_RIGHT[0] < (rel_xmin4<<shift)) P_LAST_RIGHT[0] = (rel_xmin4<<shift);        if(P_LAST_BOTTOM[1]< (rel_ymin4<<shift)) P_LAST_BOTTOM[1]= (rel_ymin4<<shift);        /* special case for first line */        if ((s->mb_y == 0 || s->first_slice_line) && block<2) {            pred_x4= P_LEFT[0];            pred_y4= P_LEFT[1];        } else {            P_TOP[0]      = s->motion_val[mot_xy - mot_stride             ][0];            P_TOP[1]      = s->motion_val[mot_xy - mot_stride             ][1];            P_TOPRIGHT[0] = s->motion_val[mot_xy - mot_stride + off[block]][0];            P_TOPRIGHT[1] = s->motion_val[mot_xy - mot_stride + off[block]][1];            if(P_TOP[1]      > (rel_ymax4<<shift)) P_TOP[1]     = (rel_ymax4<<shift);            if(P_TOPRIGHT[0] < (rel_xmin4<<shift)) P_TOPRIGHT[0]= (rel_xmin4<<shift);            if(P_TOPRIGHT[0] > (rel_xmax4<<shift)) P_TOPRIGHT[0]= (rel_xmax4<<shift);            if(P_TOPRIGHT[1] > (rel_ymax4<<shift)) P_TOPRIGHT[1]= (rel_ymax4<<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];            }else { /* mpeg1 at least */                pred_x4= P_LEFT[0];                pred_y4= P_LEFT[1];            }        }        P_MV1[0]= mx;        P_MV1[1]= my;        dmin4 = epzs_motion_search4(s, block, &mx4, &my4, P, pred_x4, pred_y4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4, ref_picture);        dmin4= fast_halfpel_motion_search(s, &mx4, &my4, dmin4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4, 					  pred_x4, pred_y4, ref_picture, s->dsp.pix_abs8x8_x2,					  s->dsp.pix_abs8x8_y2, s->dsp.pix_abs8x8_xy2, block);         s->motion_val[ s->block_index[block] ][0]= mx4;        s->motion_val[ s->block_index[block] ][1]= my4;        dmin_sum+= dmin4;    }    return dmin_sum;}void ff_estimate_p_frame_motion(MpegEncContext * s,                                int mb_x, int mb_y){    UINT8 *pix, *ppix;    int sum, varc, vard, mx, my, range, dmin, xx, yy;    int xmin, ymin, xmax, ymax;    int rel_xmin, rel_ymin, rel_xmax, rel_ymax;    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[0];    get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code);    rel_xmin= xmin - mb_x*16;    rel_xmax= xmax - mb_x*16;    rel_ymin= ymin - mb_y*16;    rel_ymax= ymax - mb_y*16;    s->skip_me=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;    case ME_FULL:	dmin = full_motion_search(s, &mx, &my, range, xmin, ymin, xmax, ymax, ref_picture);        mx-= mb_x*16;        my-= mb_y*16;        break;    case ME_LOG:	dmin = log_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax, ref_picture);        mx-= mb_x*16;        my-= mb_y*16;        break;    case ME_PHODS:	dmin = phods_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax, ref_picture);        mx-= mb_x*16;        my-= mb_y*16;        break;    case ME_X1:    case ME_EPZS:       {            const int mot_stride = s->block_wrap[0];            const int mot_xy = s->block_index[0];            P_LAST[0]       = s->motion_val[mot_xy    ][0];            P_LAST[1]       = s->motion_val[mot_xy    ][1];            P_LEFT[0]       = s->motion_val[mot_xy - 1][0];            P_LEFT[1]       = s->motion_val[mot_xy - 1][1];            P_LAST_RIGHT[0] = s->motion_val[mot_xy + 2][0];            P_LAST_RIGHT[1] = s->motion_val[mot_xy + 2][1];            P_LAST_BOTTOM[0]= s->motion_val[mot_xy + 2*mot_stride][0];            P_LAST_BOTTOM[1]= s->motion_val[mot_xy + 2*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)) {                pred_x= P_LEFT[0];                pred_y= P_LEFT[1];            } else {                P_TOP[0]      = s->motion_val[mot_xy - mot_stride    ][0];                P_TOP[1]      = s->motion_val[mot_xy - mot_stride    ][1];                P_TOPRIGHT[0] = s->motion_val[mot_xy - mot_stride + 2][0];                P_TOPRIGHT[1] = s->motion_val[mot_xy - mot_stride + 2][1];                if(P_TOP[1]      > (rel_ymax<<shift)) P_TOP[1]     = (rel_ymax<<shift);                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]);                if(s->out_format == FMT_H263){                    pred_x = P_MEDIAN[0];                    pred_y = P_MEDIAN[1];                }else { /* mpeg1 at least */                    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;    }    /* intra / predictive decision */    xx = mb_x * 16;    yy = mb_y * 16;    pix = s->new_picture[0] + (yy * s->linesize) + xx;    /* At this point (mx,my) are full-pell and the relative displacement */    ppix = ref_picture + ((yy+my) * s->linesize) + (xx+mx);        sum = s->dsp.pix_sum(pix, s->linesize);        varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;    // FIXME: MMX OPTIMIZE    vard = (pix_norm(pix, ppix, s->linesize)+128)>>8;//printf("%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);    s->mb_var   [s->mb_width * mb_y + mb_x] = varc;    s->mc_mb_var[s->mb_width * mb_y + mb_x] = vard;    s->mb_mean  [s->mb_width * mb_y + mb_x] = (sum+128)>>8;    s->mb_var_sum    += varc;    s->mc_mb_var_sum += vard;//printf("E%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);    #if 0    printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n",	   varc, s->avg_mb_var, sum, vard, mx - xx, my - yy);#endif    if(s->flags&CODEC_FLAG_HQ){        if (vard <= 64 || vard < varc)            s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);        else            s->scene_change_score+= 20;        if (vard*2 + 200 > varc)            mb_type|= MB_TYPE_INTRA;        if (varc*2 + 200 > vard){            mb_type|= MB_TYPE_INTER;            if(s->me_method >= ME_EPZS)                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);            else                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);        }else{            mx <<=1;            my <<=1;        }        if((s->flags&CODEC_FLAG_4MV)           && !s->skip_me && varc>50 && vard>10){            mv4_search(s, rel_xmin, rel_ymin, rel_xmax, rel_ymax, mx, my, shift);            mb_type|=MB_TYPE_INTER4V;            set_p_mv_tables(s, mx, my, 0);        }else            set_p_mv_tables(s, mx, my, 1);    }else{        if (vard <= 64 || vard < varc) {            s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);            mb_type|= MB_TYPE_INTER;            if (s->me_method != ME_ZERO) {                if(s->me_method >= ME_EPZS)		    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);                else                    dmin= 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);                if((s->flags&CODEC_FLAG_4MV)                   && !s->skip_me && varc>50 && vard>10){                    int dmin4= mv4_search(s, rel_xmin, rel_ymin, rel_xmax, rel_ymax, mx, my, shift);                    if(dmin4 + 128 <dmin)                        mb_type= MB_TYPE_INTER4V;                }                set_p_mv_tables(s, mx, my, mb_type!=MB_TYPE_INTER4V);            } else {                mx <<=1;                my <<=1;            }#if 0            if (vard < 10) {                skip++;                fprintf(stderr,"\nEarly skip: %d vard: %2d varc: %5d dmin: %d",                                 skip, vard, varc, dmin);            }#endif        }else{            s->scene_change_score+= 20;            mb_type|= MB_TYPE_INTRA;            mx = 0;            my = 0;        }    }    s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;}int ff_estimate_motion_b(MpegEncContext * s,                       int mb_x, int mb_y, int16_t (*mv_table)[2], uint8_t *ref_picture, int f_code){    int mx, my, range, dmin;    int xmin, ymin, xmax, ymax;    int rel_xmin, rel_ymin, rel_xmax, rel_ymax;    int pred_x=0, pred_y=0;    int P[10][2];    const int shift= 1+s->quarter_sample;    const int mot_stride = s->mb_width + 2;    const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1;        get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, f_code);    rel_xmin= xmin - mb_x*16;    rel_xmax= xmax - mb_x*16;    rel_ymin= ymin - mb_y*16;    rel_ymax= ymax - mb_y*16;    switch(s->me_method) {    case ME_ZERO:    default:	no_motion_search(s, &mx, &my);        dmin = 0;        mx-= mb_x*16;        my-= mb_y*16;        break;    case ME_FULL:	dmin = full_motion_search(s, &mx, &my, range, xmin, ymin, xmax, ymax, ref_picture);        mx-= mb_x*16;        my-= mb_y*16;        break;    case ME_LOG:	dmin = log_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax, ref_picture);        mx-= mb_x*16;        my-= mb_y*16;        break;    case ME_PHODS:	dmin = phods_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax, ref_picture);        mx-= mb_x*16;        my-= mb_y*16;        break;    case ME_X1:    case ME_EPZS:       {            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];                if(P_TOP[1] > (rel_ymax<<shift)) P_TOP[1]= (rel_ymax<<shift);                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]);

⌨️ 快捷键说明

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