[x264-devel] commit: Fix two issues in weightp (Dylan Yudaken )

git version control git at videolan.org
Mon Nov 16 01:32:17 CET 2009


x264 | branch: master | Dylan Yudaken <dyudaken at gmail.com> | Sun Nov 15 16:14:50 2009 -0800| [e8501efbd235b1b5321adda8926e7a859beafd3c] | committer: Jason Garrett-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.

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=e8501efbd235b1b5321adda8926e7a859beafd3c
---

 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 886e36a..0b4117e 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 d2585df..bd3fcb9 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<<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;



More information about the x264-devel mailing list