diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2005-12-23 16:25:00 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2005-12-23 16:25:00 +0000 |
commit | 316a2ec84ce19909e2732a1dc10be20bd38304c5 (patch) | |
tree | a6463ec661172156ff35c67d0b661791f164012c /libavcodec/motion_est.c | |
parent | 377798d6bd373eeb05e13e4015a2c8e43c19fd17 (diff) | |
download | ffmpeg-316a2ec84ce19909e2732a1dc10be20bd38304c5.tar.gz |
bidir refine support
Originally committed as revision 4768 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/motion_est.c')
-rw-r--r-- | libavcodec/motion_est.c | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index b01c386c99..b645ffef03 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -1617,6 +1617,7 @@ static inline int check_bidir_mv(MpegEncContext * s, /* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y) { + MotionEstContext * const c= &s->me; const int mot_stride = s->mb_stride; const int xy = mb_y *mot_stride + mb_x; int fbmin; @@ -1628,8 +1629,13 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y) 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 + const int flags= c->sub_flags; + const int qpel= flags&FLAG_QPEL; + const int shift= 1+qpel; + const int xmin= c->xmin<<shift; + const int ymin= c->ymin<<shift; + const int xmax= c->xmax<<shift; + const int ymax= c->ymax<<shift; fbmin= check_bidir_mv(s, motion_fx, motion_fy, motion_bx, motion_by, @@ -1637,7 +1643,61 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y) pred_bx, pred_by, 0, 16); - return fbmin; + if(s->avctx->bidir_refine){ + int score, end; +#define CHECK_BIDIR(fx,fy,bx,by)\ + score= check_bidir_mv(s, motion_fx+fx, motion_fy+fy, motion_bx+bx, motion_by+by, pred_fx, pred_fy, pred_bx, pred_by, 0, 16);\ + if(score < fbmin){\ + fbmin= score;\ + motion_fx+=fx;\ + motion_fy+=fy;\ + motion_bx+=bx;\ + motion_by+=by;\ + end=0;\ + } +#define CHECK_BIDIR2(a,b,c,d)\ +CHECK_BIDIR(a,b,c,d)\ +CHECK_BIDIR(-a,-b,-c,-d) + +#define CHECK_BIDIRR(a,b,c,d)\ +CHECK_BIDIR2(a,b,c,d)\ +CHECK_BIDIR2(b,c,d,a)\ +CHECK_BIDIR2(c,d,a,b)\ +CHECK_BIDIR2(d,a,b,c) + + do{ + end=1; + + if( motion_fx >= xmax || motion_bx >= xmax || motion_fx <= xmin || motion_bx <= xmin + || motion_fy >= ymax || motion_by >= ymax || motion_fy <= ymin || motion_by <= ymin) + break; + + CHECK_BIDIRR( 0, 0, 0, 1) + if(s->avctx->bidir_refine > 1){ + CHECK_BIDIRR( 0, 0, 1, 1) + CHECK_BIDIR2( 0, 1, 0, 1) + CHECK_BIDIR2( 1, 0, 1, 0) + CHECK_BIDIRR( 0, 0,-1, 1) + CHECK_BIDIR2( 0,-1, 0, 1) + CHECK_BIDIR2(-1, 0, 1, 0) + if(s->avctx->bidir_refine > 2){ + CHECK_BIDIRR( 0, 1, 1, 1) + CHECK_BIDIRR( 0,-1, 1, 1) + CHECK_BIDIRR( 0, 1,-1, 1) + CHECK_BIDIRR( 0, 1, 1,-1) + if(s->avctx->bidir_refine > 3){ + CHECK_BIDIR2( 1, 1, 1, 1) + CHECK_BIDIRR( 1, 1, 1,-1) + CHECK_BIDIR2( 1, 1,-1,-1) + CHECK_BIDIR2( 1,-1,-1, 1) + CHECK_BIDIR2( 1,-1, 1,-1) + } + } + } + }while(!end); + } + + return fbmin; } static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) |