X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmotion_est.c;h=99c55645446b0fab2e9aa5ac4071f429c66d9396;hb=9e6b5e61a0c91e25e298d0a21b189c4c95443795;hp=4ad47faf660ee3076a86d3b690208d9c5d8055ec;hpb=473e547e80fd74c44179905a4fa99cfc39cc9b79;p=ffmpeg diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index 4ad47faf660..99c55645446 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -30,29 +30,26 @@ #include #include #include -#include "libavutil/intmath.h" + #include "avcodec.h" -#include "dsputil.h" #include "mathops.h" #include "mpegvideo.h" #undef NDEBUG #include -#define SQ(a) ((a)*(a)) - #define P_LEFT P[1] #define P_TOP P[2] #define P_TOPRIGHT P[3] #define P_MEDIAN P[4] #define P_MV1 P[9] -static inline int sad_hpel_motion_search(MpegEncContext * s, +static int sad_hpel_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, int size, int h); -static inline int update_map_generation(MotionEstContext *c) +static inline unsigned update_map_generation(MotionEstContext *c) { c->map_generation+= 1<<(ME_MAP_MV_BITS*2); if(c->map_generation==0){ @@ -292,7 +289,7 @@ static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){ return 0; } -static void zero_hpel(uint8_t *a, const uint8_t *b, int stride, int h){ +static void zero_hpel(uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h){ } int ff_init_me(MpegEncContext *s){ @@ -304,8 +301,9 @@ int ff_init_me(MpegEncContext *s){ av_log(s->avctx, AV_LOG_ERROR, "ME_MAP size is too small for SAB diamond\n"); return -1; } - //special case of snow is needed because snow uses its own iterative ME code - if(s->me_method!=ME_ZERO && s->me_method!=ME_EPZS && s->me_method!=ME_X1 && s->avctx->codec_id != CODEC_ID_SNOW){ + if (s->me_method != ME_ZERO && + s->me_method != ME_EPZS && + s->me_method != ME_X1) { av_log(s->avctx, AV_LOG_ERROR, "me_method is only allowed to be set to zero and epzs; for hex,umh,full and others see dia_size\n"); return -1; } @@ -356,33 +354,22 @@ int ff_init_me(MpegEncContext *s){ /* 8x8 fullpel search would need a 4x4 chroma compare, which we do * not have yet, and even if we had, the motion estimation code * does not expect it. */ - if(s->codec_id != CODEC_ID_SNOW){ - if((c->avctx->me_cmp&FF_CMP_CHROMA)/* && !s->dsp.me_cmp[2]*/){ - s->dsp.me_cmp[2]= zero_cmp; - } - if((c->avctx->me_sub_cmp&FF_CMP_CHROMA) && !s->dsp.me_sub_cmp[2]){ - s->dsp.me_sub_cmp[2]= zero_cmp; - } - c->hpel_put[2][0]= c->hpel_put[2][1]= - c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel; + if((c->avctx->me_cmp&FF_CMP_CHROMA)/* && !s->dsp.me_cmp[2]*/){ + s->dsp.me_cmp[2]= zero_cmp; + } + if((c->avctx->me_sub_cmp&FF_CMP_CHROMA) && !s->dsp.me_sub_cmp[2]){ + s->dsp.me_sub_cmp[2]= zero_cmp; } + c->hpel_put[2][0]= c->hpel_put[2][1]= + c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel; - if(s->codec_id == CODEC_ID_H261){ + if(s->codec_id == AV_CODEC_ID_H261){ c->sub_motion_search= no_sub_motion_search; } return 0; } -static inline void no_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr) -{ - *mx_ptr = 16 * s->mb_x; - *my_ptr = 16 * s->mb_y; -} - -#define Z_THRESHOLD 256 - #define CHECK_SAD_HALF_MV(suffix, x, y) \ {\ d= s->dsp.pix_abs[size][(x?1:0)+(y?2:0)](NULL, pix, ptr+((x)>>1), stride, h);\ @@ -390,7 +377,7 @@ static inline void no_motion_search(MpegEncContext * s, COPY3_IF_LT(dminh, d, dx, x, dy, y)\ } -static inline int sad_hpel_motion_search(MpegEncContext * s, +static int sad_hpel_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, int size, int h) @@ -406,12 +393,10 @@ static inline int sad_hpel_motion_search(MpegEncContext * s, assert(flags == 0); if(c->skip){ -// printf("S"); *mx_ptr = 0; *my_ptr = 0; return dmin; } -// printf("N"); pix = c->src[src_index][0]; @@ -509,16 +494,16 @@ static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4) if(mv4){ int mot_xy= s->block_index[0]; - s->current_picture.f.motion_val[0][mot_xy ][0] = mx; - s->current_picture.f.motion_val[0][mot_xy ][1] = my; - s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx; - s->current_picture.f.motion_val[0][mot_xy + 1][1] = my; + 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; mot_xy += s->b8_stride; - s->current_picture.f.motion_val[0][mot_xy ][0] = mx; - s->current_picture.f.motion_val[0][mot_xy ][1] = my; - s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx; - s->current_picture.f.motion_val[0][mot_xy + 1][1] = my; + 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; } } @@ -591,8 +576,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) const int mot_stride = s->b8_stride; const int mot_xy = s->block_index[block]; - P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0]; - P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1]; + 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<xmax<pred_x= pred_x4= P_LEFT[0]; c->pred_y= pred_y4= P_LEFT[1]; } else { - P_TOP[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][0]; - P_TOP[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][1]; - P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][0]; - P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][1]; + 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] > (c->ymax<ymax<xmin<xmin< (c->xmax<xmax<current_picture.f.motion_val[0][s->block_index[block]][0] = mx4; - s->current_picture.f.motion_val[0][s->block_index[block]][1] = 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; } @@ -840,150 +825,24 @@ static int interlaced_search(MpegEncContext *s, int ref_index, } } -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.f.mb_type[mb_xy]; - int flags= c->flags; - int shift= (flags&FLAG_QPEL) + 1; - int mask= (1<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->f.motion_val[0][xy], !!IS_INTERLACED(mb_type)); - clip_input_mv(s, p->f.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->f.ref_index[0][4*mb_xy ]; - int field_select1= p->f.ref_index[0][4*mb_xy+2]; - 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->f.motion_val[0][xy ]; - *(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy] = *(uint32_t*)p->f.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->f.motion_val[0][xy ]; - *(uint32_t*)s->b_field_mv_table[0][1][field_select1][mb_xy] = *(uint32_t*)p->f.motion_val[0][xy2]; - s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_FORWARD_I; - } - - x = p->f.motion_val[0][xy ][0]; - y = p->f.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->f.motion_val[0][xy2][0]; - y = p->f.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->f.ref_index[1][4 * mb_xy ]; - int field_select1 = p->f.ref_index[1][4 * mb_xy + 2]; - 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->f.motion_val[1][xy ]; - *(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy] = *(uint32_t*)p->f.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->f.motion_val[1][xy ][0]; - y = p->f.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->f.motion_val[1][xy2][0]; - y = p->f.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->f.motion_val[0][xy][0]; - y= p->f.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->f.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->f.motion_val[0][xy]; - *(uint32_t*)s->b_bidir_back_mv_table[mb_xy] = *(uint32_t*)p->f.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->f.motion_val[0][xy]; - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_FORWARD; - } - x = p->f.motion_val[0][xy][0]; - y = p->f.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->f.motion_val[1][xy]; - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BACKWARD; - - x = p->f.motion_val[1][xy][0]; - y = p->f.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; +static inline int get_penalty_factor(int lambda, int lambda2, int type){ + switch(type&0xFF){ + default: + case FF_CMP_SAD: + return lambda>>FF_LAMBDA_SHIFT; + case FF_CMP_DCT: + return (3*lambda)>>(FF_LAMBDA_SHIFT+1); + case FF_CMP_SATD: + case FF_CMP_DCT264: + return (2*lambda)>>FF_LAMBDA_SHIFT; + case FF_CMP_RD: + case FF_CMP_PSNR: + case FF_CMP_SSE: + case FF_CMP_NSSE: + return lambda2>>FF_LAMBDA_SHIFT; + case FF_CMP_BIT: + return 1; } - return d; } void ff_estimate_p_frame_motion(MpegEncContext * s, @@ -1016,33 +875,17 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, /* 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; + 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; + mx = 0; + my = 0; dmin = 0; break; case ME_X1: @@ -1051,16 +894,16 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, const int mot_stride = s->b8_stride; const int mot_xy = s->block_index[0]; - P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0]; - P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1]; + 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<xmax<first_slice_line) { - P_TOP[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][0]; - P_TOP[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][1]; - P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][0]; - P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][1]; + 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<ymax<xmin<xmin< (c->ymax<ymax<dsp.sse[0](NULL, pix, ppix, s->linesize, 16); pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8; -// pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin; c->mc_mb_var_sum_temp += (vard+128)>>8; if(mb_type){ @@ -1152,7 +994,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip) - dmin= ff_get_mb_score(s, mx, my, 0, 0, 0, 16, 1); + dmin= get_mb_score(s, mx, my, 0, 0, 0, 16, 1); if((s->flags&CODEC_FLAG_4MV) && !c->skip && varc>50<<8 && vard>10<<8){ @@ -1171,14 +1013,13 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, } } -// pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin; set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V); /* get intra luma score */ if((c->avctx->mb_cmp&0xFF)==FF_CMP_SSE){ intra_score= varc - 500; }else{ - int mean= (sum+128)>>8; + unsigned mean = (sum+128)>>8; mean*= 0x01010101; for(i=0; i<16; i++){ @@ -1194,9 +1035,9 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, if(intra_score < dmin){ mb_type= CANDIDATE_MB_TYPE_INTRA; - s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup + s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup }else - s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = 0; + s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = 0; { int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100); @@ -1283,35 +1124,32 @@ static int ff_estimate_motion_b(MpegEncContext * s, switch(s->me_method) { case ME_ZERO: default: - no_motion_search(s, &mx, &my); + mx = 0; + my = 0; dmin = 0; - mx-= mb_x*16; - my-= mb_y*16; break; case ME_X1: case ME_EPZS: - { - P_LEFT[0] = mv_table[mot_xy - 1][0]; - P_LEFT[1] = mv_table[mot_xy - 1][1]; + P_LEFT[0] = mv_table[mot_xy - 1][0]; + P_LEFT[1] = mv_table[mot_xy - 1][1]; - if(P_LEFT[0] > (c->xmax<xmax<first_slice_line) { - 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] > (c->ymax<ymax<xmin<xmin< (c->ymax<ymax< (c->xmax << shift)) P_LEFT[0] = (c->xmax << 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]); - } - c->pred_x= P_LEFT[0]; - c->pred_y= P_LEFT[1]; + /* special case for first line */ + if (!s->first_slice_line) { + 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] > (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]); } + c->pred_x = P_LEFT[0]; + c->pred_y = P_LEFT[1]; if(mv_table == s->b_forw_mv_table){ mv_scale= (s->pb_time<<16) / (s->pp_time<sub_motion_search(s, &mx, &my, dmin, 0, ref_index, 0, 16); if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip) - dmin= ff_get_mb_score(s, mx, my, 0, ref_index, 0, 16, 1); + dmin= get_mb_score(s, mx, my, 0, ref_index, 0, 16, 1); -//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; @@ -1426,9 +1263,8 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y) #define HASH(fx,fy,bx,by) ((fx)+17*(fy)+63*(bx)+117*(by)) #define HASH8(fx,fy,bx,by) ((uint8_t)HASH(fx,fy,bx,by)) int hashidx= HASH(motion_fx,motion_fy, motion_bx, motion_by); - uint8_t map[256]; + uint8_t map[256] = { 0 }; - memset(map,0,sizeof(map)); map[hashidx&255] = 1; fbmin= check_bidir_mv(s, motion_fx, motion_fy, @@ -1567,7 +1403,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) ymin= xmin=(-32)>>shift; ymax= xmax= 31>>shift; - if (IS_8X8(s->next_picture.f.mb_type[mot_xy])) { + if (IS_8X8(s->next_picture.mb_type[mot_xy])) { s->mv_type= MV_TYPE_8X8; }else{ s->mv_type= MV_TYPE_16X16; @@ -1577,8 +1413,8 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) int index= s->block_index[i]; int min, max; - c->co_located_mv[i][0] = s->next_picture.f.motion_val[0][index][0]; - c->co_located_mv[i][1] = s->next_picture.f.motion_val[0][index][1]; + c->co_located_mv[i][0] = s->next_picture.motion_val[0][index][0]; + c->co_located_mv[i][1] = s->next_picture.motion_val[0][index][1]; c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3)); c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3)); // c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3); @@ -1640,7 +1476,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) dmin = hpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip) - dmin= ff_get_mb_score(s, mx, my, 0, 0, 0, 16, 1); + dmin= get_mb_score(s, mx, my, 0, 0, 0, 16, 1); get_limits(s, 16*mb_x, 16*mb_y); //restore c->?min/max, maybe not needed @@ -1667,7 +1503,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, c->skip=0; - if (s->codec_id == CODEC_ID_MPEG4 && s->next_picture.f.mbskip_table[xy]) { + if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]) { int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0 score= ((unsigned)(score*score + 128*256))>>16; @@ -1678,58 +1514,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, return; } - if(c->avctx->me_threshold){ - int vard= check_input_motion(s, mb_x, mb_y, 0); - - if((vard+128)>>8 < c->avctx->me_threshold){ -// 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_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8; - s->current_picture.mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8; -/* pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8; - c->mb_var_sum_temp += (varc+128)>>8;*/ - c->mc_mb_var_sum_temp += (vard+128)>>8; -/* if (vard <= 64<<8 || vard < varc) { - c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); - }else{ - c->scene_change_score+= s->qscale * s->avctx->scenechange_factor; - }*/ - return; - } - if((vard+128)>>8 < c->avctx->mb_threshold){ - type= s->mb_type[mb_y*s->mb_stride + mb_x]; - if(type == CANDIDATE_MB_TYPE_DIRECT){ - direct_search(s, mb_x, mb_y); - } - if(type == CANDIDATE_MB_TYPE_FORWARD || type == CANDIDATE_MB_TYPE_BIDIR){ - c->skip=0; - ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code); - } - if(type == CANDIDATE_MB_TYPE_BACKWARD || type == CANDIDATE_MB_TYPE_BIDIR){ - c->skip=0; - ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code); - } - if(type == CANDIDATE_MB_TYPE_FORWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){ - c->skip=0; - c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; - interlaced_search(s, 0, - s->b_field_mv_table[0], s->b_field_select_table[0], - s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 1); - } - if(type == CANDIDATE_MB_TYPE_BACKWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){ - c->skip=0; - c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_MV; - interlaced_search(s, 2, - s->b_field_mv_table[1], s->b_field_select_table[1], - s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 1); - } - return; - } - } - - if (s->codec_id == CODEC_ID_MPEG4) + if (s->codec_id == AV_CODEC_ID_MPEG4) dmin= direct_search(s, mb_x, mb_y); else dmin= INT_MAX; @@ -1739,11 +1524,11 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, c->skip=0; bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) + 2*penalty_factor; -//printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); + av_dlog(s, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); c->skip=0; fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor; -//printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin); + av_dlog(s, "%d %d %d %d\n", dmin, fmin, bmin, fbmin); if(s->flags & CODEC_FLAG_INTERLACED_ME){ //FIXME mb type penalty @@ -1800,7 +1585,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, } //FIXME something smarter if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //do not try direct mode if it is invalid for this MB - if(s->codec_id == CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT && s->flags&CODEC_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy]) + if(s->codec_id == AV_CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT && s->flags&CODEC_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy]) type |= CANDIDATE_MB_TYPE_DIRECT0; } @@ -1819,7 +1604,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) if(s->msmpeg4_version) range= FFMIN(range, 16); - else if(s->codec_id == CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) + else if(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) range= FFMIN(range, 256); for(i=0; i<8; i++) score[i]= s->mb_num*(8-i); @@ -1853,15 +1638,9 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) 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; } @@ -1877,11 +1656,10 @@ void ff_fix_long_p_mvs(MpegEncContext * s) range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code); assert(range <= 16 || !s->msmpeg4_version); - assert(range <=256 || !(s->codec_id == CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)); + assert(range <=256 || !(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)); if(c->avctx->me_range && range > c->avctx->me_range) range= c->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; @@ -1896,14 +1674,14 @@ void ff_fix_long_p_mvs(MpegEncContext * s) int block; for(block=0; block<4; block++){ int off= (block& 1) + (block>>1)*wrap; - int mx = s->current_picture.f.motion_val[0][ xy + off ][0]; - int my = s->current_picture.f.motion_val[0][ xy + off ][1]; + 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.f.mb_type[i] = CANDIDATE_MB_TYPE_INTRA; + s->current_picture.mb_type[i] = CANDIDATE_MB_TYPE_INTRA; } } }