From 118dc81e7116b16ba1d2204a387aa88669b8e0bd Mon Sep 17 00:00:00 2001 From: Dylan Yudaken Date: Sun, 15 Nov 2009 16:14:50 -0800 Subject: [PATCH] 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. --- encoder/encoder.c | 14 ++++++++++---- encoder/slicetype.c | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/encoder/encoder.c b/encoder/encoder.c index b3e71985..1fc1c7a5 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -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 ) diff --git a/encoder/slicetype.c b/encoder/slicetype.c index 9c6d2829..c12e8739 100644 --- a/encoder/slicetype.c +++ b/encoder/slicetype.c @@ -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<= 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< 0.998 ) { SET_WEIGHT( weights[0], 0, 1, 0, 0 ); return; -- 2.40.0