@ -1564,7 +1564,8 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw,
static int FUNC ( sei_buffering_period ) ( CodedBitstreamContext * ctx , RWContext * rw ,
H265RawSEIBufferingPeriod * current ,
uint32_t * payload_size )
uint32_t * payload_size ,
int * more_data )
{
CodedBitstreamH265Context * h265 = ctx - > priv_data ;
const H265RawSPS * sps ;
@ -1658,8 +1659,15 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw,
else
infer ( use_alt_cpb_params_flag , 0 ) ;
# else
if ( current - > use_alt_cpb_params_flag )
// If unknown extension data exists, then use_alt_cpb_params_flag is
// coded in the bitstream and must be written even if it's 0.
if ( current - > use_alt_cpb_params_flag | | * more_data ) {
flag ( use_alt_cpb_params_flag ) ;
// Ensure this bit is not the last in the payload by making the
// more_data_in_payload() check evaluate to true, so it may not
// be mistaken as something else by decoders.
* more_data = 1 ;
}
# endif
return 0 ;
@ -2057,11 +2065,48 @@ static int FUNC(sei_alpha_channel_info)(CodedBitstreamContext *ctx,
return 0 ;
}
static int FUNC ( payload_extension ) ( CodedBitstreamContext * ctx , RWContext * rw ,
H265RawExtensionData * current , uint32_t payload_size ,
int cur_pos )
{
int err ;
size_t byte_length , k ;
# ifdef READ
GetBitContext tmp ;
int bits_left , payload_zero_bits ;
if ( ! cbs_h265_payload_extension_present ( rw , payload_size , cur_pos ) )
return 0 ;
bits_left = 8 * payload_size - cur_pos ;
tmp = * rw ;
if ( bits_left > 8 )
skip_bits_long ( & tmp , bits_left - 8 ) ;
payload_zero_bits = get_bits ( & tmp , FFMIN ( bits_left , 8 ) ) ;
if ( ! payload_zero_bits )
return AVERROR_INVALIDDATA ;
payload_zero_bits = ff_ctz ( payload_zero_bits ) ;
current - > bit_length = bits_left - payload_zero_bits - 1 ;
allocate ( current - > data , ( current - > bit_length + 7 ) / 8 ) ;
# endif
byte_length = ( current - > bit_length + 7 ) / 8 ;
for ( k = 0 ; k < byte_length ; k + + ) {
int length = FFMIN ( current - > bit_length - k * 8 , 8 ) ;
xu ( length , reserved_payload_extension_data , current - > data [ k ] ,
0 , MAX_UINT_BITS ( length ) , 0 ) ;
}
return 0 ;
}
static int FUNC ( sei_payload ) ( CodedBitstreamContext * ctx , RWContext * rw ,
H265RawSEIPayload * current , int prefix )
{
int err , i ;
int start_position , end_position ;
int start_position , current_position ;
int more_data = ! ! current - > extension_data . bit_length ;
# ifdef READ
start_position = get_bits_count ( rw ) ;
@ -2093,8 +2138,15 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw,
CHECK ( FUNC ( sei_ # # name ) ( ctx , rw , & current - > payload . name , \
& current - > payload_size ) ) ; \
break
# define SEI_TYPE_E(type, prefix_valid, suffix_valid, name) \
case HEVC_SEI_TYPE_ # # type : \
SEI_TYPE_CHECK_VALID ( name , prefix_valid , suffix_valid ) ; \
CHECK ( FUNC ( sei_ # # name ) ( ctx , rw , & current - > payload . name , \
& current - > payload_size , \
& more_data ) ) ; \
break
SEI_TYPE_S ( BUFFERING_PERIOD , 1 , 0 , buffering_period ) ;
SEI_TYPE_E ( BUFFERING_PERIOD , 1 , 0 , buffering_period ) ;
SEI_TYPE_N ( PICTURE_TIMING , 1 , 0 , pic_timing ) ;
SEI_TYPE_N ( PAN_SCAN_RECT , 1 , 0 , pan_scan_rect ) ;
SEI_TYPE_S ( USER_DATA_REGISTERED_ITU_T_T35 ,
@ -2125,24 +2177,23 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw,
}
}
if ( byte_alignment ( rw ) ) {
// more_data_in_payload()
# ifdef READ
current_position = get_bits_count ( rw ) - start_position ;
if ( current_position < 8 * current - > payload_size ) {
# else
current_position = put_bits_count ( rw ) - start_position ;
if ( byte_alignment ( rw ) | | more_data ) {
# endif
CHECK ( FUNC ( payload_extension ) ( ctx , rw , & current - > extension_data ,
current - > payload_size , current_position ) ) ;
fixed ( 1 , bit_equal_to_one , 1 ) ;
while ( byte_alignment ( rw ) )
fixed ( 1 , bit_equal_to_zero , 0 ) ;
}
# ifdef READ
end_position = get_bits_count ( rw ) ;
if ( end_position < start_position + 8 * current - > payload_size ) {
av_log ( ctx - > log_ctx , AV_LOG_ERROR , " Incorrect SEI payload length: "
" header % " PRIu32 " bits, actually %d bits. \n " ,
8 * current - > payload_size ,
end_position - start_position ) ;
return AVERROR_INVALIDDATA ;
}
# else
end_position = put_bits_count ( rw ) ;
current - > payload_size = ( end_position - start_position ) > > 3 ;
# ifdef WRITE
current - > payload_size = ( put_bits_count ( rw ) - start_position ) > > 3 ;
# endif
return 0 ;