[x264-devel] Improve slice-max-size handling of escape bytes

Jason Garrett-Glaser git at videolan.org
Sat Feb 19 00:34:09 CET 2011


x264 | branch: master | Jason Garrett-Glaser <jason at x264.com> | Fri Feb 11 00:54:51 2011 -0800| [d00e31aa3285cc5f2f7e1355d31ff4a5014b37e0] | committer: Jason Garrett-Glaser

Improve slice-max-size handling of escape bytes
More accurate but a bit slower.  Helps deal with a few obnoxious corner cases where the current algorithm failed.

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

 encoder/encoder.c |   21 ++++++++++++---------
 1 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/encoder/encoder.c b/encoder/encoder.c
index e1c2a2e..67646df 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -1888,6 +1888,7 @@ static int x264_slice_write( x264_t *h )
     int starting_bits = bs_pos(&h->out.bs);
     int b_deblock = h->sh.i_disable_deblocking_filter_idc != 1;
     int b_hpel = h->fdec->b_kept_as_ref;
+    uint8_t *last_emu_check;
     b_deblock &= b_hpel || h->param.psz_dump_yuv;
     bs_realign( &h->out.bs );
 
@@ -1916,7 +1917,10 @@ static int x264_slice_write( x264_t *h )
         /* init cabac */
         x264_cabac_context_init( &h->cabac, h->sh.i_type, x264_clip3( h->sh.i_qp-QP_BD_OFFSET, 0, 51 ), h->sh.i_cabac_init_idc );
         x264_cabac_encode_init ( &h->cabac, h->out.bs.p, h->out.bs.p_end );
+        last_emu_check = h->cabac.p;
     }
+    else
+        last_emu_check = h->out.bs.p;
     h->mb.i_last_qp = h->sh.i_qp;
     h->mb.i_last_dqp = 0;
 
@@ -2000,15 +2004,14 @@ static int x264_slice_write( x264_t *h )
             /* Count the skip run, just in case. */
             if( !h->param.b_cabac )
                 total_bits += bs_size_ue_big( i_skip );
-            /* HACK: we assume no more than 3 bytes of NALU escaping, but
-             * this can fail in CABAC streams with an extremely large number of identical
-             * blocks in sequence (e.g. all-black intra blocks).
-             * Thus, every 64 blocks, pretend we've used a byte.
-             * For reference, a seqeuence of identical empty-CBP i16x16 blocks will use
-             * one byte after 26 macroblocks, assuming a perfectly adapted CABAC.
-             * That's 78 macroblocks to generate the 3-byte sequence to trigger an escape. */
-            else if( ((mb_xy - h->sh.i_first_mb) & 63) == 63 )
-                slice_max_size -= 8;
+            /* Check for escape bytes. */
+            uint8_t *end = h->param.b_cabac ? h->cabac.p : h->out.bs.p;
+            for( ; last_emu_check < end - 2; last_emu_check++ )
+                if( last_emu_check[0] == 0 && last_emu_check[1] == 0 && last_emu_check[2] <= 3 )
+                {
+                    slice_max_size -= 8;
+                    last_emu_check++;
+                }
             /* We'll just re-encode this last macroblock if we go over the max slice size. */
             if( total_bits - starting_bits > slice_max_size && !h->mb.b_reencode_mb )
             {



More information about the x264-devel mailing list