Use short startcodes whenever possible
authorJason Garrett-Glaser <darkshikari@gmail.com>
Mon, 22 Feb 2010 01:30:52 +0000 (17:30 -0800)
committerJason Garrett-Glaser <darkshikari@gmail.com>
Tue, 23 Feb 2010 09:46:24 +0000 (01:46 -0800)
Saves one byte per frame for every slice beyond the first.
Only applies to Annex-B output mode.

common/common.c
common/common.h
encoder/encoder.c

index 2faf139..0410588 100644 (file)
@@ -985,17 +985,17 @@ void x264_picture_clean( x264_picture_t *pic )
 /****************************************************************************
  * x264_nal_encode:
  ****************************************************************************/
-int x264_nal_encode( uint8_t *dst, int b_annexb, x264_nal_t *nal )
+int x264_nal_encode( uint8_t *dst, x264_nal_t *nal, int b_annexb, int b_long_startcode )
 {
     uint8_t *src = nal->p_payload;
     uint8_t *end = nal->p_payload + nal->i_payload;
     uint8_t *orig_dst = dst;
     int i_count = 0, size;
 
-    /* long nal start code (we always use long ones) */
     if( b_annexb )
     {
-        *dst++ = 0x00;
+        if( b_long_startcode )
+            *dst++ = 0x00;
         *dst++ = 0x00;
         *dst++ = 0x00;
         *dst++ = 0x01;
index 18c172e..d69ce65 100644 (file)
@@ -121,7 +121,7 @@ int64_t x264_mdate( void );
  * the encoding options */
 char *x264_param2string( x264_param_t *p, int b_res );
 
-int x264_nal_encode( uint8_t *dst, int b_annexb, x264_nal_t *nal );
+int x264_nal_encode( uint8_t *dst, x264_nal_t *nal, int b_annexb, int b_long_startcode );
 
 /* log */
 void x264_log( x264_t *h, int i_level, const char *psz_fmt, ... );
index 89bf457..c76938c 100644 (file)
@@ -1228,10 +1228,14 @@ static int x264_encoder_encapsulate_nals( x264_t *h )
     }
 
     uint8_t *nal_buffer = h->nal_buffer;
+    int long_startcode = 1;
 
     for( i = 0; i < h->out.i_nal; i++ )
     {
-        int size = x264_nal_encode( nal_buffer, h->param.b_annexb, &h->out.nal[i] );
+        int size = x264_nal_encode( nal_buffer, &h->out.nal[i], h->param.b_annexb, long_startcode );
+        /* Don't use long startcodes for any slice beyond the first. */
+        if( h->out.nal[i].i_type >= NAL_SLICE && h->out.nal[i].i_type <= NAL_SLICE_IDR )
+            long_startcode = 0;
         h->out.nal[i].i_payload = size;
         h->out.nal[i].p_payload = nal_buffer;
         nal_buffer += size;
@@ -1715,8 +1719,10 @@ static int x264_slice_write( x264_t *h )
     bs_t bs_bak;
     x264_cabac_t cabac_bak;
     uint8_t cabac_prevbyte_bak = 0; /* Shut up GCC. */
-    /* Assume no more than 3 bytes of NALU escaping. */
-    int slice_max_size = h->param.i_slice_max_size > 0 ? (h->param.i_slice_max_size-3-NALU_OVERHEAD)*8 : INT_MAX;
+    /* Assume no more than 3 bytes of NALU escaping.
+     * Slices other than the first use a 3-byte startcode. */
+    int overhead_guess = (NALU_OVERHEAD - (h->param.b_annexb && h->sh.i_first_mb)) + 3;
+    int slice_max_size = h->param.i_slice_max_size > 0 ? (h->param.i_slice_max_size-overhead_guess)*8 : INT_MAX;
     int starting_bits = bs_pos(&h->out.bs);
     bs_realign( &h->out.bs );