Commit 535f0fa5 authored by Fiona Glaser's avatar Fiona 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.
parent f4186f5e
......@@ -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 )
{
......
......@@ -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 );
......
......@@ -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 );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment