[x264-devel] commit: Fix bitstream alignment with multiple slices (Jason Garrett-Glaser )

git version control git at videolan.org
Sat Jan 30 13:58:00 CET 2010


x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Thu Jan 21 23:07:11 2010 -0800| [1a1b356a2996629d2c5ad2b568df8df9bff32954] | committer: Jason Garrett-Glaser 

Fix bitstream alignment with multiple slices
Broke multi-slice encoding on CPUs without unaligned access.
New system simply forces a bitstream realignment at the start of each writing function and flushes when it reaches the end.

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

 common/bs.h       |   14 +++++++++++++-
 encoder/encoder.c |    2 +-
 encoder/set.c     |    8 ++++++++
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/common/bs.h b/common/bs.h
index d13eb03..0773de6 100644
--- a/common/bs.h
+++ b/common/bs.h
@@ -77,7 +77,7 @@ static inline void bs_init( bs_t *s, void *p_data, int i_data )
     s->p       = s->p_start = (uint8_t*)p_data - offset;
     s->p_end   = (uint8_t*)p_data + i_data;
     s->i_left  = (WORD_SIZE - offset)*8;
-    s->cur_bits = endian_fix32(*(uint32_t *)(s->p));
+    s->cur_bits = endian_fix32( M32(s->p) );
     s->cur_bits >>= (4-offset)*8;
 }
 static inline int bs_pos( bs_t *s )
@@ -92,6 +92,18 @@ static inline void bs_flush( bs_t *s )
     s->p += WORD_SIZE - s->i_left / 8;
     s->i_left = WORD_SIZE*8;
 }
+/* The inverse of bs_flush: prepare the bitstream to be written to again. */
+static inline void bs_realign( bs_t *s )
+{
+    int offset = ((intptr_t)s->p & 3);
+    if( offset )
+    {
+        s->p       = (uint8_t*)s->p - offset;
+        s->i_left  = (WORD_SIZE - offset)*8;
+        s->cur_bits = endian_fix32( M32(s->p) );
+        s->cur_bits >>= (4-offset)*8;
+    }
+}
 
 static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
 {
diff --git a/encoder/encoder.c b/encoder/encoder.c
index db2c861..c7065a2 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -1206,7 +1206,6 @@ int x264_encoder_headers( x264_t *h, x264_nal_t **pp_nal, int *pi_nal )
     x264_pps_write( &h->out.bs, h->pps );
     if( x264_nal_end( h ) )
         return -1;
-    bs_flush( &h->out.bs );
 
     frame_size = x264_encoder_encapsulate_nals( h );
 
@@ -1657,6 +1656,7 @@ static int x264_slice_write( x264_t *h )
     /* 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;
     int starting_bits = bs_pos(&h->out.bs);
+    bs_realign( &h->out.bs );
 
     /* Slice */
     x264_nal_start( h, h->i_nal_type, h->i_nal_ref_idc );
diff --git a/encoder/set.c b/encoder/set.c
index 641eae9..f79919b 100644
--- a/encoder/set.c
+++ b/encoder/set.c
@@ -210,6 +210,7 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
 
 void x264_sps_write( bs_t *s, x264_sps_t *sps )
 {
+    bs_realign( s );
     bs_write( s, 8, sps->i_profile_idc );
     bs_write( s, 1, sps->b_constraint_set0 );
     bs_write( s, 1, sps->b_constraint_set1 );
@@ -359,6 +360,7 @@ void x264_sps_write( bs_t *s, x264_sps_t *sps )
     }
 
     bs_rbsp_trailing( s );
+    bs_flush( s );
 }
 
 void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *sps )
@@ -423,6 +425,7 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *
 
 void x264_pps_write( bs_t *s, x264_pps_t *pps )
 {
+    bs_realign( s );
     bs_write_ue( s, pps->i_id );
     bs_write_ue( s, pps->i_sps_id );
 
@@ -465,12 +468,14 @@ void x264_pps_write( bs_t *s, x264_pps_t *pps )
     }
 
     bs_rbsp_trailing( s );
+    bs_flush( s );
 }
 
 void x264_sei_recovery_point_write( x264_t *h, bs_t *s, int recovery_frame_cnt )
 {
     int payload_size;
 
+    bs_realign( s );
     bs_write( s, 8, 0x06 ); // payload_type = Recovery Point
     payload_size = bs_size_ue( recovery_frame_cnt ) + 4;
 
@@ -482,6 +487,7 @@ void x264_sei_recovery_point_write( x264_t *h, bs_t *s, int recovery_frame_cnt )
 
     bs_align_10( s );
     bs_rbsp_trailing( s );
+    bs_flush( s );
 }
 
 int x264_sei_version_write( x264_t *h, bs_t *s )
@@ -505,6 +511,7 @@ int x264_sei_version_write( x264_t *h, bs_t *s )
              X264_BUILD, X264_VERSION, opts );
     length = strlen(version)+1+16;
 
+    bs_realign( s );
     bs_write( s, 8, 0x5 ); // payload_type = user_data_unregistered
     // payload_size
     for( i = 0; i <= length-255; i += 255 )
@@ -517,6 +524,7 @@ int x264_sei_version_write( x264_t *h, bs_t *s )
         bs_write( s, 8, version[i] );
 
     bs_rbsp_trailing( s );
+    bs_flush( s );
 
     x264_free( opts );
     x264_free( version );



More information about the x264-devel mailing list