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 | |
parent | 377798d6bd373eeb05e13e4015a2c8e43c19fd17 (diff) | |
download | ffmpeg-316a2ec84ce19909e2732a1dc10be20bd38304c5.tar.gz |
bidir refine support
Originally committed as revision 4768 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/avcodec.h | 7 | ||||
-rw-r--r-- | libavcodec/motion_est.c | 66 | ||||
-rw-r--r-- | libavcodec/utils.c | 1 |
3 files changed, 71 insertions, 3 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index fd66eb3735..e09351f94b 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1862,6 +1862,13 @@ typedef struct AVCodecContext { * - decoding: set by user. */ enum AVDiscard skip_frame; + + /** + * + * - encoding: set by user. + * - decoding: unused + */ + int bidir_refine; } AVCodecContext; /** 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) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index fa4ed68399..0c51d961d0 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -707,6 +707,7 @@ static AVOption options[]={ {"mb_lmin", NULL, OFFSET(mb_lmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, {"mb_lmax", NULL, OFFSET(mb_lmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, {"me_penalty_compensation", NULL, OFFSET(me_penalty_compensation), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, +{"bidir_refine", NULL, OFFSET(bidir_refine), FF_OPT_TYPE_INT, DEFAULT, 0, 4, V|E}, {NULL}, }; |