Tweak i16x16-delta-quant-avoidance code
authorFiona Glaser <fiona@x264.com>
Thu, 20 Jun 2013 22:51:39 +0000 (15:51 -0700)
committerFiona Glaser <fiona@x264.com>
Wed, 3 Jul 2013 00:13:10 +0000 (17:13 -0700)
Don't omit the delta quant if it'd raise the quantizer to do so; this fixes
a rare flickering issue caused by deblocking.

encoder/cabac.c
encoder/cavlc.c

index 0a14ecd..2a9297d 100644 (file)
@@ -152,8 +152,10 @@ static void x264_cabac_qp_delta( x264_t *h, x264_cabac_t *cb )
     int i_dqp = h->mb.i_qp - h->mb.i_last_qp;
     int ctx;
 
-    /* Avoid writing a delta quant if we have an empty i16x16 block, e.g. in a completely flat background area */
-    if( h->mb.i_type == I_16x16 && !h->mb.cbp[h->mb.i_mb_xy] )
+    /* Avoid writing a delta quant if we have an empty i16x16 block, e.g. in a completely
+     * flat background area. Don't do this if it would raise the quantizer, since that could
+     * cause unexpected deblocking artifacts. */
+    if( h->mb.i_type == I_16x16 && !h->mb.cbp[h->mb.i_mb_xy] && h->mb.i_qp > h->mb.i_last_qp )
     {
 #if !RDO_SKIP_BS
         h->mb.i_qp = h->mb.i_last_qp;
@@ -161,9 +163,7 @@ static void x264_cabac_qp_delta( x264_t *h, x264_cabac_t *cb )
         i_dqp = 0;
     }
 
-    /* Since, per the above, empty-CBP I16x16 blocks never have delta quants,
-     * we don't have to check for them. */
-    ctx = h->mb.i_last_dqp && h->mb.cbp[h->mb.i_mb_prev_xy];
+    ctx = h->mb.i_last_dqp && (h->mb.type[h->mb.i_mb_prev_xy] == I_16x16 || (h->mb.cbp[h->mb.i_mb_prev_xy]&0x3f));
 
     if( i_dqp != 0 )
     {
index daf0614..dfdfd91 100644 (file)
@@ -213,11 +213,14 @@ static void x264_cavlc_qp_delta( x264_t *h )
     bs_t *s = &h->out.bs;
     int i_dqp = h->mb.i_qp - h->mb.i_last_qp;
 
-    /* Avoid writing a delta quant if we have an empty i16x16 block, e.g. in a completely flat background area */
+    /* Avoid writing a delta quant if we have an empty i16x16 block, e.g. in a completely
+     * flat background area. Don't do this if it would raise the quantizer, since that could
+     * cause unexpected deblocking artifacts. */
     if( h->mb.i_type == I_16x16 && !(h->mb.i_cbp_luma | h->mb.i_cbp_chroma)
         && !h->mb.cache.non_zero_count[x264_scan8[LUMA_DC]]
         && !h->mb.cache.non_zero_count[x264_scan8[CHROMA_DC+0]]
-        && !h->mb.cache.non_zero_count[x264_scan8[CHROMA_DC+1]] )
+        && !h->mb.cache.non_zero_count[x264_scan8[CHROMA_DC+1]]
+        && h->mb.i_qp > h->mb.i_last_qp )
     {
 #if !RDO_SKIP_BS
         h->mb.i_qp = h->mb.i_last_qp;