Commit 118dc81e authored by Dylan Yudaken's avatar Dylan Yudaken Committed by Fiona Glaser

Fix two issues in weightp

If analysis decided on an offset of -128, x264 would create non-compliant streams.
Fix some cases with nearly all intra blocks where analysis could pick very weird weights.
Also add some asserts to check compliancy.
parent 876c9e52
......@@ -1232,8 +1232,11 @@ static void x264_weighted_pred_init( x264_t *h )
{
weightluma = 1;
h->sh.weight[0][0].i_denom = denom = h->sh.weight[j][0].i_denom;
assert( x264_clip3( denom, 0, 7 ) == denom );
}
assert( h->sh.weight[j][0].i_denom == denom );
assert( x264_clip3( h->sh.weight[j][0].i_scale, 0, 127 ) == h->sh.weight[j][0].i_scale );
assert( x264_clip3( h->sh.weight[j][0].i_offset, -128, 127 ) == h->sh.weight[j][0].i_offset );
h->fenc->weighted[j] = h->mb.p_weight_buf[buffer_next++] +
h->fenc->i_stride[0] * i_padv + PADH;
}
......@@ -1342,10 +1345,13 @@ static inline void x264_reference_build_list( x264_t *h, int i_poc )
SET_WEIGHT( h->fenc->weight[0][0], 1, 1, 0, h->fenc->weight[0][0].i_offset );
}
x264_weighted_reference_duplicate( h, 0, weight_none );
w[0] = h->fenc->weight[0][0];
w[0].i_offset--;
h->mc.weight_cache( h, &w[0] );
x264_weighted_reference_duplicate( h, 0, w );
if( h->fenc->weight[0][0].i_offset > -128 )
{
w[0] = h->fenc->weight[0][0];
w[0].i_offset--;
h->mc.weight_cache( h, &w[0] );
x264_weighted_reference_duplicate( h, 0, w );
}
}
}
else if( h->param.analyse.i_weighted_pred == X264_WEIGHTP_BLIND )
......
......@@ -184,7 +184,6 @@ void x264_weights_analyse( x264_t *h, x264_frame_t *fenc, x264_frame_t *ref, int
ref_mean = (float)ref_sum / (fenc->i_lines[0] * fenc->i_width[0]);
//early termination
if( fabs( ref_mean - fenc_mean ) < 0.5 && fabsf( 1 - (float)fenc_var / ref_var ) < epsilon )
return;
......@@ -221,7 +220,8 @@ void x264_weights_analyse( x264_t *h, x264_frame_t *fenc, x264_frame_t *ref, int
x264_emms();
/* FIXME: More analysis can be done here on SAD vs. SATD termination. */
if( !found || (minscale == 1<<mindenom && minoff == 0) || minscore >= fenc->i_width[0] * fenc->i_lines[0] * 2 )
/* 0.2% termination derived experimentally to avoid weird weights in frames that are mostly intra. */
if( !found || (minscale == 1<<mindenom && minoff == 0) || (float)minscore / origscore > 0.998 )
{
SET_WEIGHT( weights[0], 0, 1, 0, 0 );
return;
......
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