Commit a373f2ae authored by Loren Merritt's avatar Loren Merritt

split mv_range enforcement from edge-of-frame clipping. fixes an occasional artifact with long mvs.



git-svn-id: svn://svn.videolan.org/x264/trunk@405 df754926-b1dd-0310-bc7b-ec298dee348c
parent 61b57afb
......@@ -359,6 +359,10 @@ struct x264_t
/* Allowed qpel MV range to stay within the picture + emulated edge pixels */
int mv_min[2];
int mv_max[2];
/* Subpel MV range for motion search.
* same mv_min/max but includes levels' i_mv_range. */
int mv_min_spel[2];
int mv_max_spel[2];
/* Fullpel MV range for motion search */
int mv_min_fpel[2];
int mv_max_fpel[2];
......
......@@ -168,9 +168,9 @@ static void x264_mb_analyse_load_costs( x264_t *h, x264_mb_analysis_t *a )
/* could be faster, but isn't called many times */
/* factor of 4 from qpel, 2 from sign, and 2 because mv can be opposite from mvp */
int i;
p_cost_mv[a->i_qp] = x264_malloc( (4*4*h->param.analyse.i_mv_range + 1) * sizeof(int16_t) );
p_cost_mv[a->i_qp] += 2*4*h->param.analyse.i_mv_range;
for( i = 0; i <= 2*4*h->param.analyse.i_mv_range; i++ )
p_cost_mv[a->i_qp] = x264_malloc( (4*4*2048 + 1) * sizeof(int16_t) );
p_cost_mv[a->i_qp] += 2*4*2048;
for( i = 0; i <= 2*4*2048; i++ )
{
p_cost_mv[a->i_qp][-i] =
p_cost_mv[a->i_qp][i] = a->i_lambda * bs_size_se( i );
......@@ -216,16 +216,20 @@ static void x264_mb_analyse_init( x264_t *h, x264_mb_analysis_t *a, int i_qp )
/* Calculate max allowed MV range */
#define CLIP_FMV(mv) x264_clip3( mv, -i_fmv_range, i_fmv_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 - 1 ) + 24 );
h->mb.mv_min_fpel[0] = CLIP_FMV( -16*h->mb.i_mb_x - 8 );
h->mb.mv_max_fpel[0] = CLIP_FMV( 16*( h->sps->i_mb_width - h->mb.i_mb_x ) - 8 );
h->mb.mv_min[0] = 4*( h->mb.mv_min_fpel[0] - 16 );
h->mb.mv_max[0] = 4*( h->mb.mv_max_fpel[0] + 16 );
h->mb.mv_max_fpel[0] = CLIP_FMV( 16*( h->sps->i_mb_width - h->mb.i_mb_x - 1 ) + 8 );
h->mb.mv_min_spel[0] = 4*( h->mb.mv_min_fpel[0] - 16 );
h->mb.mv_max_spel[0] = 4*( h->mb.mv_max_fpel[0] + 16 );
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 - 1 ) + 24 );
h->mb.mv_min_fpel[1] = CLIP_FMV( -16*h->mb.i_mb_y - 8 );
h->mb.mv_max_fpel[1] = CLIP_FMV( 16*( h->sps->i_mb_height - h->mb.i_mb_y ) - 8 );
h->mb.mv_min[1] = 4*( h->mb.mv_min_fpel[1] - 16 );
h->mb.mv_max[1] = 4*( h->mb.mv_max_fpel[1] + 16 );
h->mb.mv_max_fpel[1] = CLIP_FMV( 16*( h->sps->i_mb_height - h->mb.i_mb_y - 1 ) + 8 );
h->mb.mv_min_spel[1] = 4*( h->mb.mv_min_fpel[1] - 16 );
h->mb.mv_max_spel[1] = 4*( h->mb.mv_max_fpel[1] + 16 );
}
#undef CLIP_FMV
......
......@@ -105,8 +105,8 @@ void x264_me_search_ref( x264_t *h, x264_me_t *m, int (*mvc)[2], int i_mvc, int
if( h->mb.i_me_method == X264_ME_UMH )
{
/* clamp mvp to inside frame+padding, so that we don't have to check it each iteration */
p_cost_mvx = m->p_cost_mv - x264_clip3( m->mvp[0], h->mb.mv_min[0], h->mb.mv_max[0] );
p_cost_mvy = m->p_cost_mv - x264_clip3( m->mvp[1], h->mb.mv_min[1], h->mb.mv_max[1] );
p_cost_mvx = m->p_cost_mv - x264_clip3( m->mvp[0], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
p_cost_mvy = m->p_cost_mv - x264_clip3( m->mvp[1], h->mb.mv_min_spel[1], h->mb.mv_max_spel[1] );
}
bmx = pmx = x264_clip3( ( m->mvp[0] + 2 ) >> 2, mv_x_min, mv_x_max );
......@@ -433,8 +433,8 @@ static void refine_subpel( x264_t *h, x264_me_t *m, int hpel_iters, int qpel_ite
/* try the subpel component of the predicted mv */
if( hpel_iters )
{
int mx = x264_clip3( m->mvp[0], h->mb.mv_min[0], h->mb.mv_max[0] );
int my = x264_clip3( m->mvp[1], h->mb.mv_min[1], h->mb.mv_max[1] );
int mx = x264_clip3( m->mvp[0], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
int my = x264_clip3( m->mvp[1], h->mb.mv_min_spel[1], h->mb.mv_max_spel[1] );
if( mx != bmx || my != bmy )
COST_MV_SAD( mx, my, -1 );
}
......@@ -551,10 +551,10 @@ int x264_me_refine_bidir( x264_t *h, x264_me_t *m0, x264_me_t *m1, int i_weight
const int bw = x264_pixel_size[i_pixel].w;
const int bh = x264_pixel_size[i_pixel].h;
const int bs = bw*bh;
const int16_t *p_cost_m0x = m0->p_cost_mv - x264_clip3( m0->mvp[0], h->mb.mv_min[0], h->mb.mv_max[0] );
const int16_t *p_cost_m0y = m0->p_cost_mv - x264_clip3( m0->mvp[1], h->mb.mv_min[0], h->mb.mv_max[0] );
const int16_t *p_cost_m1x = m1->p_cost_mv - x264_clip3( m1->mvp[0], h->mb.mv_min[0], h->mb.mv_max[0] );
const int16_t *p_cost_m1y = m1->p_cost_mv - x264_clip3( m1->mvp[1], h->mb.mv_min[0], h->mb.mv_max[0] );
const int16_t *p_cost_m0x = m0->p_cost_mv - x264_clip3( m0->mvp[0], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
const int16_t *p_cost_m0y = m0->p_cost_mv - x264_clip3( m0->mvp[1], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
const int16_t *p_cost_m1x = m1->p_cost_mv - x264_clip3( m1->mvp[0], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
const int16_t *p_cost_m1y = m1->p_cost_mv - x264_clip3( m1->mvp[1], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
DECLARE_ALIGNED( uint8_t, pix0[9][16*16], 16 );
DECLARE_ALIGNED( uint8_t, pix1[9][16*16], 16 );
DECLARE_ALIGNED( uint8_t, pix[16*16], 16 );
......
......@@ -61,6 +61,10 @@ static void x264_lowres_context_init( x264_t *h, x264_mb_analysis_t *a )
h->mb.mv_min_fpel[1] = -16;
h->mb.mv_max_fpel[0] =
h->mb.mv_max_fpel[1] = 16;
h->mb.mv_min_spel[0] =
h->mb.mv_min_spel[1] = -4*32;
h->mb.mv_max_spel[0] =
h->mb.mv_max_spel[1] = 4*32;
h->mb.mv_min[0] =
h->mb.mv_min[1] = -4*32;
h->mb.mv_max[0] =
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment