@ -54,30 +54,22 @@ void ff_h264_sei_uninit(H264SEIContext *h)
av_buffer_unref ( & h - > a53_caption . buf_ref ) ;
}
static int decode _picture_timing( H264SEIPictureTiming * h , GetBitContext * gb ,
const H264ParamSets * ps , void * logctx )
int ff_h264_sei_process _picture_timing( H264SEIPictureTiming * h , const SPS * sps ,
void * logctx )
{
int i ;
const SPS * sps = ps - > sps ;
for ( i = 0 ; i < MAX_SPS_COUNT ; i + + )
if ( ( ! sps | | ! sps - > log2_max_frame_num ) & & ps - > sps_list [ i ] )
sps = ( const SPS * ) ps - > sps_list [ i ] - > data ;
GetBitContext gb ;
if ( ! sps ) {
av_log ( logctx , AV_LOG_ERROR , " SPS unavailable in decode_picture_timing \n " ) ;
return AVERROR_PS_NOT_FOUND ;
}
init_get_bits ( & gb , h - > payload , h - > payload_size_bits ) ;
if ( sps - > nal_hrd_parameters_present_flag | |
sps - > vcl_hrd_parameters_present_flag ) {
h - > cpb_removal_delay = get_bits_long ( gb , sps - > cpb_removal_delay_length ) ;
h - > dpb_output_delay = get_bits_long ( gb , sps - > dpb_output_delay_length ) ;
h - > cpb_removal_delay = get_bits_long ( & gb , sps - > cpb_removal_delay_length ) ;
h - > dpb_output_delay = get_bits_long ( & gb , sps - > dpb_output_delay_length ) ;
}
if ( sps - > pic_struct_present_flag ) {
unsigned int i , num_clock_ts ;
h - > pic_struct = get_bits ( gb , 4 ) ;
h - > pic_struct = get_bits ( & gb , 4 ) ;
h - > ct_type = 0 ;
if ( h - > pic_struct > H264_SEI_PIC_STRUCT_FRAME_TRIPLING )
@ -86,38 +78,38 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb,
num_clock_ts = sei_num_clock_ts_table [ h - > pic_struct ] ;
h - > timecode_cnt = 0 ;
for ( i = 0 ; i < num_clock_ts ; i + + ) {
if ( get_bits ( gb , 1 ) ) { /* clock_timestamp_flag */
if ( get_bits ( & gb , 1 ) ) { /* clock_timestamp_flag */
H264SEITimeCode * tc = & h - > timecode [ h - > timecode_cnt + + ] ;
unsigned int full_timestamp_flag ;
unsigned int counting_type , cnt_dropped_flag ;
h - > ct_type | = 1 < < get_bits ( gb , 2 ) ;
skip_bits ( gb , 1 ) ; /* nuit_field_based_flag */
counting_type = get_bits ( gb , 5 ) ; /* counting_type */
full_timestamp_flag = get_bits ( gb , 1 ) ;
skip_bits ( gb , 1 ) ; /* discontinuity_flag */
cnt_dropped_flag = get_bits ( gb , 1 ) ; /* cnt_dropped_flag */
h - > ct_type | = 1 < < get_bits ( & gb , 2 ) ;
skip_bits ( & gb , 1 ) ; /* nuit_field_based_flag */
counting_type = get_bits ( & gb , 5 ) ; /* counting_type */
full_timestamp_flag = get_bits ( & gb , 1 ) ;
skip_bits ( & gb , 1 ) ; /* discontinuity_flag */
cnt_dropped_flag = get_bits ( & gb , 1 ) ; /* cnt_dropped_flag */
if ( cnt_dropped_flag & & counting_type > 1 & & counting_type < 7 )
tc - > dropframe = 1 ;
tc - > frame = get_bits ( gb , 8 ) ; /* n_frames */
tc - > frame = get_bits ( & gb , 8 ) ; /* n_frames */
if ( full_timestamp_flag ) {
tc - > full = 1 ;
tc - > seconds = get_bits ( gb , 6 ) ; /* seconds_value 0..59 */
tc - > minutes = get_bits ( gb , 6 ) ; /* minutes_value 0..59 */
tc - > hours = get_bits ( gb , 5 ) ; /* hours_value 0..23 */
tc - > seconds = get_bits ( & gb , 6 ) ; /* seconds_value 0..59 */
tc - > minutes = get_bits ( & gb , 6 ) ; /* minutes_value 0..59 */
tc - > hours = get_bits ( & gb , 5 ) ; /* hours_value 0..23 */
} else {
tc - > seconds = tc - > minutes = tc - > hours = tc - > full = 0 ;
if ( get_bits ( gb , 1 ) ) { /* seconds_flag */
tc - > seconds = get_bits ( gb , 6 ) ;
if ( get_bits ( gb , 1 ) ) { /* minutes_flag */
tc - > minutes = get_bits ( gb , 6 ) ;
if ( get_bits ( gb , 1 ) ) /* hours_flag */
tc - > hours = get_bits ( gb , 5 ) ;
if ( get_bits ( & gb , 1 ) ) { /* seconds_flag */
tc - > seconds = get_bits ( & gb , 6 ) ;
if ( get_bits ( & gb , 1 ) ) { /* minutes_flag */
tc - > minutes = get_bits ( & gb , 6 ) ;
if ( get_bits ( & gb , 1 ) ) /* hours_flag */
tc - > hours = get_bits ( & gb , 5 ) ;
}
}
}
if ( sps - > time_offset_length > 0 )
skip_bits ( gb ,
skip_bits ( & gb ,
sps - > time_offset_length ) ; /* time_offset */
}
}
@ -126,6 +118,28 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb,
h - > ct_type , h - > pic_struct ) ;
}
return 0 ;
}
static int decode_picture_timing ( H264SEIPictureTiming * h , GetBitContext * gb ,
void * logctx )
{
int index = get_bits_count ( gb ) ;
int size_bits = get_bits_left ( gb ) ;
int size = ( size_bits + 7 ) / 8 ;
if ( index & 7 ) {
av_log ( logctx , AV_LOG_ERROR , " Unaligned SEI payload \n " ) ;
return AVERROR_INVALIDDATA ;
}
if ( size > sizeof ( h - > payload ) ) {
av_log ( logctx , AV_LOG_ERROR , " Picture timing SEI payload too large \n " ) ;
return AVERROR_INVALIDDATA ;
}
memcpy ( h - > payload , gb - > buffer + index / 8 , size ) ;
h - > payload_size_bits = size_bits ;
h - > present = 1 ;
return 0 ;
}
@ -436,7 +450,7 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb,
switch ( type ) {
case H264_SEI_TYPE_PIC_TIMING : // Picture timing SEI
ret = decode_picture_timing ( & h - > picture_timing , & gb_payload , ps , logctx ) ;
ret = decode_picture_timing ( & h - > picture_timing , & gb_payload , logctx ) ;
break ;
case H264_SEI_TYPE_USER_DATA_REGISTERED :
ret = decode_registered_user_data ( h , & gb_payload , logctx , size ) ;