[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