From: Loren Merritt Date: Fri, 28 Jan 2005 02:51:21 +0000 (+0000) Subject: Clipping mvs to within picture + emulated border when running motion compensation. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bccb009f9fa67797da6cd3da742ad9a27266b12b;p=libx264 Clipping mvs to within picture + emulated border when running motion compensation. git-svn-id: svn://svn.videolan.org/x264/trunk@109 df754926-b1dd-0310-bc7b-ec298dee348c --- diff --git a/common/common.h b/common/common.h index 93ed97e7..03b93259 100644 --- a/common/common.h +++ b/common/common.h @@ -263,6 +263,10 @@ struct x264_t int i_b8_xy; int i_b4_xy; + /* Allowed MV range to stay within the picture + emulated edge pixels */ + int mv_min[2]; + int mv_max[2]; + unsigned int i_neighbour; /* mb table */ diff --git a/common/macroblock.c b/common/macroblock.c index 44a4f5f7..851c1649 100644 --- a/common/macroblock.c +++ b/common/macroblock.c @@ -347,10 +347,6 @@ void x264_mb_predict_mv_pskip( x264_t *h, int mv[2] ) { x264_mb_predict_mv_16x16( h, 0, 0, mv ); } - - /* FIXME: ensure that mvp doesn't extend past picture edge + padding. - * we can't just clip the mv here, since the original value may be - * needed for predicting other mvs. */ } static int x264_mb_predict_mv_direct16x16_temporal( x264_t *h ) @@ -455,8 +451,6 @@ static int x264_mb_predict_mv_direct16x16_spatial( x264_t *h ) } } - /* FIXME: clip mv ? */ - x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, ref[0] ); x264_macroblock_cache_ref( h, 0, 0, 4, 4, 1, ref[1] ); x264_macroblock_cache_mv( h, 0, 0, 4, 4, 0, mv[0][0], mv[0][1] ); @@ -580,8 +574,8 @@ static inline void x264_mb_mc_0xywh( x264_t *h, int x, int y, int width, int hei { const int i8 = x264_scan8[0]+x+8*y; const int i_ref = h->mb.cache.ref[0][i8]; - const int mvx = h->mb.cache.mv[0][i8][0]; - const int mvy = h->mb.cache.mv[0][i8][1]; + const int mvx = x264_clip3( h->mb.cache.mv[0][i8][0], h->mb.mv_min[0], h->mb.mv_max[0] ); + const int mvy = x264_clip3( h->mb.cache.mv[0][i8][1], h->mb.mv_min[1], h->mb.mv_max[1] ); h->mc[MC_LUMA]( &h->mb.pic.p_fref[0][i_ref][0][4*y * h->mb.pic.i_stride[0]+4*x], h->mb.pic.i_stride[0], &h->mb.pic.p_fdec[0][4*y * h->mb.pic.i_stride[0]+4*x], h->mb.pic.i_stride[0], @@ -599,8 +593,8 @@ static inline void x264_mb_mc_1xywh( x264_t *h, int x, int y, int width, int hei { const int i8 = x264_scan8[0]+x+8*y; const int i_ref = h->mb.cache.ref[1][i8]; - const int mvx = h->mb.cache.mv[1][i8][0]; - const int mvy = h->mb.cache.mv[1][i8][1]; + const int mvx = x264_clip3( h->mb.cache.mv[1][i8][0], h->mb.mv_min[0], h->mb.mv_max[0] ); + const int mvy = x264_clip3( h->mb.cache.mv[1][i8][1], h->mb.mv_min[1], h->mb.mv_max[1] ); h->mc[MC_LUMA]( &h->mb.pic.p_fref[1][i_ref][0][4*y * h->mb.pic.i_stride[0]+4*x], h->mb.pic.i_stride[0], &h->mb.pic.p_fdec[0][4*y *h->mb.pic.i_stride[0]+4*x], h->mb.pic.i_stride[0], @@ -620,12 +614,12 @@ static inline void x264_mb_mc_01xywh( x264_t *h, int x, int y, int width, int he const int i8 = x264_scan8[0]+x+8*y; const int i_ref0 = h->mb.cache.ref[0][i8]; - const int mvx0 = h->mb.cache.mv[0][i8][0]; - const int mvy0 = h->mb.cache.mv[0][i8][1]; + const int mvx0 = x264_clip3( h->mb.cache.mv[0][i8][0], h->mb.mv_min[0], h->mb.mv_max[0] ); + const int mvy0 = x264_clip3( h->mb.cache.mv[0][i8][1], h->mb.mv_min[1], h->mb.mv_max[1] ); const int i_ref1 = h->mb.cache.ref[1][i8]; - const int mvx1 = h->mb.cache.mv[1][i8][0]; - const int mvy1 = h->mb.cache.mv[1][i8][1]; + const int mvx1 = x264_clip3( h->mb.cache.mv[1][i8][0], h->mb.mv_min[0], h->mb.mv_max[0] ); + const int mvy1 = x264_clip3( h->mb.cache.mv[1][i8][1], h->mb.mv_min[1], h->mb.mv_max[1] ); DECLARE_ALIGNED( uint8_t, tmp[16*16], 16 ); int i_mode = 0; diff --git a/encoder/analyse.c b/encoder/analyse.c index 0e9af6b5..a21e6f7b 100644 --- a/encoder/analyse.c +++ b/encoder/analyse.c @@ -156,7 +156,17 @@ static void x264_mb_analyse_init( x264_t *h, x264_mb_analysis_t *a, int i_qp ) int dmb; int i; + /* Calculate max allowed MV range */ + h->mb.mv_min[0] = 4*( -16*h->mb.i_mb_x - 24 ); + h->mb.mv_max[0] = 4*( 16*( h->sps->i_mb_width - h->mb.i_mb_x ) + 8 ); + if( h->mb.i_mb_x == 0) + { + h->mb.mv_min[1] = 4*( -16*h->mb.i_mb_y - 24 ); + h->mb.mv_max[1] = 4*( 16*( h->sps->i_mb_height - h->mb.i_mb_y ) + 8 ); + } + /* Calculate max start MV range */ + /* FIXME: use the above ranges */ dmb = h->mb.i_mb_x; if( h->mb.i_mb_y < dmb ) dmb = h->mb.i_mb_y; diff --git a/encoder/macroblock.c b/encoder/macroblock.c index 2aec1eb7..ea371d37 100644 --- a/encoder/macroblock.c +++ b/encoder/macroblock.c @@ -512,8 +512,10 @@ static void x264_macroblock_encode_skip( x264_t *h ) *****************************************************************************/ void x264_macroblock_encode_pskip( x264_t *h ) { - const int mvx = h->mb.cache.mv[0][x264_scan8[0]][0]; - const int mvy = h->mb.cache.mv[0][x264_scan8[0]][1]; + const int mvx = x264_clip3( h->mb.cache.mv[0][x264_scan8[0]][0], + h->mb.mv_min[0], h->mb.mv_max[0] ); + const int mvy = x264_clip3( h->mb.cache.mv[0][x264_scan8[0]][1], + h->mb.mv_min[1], h->mb.mv_max[1] ); /* Motion compensation XXX probably unneeded */ h->mc[MC_LUMA]( h->mb.pic.p_fref[0][0][0], h->mb.pic.i_stride[0], @@ -786,7 +788,6 @@ int x264_macroblock_probe_skip( x264_t *h, int b_bidir ) int i_qp; int mvp[2]; int ch; - int n; int i8x8, i4x4; int i_decimate_mb; @@ -798,13 +799,8 @@ int x264_macroblock_probe_skip( x264_t *h, int b_bidir ) { /* Get the MV */ x264_mb_predict_mv_pskip( h, mvp ); - - mvp[0] = x264_clip3( mvp[0], - 4*( -16*h->mb.i_mb_x - 24 ), - 4*( 16*( h->sps->i_mb_width - h->mb.i_mb_x ) + 8 ) ); - mvp[1] = x264_clip3( mvp[1], - 4*( -16*h->mb.i_mb_y - 24 ), - 4*( 16*( h->sps->i_mb_height - h->mb.i_mb_y ) + 8 ) ); + mvp[0] = x264_clip3( mvp[0], h->mb.mv_min[0], h->mb.mv_max[0] ); + mvp[1] = x264_clip3( mvp[1], h->mb.mv_min[1], h->mb.mv_max[1] ); /* Motion compensation */ h->mc[MC_LUMA]( h->mb.pic.p_fref[0][0][0], h->mb.pic.i_stride[0],