[x264-devel] commit: improve handling of cavlc dct coef overflows (Jason Garrett-Glaser )

git version control git at videolan.org
Thu Apr 10 09:32:49 CEST 2008


x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Wed Apr  2 05:06:02 2008 -0600| [6cf65da995c454f5d9330a1f07718ec1734f8454]

improve handling of cavlc dct coef overflows
support large coefs in high profile, and clip to allowed range in baseline/main

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

 common/vlc.h    |   20 --------------------
 encoder/cavlc.c |   35 +++++++++++++++++++++++++++++------
 2 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/common/vlc.h b/common/vlc.h
index 3986f58..18a8370 100644
--- a/common/vlc.h
+++ b/common/vlc.h
@@ -471,26 +471,6 @@ static const vlc_t x264_coeff_token[5][17*4] =
     }
 };
 
-static const vlc_t x264_level_prefix[16] =
-{
-    MKVLC( 0x01,  1 ),
-    MKVLC( 0x01,  2 ),
-    MKVLC( 0x01,  3 ),
-    MKVLC( 0x01,  4 ),
-    MKVLC( 0x01,  5 ),
-    MKVLC( 0x01,  6 ),
-    MKVLC( 0x01,  7 ),
-    MKVLC( 0x01,  8 ),
-    MKVLC( 0x01,  9 ),
-    MKVLC( 0x01, 10 ),
-    MKVLC( 0x01, 11 ),
-    MKVLC( 0x01, 12 ),
-    MKVLC( 0x01, 13 ),
-    MKVLC( 0x01, 14 ),
-    MKVLC( 0x01, 15 ),
-    MKVLC( 0x01, 16 )
-};
-
 /* [i_total_coeff-1][i_total_zeros] */
 static const vlc_t x264_total_zeros[15][16] =
 {
diff --git a/encoder/cavlc.c b/encoder/cavlc.c
index e4e84cc..6ccbfdb 100644
--- a/encoder/cavlc.c
+++ b/encoder/cavlc.c
@@ -147,29 +147,52 @@ static void block_residual_write_cavlc( x264_t *h, bs_t *s, int i_idx, int16_t *
 
         if( ( i_level_code >> i_suffix_length ) < 14 )
         {
-            bs_write_vlc( s, x264_level_prefix[i_level_code >> i_suffix_length] );
+            bs_write( s, (i_level_code >> i_suffix_length) + 1, 1 );
             if( i_suffix_length > 0 )
                 bs_write( s, i_suffix_length, i_level_code );
         }
         else if( i_suffix_length == 0 && i_level_code < 30 )
         {
-            bs_write_vlc( s, x264_level_prefix[14] );
+            bs_write( s, 15, 1 );
             bs_write( s, 4, i_level_code - 14 );
         }
         else if( i_suffix_length > 0 && ( i_level_code >> i_suffix_length ) == 14 )
         {
-            bs_write_vlc( s, x264_level_prefix[14] );
+            bs_write( s, 15, 1 );
             bs_write( s, i_suffix_length, i_level_code );
         }
         else
         {
-            bs_write_vlc( s, x264_level_prefix[15] );
+            int i_level_prefix = 15;
             i_level_code -= 15 << i_suffix_length;
             if( i_suffix_length == 0 )
                 i_level_code -= 15;
+
+            /* If the prefix size exceeds 15, High Profile is required. */
             if( i_level_code >= 1<<12 )
-                x264_log(h, X264_LOG_WARNING, "OVERFLOW levelcode=%d\n", i_level_code );
-            bs_write( s, 12, i_level_code );
+            {
+                if( h->sps->i_profile_idc >= PROFILE_HIGH )
+                {
+                    while( i_level_code > 1<<(i_level_prefix-3) )
+                    {
+                        i_level_code -= 1<<(i_level_prefix-3);
+                        i_level_prefix++;
+                    }
+                }
+                else
+                {
+#ifdef RDO_SKIP_BS
+                    /* Weight highly against overflows. */
+                    s->i_bits_encoded += 1000000;
+#else
+                    x264_log(h, X264_LOG_WARNING, "OVERFLOW levelcode=%d is only allowed in High Profile", i_level_code );
+                    /* clip level, preserving sign */
+                    i_level_code = (1<<12) - 2 + (i_level_code & 1);
+#endif
+                }
+            }
+            bs_write( s, i_level_prefix + 1, 1 );
+            bs_write( s, i_level_prefix - 3, i_level_code );
         }
 
         if( i_suffix_length == 0 )



More information about the x264-devel mailing list