2023-09-27 12:14:28 -07:00
/*
2025-01-05 16:25:39 -05:00
Copyright (c) 2023 - 2025 Advanced Micro Devices, Inc. All rights reserved.
2023-09-27 12:14:28 -07:00
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
# include "hevc_parser.h"
2024-01-10 11:44:07 -05:00
HevcVideoParser : : HevcVideoParser ( ) {
2023-11-15 16:07:18 -05:00
first_pic_after_eos_nal_unit_ = 0 ;
2025-03-26 08:16:36 -04:00
slice_info_list_ . assign ( INIT_SLICE_LIST_NUM , { { 0 } } ) ;
active_vps_id_ = - 1 ;
active_sps_id_ = - 1 ;
active_pps_id_ = - 1 ;
2025-03-20 06:12:16 -07:00
slice_info_list_ . assign ( INIT_SLICE_LIST_NUM , { { 0 } } ) ;
2024-02-09 15:09:49 -05:00
slice_param_list_ . assign ( INIT_SLICE_LIST_NUM , { 0 } ) ;
2023-11-02 18:08:24 -04:00
memset ( & curr_pic_info_ , 0 , sizeof ( HevcPicInfo ) ) ;
2024-11-19 15:10:35 -05:00
for ( int i = 0 ; i < MAX_VPS_COUNT ; i + + ) {
vps_list_ [ i ] . is_received = 0 ;
}
for ( int i = 0 ; i < MAX_SPS_COUNT ; i + + ) {
sps_list_ [ i ] . is_received = 0 ;
}
for ( int i = 0 ; i < MAX_PPS_COUNT ; i + + ) {
pps_list_ [ i ] . is_received = 0 ;
}
2023-11-27 11:04:01 -05:00
InitDpb ( ) ;
2023-10-18 06:01:44 -07:00
}
2024-02-15 08:42:51 -05:00
HevcVideoParser : : ~ HevcVideoParser ( ) {
}
2024-01-10 11:44:07 -05:00
rocDecStatus HevcVideoParser : : Initialize ( RocdecParserParams * p_params ) {
2024-01-16 20:57:40 -05:00
return RocVideoParser : : Initialize ( p_params ) ;
2023-09-27 12:14:28 -07:00
}
2024-01-10 11:44:07 -05:00
rocDecStatus HevcVideoParser : : UnInitialize ( ) {
2023-10-23 09:16:45 -07:00
//todo:: do any uninitialization here
return ROCDEC_SUCCESS ;
}
2024-01-10 11:44:07 -05:00
rocDecStatus HevcVideoParser : : ParseVideoData ( RocdecSourceDataPacket * p_data ) {
2023-11-27 13:03:26 -05:00
if ( p_data - > payload & & p_data - > payload_size ) {
2024-07-25 16:53:20 -04:00
curr_pts_ = p_data - > pts ;
2024-05-03 15:18:08 -04:00
if ( ParsePictureData ( p_data - > payload , p_data - > payload_size ) ! = PARSER_OK ) {
2023-11-27 13:03:26 -05:00
ERR ( STR ( " Parser failed! " ) ) ;
return ROCDEC_RUNTIME_ERROR ;
}
2023-10-27 15:13:12 -04:00
2023-11-27 13:03:26 -05:00
// Init Roc decoder for the first time or reconfigure the existing decoder
2024-06-26 12:46:11 -04:00
if ( new_seq_activated_ ) {
2025-03-26 08:16:36 -04:00
if ( FillSeqCallbackFn ( & sps_list_ [ active_sps_id_ ] ) ! = PARSER_OK ) {
2023-12-01 14:50:33 -05:00
return ROCDEC_RUNTIME_ERROR ;
}
2024-06-26 12:46:11 -04:00
new_seq_activated_ = false ;
2023-11-27 13:03:26 -05:00
}
2023-10-27 15:13:12 -04:00
2023-11-27 13:03:26 -05:00
// Whenever new sei message found
if ( pfn_get_sei_message_cb_ & & sei_message_count_ > 0 ) {
2024-02-15 08:42:51 -05:00
SendSeiMsgPayload ( ) ;
2023-11-27 13:03:26 -05:00
}
2023-11-06 22:04:25 -05:00
2024-05-14 14:07:23 -04:00
// Error handling: if there is no slice data, return gracefully.
if ( num_slices_ = = 0 ) {
return ROCDEC_SUCCESS ;
}
2023-11-27 13:03:26 -05:00
// Decode the picture
if ( SendPicForDecode ( ) ! = PARSER_OK ) {
ERR ( STR ( " Failed to decode! " ) ) ;
return ROCDEC_RUNTIME_ERROR ;
}
2023-11-06 22:04:25 -05:00
2023-11-27 13:03:26 -05:00
// Output decoded pictures from DPB if any are ready
2024-05-31 13:14:02 -04:00
if ( pfn_display_picture_cb_ & & num_output_pics_ > 0 ) {
if ( OutputDecodedPictures ( false ) ! = PARSER_OK ) {
2023-11-27 13:03:26 -05:00
return ROCDEC_RUNTIME_ERROR ;
}
}
pic_count_ + + ;
} else if ( ! ( p_data - > flags & ROCDEC_PKT_ENDOFSTREAM ) ) {
// If no payload and EOS is not set, treated as invalid.
return ROCDEC_INVALID_PARAMETER ;
2023-11-27 11:04:01 -05:00
}
2023-11-27 13:03:26 -05:00
if ( p_data - > flags & ROCDEC_PKT_ENDOFSTREAM ) {
if ( FlushDpb ( ) ! = PARSER_OK ) {
return ROCDEC_RUNTIME_ERROR ;
}
}
2023-11-15 16:07:18 -05:00
2023-10-05 08:20:07 -07:00
return ROCDEC_SUCCESS ;
}
2024-01-10 11:44:07 -05:00
int HevcVideoParser : : FillSeqCallbackFn ( HevcSeqParamSet * sps_data ) {
2023-10-27 06:11:00 -07:00
video_format_params_ . codec = rocDecVideoCodec_HEVC ;
2023-12-12 13:47:19 -05:00
video_format_params_ . frame_rate . numerator = frame_rate_ . numerator ;
video_format_params_ . frame_rate . denominator = frame_rate_ . denominator ;
2023-10-27 06:11:00 -07:00
video_format_params_ . bit_depth_luma_minus8 = sps_data - > bit_depth_luma_minus8 ;
video_format_params_ . bit_depth_chroma_minus8 = sps_data - > bit_depth_chroma_minus8 ;
if ( sps_data - > profile_tier_level . general_progressive_source_flag & & ! sps_data - > profile_tier_level . general_interlaced_source_flag )
video_format_params_ . progressive_sequence = 1 ;
else if ( ! sps_data - > profile_tier_level . general_progressive_source_flag & & sps_data - > profile_tier_level . general_interlaced_source_flag )
video_format_params_ . progressive_sequence = 0 ;
else // default value
video_format_params_ . progressive_sequence = 1 ;
2024-05-31 13:14:02 -04:00
video_format_params_ . min_num_decode_surfaces = dec_buf_pool_size_ ;
2023-10-27 06:11:00 -07:00
video_format_params_ . coded_width = sps_data - > pic_width_in_luma_samples ;
video_format_params_ . coded_height = sps_data - > pic_height_in_luma_samples ;
video_format_params_ . chroma_format = static_cast < rocDecVideoChromaFormat > ( sps_data - > chroma_format_idc ) ;
int sub_width_c , sub_height_c ;
switch ( video_format_params_ . chroma_format ) {
case rocDecVideoChromaFormat_Monochrome : {
sub_width_c = 1 ;
sub_height_c = 1 ;
break ;
}
case rocDecVideoChromaFormat_420 : {
sub_width_c = 2 ;
sub_height_c = 2 ;
break ;
}
case rocDecVideoChromaFormat_422 : {
sub_width_c = 2 ;
sub_height_c = 1 ;
break ;
}
case rocDecVideoChromaFormat_444 : {
sub_width_c = 1 ;
sub_height_c = 1 ;
break ;
}
default :
ERR ( STR ( " Error: Sequence Callback function - Chroma Format is not supported " ) ) ;
2023-12-01 14:50:33 -05:00
return PARSER_FAIL ;
2023-10-27 06:11:00 -07:00
}
if ( sps_data - > conformance_window_flag ) {
video_format_params_ . display_area . left = sub_width_c * sps_data - > conf_win_left_offset ;
video_format_params_ . display_area . top = sub_height_c * sps_data - > conf_win_top_offset ;
video_format_params_ . display_area . right = sps_data - > pic_width_in_luma_samples - ( sub_width_c * sps_data - > conf_win_right_offset ) ;
video_format_params_ . display_area . bottom = sps_data - > pic_height_in_luma_samples - ( sub_height_c * sps_data - > conf_win_bottom_offset ) ;
2024-01-05 09:15:33 -05:00
} else { // default values
2023-10-27 06:11:00 -07:00
video_format_params_ . display_area . left = 0 ;
video_format_params_ . display_area . top = 0 ;
video_format_params_ . display_area . right = video_format_params_ . coded_width ;
video_format_params_ . display_area . bottom = video_format_params_ . coded_height ;
}
video_format_params_ . bitrate = 0 ;
2024-01-18 14:31:54 -05:00
// Dispaly aspect ratio
// Table E-1.
static const Rational hevc_sar [ ] = {
{ 0 , 0 } , // unspecified
{ 1 , 1 } , { 12 , 11 } , { 10 , 11 } , { 16 , 11 } , { 40 , 33 } , { 24 , 11 } , { 20 , 11 } , { 32 , 11 } ,
{ 80 , 33 } , { 18 , 11 } , { 15 , 11 } , { 64 , 33 } , { 160 , 99 } , { 4 , 3 } , { 3 , 2 } , { 2 , 1 } ,
} ;
Rational sar ;
sar . numerator = 1 ; // set to square pixel if not present or unspecified
sar . denominator = 1 ; // set to square pixel if not present or unspecified
2023-10-27 06:11:00 -07:00
if ( sps_data - > vui_parameters_present_flag ) {
if ( sps_data - > vui_parameters . aspect_ratio_info_present_flag ) {
2024-01-18 14:31:54 -05:00
if ( sps_data - > vui_parameters . aspect_ratio_idc = = 255 /*Extended_SAR*/ ) {
sar . numerator = sps_data - > vui_parameters . sar_width ;
sar . denominator = sps_data - > vui_parameters . sar_height ;
} else if ( sps_data - > vui_parameters . aspect_ratio_idc > 0 & & sps_data - > vui_parameters . aspect_ratio_idc < 17 ) {
sar = hevc_sar [ sps_data - > vui_parameters . aspect_ratio_idc ] ;
}
2023-10-27 06:11:00 -07:00
}
}
2024-01-18 14:31:54 -05:00
int disp_width = ( video_format_params_ . display_area . right - video_format_params_ . display_area . left ) * sar . numerator ;
int disp_height = ( video_format_params_ . display_area . bottom - video_format_params_ . display_area . top ) * sar . denominator ;
int gcd = std : : __gcd ( disp_width , disp_height ) ; // greatest common divisor
video_format_params_ . display_aspect_ratio . x = disp_width / gcd ;
video_format_params_ . display_aspect_ratio . y = disp_height / gcd ;
2025-02-12 17:18:09 -05:00
video_format_params_ . reconfig_options = ROCDEC_RECONFIG_NEW_SURFACES ;
2023-10-27 06:11:00 -07:00
if ( sps_data - > vui_parameters_present_flag ) {
video_format_params_ . video_signal_description . video_format = sps_data - > vui_parameters . video_format ;
video_format_params_ . video_signal_description . video_full_range_flag = sps_data - > vui_parameters . video_full_range_flag ;
video_format_params_ . video_signal_description . color_primaries = sps_data - > vui_parameters . colour_primaries ;
video_format_params_ . video_signal_description . transfer_characteristics = sps_data - > vui_parameters . transfer_characteristics ;
video_format_params_ . video_signal_description . matrix_coefficients = sps_data - > vui_parameters . matrix_coeffs ;
video_format_params_ . video_signal_description . reserved_zero_bits = 0 ;
}
video_format_params_ . seqhdr_data_length = 0 ;
// callback function with RocdecVideoFormat params filled out
2025-02-25 20:43:46 -05:00
if ( pfn_sequence_cb_ ( parser_params_ . user_data , & video_format_params_ ) = = 0 ) {
2023-12-01 14:50:33 -05:00
ERR ( " Sequence callback function failed. " ) ;
return PARSER_FAIL ;
} else {
return PARSER_OK ;
}
2023-10-27 06:11:00 -07:00
}
2024-02-15 08:42:51 -05:00
void HevcVideoParser : : SendSeiMsgPayload ( ) {
2023-11-06 06:25:09 -08:00
sei_message_info_params_ . sei_message_count = sei_message_count_ ;
2024-01-24 18:03:46 -05:00
sei_message_info_params_ . sei_message = sei_message_list_ . data ( ) ;
sei_message_info_params_ . sei_data = ( void * ) sei_payload_buf_ ;
2024-05-31 13:14:02 -04:00
sei_message_info_params_ . picIdx = curr_pic_info_ . dec_buf_idx ;
2023-11-06 06:25:09 -08:00
// callback function with RocdecSeiMessageInfo params filled out
2024-01-24 18:03:46 -05:00
if ( pfn_get_sei_message_cb_ ) pfn_get_sei_message_cb_ ( parser_params_ . user_data , & sei_message_info_params_ ) ;
2023-11-06 06:25:09 -08:00
}
2024-01-10 11:44:07 -05:00
int HevcVideoParser : : SendPicForDecode ( ) {
2023-11-09 13:52:02 -05:00
int i , j , ref_idx , buf_idx ;
2025-03-26 08:16:36 -04:00
HevcSeqParamSet * sps_ptr = & sps_list_ [ active_sps_id_ ] ;
HevcPicParamSet * pps_ptr = & pps_list_ [ active_pps_id_ ] ;
2023-11-06 22:04:25 -05:00
dec_pic_params_ = { 0 } ;
2024-01-24 18:03:46 -05:00
dec_pic_params_ . pic_width = sps_ptr - > pic_width_in_luma_samples ;
dec_pic_params_ . pic_height = sps_ptr - > pic_height_in_luma_samples ;
2024-05-31 13:14:02 -04:00
dec_pic_params_ . curr_pic_idx = curr_pic_info_ . dec_buf_idx ;
2023-11-06 22:04:25 -05:00
dec_pic_params_ . field_pic_flag = sps_ptr - > profile_tier_level . general_interlaced_source_flag ;
dec_pic_params_ . bottom_field_flag = 0 ; // For now. Need to parse VUI/SEI pic_timing()
dec_pic_params_ . second_field = 0 ; // For now. Need to parse VUI/SEI pic_timing()
2024-01-24 18:03:46 -05:00
dec_pic_params_ . bitstream_data_len = pic_stream_data_size_ ;
dec_pic_params_ . bitstream_data = pic_stream_data_ptr_ ;
2024-02-09 15:09:49 -05:00
dec_pic_params_ . num_slices = num_slices_ ;
2023-11-06 22:04:25 -05:00
dec_pic_params_ . ref_pic_flag = 1 ; // HEVC decoded picture is always marked as short term at first.
2024-02-09 15:09:49 -05:00
dec_pic_params_ . intra_pic_flag = slice_info_list_ [ 0 ] . slice_header . slice_type = = HEVC_SLICE_TYPE_I ? 1 : 0 ;
2023-11-06 22:04:25 -05:00
// Todo: field_pic_flag, bottom_field_flag, second_field, ref_pic_flag, and intra_pic_flag seems to be associated with AVC/H.264.
// Do we need them for general purpose? Reomve if not.
2023-11-09 13:52:02 -05:00
// Fill picture parameters
RocdecHevcPicParams * pic_param_ptr = & dec_pic_params_ . pic_params . hevc ;
// Current picture
2024-05-31 13:14:02 -04:00
pic_param_ptr - > curr_pic . pic_idx = curr_pic_info_ . dec_buf_idx ;
2024-01-24 18:03:46 -05:00
pic_param_ptr - > curr_pic . poc = curr_pic_info_ . pic_order_cnt ;
2023-11-09 13:52:02 -05:00
// Reference pictures
ref_idx = 0 ;
for ( i = 0 ; i < num_poc_st_curr_before_ ; i + + ) {
buf_idx = ref_pic_set_st_curr_before_ [ i ] ; // buffer index in DPB
2024-05-31 13:14:02 -04:00
pic_param_ptr - > ref_frames [ ref_idx ] . pic_idx = dpb_buffer_ . frame_buffer_list [ buf_idx ] . dec_buf_idx ;
2024-01-24 18:03:46 -05:00
pic_param_ptr - > ref_frames [ ref_idx ] . poc = dpb_buffer_ . frame_buffer_list [ buf_idx ] . pic_order_cnt ;
pic_param_ptr - > ref_frames [ ref_idx ] . flags = 0 ; // assume frame picture for now
pic_param_ptr - > ref_frames [ ref_idx ] . flags | = RocdecHevcPicture_RPS_ST_CURR_BEFORE ;
2023-11-09 13:52:02 -05:00
ref_idx + + ;
}
for ( i = 0 ; i < num_poc_st_curr_after_ ; i + + ) {
buf_idx = ref_pic_set_st_curr_after_ [ i ] ; // buffer index in DPB
2024-05-31 13:14:02 -04:00
pic_param_ptr - > ref_frames [ ref_idx ] . pic_idx = dpb_buffer_ . frame_buffer_list [ buf_idx ] . dec_buf_idx ;
2024-01-24 18:03:46 -05:00
pic_param_ptr - > ref_frames [ ref_idx ] . poc = dpb_buffer_ . frame_buffer_list [ buf_idx ] . pic_order_cnt ;
pic_param_ptr - > ref_frames [ ref_idx ] . flags = 0 ; // assume frame picture for now
pic_param_ptr - > ref_frames [ ref_idx ] . flags | = RocdecHevcPicture_RPS_ST_CURR_AFTER ;
2023-11-09 13:52:02 -05:00
ref_idx + + ;
}
for ( i = 0 ; i < num_poc_lt_curr_ ; i + + ) {
buf_idx = ref_pic_set_lt_curr_ [ i ] ; // buffer index in DPB
2024-05-31 13:14:02 -04:00
pic_param_ptr - > ref_frames [ ref_idx ] . pic_idx = dpb_buffer_ . frame_buffer_list [ buf_idx ] . dec_buf_idx ;
2024-01-24 18:03:46 -05:00
pic_param_ptr - > ref_frames [ ref_idx ] . poc = dpb_buffer_ . frame_buffer_list [ buf_idx ] . pic_order_cnt ;
pic_param_ptr - > ref_frames [ ref_idx ] . flags = 0 ; // assume frame picture for now
pic_param_ptr - > ref_frames [ ref_idx ] . flags | = RocdecHevcPicture_LONG_TERM_REFERENCE | RocdecHevcPicture_RPS_LT_CURR ;
2023-11-09 13:52:02 -05:00
ref_idx + + ;
}
2023-11-29 08:33:00 -05:00
for ( i = 0 ; i < num_poc_st_foll_ ; i + + ) {
buf_idx = ref_pic_set_st_foll_ [ i ] ; // buffer index in DPB
2024-05-31 13:14:02 -04:00
pic_param_ptr - > ref_frames [ ref_idx ] . pic_idx = dpb_buffer_ . frame_buffer_list [ buf_idx ] . dec_buf_idx ;
2024-01-24 18:03:46 -05:00
pic_param_ptr - > ref_frames [ ref_idx ] . poc = dpb_buffer_ . frame_buffer_list [ buf_idx ] . pic_order_cnt ;
pic_param_ptr - > ref_frames [ ref_idx ] . flags = 0 ; // assume frame picture for now
2023-11-29 08:33:00 -05:00
ref_idx + + ;
}
for ( i = 0 ; i < num_poc_lt_foll_ ; i + + ) {
buf_idx = ref_pic_set_lt_foll_ [ i ] ; // buffer index in DPB
2024-05-31 13:14:02 -04:00
pic_param_ptr - > ref_frames [ ref_idx ] . pic_idx = dpb_buffer_ . frame_buffer_list [ buf_idx ] . dec_buf_idx ;
2024-01-24 18:03:46 -05:00
pic_param_ptr - > ref_frames [ ref_idx ] . poc = dpb_buffer_ . frame_buffer_list [ buf_idx ] . pic_order_cnt ;
pic_param_ptr - > ref_frames [ ref_idx ] . flags = 0 ; // assume frame picture for now
2023-11-29 08:33:00 -05:00
ref_idx + + ;
}
2023-11-09 13:52:02 -05:00
for ( i = ref_idx ; i < 15 ; i + + ) {
2024-01-24 18:03:46 -05:00
pic_param_ptr - > ref_frames [ i ] . pic_idx = 0xFF ;
2023-11-09 13:52:02 -05:00
}
pic_param_ptr - > picture_width_in_luma_samples = sps_ptr - > pic_width_in_luma_samples ;
pic_param_ptr - > picture_height_in_luma_samples = sps_ptr - > pic_height_in_luma_samples ;
pic_param_ptr - > pic_fields . bits . chroma_format_idc = sps_ptr - > chroma_format_idc ;
pic_param_ptr - > pic_fields . bits . separate_colour_plane_flag = sps_ptr - > separate_colour_plane_flag ;
pic_param_ptr - > pic_fields . bits . pcm_enabled_flag = sps_ptr - > pcm_enabled_flag ;
pic_param_ptr - > pic_fields . bits . scaling_list_enabled_flag = sps_ptr - > scaling_list_enabled_flag ;
pic_param_ptr - > pic_fields . bits . transform_skip_enabled_flag = pps_ptr - > transform_skip_enabled_flag ;
pic_param_ptr - > pic_fields . bits . amp_enabled_flag = sps_ptr - > amp_enabled_flag ;
pic_param_ptr - > pic_fields . bits . strong_intra_smoothing_enabled_flag = sps_ptr - > strong_intra_smoothing_enabled_flag ;
pic_param_ptr - > pic_fields . bits . sign_data_hiding_enabled_flag = pps_ptr - > sign_data_hiding_enabled_flag ;
pic_param_ptr - > pic_fields . bits . constrained_intra_pred_flag = pps_ptr - > constrained_intra_pred_flag ;
pic_param_ptr - > pic_fields . bits . cu_qp_delta_enabled_flag = pps_ptr - > cu_qp_delta_enabled_flag ;
pic_param_ptr - > pic_fields . bits . weighted_pred_flag = pps_ptr - > weighted_pred_flag ;
pic_param_ptr - > pic_fields . bits . weighted_bipred_flag = pps_ptr - > weighted_bipred_flag ;
pic_param_ptr - > pic_fields . bits . transquant_bypass_enabled_flag = pps_ptr - > transquant_bypass_enabled_flag ;
pic_param_ptr - > pic_fields . bits . tiles_enabled_flag = pps_ptr - > tiles_enabled_flag ;
pic_param_ptr - > pic_fields . bits . entropy_coding_sync_enabled_flag = pps_ptr - > entropy_coding_sync_enabled_flag ;
pic_param_ptr - > pic_fields . bits . pps_loop_filter_across_slices_enabled_flag = pps_ptr - > pps_loop_filter_across_slices_enabled_flag ;
pic_param_ptr - > pic_fields . bits . loop_filter_across_tiles_enabled_flag = pps_ptr - > loop_filter_across_tiles_enabled_flag ;
pic_param_ptr - > pic_fields . bits . pcm_loop_filter_disabled_flag = sps_ptr - > pcm_loop_filter_disabled_flag ;
2024-01-24 18:03:46 -05:00
pic_param_ptr - > pic_fields . bits . no_pic_reordering_flag = sps_ptr - > sps_max_num_reorder_pics [ 0 ] ? 0 : 1 ;
2024-02-09 15:09:49 -05:00
pic_param_ptr - > pic_fields . bits . no_bi_pred_flag = slice_info_list_ [ 0 ] . slice_header . slice_type = = HEVC_SLICE_TYPE_B ? 0 : 1 ;
2023-11-09 13:52:02 -05:00
pic_param_ptr - > sps_max_dec_pic_buffering_minus1 = sps_ptr - > sps_max_dec_pic_buffering_minus1 [ sps_ptr - > sps_max_sub_layers_minus1 ] ; // HighestTid
pic_param_ptr - > bit_depth_luma_minus8 = sps_ptr - > bit_depth_luma_minus8 ;
pic_param_ptr - > bit_depth_chroma_minus8 = sps_ptr - > bit_depth_chroma_minus8 ;
pic_param_ptr - > pcm_sample_bit_depth_luma_minus1 = sps_ptr - > pcm_sample_bit_depth_luma_minus1 ;
pic_param_ptr - > pcm_sample_bit_depth_chroma_minus1 = sps_ptr - > pcm_sample_bit_depth_chroma_minus1 ;
pic_param_ptr - > log2_min_luma_coding_block_size_minus3 = sps_ptr - > log2_min_luma_coding_block_size_minus3 ;
pic_param_ptr - > log2_diff_max_min_luma_coding_block_size = sps_ptr - > log2_diff_max_min_luma_coding_block_size ;
2025-03-26 08:16:36 -04:00
pic_param_ptr - > log2_min_luma_transform_block_size_minus2 = sps_ptr - > log2_min_luma_transform_block_size_minus2 ;
pic_param_ptr - > log2_diff_max_min_luma_transform_block_size = sps_ptr - > log2_diff_max_min_luma_transform_block_size ;
2023-11-09 13:52:02 -05:00
pic_param_ptr - > log2_min_pcm_luma_coding_block_size_minus3 = sps_ptr - > log2_min_pcm_luma_coding_block_size_minus3 ;
pic_param_ptr - > log2_diff_max_min_pcm_luma_coding_block_size = sps_ptr - > log2_diff_max_min_pcm_luma_coding_block_size ;
pic_param_ptr - > max_transform_hierarchy_depth_intra = sps_ptr - > max_transform_hierarchy_depth_intra ;
pic_param_ptr - > max_transform_hierarchy_depth_inter = sps_ptr - > max_transform_hierarchy_depth_inter ;
pic_param_ptr - > init_qp_minus26 = pps_ptr - > init_qp_minus26 ;
pic_param_ptr - > diff_cu_qp_delta_depth = pps_ptr - > diff_cu_qp_delta_depth ;
pic_param_ptr - > pps_cb_qp_offset = pps_ptr - > pps_cb_qp_offset ;
pic_param_ptr - > pps_cr_qp_offset = pps_ptr - > pps_cr_qp_offset ;
pic_param_ptr - > log2_parallel_merge_level_minus2 = pps_ptr - > log2_parallel_merge_level_minus2 ;
if ( pps_ptr - > tiles_enabled_flag ) {
pic_param_ptr - > num_tile_columns_minus1 = pps_ptr - > num_tile_columns_minus1 ;
pic_param_ptr - > num_tile_rows_minus1 = pps_ptr - > num_tile_rows_minus1 ;
for ( i = 0 ; i < = pps_ptr - > num_tile_columns_minus1 ; i + + ) {
pic_param_ptr - > column_width_minus1 [ i ] = pps_ptr - > column_width_minus1 [ i ] ;
}
for ( i = 0 ; i < = pps_ptr - > num_tile_rows_minus1 ; i + + ) {
pic_param_ptr - > row_height_minus1 [ i ] = pps_ptr - > row_height_minus1 [ i ] ;
}
}
pic_param_ptr - > slice_parsing_fields . bits . lists_modification_present_flag = pps_ptr - > lists_modification_present_flag ;
pic_param_ptr - > slice_parsing_fields . bits . long_term_ref_pics_present_flag = sps_ptr - > long_term_ref_pics_present_flag ;
pic_param_ptr - > slice_parsing_fields . bits . sps_temporal_mvp_enabled_flag = sps_ptr - > sps_temporal_mvp_enabled_flag ;
pic_param_ptr - > slice_parsing_fields . bits . cabac_init_present_flag = pps_ptr - > cabac_init_present_flag ;
pic_param_ptr - > slice_parsing_fields . bits . output_flag_present_flag = pps_ptr - > output_flag_present_flag ;
pic_param_ptr - > slice_parsing_fields . bits . dependent_slice_segments_enabled_flag = pps_ptr - > dependent_slice_segments_enabled_flag ;
pic_param_ptr - > slice_parsing_fields . bits . pps_slice_chroma_qp_offsets_present_flag = pps_ptr - > pps_slice_chroma_qp_offsets_present_flag ;
pic_param_ptr - > slice_parsing_fields . bits . sample_adaptive_offset_enabled_flag = sps_ptr - > sample_adaptive_offset_enabled_flag ;
pic_param_ptr - > slice_parsing_fields . bits . deblocking_filter_override_enabled_flag = pps_ptr - > deblocking_filter_override_enabled_flag ;
pic_param_ptr - > slice_parsing_fields . bits . pps_disable_deblocking_filter_flag = pps_ptr - > pps_deblocking_filter_disabled_flag ;
pic_param_ptr - > slice_parsing_fields . bits . slice_segment_header_extension_present_flag = pps_ptr - > slice_segment_header_extension_present_flag ;
2024-01-24 18:03:46 -05:00
pic_param_ptr - > slice_parsing_fields . bits . rap_pic_flag = IsIrapPic ( & slice_nal_unit_header_ ) ? 1 : 0 ;
pic_param_ptr - > slice_parsing_fields . bits . idr_pic_flag = IsIdrPic ( & slice_nal_unit_header_ ) ? 1 : 0 ;
2024-02-09 15:09:49 -05:00
pic_param_ptr - > slice_parsing_fields . bits . intra_pic_flag = slice_info_list_ [ 0 ] . slice_header . slice_type = = HEVC_SLICE_TYPE_I ? 1 : 0 ;
2023-11-09 13:52:02 -05:00
pic_param_ptr - > log2_max_pic_order_cnt_lsb_minus4 = sps_ptr - > log2_max_pic_order_cnt_lsb_minus4 ;
pic_param_ptr - > num_short_term_ref_pic_sets = sps_ptr - > num_short_term_ref_pic_sets ;
pic_param_ptr - > num_long_term_ref_pic_sps = sps_ptr - > num_long_term_ref_pics_sps ;
pic_param_ptr - > num_ref_idx_l0_default_active_minus1 = pps_ptr - > num_ref_idx_l0_default_active_minus1 ;
pic_param_ptr - > num_ref_idx_l1_default_active_minus1 = pps_ptr - > num_ref_idx_l1_default_active_minus1 ;
pic_param_ptr - > pps_beta_offset_div2 = pps_ptr - > pps_beta_offset_div2 ;
pic_param_ptr - > pps_tc_offset_div2 = pps_ptr - > pps_tc_offset_div2 ;
pic_param_ptr - > num_extra_slice_header_bits = pps_ptr - > num_extra_slice_header_bits ;
2024-02-09 15:09:49 -05:00
pic_param_ptr - > st_rps_bits = slice_info_list_ [ 0 ] . slice_header . short_term_ref_pic_set_size ;
2023-11-09 13:52:02 -05:00
/// Fill slice parameters
2024-02-09 15:09:49 -05:00
// Resize if needed
if ( num_slices_ > slice_param_list_ . size ( ) ) {
slice_param_list_ . resize ( num_slices_ , { 0 } ) ;
}
for ( int slice_index = 0 ; slice_index < num_slices_ ; slice_index + + ) {
RocdecHevcSliceParams * slice_params_ptr = & slice_param_list_ [ slice_index ] ;
HevcSliceInfo * p_slice_info = & slice_info_list_ [ slice_index ] ;
HevcSliceSegHeader * p_slice_header = & p_slice_info - > slice_header ;
// We put all slices into one slice data buffer.
slice_params_ptr - > slice_data_size = p_slice_info - > slice_data_size ;
slice_params_ptr - > slice_data_offset = p_slice_info - > slice_data_offset ; // point to the start code
slice_params_ptr - > slice_data_flag = 0x00 ; // VA_SLICE_DATA_FLAG_ALL;
slice_params_ptr - > slice_data_byte_offset = 0 ; // VCN consumes from the start code
slice_params_ptr - > slice_segment_address = p_slice_header - > slice_segment_address ;
// Ref lists
memset ( slice_params_ptr - > ref_pic_list , 0xFF , sizeof ( slice_params_ptr - > ref_pic_list ) ) ;
if ( p_slice_header - > slice_type ! = HEVC_SLICE_TYPE_I ) {
for ( i = 0 ; i < = p_slice_header - > num_ref_idx_l0_active_minus1 ; i + + ) {
int idx = p_slice_info - > ref_pic_list_0_ [ i ] ; // pic_idx of the ref pic
2024-05-31 13:14:02 -04:00
int dec_buf_idx = dpb_buffer_ . frame_buffer_list [ idx ] . dec_buf_idx ;
2023-11-14 15:44:35 -05:00
for ( j = 0 ; j < 15 ; j + + ) {
2024-05-31 13:14:02 -04:00
if ( pic_param_ptr - > ref_frames [ j ] . pic_idx = = dec_buf_idx ) {
2023-11-14 15:44:35 -05:00
break ;
}
}
if ( j = = 15 ) {
2024-02-09 15:09:49 -05:00
ERR ( " Could not find matching pic in ref_frames list. The slice type is P/B, and the idx from the ref_pic_list_0_ is: " + TOSTR ( idx ) ) ;
2023-11-16 12:39:23 -05:00
return PARSER_FAIL ;
2024-01-05 09:15:33 -05:00
} else {
2024-02-09 15:09:49 -05:00
slice_params_ptr - > ref_pic_list [ 0 ] [ i ] = j ;
2023-11-14 15:44:35 -05:00
}
2023-11-09 13:52:02 -05:00
}
2024-02-09 15:09:49 -05:00
if ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) {
for ( i = 0 ; i < = p_slice_header - > num_ref_idx_l1_active_minus1 ; i + + ) {
int idx = p_slice_info - > ref_pic_list_1_ [ i ] ; // pic_idx of the ref pic
2024-05-31 13:14:02 -04:00
int dec_buf_idx = dpb_buffer_ . frame_buffer_list [ idx ] . dec_buf_idx ;
2024-02-09 15:09:49 -05:00
for ( j = 0 ; j < 15 ; j + + ) {
2024-05-31 13:14:02 -04:00
if ( pic_param_ptr - > ref_frames [ j ] . pic_idx = = dec_buf_idx ) {
2024-02-09 15:09:49 -05:00
break ;
}
}
if ( j = = 15 ) {
ERR ( " Could not find matching pic in ref_frames list. The slice type is B, and the idx from the ref_pic_list_1_ is: " + TOSTR ( idx ) ) ;
return PARSER_FAIL ;
} else {
slice_params_ptr - > ref_pic_list [ 1 ] [ i ] = j ;
}
}
}
2023-11-09 13:52:02 -05:00
}
2024-02-09 15:09:49 -05:00
slice_params_ptr - > long_slice_flags . fields . last_slice_of_pic = ( slice_index = = num_slices_ - 1 ) ? 1 : 0 ;
slice_params_ptr - > long_slice_flags . fields . dependent_slice_segment_flag = p_slice_header - > dependent_slice_segment_flag ;
slice_params_ptr - > long_slice_flags . fields . slice_type = p_slice_header - > slice_type ;
slice_params_ptr - > long_slice_flags . fields . color_plane_id = p_slice_header - > colour_plane_id ;
slice_params_ptr - > long_slice_flags . fields . slice_sao_luma_flag = p_slice_header - > slice_sao_luma_flag ;
slice_params_ptr - > long_slice_flags . fields . slice_sao_chroma_flag = p_slice_header - > slice_sao_chroma_flag ;
slice_params_ptr - > long_slice_flags . fields . mvd_l1_zero_flag = p_slice_header - > mvd_l1_zero_flag ;
slice_params_ptr - > long_slice_flags . fields . cabac_init_flag = p_slice_header - > cabac_init_flag ;
slice_params_ptr - > long_slice_flags . fields . slice_temporal_mvp_enabled_flag = p_slice_header - > slice_temporal_mvp_enabled_flag ;
slice_params_ptr - > long_slice_flags . fields . slice_deblocking_filter_disabled_flag = p_slice_header - > slice_deblocking_filter_disabled_flag ;
slice_params_ptr - > long_slice_flags . fields . collocated_from_l0_flag = p_slice_header - > collocated_from_l0_flag ;
slice_params_ptr - > long_slice_flags . fields . slice_loop_filter_across_slices_enabled_flag = p_slice_header - > slice_loop_filter_across_slices_enabled_flag ;
slice_params_ptr - > collocated_ref_idx = p_slice_header - > collocated_ref_idx ;
slice_params_ptr - > num_ref_idx_l0_active_minus1 = p_slice_header - > num_ref_idx_l0_active_minus1 ;
slice_params_ptr - > num_ref_idx_l1_active_minus1 = p_slice_header - > num_ref_idx_l1_active_minus1 ;
slice_params_ptr - > slice_qp_delta = p_slice_header - > slice_qp_delta ;
slice_params_ptr - > slice_cb_qp_offset = p_slice_header - > slice_cb_qp_offset ;
slice_params_ptr - > slice_cr_qp_offset = p_slice_header - > slice_cr_qp_offset ;
slice_params_ptr - > slice_beta_offset_div2 = p_slice_header - > slice_beta_offset_div2 ;
slice_params_ptr - > slice_tc_offset_div2 = p_slice_header - > slice_tc_offset_div2 ;
if ( ( pps_ptr - > weighted_pred_flag & & p_slice_header - > slice_type = = HEVC_SLICE_TYPE_P ) | | ( pps_ptr - > weighted_bipred_flag & & p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) ) {
slice_params_ptr - > luma_log2_weight_denom = p_slice_header - > pred_weight_table . luma_log2_weight_denom ;
slice_params_ptr - > delta_chroma_log2_weight_denom = p_slice_header - > pred_weight_table . delta_chroma_log2_weight_denom ;
for ( i = 0 ; i < p_slice_header - > num_ref_idx_l0_active_minus1 ; i + + ) {
slice_params_ptr - > delta_luma_weight_l0 [ i ] = p_slice_header - > pred_weight_table . delta_luma_weight_l0 [ i ] ;
slice_params_ptr - > luma_offset_l0 [ i ] = p_slice_header - > pred_weight_table . luma_offset_l0 [ i ] ;
slice_params_ptr - > delta_chroma_weight_l0 [ i ] [ 0 ] = p_slice_header - > pred_weight_table . delta_chroma_weight_l0 [ i ] [ 0 ] ;
slice_params_ptr - > delta_chroma_weight_l0 [ i ] [ 1 ] = p_slice_header - > pred_weight_table . delta_chroma_weight_l0 [ i ] [ 1 ] ;
slice_params_ptr - > chroma_offset_l0 [ i ] [ 0 ] = p_slice_header - > pred_weight_table . chroma_offset_l0 [ i ] [ 0 ] ;
slice_params_ptr - > chroma_offset_l0 [ i ] [ 1 ] = p_slice_header - > pred_weight_table . chroma_offset_l0 [ i ] [ 1 ] ;
}
if ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) {
for ( i = 0 ; i < p_slice_header - > num_ref_idx_l1_active_minus1 ; i + + ) {
slice_params_ptr - > delta_luma_weight_l1 [ i ] = p_slice_header - > pred_weight_table . delta_luma_weight_l1 [ i ] ;
slice_params_ptr - > luma_offset_l1 [ i ] = p_slice_header - > pred_weight_table . luma_offset_l1 [ i ] ;
slice_params_ptr - > delta_chroma_weight_l1 [ i ] [ 0 ] = p_slice_header - > pred_weight_table . delta_chroma_weight_l1 [ i ] [ 0 ] ;
slice_params_ptr - > delta_chroma_weight_l1 [ i ] [ 1 ] = p_slice_header - > pred_weight_table . delta_chroma_weight_l1 [ i ] [ 1 ] ;
slice_params_ptr - > chroma_offset_l1 [ i ] [ 0 ] = p_slice_header - > pred_weight_table . chroma_offset_l1 [ i ] [ 0 ] ;
slice_params_ptr - > chroma_offset_l1 [ i ] [ 1 ] = p_slice_header - > pred_weight_table . chroma_offset_l1 [ i ] [ 1 ] ;
}
2023-11-09 13:52:02 -05:00
}
}
2024-02-09 15:09:49 -05:00
slice_params_ptr - > five_minus_max_num_merge_cand = p_slice_header - > five_minus_max_num_merge_cand ;
slice_params_ptr - > num_entry_point_offsets = p_slice_header - > num_entry_point_offsets ;
slice_params_ptr - > entry_offset_to_subset_array = 0 ; // don't care
slice_params_ptr - > slice_data_num_emu_prevn_bytes = 0 ; // don't care
}
dec_pic_params_ . slice_params . hevc = slice_param_list_ . data ( ) ;
2023-11-09 13:52:02 -05:00
/// Fill scaling lists
if ( sps_ptr - > scaling_list_enabled_flag ) {
RocdecHevcIQMatrix * iq_matrix_ptr = & dec_pic_params_ . iq_matrix . hevc ;
2024-01-10 11:44:07 -05:00
HevcScalingListData * scaling_list_data_ptr = & pps_ptr - > scaling_list_data ;
2023-11-09 13:52:02 -05:00
for ( i = 0 ; i < 6 ; i + + ) {
for ( j = 0 ; j < 16 ; j + + ) {
2024-01-24 18:03:46 -05:00
iq_matrix_ptr - > scaling_list_4x4 [ i ] [ j ] = scaling_list_data_ptr - > scaling_list [ 0 ] [ i ] [ j ] ;
2023-11-09 13:52:02 -05:00
}
for ( j = 0 ; j < 64 ; j + + ) {
2024-01-24 18:03:46 -05:00
iq_matrix_ptr - > scaling_list_8x8 [ i ] [ j ] = scaling_list_data_ptr - > scaling_list [ 1 ] [ i ] [ j ] ;
iq_matrix_ptr - > scaling_list_16x16 [ i ] [ j ] = scaling_list_data_ptr - > scaling_list [ 2 ] [ i ] [ j ] ;
2023-11-09 13:52:02 -05:00
if ( i < 2 ) {
2024-01-24 18:03:46 -05:00
iq_matrix_ptr - > scaling_list_32x32 [ i ] [ j ] = scaling_list_data_ptr - > scaling_list [ 3 ] [ i * 3 ] [ j ] ;
2023-11-09 13:52:02 -05:00
}
}
2024-01-24 18:03:46 -05:00
iq_matrix_ptr - > scaling_list_dc_16x16 [ i ] = scaling_list_data_ptr - > scaling_list_dc_coef [ 0 ] [ i ] ;
2023-11-09 13:52:02 -05:00
if ( i < 2 ) {
2024-01-24 18:03:46 -05:00
iq_matrix_ptr - > scaling_list_dc_32x32 [ i ] = scaling_list_data_ptr - > scaling_list_dc_coef [ 1 ] [ i * 3 ] ;
2023-11-09 13:52:02 -05:00
}
}
}
2023-11-06 22:04:25 -05:00
2024-05-31 13:14:02 -04:00
# if DBGINFO
PrintVappiBufInfo ( ) ;
# endif // DBGINFO
2024-01-24 18:03:46 -05:00
if ( pfn_decode_picture_cb_ ( parser_params_ . user_data , & dec_pic_params_ ) = = 0 ) {
2023-11-06 22:04:25 -05:00
ERR ( " Decode error occurred. " ) ;
return PARSER_FAIL ;
2024-01-05 09:15:33 -05:00
} else {
2023-11-06 22:04:25 -05:00
return PARSER_OK ;
}
}
2024-05-03 15:18:08 -04:00
ParserResult HevcVideoParser : : ParsePictureData ( const uint8_t * p_stream , uint32_t pic_data_size ) {
ParserResult ret = PARSER_OK ;
ParserResult ret2 ;
2023-10-05 08:20:07 -07:00
2024-01-16 20:57:40 -05:00
pic_data_buffer_ptr_ = ( uint8_t * ) p_stream ;
pic_data_size_ = pic_data_size ;
2023-10-18 06:01:44 -07:00
curr_byte_offset_ = 0 ;
start_code_num_ = 0 ;
curr_start_code_offset_ = 0 ;
next_start_code_offset_ = 0 ;
2023-10-05 08:20:07 -07:00
2024-02-09 15:09:49 -05:00
num_slices_ = 0 ;
2023-11-06 06:25:09 -08:00
sei_message_count_ = 0 ;
2023-11-21 14:33:15 -05:00
sei_payload_size_ = 0 ;
2023-10-05 08:20:07 -07:00
2023-10-18 06:01:44 -07:00
do {
ret = GetNalUnit ( ) ;
if ( ret = = PARSER_NOT_FOUND ) {
2023-10-20 10:39:21 -04:00
ERR ( STR ( " Error: no start code found in the frame data. " ) ) ;
2024-05-03 15:18:08 -04:00
return ret ;
2023-10-05 08:20:07 -07:00
}
2023-10-18 06:01:44 -07:00
// Parse the NAL unit
2024-11-13 13:28:29 -05:00
if ( nal_unit_size_ > = 5 ) {
2023-10-18 06:01:44 -07:00
// start code + NAL unit header = 5 bytes
int ebsp_size = nal_unit_size_ - 5 > RBSP_BUF_SIZE ? RBSP_BUF_SIZE : nal_unit_size_ - 5 ; // only copy enough bytes for header parsing
2023-10-05 08:20:07 -07:00
2024-01-16 20:57:40 -05:00
nal_unit_header_ = ParseNalUnitHeader ( & pic_data_buffer_ptr_ [ curr_start_code_offset_ + 3 ] ) ;
2023-11-02 18:08:24 -04:00
switch ( nal_unit_header_ . nal_unit_type ) {
2023-10-18 06:01:44 -07:00
case NAL_UNIT_VPS : {
2024-01-16 20:57:40 -05:00
memcpy ( rbsp_buf_ , ( pic_data_buffer_ptr_ + curr_start_code_offset_ + 5 ) , ebsp_size ) ;
rbsp_size_ = EbspToRbsp ( rbsp_buf_ , 0 , ebsp_size ) ;
ParseVps ( rbsp_buf_ , rbsp_size_ ) ;
2023-10-18 06:01:44 -07:00
break ;
}
2023-10-05 08:20:07 -07:00
2023-10-18 06:01:44 -07:00
case NAL_UNIT_SPS : {
2024-01-16 20:57:40 -05:00
memcpy ( rbsp_buf_ , ( pic_data_buffer_ptr_ + curr_start_code_offset_ + 5 ) , ebsp_size ) ;
rbsp_size_ = EbspToRbsp ( rbsp_buf_ , 0 , ebsp_size ) ;
ParseSps ( rbsp_buf_ , rbsp_size_ ) ;
2023-10-18 06:01:44 -07:00
break ;
}
2023-10-05 08:20:07 -07:00
2023-10-18 06:01:44 -07:00
case NAL_UNIT_PPS : {
2024-01-16 20:57:40 -05:00
memcpy ( rbsp_buf_ , ( pic_data_buffer_ptr_ + curr_start_code_offset_ + 5 ) , ebsp_size ) ;
rbsp_size_ = EbspToRbsp ( rbsp_buf_ , 0 , ebsp_size ) ;
ParsePps ( rbsp_buf_ , rbsp_size_ ) ;
2023-10-18 06:01:44 -07:00
break ;
}
case NAL_UNIT_CODED_SLICE_TRAIL_R :
case NAL_UNIT_CODED_SLICE_TRAIL_N :
case NAL_UNIT_CODED_SLICE_TLA_R :
case NAL_UNIT_CODED_SLICE_TSA_N :
case NAL_UNIT_CODED_SLICE_STSA_R :
case NAL_UNIT_CODED_SLICE_STSA_N :
case NAL_UNIT_CODED_SLICE_BLA_W_LP :
case NAL_UNIT_CODED_SLICE_BLA_W_RADL :
case NAL_UNIT_CODED_SLICE_BLA_N_LP :
case NAL_UNIT_CODED_SLICE_IDR_W_RADL :
case NAL_UNIT_CODED_SLICE_IDR_N_LP :
2023-10-19 14:07:36 -04:00
case NAL_UNIT_CODED_SLICE_CRA_NUT :
2023-10-18 06:01:44 -07:00
case NAL_UNIT_CODED_SLICE_RADL_N :
case NAL_UNIT_CODED_SLICE_RADL_R :
case NAL_UNIT_CODED_SLICE_RASL_N :
case NAL_UNIT_CODED_SLICE_RASL_R : {
2024-02-09 15:09:49 -05:00
// Save slice NAL unit header
slice_nal_unit_header_ = nal_unit_header_ ;
// Resize slice info list if needed
if ( ( num_slices_ + 1 ) > slice_info_list_ . size ( ) ) {
2025-03-20 06:12:16 -07:00
slice_info_list_ . resize ( num_slices_ + 1 , { { 0 } } ) ;
2024-02-09 15:09:49 -05:00
}
2024-01-16 20:57:40 -05:00
memcpy ( rbsp_buf_ , ( pic_data_buffer_ptr_ + curr_start_code_offset_ + 5 ) , ebsp_size ) ;
rbsp_size_ = EbspToRbsp ( rbsp_buf_ , 0 , ebsp_size ) ;
2024-02-09 15:09:49 -05:00
HevcSliceSegHeader * p_slice_header = & slice_info_list_ [ num_slices_ ] . slice_header ;
2024-05-03 15:18:08 -04:00
if ( ( ret2 = ParseSliceHeader ( rbsp_buf_ , rbsp_size_ , p_slice_header ) ) ! = PARSER_OK ) {
2024-11-11 14:33:17 -08:00
// we got an error while parsing this NAL unit. ignore and continue with next NAL unit
break ; // ignore and continue to next nal_unit
2024-05-03 15:18:08 -04:00
}
2023-11-09 13:52:02 -05:00
2025-03-28 16:35:03 -04:00
slice_info_list_ [ num_slices_ ] . slice_data_offset = curr_start_code_offset_ ;
slice_info_list_ [ num_slices_ ] . slice_data_size = nal_unit_size_ ;
2024-02-09 15:09:49 -05:00
// Start decode process
if ( num_slices_ = = 0 ) {
2023-11-06 22:04:25 -05:00
// Use the data directly from demuxer without copying
2024-01-16 20:57:40 -05:00
pic_stream_data_ptr_ = pic_data_buffer_ptr_ + curr_start_code_offset_ ;
2023-11-06 22:04:25 -05:00
// Picture stream data size is calculated as the diff between the frame end and the first slice offset.
// This is to consider the possibility of non-slice NAL units between slices.
2024-01-16 20:57:40 -05:00
pic_stream_data_size_ = pic_data_size - curr_start_code_offset_ ;
2023-11-06 22:04:25 -05:00
2023-11-15 16:07:18 -05:00
if ( IsIrapPic ( & slice_nal_unit_header_ ) ) {
if ( IsIdrPic ( & slice_nal_unit_header_ ) | | IsBlaPic ( & slice_nal_unit_header_ ) | | pic_count_ = = 0 | | first_pic_after_eos_nal_unit_ ) {
no_rasl_output_flag_ = 1 ;
2023-11-27 11:04:01 -05:00
} else {
2023-11-15 16:07:18 -05:00
no_rasl_output_flag_ = 0 ;
}
}
if ( first_pic_after_eos_nal_unit_ ) {
first_pic_after_eos_nal_unit_ = 0 ; // clear the flag
}
2023-11-02 18:08:24 -04:00
2023-11-27 11:04:01 -05:00
if ( IsRaslPic ( & slice_nal_unit_header_ ) & & no_rasl_output_flag_ = = 1 ) {
curr_pic_info_ . pic_output_flag = 0 ;
} else {
2024-02-09 15:09:49 -05:00
curr_pic_info_ . pic_output_flag = p_slice_header - > pic_output_flag ;
2023-11-27 11:04:01 -05:00
}
// Get POC. 8.3.1.
2024-01-29 12:09:36 -05:00
CalculateCurrPoc ( ) ;
2023-11-02 18:08:24 -04:00
2024-05-31 13:14:02 -04:00
// Locate a free buffer for the current picutre in decode buffer pool before output picture marking (C.5.2.2)
if ( FindFreeInDecBufPool ( ) ! = PARSER_OK ) {
return PARSER_FAIL ;
}
2023-11-27 11:04:01 -05:00
// Decode RPS. 8.3.2.
2023-11-28 14:03:13 -05:00
DecodeRps ( ) ;
2024-02-09 15:09:49 -05:00
}
2023-11-02 18:08:24 -04:00
2024-02-09 15:09:49 -05:00
// Construct ref lists. 8.3.4.
if ( p_slice_header - > slice_type ! = HEVC_SLICE_TYPE_I ) {
ConstructRefPicLists ( & slice_info_list_ [ num_slices_ ] ) ;
}
2023-11-02 18:08:24 -04:00
2024-02-09 15:09:49 -05:00
if ( num_slices_ = = 0 ) {
2023-11-27 11:04:01 -05:00
// C.5.2.2. Mark output buffers. (After 8.3.2.)
if ( MarkOutputPictures ( ) ! = PARSER_OK ) {
return PARSER_FAIL ;
}
// C.5.2.3. Find a free buffer in DPB and mark as used. (After 8.3.2.)
2024-05-31 13:14:02 -04:00
if ( FindFreeInDpbAndMark ( ) ! = PARSER_OK ) {
2023-11-27 11:04:01 -05:00
return PARSER_FAIL ;
}
2024-05-31 13:14:02 -04:00
# if DBGINFO
PrintDpb ( ) ;
# endif // DBGINFO
2023-10-27 15:13:12 -04:00
}
2024-02-09 15:09:49 -05:00
num_slices_ + + ;
2023-10-18 06:01:44 -07:00
break ;
}
2023-11-21 14:33:15 -05:00
case NAL_UNIT_PREFIX_SEI :
case NAL_UNIT_SUFFIX_SEI : {
2023-11-21 08:23:47 -08:00
if ( pfn_get_sei_message_cb_ ) {
2023-11-21 14:33:15 -05:00
int sei_ebsp_size = nal_unit_size_ - 5 ; // copy the entire NAL unit
if ( sei_rbsp_buf_ ) {
if ( sei_ebsp_size > sei_rbsp_buf_size_ ) {
delete [ ] sei_rbsp_buf_ ;
sei_rbsp_buf_ = new uint8_t [ sei_ebsp_size ] ;
sei_rbsp_buf_size_ = sei_ebsp_size ;
}
2024-01-05 09:15:33 -05:00
} else {
2023-11-21 14:33:15 -05:00
sei_rbsp_buf_size_ = sei_ebsp_size > INIT_SEI_PAYLOAD_BUF_SIZE ? sei_ebsp_size : INIT_SEI_PAYLOAD_BUF_SIZE ;
sei_rbsp_buf_ = new uint8_t [ sei_rbsp_buf_size_ ] ;
}
2024-01-16 20:57:40 -05:00
memcpy ( sei_rbsp_buf_ , ( pic_data_buffer_ptr_ + curr_start_code_offset_ + 5 ) , sei_ebsp_size ) ;
rbsp_size_ = EbspToRbsp ( sei_rbsp_buf_ , 0 , sei_ebsp_size ) ;
ParseSeiMessage ( sei_rbsp_buf_ , rbsp_size_ ) ;
2023-11-21 08:23:47 -08:00
}
2023-10-18 06:01:44 -07:00
break ;
2023-11-06 06:25:09 -08:00
}
2023-11-15 16:07:18 -05:00
case NAL_UNIT_EOS : {
first_pic_after_eos_nal_unit_ = 1 ;
break ;
}
case NAL_UNIT_EOB : {
pic_count_ = 0 ;
break ;
}
2023-11-06 06:25:09 -08:00
default :
2023-11-09 14:57:22 -05:00
break ;
2023-10-18 06:01:44 -07:00
}
}
2023-10-05 08:20:07 -07:00
2023-10-18 06:01:44 -07:00
// Break if this is the last NAL unit
if ( ret = = PARSER_EOF ) {
break ;
}
} while ( 1 ) ;
2023-10-05 08:20:07 -07:00
2024-05-03 15:18:08 -04:00
return PARSER_OK ;
2023-10-18 06:01:44 -07:00
}
2023-10-05 08:20:07 -07:00
2024-01-10 11:44:07 -05:00
void HevcVideoParser : : ParsePtl ( HevcProfileTierLevel * ptl , bool profile_present_flag , uint32_t max_num_sub_layers_minus1 , uint8_t * nalu , size_t size , size_t & offset ) {
2023-10-05 08:20:07 -07:00
if ( profile_present_flag ) {
2023-10-18 06:01:44 -07:00
ptl - > general_profile_space = Parser : : ReadBits ( nalu , offset , 2 ) ;
2023-10-05 08:20:07 -07:00
ptl - > general_tier_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
ptl - > general_profile_idc = Parser : : ReadBits ( nalu , offset , 5 ) ;
2023-10-05 08:20:07 -07:00
for ( int i = 0 ; i < 32 ; i + + ) {
ptl - > general_profile_compatibility_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
}
ptl - > general_progressive_source_flag = Parser : : GetBit ( nalu , offset ) ;
ptl - > general_interlaced_source_flag = Parser : : GetBit ( nalu , offset ) ;
ptl - > general_non_packed_constraint_flag = Parser : : GetBit ( nalu , offset ) ;
ptl - > general_frame_only_constraint_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-24 16:20:56 -04:00
// ReadBits is limited to 32
offset + = 44 ; // skip 44 bits
// Todo: add constrant flags parsing for higher profiles when needed
2023-10-05 08:20:07 -07:00
}
2023-10-18 15:36:19 -07:00
2023-10-18 06:01:44 -07:00
ptl - > general_level_idc = Parser : : ReadBits ( nalu , offset , 8 ) ;
2023-10-05 08:20:07 -07:00
for ( uint32_t i = 0 ; i < max_num_sub_layers_minus1 ; i + + ) {
ptl - > sub_layer_profile_present_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
ptl - > sub_layer_level_present_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
}
if ( max_num_sub_layers_minus1 > 0 ) {
2023-10-18 06:01:44 -07:00
for ( uint32_t i = max_num_sub_layers_minus1 ; i < 8 ; i + + ) {
ptl - > reserved_zero_2bits [ i ] = Parser : : ReadBits ( nalu , offset , 2 ) ;
2023-10-05 08:20:07 -07:00
}
}
for ( uint32_t i = 0 ; i < max_num_sub_layers_minus1 ; i + + ) {
if ( ptl - > sub_layer_profile_present_flag [ i ] ) {
2023-10-18 06:01:44 -07:00
ptl - > sub_layer_profile_space [ i ] = Parser : : ReadBits ( nalu , offset , 2 ) ;
2023-10-05 08:20:07 -07:00
ptl - > sub_layer_tier_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
ptl - > sub_layer_profile_idc [ i ] = Parser : : ReadBits ( nalu , offset , 5 ) ;
2023-10-18 15:36:19 -07:00
for ( int j = 0 ; j < 32 ; j + + ) {
ptl - > sub_layer_profile_compatibility_flag [ i ] [ j ] = Parser : : GetBit ( nalu , offset ) ;
}
ptl - > sub_layer_progressive_source_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
ptl - > sub_layer_interlaced_source_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
2023-10-05 08:20:07 -07:00
ptl - > sub_layer_non_packed_constraint_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
ptl - > sub_layer_frame_only_constraint_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
2023-10-24 16:20:56 -04:00
// ReadBits is limited to 32
offset + = 44 ; // skip 44 bits
// Todo: add constrant flags parsing for higher profiles when needed
2023-10-05 08:20:07 -07:00
}
if ( ptl - > sub_layer_level_present_flag [ i ] ) {
2023-10-18 06:01:44 -07:00
ptl - > sub_layer_level_idc [ i ] = Parser : : ReadBits ( nalu , offset , 8 ) ;
2023-10-05 08:20:07 -07:00
}
}
}
2024-01-10 11:44:07 -05:00
void HevcVideoParser : : ParseSubLayerHrdParameters ( HevcSubLayerHrdParameters * sub_hrd , uint32_t cpb_cnt , bool sub_pic_hrd_params_present_flag , uint8_t * nalu , size_t /*size*/ , size_t & offset ) {
2023-10-18 06:01:44 -07:00
for ( uint32_t i = 0 ; i < = cpb_cnt ; i + + ) {
2023-10-05 08:20:07 -07:00
sub_hrd - > bit_rate_value_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
sub_hrd - > cpb_size_value_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
if ( sub_pic_hrd_params_present_flag ) {
sub_hrd - > cpb_size_du_value_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
sub_hrd - > bit_rate_du_value_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
}
sub_hrd - > cbr_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
}
}
2025-03-10 09:15:12 -04:00
ParserResult HevcVideoParser : : ParseHrdParameters ( HevcHrdParameters * hrd , bool common_inf_present_flag , uint32_t max_num_sub_layers_minus1 , uint8_t * nalu , size_t size , size_t & offset ) {
2023-10-05 08:20:07 -07:00
if ( common_inf_present_flag ) {
hrd - > nal_hrd_parameters_present_flag = Parser : : GetBit ( nalu , offset ) ;
hrd - > vcl_hrd_parameters_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( hrd - > nal_hrd_parameters_present_flag | | hrd - > vcl_hrd_parameters_present_flag ) {
hrd - > sub_pic_hrd_params_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( hrd - > sub_pic_hrd_params_present_flag ) {
2023-10-18 06:01:44 -07:00
hrd - > tick_divisor_minus2 = Parser : : ReadBits ( nalu , offset , 8 ) ;
hrd - > du_cpb_removal_delay_increment_length_minus1 = Parser : : ReadBits ( nalu , offset , 5 ) ;
2023-10-05 08:20:07 -07:00
hrd - > sub_pic_cpb_params_in_pic_timing_sei_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
hrd - > dpb_output_delay_du_length_minus1 = Parser : : ReadBits ( nalu , offset , 5 ) ;
2023-10-05 08:20:07 -07:00
}
2023-10-18 06:01:44 -07:00
hrd - > bit_rate_scale = Parser : : ReadBits ( nalu , offset , 4 ) ;
hrd - > cpb_size_scale = Parser : : ReadBits ( nalu , offset , 4 ) ;
2023-10-05 08:20:07 -07:00
if ( hrd - > sub_pic_hrd_params_present_flag ) {
2023-10-18 06:01:44 -07:00
hrd - > cpb_size_du_scale = Parser : : ReadBits ( nalu , offset , 4 ) ;
2023-10-05 08:20:07 -07:00
}
2023-10-18 06:01:44 -07:00
hrd - > initial_cpb_removal_delay_length_minus1 = Parser : : ReadBits ( nalu , offset , 5 ) ;
hrd - > au_cpb_removal_delay_length_minus1 = Parser : : ReadBits ( nalu , offset , 5 ) ;
hrd - > dpb_output_delay_length_minus1 = Parser : : ReadBits ( nalu , offset , 5 ) ;
2023-10-05 08:20:07 -07:00
}
}
for ( uint32_t i = 0 ; i < = max_num_sub_layers_minus1 ; i + + ) {
hrd - > fixed_pic_rate_general_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
if ( ! hrd - > fixed_pic_rate_general_flag [ i ] ) {
hrd - > fixed_pic_rate_within_cvs_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-10-05 08:20:07 -07:00
hrd - > fixed_pic_rate_within_cvs_flag [ i ] = hrd - > fixed_pic_rate_general_flag [ i ] ;
}
if ( hrd - > fixed_pic_rate_within_cvs_flag [ i ] ) {
hrd - > elemental_duration_in_tc_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " elemental_duration_in_tc_minus1 " , hrd - > elemental_duration_in_tc_minus1 [ i ] , 0 , 2047 ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-10-05 08:20:07 -07:00
hrd - > low_delay_hrd_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
}
if ( ! hrd - > low_delay_hrd_flag [ i ] ) {
hrd - > cpb_cnt_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " cpb_cnt_minus1 " , hrd - > cpb_cnt_minus1 [ i ] , 0 , 31 ) ;
2023-10-05 08:20:07 -07:00
}
if ( hrd - > nal_hrd_parameters_present_flag ) {
//sub_layer_hrd_parameters( i )
ParseSubLayerHrdParameters ( & hrd - > sub_layer_hrd_parameters_0 [ i ] , hrd - > cpb_cnt_minus1 [ i ] , hrd - > sub_pic_hrd_params_present_flag , nalu , size , offset ) ;
}
if ( hrd - > vcl_hrd_parameters_present_flag ) {
//sub_layer_hrd_parameters( i )
ParseSubLayerHrdParameters ( & hrd - > sub_layer_hrd_parameters_1 [ i ] , hrd - > cpb_cnt_minus1 [ i ] , hrd - > sub_pic_hrd_params_present_flag , nalu , size , offset ) ;
}
}
2025-03-10 09:15:12 -04:00
return PARSER_OK ;
2023-10-05 08:20:07 -07:00
}
2023-10-24 16:20:56 -04:00
// Table 7-5. Default values of ScalingList[ 0 ][ matrixId ][ i ] with i = 0..15.
static const uint8_t default_scaling_list_side_id_0 [ ] = {
16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16
} ;
// Table 7-6. Default values of ScalingList[ 1..3 ][ 0..2 ][ i ] with i = 0..63.
static const uint8_t default_scaling_list_intra [ ] = {
16 , 16 , 16 , 16 , 17 , 18 , 21 , 24 ,
16 , 16 , 16 , 16 , 17 , 19 , 22 , 25 ,
16 , 16 , 17 , 18 , 20 , 22 , 25 , 29 ,
16 , 16 , 18 , 21 , 24 , 27 , 31 , 36 ,
17 , 17 , 20 , 24 , 30 , 35 , 41 , 47 ,
18 , 19 , 22 , 27 , 35 , 44 , 54 , 65 ,
21 , 22 , 25 , 31 , 41 , 54 , 70 , 88 ,
24 , 25 , 29 , 36 , 47 , 65 , 88 , 115
} ;
// Table 7-6. Default values of ScalingList[ 1..3 ][ 3..5 ][ i ] with i = 0..63.
static const uint8_t default_scaling_list_inter [ ] = {
16 , 16 , 16 , 16 , 17 , 18 , 20 , 24 ,
16 , 16 , 16 , 17 , 18 , 20 , 24 , 25 ,
16 , 16 , 17 , 18 , 20 , 24 , 25 , 28 ,
16 , 17 , 18 , 20 , 24 , 25 , 28 , 33 ,
17 , 18 , 20 , 24 , 25 , 28 , 33 , 41 ,
18 , 20 , 24 , 25 , 28 , 33 , 41 , 54 ,
20 , 24 , 25 , 28 , 33 , 41 , 54 , 71 ,
24 , 25 , 28 , 33 , 41 , 54 , 71 , 91
} ;
static const int diag_scan_4x4 [ 16 ] = {
0 , 4 , 1 , 8 ,
5 , 2 , 12 , 9 ,
6 , 3 , 13 , 10 ,
7 , 14 , 11 , 15
} ;
static const int diag_scan_8x8 [ 64 ] = {
0 , 8 , 1 , 16 , 9 , 2 , 24 , 17 ,
10 , 3 , 32 , 25 , 18 , 11 , 4 , 40 ,
33 , 26 , 19 , 12 , 5 , 48 , 41 , 34 ,
27 , 20 , 13 , 6 , 56 , 49 , 42 , 35 ,
28 , 21 , 14 , 7 , 57 , 50 , 43 , 36 ,
29 , 22 , 15 , 58 , 51 , 44 , 37 , 30 ,
23 , 59 , 52 , 45 , 38 , 31 , 60 , 53 ,
46 , 39 , 61 , 54 , 47 , 62 , 55 , 63
} ;
2024-01-10 11:44:07 -05:00
void HevcVideoParser : : SetDefaultScalingList ( HevcScalingListData * sl_ptr ) {
2023-10-24 16:20:56 -04:00
int size_id , matrix_id , i ;
// DC coefficient for 16x16 and 32x32
for ( matrix_id = 0 ; matrix_id < 6 ; matrix_id + + ) {
sl_ptr - > scaling_list_dc_coef [ 0 ] [ matrix_id ] = 16 ;
sl_ptr - > scaling_list_dc_coef [ 1 ] [ matrix_id ] = 16 ;
}
// sizeId 0
for ( matrix_id = 0 ; matrix_id < 6 ; matrix_id + + ) {
for ( i = 0 ; i < 16 ; i + + ) {
sl_ptr - > scaling_list [ 0 ] [ matrix_id ] [ i ] = default_scaling_list_side_id_0 [ i ] ;
}
}
// sizeId 1..3, matrixId 0..2
for ( size_id = 1 ; size_id < = 3 ; size_id + + ) {
for ( matrix_id = 0 ; matrix_id < = 2 ; matrix_id + + ) {
for ( i = 0 ; i < 64 ; i + + ) {
sl_ptr - > scaling_list [ size_id ] [ matrix_id ] [ i ] = default_scaling_list_intra [ i ] ;
}
}
}
// sizeId 1..3, matrixId 3..5
for ( size_id = 1 ; size_id < = 3 ; size_id + + ) {
for ( matrix_id = 3 ; matrix_id < = 5 ; matrix_id + + ) {
for ( i = 0 ; i < 64 ; i + + ) {
sl_ptr - > scaling_list [ size_id ] [ matrix_id ] [ i ] = default_scaling_list_inter [ i ] ;
}
}
}
}
2023-10-18 15:36:19 -07:00
2025-03-26 08:16:36 -04:00
ParserResult HevcVideoParser : : ParseScalingList ( HevcScalingListData * sl_ptr , uint8_t * nalu , size_t size , size_t & offset , HevcSeqParamSet * sps_ptr ) {
2023-10-24 16:20:56 -04:00
for ( int size_id = 0 ; size_id < 4 ; size_id + + ) {
for ( int matrix_id = 0 ; matrix_id < 6 ; matrix_id + = ( size_id = = 3 ) ? 3 : 1 ) {
sl_ptr - > scaling_list_pred_mode_flag [ size_id ] [ matrix_id ] = Parser : : GetBit ( nalu , offset ) ;
if ( ! sl_ptr - > scaling_list_pred_mode_flag [ size_id ] [ matrix_id ] ) {
sl_ptr - > scaling_list_pred_matrix_id_delta [ size_id ] [ matrix_id ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
if ( size_id = = 3 ) {
CHECK_ALLOWED_RANGE ( " scaling_list_pred_matrix_id_delta " , sl_ptr - > scaling_list_pred_matrix_id_delta [ size_id ] [ matrix_id ] , 0 , matrix_id / 3 ) ;
} else {
CHECK_ALLOWED_RANGE ( " scaling_list_pred_matrix_id_delta " , sl_ptr - > scaling_list_pred_matrix_id_delta [ size_id ] [ matrix_id ] , 0 , matrix_id ) ;
}
2023-10-24 16:20:56 -04:00
// If scaling_list_pred_matrix_id_delta is 0, infer from default scaling list. We have filled the scaling
// list with default values earlier.
if ( sl_ptr - > scaling_list_pred_matrix_id_delta [ size_id ] [ matrix_id ] ) {
// Infer from the reference scaling list
int ref_matrix_id = matrix_id - sl_ptr - > scaling_list_pred_matrix_id_delta [ size_id ] [ matrix_id ] * ( size_id = = 3 ? 3 : 1 ) ;
int coef_num = std : : min ( 64 , ( 1 < < ( 4 + ( size_id < < 1 ) ) ) ) ;
for ( int i = 0 ; i < coef_num ; i + + ) {
sl_ptr - > scaling_list [ size_id ] [ matrix_id ] [ i ] = sl_ptr - > scaling_list [ size_id ] [ ref_matrix_id ] [ i ] ;
2023-10-05 08:20:07 -07:00
}
2023-10-24 16:20:56 -04:00
// Copy to DC coefficient for 16x16 or 32x32
if ( size_id > 1 ) {
sl_ptr - > scaling_list_dc_coef [ size_id - 2 ] [ matrix_id ] = sl_ptr - > scaling_list_dc_coef [ size_id - 2 ] [ ref_matrix_id ] ;
2023-10-05 08:20:07 -07:00
}
2023-10-24 16:20:56 -04:00
}
2024-01-05 09:15:33 -05:00
} else {
2023-10-05 08:20:07 -07:00
int next_coef = 8 ;
int coef_num = std : : min ( 64 , ( 1 < < ( 4 + ( size_id < < 1 ) ) ) ) ;
if ( size_id > 1 ) {
2023-10-24 16:20:56 -04:00
sl_ptr - > scaling_list_dc_coef_minus8 [ size_id - 2 ] [ matrix_id ] = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " scaling_list_dc_coef_minus8 " , sl_ptr - > scaling_list_dc_coef_minus8 [ size_id - 2 ] [ matrix_id ] , - 7 , 247 ) ;
2023-10-24 16:20:56 -04:00
next_coef = sl_ptr - > scaling_list_dc_coef_minus8 [ size_id - 2 ] [ matrix_id ] + 8 ;
// Record DC coefficient for 16x16 or 32x32
sl_ptr - > scaling_list_dc_coef [ size_id - 2 ] [ matrix_id ] = next_coef ;
2023-10-05 08:20:07 -07:00
}
for ( int i = 0 ; i < coef_num ; i + + ) {
2023-10-24 16:20:56 -04:00
sl_ptr - > scaling_list_delta_coef = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " scaling_list_delta_coef " , sl_ptr - > scaling_list_delta_coef , - 128 , 127 ) ;
2023-10-24 16:20:56 -04:00
next_coef = ( next_coef + sl_ptr - > scaling_list_delta_coef + 256 ) % 256 ;
if ( size_id = = 0 ) {
sl_ptr - > scaling_list [ size_id ] [ matrix_id ] [ diag_scan_4x4 [ i ] ] = next_coef ;
2024-01-05 09:15:33 -05:00
} else {
2023-10-24 16:20:56 -04:00
sl_ptr - > scaling_list [ size_id ] [ matrix_id ] [ diag_scan_8x8 [ i ] ] = next_coef ;
}
2023-10-05 08:20:07 -07:00
}
}
}
}
2023-10-24 16:20:56 -04:00
if ( sps_ptr - > chroma_format_idc = = 3 ) {
for ( int i = 0 ; i < 64 ; i + + ) {
sl_ptr - > scaling_list [ 3 ] [ 1 ] [ i ] = sl_ptr - > scaling_list [ 2 ] [ 1 ] [ i ] ;
sl_ptr - > scaling_list [ 3 ] [ 2 ] [ i ] = sl_ptr - > scaling_list [ 2 ] [ 2 ] [ i ] ;
sl_ptr - > scaling_list [ 3 ] [ 4 ] [ i ] = sl_ptr - > scaling_list [ 2 ] [ 4 ] [ i ] ;
sl_ptr - > scaling_list [ 3 ] [ 5 ] [ i ] = sl_ptr - > scaling_list [ 2 ] [ 5 ] [ i ] ;
}
sl_ptr - > scaling_list_dc_coef [ 1 ] [ 1 ] = sl_ptr - > scaling_list_dc_coef [ 0 ] [ 1 ] ;
sl_ptr - > scaling_list_dc_coef [ 1 ] [ 2 ] = sl_ptr - > scaling_list_dc_coef [ 0 ] [ 2 ] ;
sl_ptr - > scaling_list_dc_coef [ 1 ] [ 4 ] = sl_ptr - > scaling_list_dc_coef [ 0 ] [ 4 ] ;
sl_ptr - > scaling_list_dc_coef [ 1 ] [ 5 ] = sl_ptr - > scaling_list_dc_coef [ 0 ] [ 5 ] ;
}
2025-03-26 08:16:36 -04:00
return PARSER_OK ;
2023-10-05 08:20:07 -07:00
}
2025-01-22 12:47:01 -05:00
ParserResult HevcVideoParser : : ParseShortTermRefPicSet ( HevcSeqParamSet * sps_ptr , HevcShortTermRps * rps , uint32_t st_rps_idx , uint32_t number_short_term_ref_pic_sets , HevcShortTermRps rps_ref [ ] , uint8_t * nalu , size_t /*size*/ , size_t & offset ) {
2023-12-04 11:53:26 -05:00
int i , j ;
2023-10-05 08:20:07 -07:00
2024-01-10 11:44:07 -05:00
memset ( rps , 0 , sizeof ( HevcShortTermRps ) ) ;
2023-12-04 11:53:26 -05:00
if ( st_rps_idx ! = 0 ) {
2023-10-24 16:20:56 -04:00
rps - > inter_ref_pic_set_prediction_flag = Parser : : GetBit ( nalu , offset ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-10-24 16:20:56 -04:00
rps - > inter_ref_pic_set_prediction_flag = 0 ;
2023-10-05 08:20:07 -07:00
}
2023-10-24 16:20:56 -04:00
if ( rps - > inter_ref_pic_set_prediction_flag ) {
2023-12-04 11:53:26 -05:00
if ( st_rps_idx = = number_short_term_ref_pic_sets ) {
2023-10-24 16:20:56 -04:00
rps - > delta_idx_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " delta_idx_minus1 " , rps - > delta_idx_minus1 , 0 , st_rps_idx - 1 ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-10-24 16:20:56 -04:00
rps - > delta_idx_minus1 = 0 ;
}
rps - > delta_rps_sign = Parser : : GetBit ( nalu , offset ) ;
rps - > abs_delta_rps_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " abs_delta_rps_minus1 " , rps - > abs_delta_rps_minus1 , 0 , ( ( 1 < < 15 ) - 1 ) ) ;
2023-12-04 11:53:26 -05:00
int ref_rps_idx = st_rps_idx - ( rps - > delta_idx_minus1 + 1 ) ; // (7-59)
int delta_rps = ( 1 - 2 * rps - > delta_rps_sign ) * ( rps - > abs_delta_rps_minus1 + 1 ) ; // (7-60)
2024-01-10 11:44:07 -05:00
HevcShortTermRps * ref_rps = & rps_ref [ ref_rps_idx ] ;
2023-12-04 11:53:26 -05:00
for ( j = 0 ; j < = ref_rps - > num_of_delta_pocs ; j + + ) {
2023-10-24 16:20:56 -04:00
rps - > used_by_curr_pic_flag [ j ] = Parser : : GetBit ( nalu , offset ) ;
if ( ! rps - > used_by_curr_pic_flag [ j ] ) {
rps - > use_delta_flag [ j ] = Parser : : GetBit ( nalu , offset ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-10-24 16:20:56 -04:00
rps - > use_delta_flag [ j ] = 1 ;
2023-10-05 08:20:07 -07:00
}
}
2023-12-04 11:53:26 -05:00
int d_poc ;
i = 0 ;
for ( j = ref_rps - > num_positive_pics - 1 ; j > = 0 ; j - - ) {
d_poc = ref_rps - > delta_poc_s1 [ j ] + delta_rps ;
if ( d_poc < 0 & & rps - > use_delta_flag [ ref_rps - > num_negative_pics + j ] ) {
rps - > delta_poc_s0 [ i ] = d_poc ;
rps - > used_by_curr_pic_s0 [ i + + ] = rps - > used_by_curr_pic_flag [ ref_rps - > num_negative_pics + j ] ;
2023-10-05 08:20:07 -07:00
}
}
2023-12-04 11:53:26 -05:00
if ( delta_rps < 0 & & rps - > use_delta_flag [ ref_rps - > num_of_delta_pocs ] ) {
rps - > delta_poc_s0 [ i ] = delta_rps ;
rps - > used_by_curr_pic_s0 [ i + + ] = rps - > used_by_curr_pic_flag [ ref_rps - > num_of_delta_pocs ] ;
2023-10-05 08:20:07 -07:00
}
2023-12-04 11:53:26 -05:00
for ( j = 0 ; j < ref_rps - > num_negative_pics ; j + + ) {
d_poc = ref_rps - > delta_poc_s0 [ j ] + delta_rps ;
if ( d_poc < 0 & & rps - > use_delta_flag [ j ] ) {
rps - > delta_poc_s0 [ i ] = d_poc ;
rps - > used_by_curr_pic_s0 [ i + + ] = rps - > used_by_curr_pic_flag [ j ] ;
2023-10-05 08:20:07 -07:00
}
}
rps - > num_negative_pics = i ;
2023-12-04 11:53:26 -05:00
i = 0 ;
for ( j = ref_rps - > num_negative_pics - 1 ; j > = 0 ; j - - ) {
d_poc = ref_rps - > delta_poc_s0 [ j ] + delta_rps ;
if ( d_poc > 0 & & rps - > use_delta_flag [ j ] ) {
rps - > delta_poc_s1 [ i ] = d_poc ;
rps - > used_by_curr_pic_s1 [ i + + ] = rps - > used_by_curr_pic_flag [ j ] ;
2023-10-05 08:20:07 -07:00
}
}
2023-12-04 11:53:26 -05:00
if ( delta_rps > 0 & & rps - > use_delta_flag [ ref_rps - > num_of_delta_pocs ] ) {
rps - > delta_poc_s1 [ i ] = delta_rps ;
rps - > used_by_curr_pic_s1 [ i + + ] = rps - > used_by_curr_pic_flag [ ref_rps - > num_of_delta_pocs ] ;
2023-10-05 08:20:07 -07:00
}
2023-12-04 11:53:26 -05:00
for ( j = 0 ; j < ref_rps - > num_positive_pics ; j + + ) {
d_poc = ref_rps - > delta_poc_s1 [ j ] + delta_rps ;
if ( d_poc > 0 & & rps - > use_delta_flag [ ref_rps - > num_negative_pics + j ] ) {
rps - > delta_poc_s1 [ i ] = d_poc ;
rps - > used_by_curr_pic_s1 [ i + + ] = rps - > used_by_curr_pic_flag [ ref_rps - > num_negative_pics + j ] ;
2023-10-05 08:20:07 -07:00
}
}
2023-12-04 11:53:26 -05:00
rps - > num_positive_pics = i ;
rps - > num_of_delta_pocs = rps - > num_negative_pics + rps - > num_positive_pics ;
} else {
2023-10-05 08:20:07 -07:00
rps - > num_negative_pics = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " num_negative_pics " , rps - > num_negative_pics , 0 , sps_ptr - > sps_max_dec_pic_buffering_minus1 [ sps_ptr - > sps_max_sub_layers_minus1 ] ) ;
2023-10-05 08:20:07 -07:00
rps - > num_positive_pics = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " num_positive_pics " , rps - > num_positive_pics , 0 , sps_ptr - > sps_max_dec_pic_buffering_minus1 [ sps_ptr - > sps_max_sub_layers_minus1 ] - rps - > num_negative_pics ) ;
2023-12-04 11:53:26 -05:00
rps - > num_of_delta_pocs = rps - > num_negative_pics + rps - > num_positive_pics ;
for ( i = 0 ; i < rps - > num_negative_pics ; i + + ) {
rps - > delta_poc_s0_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " delta_poc_s0_minus1 " , rps - > delta_poc_s0_minus1 [ i ] , 0 , ( ( 1 < < 15 ) - 1 ) ) ;
2023-12-04 11:53:26 -05:00
if ( i = = 0 ) {
rps - > delta_poc_s0 [ i ] = - ( rps - > delta_poc_s0_minus1 [ i ] + 1 ) ;
} else {
rps - > delta_poc_s0 [ i ] = rps - > delta_poc_s0 [ i - 1 ] - ( rps - > delta_poc_s0_minus1 [ i ] + 1 ) ;
}
rps - > used_by_curr_pic_s0 [ i ] = Parser : : GetBit ( nalu , offset ) ;
}
for ( i = 0 ; i < rps - > num_positive_pics ; i + + ) {
rps - > delta_poc_s1_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " delta_poc_s1_minus1 " , rps - > delta_poc_s1_minus1 [ i ] , 0 , ( ( 1 < < 15 ) - 1 ) ) ;
2023-12-04 11:53:26 -05:00
if ( i = = 0 ) {
rps - > delta_poc_s1 [ i ] = rps - > delta_poc_s1_minus1 [ i ] + 1 ;
} else {
rps - > delta_poc_s1 [ i ] = rps - > delta_poc_s1 [ i - 1 ] + ( rps - > delta_poc_s1_minus1 [ i ] + 1 ) ;
}
rps - > used_by_curr_pic_s1 [ i ] = Parser : : GetBit ( nalu , offset ) ;
}
2023-10-05 08:20:07 -07:00
}
2025-01-22 12:47:01 -05:00
return PARSER_OK ;
2023-10-05 08:20:07 -07:00
}
2025-03-26 08:16:36 -04:00
ParserResult HevcVideoParser : : ParsePredWeightTable ( HevcSliceSegHeader * slice_header_ptr , int chroma_array_type , uint8_t * stream_ptr , size_t & offset ) {
2023-10-26 11:38:46 -04:00
HevcPredWeightTable * pred_weight_table_ptr = & slice_header_ptr - > pred_weight_table ;
2023-11-09 13:52:02 -05:00
int chroma_log2_weight_denom ; // ChromaLog2WeightDenom
2023-10-26 11:38:46 -04:00
int i , j ;
pred_weight_table_ptr - > luma_log2_weight_denom = Parser : : ExpGolomb : : ReadUe ( stream_ptr , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " luma_log2_weight_denom " , pred_weight_table_ptr - > luma_log2_weight_denom , 0 , 7 ) ;
2023-10-26 11:38:46 -04:00
if ( chroma_array_type ) {
pred_weight_table_ptr - > delta_chroma_log2_weight_denom = Parser : : ExpGolomb : : ReadSe ( stream_ptr , offset ) ;
}
2023-11-09 13:52:02 -05:00
chroma_log2_weight_denom = pred_weight_table_ptr - > luma_log2_weight_denom + pred_weight_table_ptr - > delta_chroma_log2_weight_denom ;
2023-10-26 11:38:46 -04:00
for ( i = 0 ; i < = slice_header_ptr - > num_ref_idx_l0_active_minus1 ; i + + ) {
pred_weight_table_ptr - > luma_weight_l0_flag [ i ] = Parser : : GetBit ( stream_ptr , offset ) ;
}
if ( chroma_array_type ) {
for ( i = 0 ; i < = slice_header_ptr - > num_ref_idx_l0_active_minus1 ; i + + ) {
pred_weight_table_ptr - > chroma_weight_l0_flag [ i ] = Parser : : GetBit ( stream_ptr , offset ) ;
}
}
for ( i = 0 ; i < = slice_header_ptr - > num_ref_idx_l0_active_minus1 ; i + + ) {
if ( pred_weight_table_ptr - > luma_weight_l0_flag [ i ] ) {
pred_weight_table_ptr - > delta_luma_weight_l0 [ i ] = Parser : : ExpGolomb : : ReadSe ( stream_ptr , offset ) ;
pred_weight_table_ptr - > luma_offset_l0 [ i ] = Parser : : ExpGolomb : : ReadSe ( stream_ptr , offset ) ;
}
if ( pred_weight_table_ptr - > chroma_weight_l0_flag [ i ] ) {
for ( j = 0 ; j < 2 ; j + + ) {
pred_weight_table_ptr - > delta_chroma_weight_l0 [ i ] [ j ] = Parser : : ExpGolomb : : ReadSe ( stream_ptr , offset ) ;
pred_weight_table_ptr - > delta_chroma_offset_l0 [ i ] [ j ] = Parser : : ExpGolomb : : ReadSe ( stream_ptr , offset ) ;
2023-11-09 13:52:02 -05:00
pred_weight_table_ptr - > chroma_weight_l0 [ i ] [ j ] = ( 1 < < chroma_log2_weight_denom ) + pred_weight_table_ptr - > delta_chroma_weight_l0 [ i ] [ j ] ;
pred_weight_table_ptr - > chroma_offset_l0 [ i ] [ j ] = std : : clamp ( ( pred_weight_table_ptr - > delta_chroma_offset_l0 [ i ] [ j ] - ( ( 128 * pred_weight_table_ptr - > chroma_weight_l0 [ i ] [ j ] ) > > chroma_log2_weight_denom ) + 128 ) , - 128 , 127 ) ;
2023-10-26 11:38:46 -04:00
}
2024-01-05 09:15:33 -05:00
} else {
2023-11-09 13:52:02 -05:00
pred_weight_table_ptr - > chroma_weight_l0 [ i ] [ 0 ] = 1 < < chroma_log2_weight_denom ;
pred_weight_table_ptr - > chroma_offset_l0 [ i ] [ 0 ] = 0 ;
pred_weight_table_ptr - > chroma_weight_l0 [ i ] [ 1 ] = 1 < < chroma_log2_weight_denom ;
pred_weight_table_ptr - > chroma_offset_l0 [ i ] [ 1 ] = 0 ;
}
2023-10-26 11:38:46 -04:00
}
if ( slice_header_ptr - > slice_type = = HEVC_SLICE_TYPE_B ) {
for ( i = 0 ; i < = slice_header_ptr - > num_ref_idx_l1_active_minus1 ; i + + ) {
pred_weight_table_ptr - > luma_weight_l1_flag [ i ] = Parser : : GetBit ( stream_ptr , offset ) ;
}
if ( chroma_array_type ) {
for ( i = 0 ; i < = slice_header_ptr - > num_ref_idx_l1_active_minus1 ; i + + ) {
pred_weight_table_ptr - > chroma_weight_l1_flag [ i ] = Parser : : GetBit ( stream_ptr , offset ) ;
}
}
for ( i = 0 ; i < = slice_header_ptr - > num_ref_idx_l1_active_minus1 ; i + + ) {
if ( pred_weight_table_ptr - > luma_weight_l1_flag [ i ] ) {
pred_weight_table_ptr - > delta_luma_weight_l1 [ i ] = Parser : : ExpGolomb : : ReadSe ( stream_ptr , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " delta_luma_weight_l1 " , pred_weight_table_ptr - > delta_luma_weight_l1 [ i ] , - 128 , 127 ) ;
2023-10-26 11:38:46 -04:00
pred_weight_table_ptr - > luma_offset_l1 [ i ] = Parser : : ExpGolomb : : ReadSe ( stream_ptr , offset ) ;
}
if ( pred_weight_table_ptr - > chroma_weight_l1_flag [ i ] ) {
for ( j = 0 ; j < 2 ; j + + ) {
pred_weight_table_ptr - > delta_chroma_weight_l1 [ i ] [ j ] = Parser : : ExpGolomb : : ReadSe ( stream_ptr , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " delta_chroma_weight_l1 " , pred_weight_table_ptr - > delta_chroma_weight_l1 [ i ] [ j ] , - 128 , 127 ) ;
2023-10-26 11:38:46 -04:00
pred_weight_table_ptr - > delta_chroma_offset_l1 [ i ] [ j ] = Parser : : ExpGolomb : : ReadSe ( stream_ptr , offset ) ;
2023-11-09 13:52:02 -05:00
pred_weight_table_ptr - > chroma_weight_l1 [ i ] [ j ] = ( 1 < < chroma_log2_weight_denom ) + pred_weight_table_ptr - > delta_chroma_weight_l1 [ i ] [ j ] ;
pred_weight_table_ptr - > chroma_offset_l1 [ i ] [ j ] = std : : clamp ( ( pred_weight_table_ptr - > delta_chroma_offset_l1 [ i ] [ j ] - ( ( 128 * pred_weight_table_ptr - > chroma_weight_l1 [ i ] [ j ] ) > > chroma_log2_weight_denom ) + 128 ) , - 128 , 127 ) ;
2023-10-26 11:38:46 -04:00
}
2024-01-05 09:15:33 -05:00
} else {
2023-11-09 13:52:02 -05:00
pred_weight_table_ptr - > chroma_weight_l1 [ i ] [ 0 ] = 1 < < chroma_log2_weight_denom ;
pred_weight_table_ptr - > chroma_offset_l1 [ i ] [ 0 ] = 0 ;
pred_weight_table_ptr - > chroma_weight_l1 [ i ] [ 1 ] = 1 < < chroma_log2_weight_denom ;
pred_weight_table_ptr - > chroma_offset_l1 [ i ] [ 1 ] = 0 ;
}
2023-10-26 11:38:46 -04:00
}
}
2025-03-26 08:16:36 -04:00
return PARSER_OK ;
2023-10-26 11:38:46 -04:00
}
2025-03-26 08:16:36 -04:00
ParserResult HevcVideoParser : : ParseVui ( HevcSeqParamSet * sps_ptr , uint8_t * nalu , size_t size , size_t & offset ) {
HevcVuiParameters * vui = & sps_ptr - > vui_parameters ;
2023-10-05 08:20:07 -07:00
vui - > aspect_ratio_info_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > aspect_ratio_info_present_flag ) {
2023-10-18 06:01:44 -07:00
vui - > aspect_ratio_idc = Parser : : ReadBits ( nalu , offset , 8 ) ;
2023-10-05 08:20:07 -07:00
if ( vui - > aspect_ratio_idc = = 255 ) {
2023-10-18 06:01:44 -07:00
vui - > sar_width = Parser : : ReadBits ( nalu , offset , 16 ) ;
vui - > sar_height = Parser : : ReadBits ( nalu , offset , 16 ) ;
2023-10-05 08:20:07 -07:00
}
}
vui - > overscan_info_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > overscan_info_present_flag ) {
vui - > overscan_appropriate_flag = Parser : : GetBit ( nalu , offset ) ;
}
vui - > video_signal_type_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > video_signal_type_present_flag ) {
2023-10-18 06:01:44 -07:00
vui - > video_format = Parser : : ReadBits ( nalu , offset , 3 ) ;
2023-10-05 08:20:07 -07:00
vui - > video_full_range_flag = Parser : : GetBit ( nalu , offset ) ;
vui - > colour_description_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > colour_description_present_flag ) {
2023-10-18 06:01:44 -07:00
vui - > colour_primaries = Parser : : ReadBits ( nalu , offset , 8 ) ;
vui - > transfer_characteristics = Parser : : ReadBits ( nalu , offset , 8 ) ;
vui - > matrix_coeffs = Parser : : ReadBits ( nalu , offset , 8 ) ;
2023-10-05 08:20:07 -07:00
}
}
vui - > chroma_loc_info_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > chroma_loc_info_present_flag ) {
vui - > chroma_sample_loc_type_top_field = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " chroma_sample_loc_type_top_field " , vui - > chroma_sample_loc_type_top_field , 0 , 5 ) ;
2023-10-05 08:20:07 -07:00
vui - > chroma_sample_loc_type_bottom_field = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " chroma_sample_loc_type_bottom_field " , vui - > chroma_sample_loc_type_bottom_field , 0 , 5 ) ;
2023-10-05 08:20:07 -07:00
}
vui - > neutral_chroma_indication_flag = Parser : : GetBit ( nalu , offset ) ;
vui - > field_seq_flag = Parser : : GetBit ( nalu , offset ) ;
vui - > frame_field_info_present_flag = Parser : : GetBit ( nalu , offset ) ;
vui - > default_display_window_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > default_display_window_flag ) {
vui - > def_disp_win_left_offset = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
vui - > def_disp_win_right_offset = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
uint32_t left_offset = sps_ptr - > conf_win_left_offset + vui - > def_disp_win_left_offset ;
uint32_t right_offset = sps_ptr - > conf_win_right_offset + vui - > def_disp_win_right_offset ;
CHECK_ALLOWED_MAX ( " SubWidthC * (leftOffset + rightOffset) " , sub_width_c_ * ( left_offset + right_offset ) , sps_ptr - > pic_width_in_luma_samples - 1 ) ;
2023-10-05 08:20:07 -07:00
vui - > def_disp_win_top_offset = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
vui - > def_disp_win_bottom_offset = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
uint32_t top_offset = sps_ptr - > conf_win_top_offset + vui - > def_disp_win_top_offset ;
uint32_t bottom_offset = sps_ptr - > conf_win_bottom_offset + vui - > def_disp_win_bottom_offset ;
CHECK_ALLOWED_MAX ( " SubHeightC * (topOffset + bottomOffset) " , sub_height_c_ * ( top_offset + bottom_offset ) , sps_ptr - > pic_height_in_luma_samples ) ;
2023-10-05 08:20:07 -07:00
}
vui - > vui_timing_info_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > vui_timing_info_present_flag ) {
2023-10-18 06:01:44 -07:00
vui - > vui_num_units_in_tick = Parser : : ReadBits ( nalu , offset , 32 ) ;
vui - > vui_time_scale = Parser : : ReadBits ( nalu , offset , 32 ) ;
2023-10-05 08:20:07 -07:00
vui - > vui_poc_proportional_to_timing_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > vui_poc_proportional_to_timing_flag ) {
vui - > vui_num_ticks_poc_diff_one_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
}
vui - > vui_hrd_parameters_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > vui_hrd_parameters_present_flag ) {
2025-03-26 08:16:36 -04:00
ParserResult ret ;
if ( ( ret = ParseHrdParameters ( & vui - > hrd_parameters , 1 , sps_ptr - > sps_max_sub_layers_minus1 , nalu , size , offset ) ) ! = PARSER_OK ) {
return ret ;
}
2023-10-05 08:20:07 -07:00
}
}
vui - > bitstream_restriction_flag = Parser : : GetBit ( nalu , offset ) ;
if ( vui - > bitstream_restriction_flag ) {
vui - > tiles_fixed_structure_flag = Parser : : GetBit ( nalu , offset ) ;
vui - > motion_vectors_over_pic_boundaries_flag = Parser : : GetBit ( nalu , offset ) ;
vui - > restricted_ref_pic_lists_flag = Parser : : GetBit ( nalu , offset ) ;
vui - > min_spatial_segmentation_idc = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " min_spatial_segmentation_idc " , vui - > min_spatial_segmentation_idc , 0 , 4095 ) ;
2023-10-05 08:20:07 -07:00
vui - > max_bytes_per_pic_denom = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " max_bytes_per_pic_denom " , vui - > max_bytes_per_pic_denom , 0 , 16 ) ;
2023-10-05 08:20:07 -07:00
vui - > max_bits_per_min_cu_denom = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " max_bits_per_min_cu_denom " , vui - > max_bits_per_min_cu_denom , 0 , 16 ) ;
2023-10-05 08:20:07 -07:00
vui - > log2_max_mv_length_horizontal = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " log2_max_mv_length_horizontal " , vui - > log2_max_mv_length_horizontal , 0 , 16 ) ;
2023-10-05 08:20:07 -07:00
vui - > log2_max_mv_length_vertical = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " log2_max_mv_length_vertical " , vui - > log2_max_mv_length_vertical , 0 , 15 ) ;
2023-10-05 08:20:07 -07:00
}
2025-03-26 08:16:36 -04:00
return PARSER_OK ;
2023-10-05 08:20:07 -07:00
}
2025-03-10 09:15:12 -04:00
ParserResult HevcVideoParser : : ParseVps ( uint8_t * nalu , size_t size ) {
2023-10-18 06:01:44 -07:00
size_t offset = 0 ; // current bit offset
uint32_t vps_id = Parser : : ReadBits ( nalu , offset , 4 ) ;
2024-11-19 15:10:35 -05:00
HevcVideoParamSet * p_vps = & vps_list_ [ vps_id ] ;
2024-01-10 11:44:07 -05:00
memset ( p_vps , 0 , sizeof ( HevcVideoParamSet ) ) ;
2023-12-12 13:47:19 -05:00
p_vps - > vps_video_parameter_set_id = vps_id ;
p_vps - > vps_base_layer_internal_flag = Parser : : GetBit ( nalu , offset ) ;
p_vps - > vps_base_layer_available_flag = Parser : : GetBit ( nalu , offset ) ;
p_vps - > vps_max_layers_minus1 = Parser : : ReadBits ( nalu , offset , 6 ) ;
p_vps - > vps_max_sub_layers_minus1 = Parser : : ReadBits ( nalu , offset , 3 ) ;
p_vps - > vps_temporal_id_nesting_flag = Parser : : GetBit ( nalu , offset ) ;
p_vps - > vps_reserved_0xffff_16bits = Parser : : ReadBits ( nalu , offset , 16 ) ;
2025-03-10 09:15:12 -04:00
if ( p_vps - > vps_reserved_0xffff_16bits ! = 0xFFFF ) {
ERR ( " vps_reserved_0xffff_16bits is not equal to 0xFFFF. " ) ;
return PARSER_INVALID_ARG ;
}
2023-12-12 13:47:19 -05:00
ParsePtl ( & p_vps - > profile_tier_level , true , p_vps - > vps_max_sub_layers_minus1 , nalu , size , offset ) ;
p_vps - > vps_sub_layer_ordering_info_present_flag = Parser : : GetBit ( nalu , offset ) ;
for ( int i = 0 ; i < = p_vps - > vps_max_sub_layers_minus1 ; i + + ) {
if ( p_vps - > vps_sub_layer_ordering_info_present_flag | | ( i = = 0 ) ) {
p_vps - > vps_max_dec_pic_buffering_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " vps_max_dec_pic_buffering_minus1 " , p_vps - > vps_max_dec_pic_buffering_minus1 [ i ] , 0 , HEVC_MAX_DPB_FRAMES - 1 ) ;
2023-12-12 13:47:19 -05:00
p_vps - > vps_max_num_reorder_pics [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " vps_max_num_reorder_pics " , p_vps - > vps_max_num_reorder_pics [ i ] , 0 , p_vps - > vps_max_dec_pic_buffering_minus1 [ i ] ) ;
2023-12-12 13:47:19 -05:00
p_vps - > vps_max_latency_increase_plus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-12-12 13:47:19 -05:00
p_vps - > vps_max_dec_pic_buffering_minus1 [ i ] = p_vps - > vps_max_dec_pic_buffering_minus1 [ 0 ] ;
p_vps - > vps_max_num_reorder_pics [ i ] = p_vps - > vps_max_num_reorder_pics [ 0 ] ;
p_vps - > vps_max_latency_increase_plus1 [ i ] = p_vps - > vps_max_latency_increase_plus1 [ 0 ] ;
2023-10-18 06:01:44 -07:00
}
}
2023-12-12 13:47:19 -05:00
p_vps - > vps_max_layer_id = Parser : : ReadBits ( nalu , offset , 6 ) ;
p_vps - > vps_num_layer_sets_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " vps_num_layer_sets_minus1 " , p_vps - > vps_num_layer_sets_minus1 , 0 , 1023 ) ;
2023-12-12 13:47:19 -05:00
for ( int i = 1 ; i < = p_vps - > vps_num_layer_sets_minus1 ; i + + ) {
for ( int j = 0 ; j < = p_vps - > vps_max_layer_id ; j + + ) {
p_vps - > layer_id_included_flag [ i ] [ j ] = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
}
}
2023-12-12 13:47:19 -05:00
p_vps - > vps_timing_info_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( p_vps - > vps_timing_info_present_flag ) {
p_vps - > vps_num_units_in_tick = Parser : : ReadBits ( nalu , offset , 32 ) ;
p_vps - > vps_time_scale = Parser : : ReadBits ( nalu , offset , 32 ) ;
p_vps - > vps_poc_proportional_to_timing_flag = Parser : : GetBit ( nalu , offset ) ;
if ( p_vps - > vps_poc_proportional_to_timing_flag ) {
p_vps - > vps_num_ticks_poc_diff_one_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
}
2023-12-12 13:47:19 -05:00
p_vps - > vps_num_hrd_parameters = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " vps_num_hrd_parameters " , p_vps - > vps_num_hrd_parameters , 0 , p_vps - > vps_num_layer_sets_minus1 + 1 ) ;
2023-12-12 13:47:19 -05:00
for ( int i = 0 ; i < p_vps - > vps_num_hrd_parameters ; i + + ) {
p_vps - > hrd_layer_set_idx [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " hrd_layer_set_idx " , p_vps - > hrd_layer_set_idx [ i ] , ( p_vps - > vps_base_layer_internal_flag ? 0 : 1 ) , p_vps - > vps_num_layer_sets_minus1 ) ;
2023-10-18 06:01:44 -07:00
if ( i > 0 ) {
2023-12-12 13:47:19 -05:00
p_vps - > cprms_present_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
}
//parse HRD parameters
2025-03-10 09:15:12 -04:00
ParserResult ret ;
if ( ( ret = ParseHrdParameters ( & p_vps - > hrd_parameters [ i ] , p_vps - > cprms_present_flag [ i ] , p_vps - > vps_max_sub_layers_minus1 , nalu , size , offset ) ) ! = PARSER_OK ) {
return ret ;
}
2023-10-18 06:01:44 -07:00
}
}
2023-12-12 13:47:19 -05:00
p_vps - > vps_extension_flag = Parser : : GetBit ( nalu , offset ) ;
2024-05-03 15:18:08 -04:00
p_vps - > is_received = 1 ;
2023-10-20 10:39:21 -04:00
# if DBGINFO
2023-12-12 13:47:19 -05:00
PrintVps ( p_vps ) ;
2023-10-20 10:39:21 -04:00
# endif // DBGINFO
2025-03-10 09:15:12 -04:00
return PARSER_OK ;
2023-10-05 08:20:07 -07:00
}
2025-03-26 08:16:36 -04:00
ParserResult HevcVideoParser : : ParseSps ( uint8_t * nalu , size_t size ) {
ParserResult ret = PARSER_OK ;
2024-01-10 11:44:07 -05:00
HevcSeqParamSet * sps_ptr = nullptr ;
2023-10-18 06:01:44 -07:00
size_t offset = 0 ;
2023-10-24 16:20:56 -04:00
2023-10-19 14:07:36 -04:00
uint32_t vps_id = Parser : : ReadBits ( nalu , offset , 4 ) ;
2023-10-18 06:01:44 -07:00
uint32_t max_sub_layer_minus1 = Parser : : ReadBits ( nalu , offset , 3 ) ;
uint32_t sps_temporal_id_nesting_flag = Parser : : GetBit ( nalu , offset ) ;
2024-01-10 11:44:07 -05:00
HevcProfileTierLevel ptl ;
2023-10-18 06:01:44 -07:00
memset ( & ptl , 0 , sizeof ( ptl ) ) ;
ParsePtl ( & ptl , true , max_sub_layer_minus1 , nalu , size , offset ) ;
2023-10-24 16:20:56 -04:00
2023-10-18 06:01:44 -07:00
uint32_t sps_id = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " sps_seq_parameter_set_id " , sps_id , 0 , 15 ) ;
2024-11-19 15:10:35 -05:00
sps_ptr = & sps_list_ [ sps_id ] ;
2023-10-24 16:20:56 -04:00
2024-01-10 11:44:07 -05:00
memset ( sps_ptr , 0 , sizeof ( HevcSeqParamSet ) ) ;
2023-10-24 16:20:56 -04:00
sps_ptr - > sps_video_parameter_set_id = vps_id ;
sps_ptr - > sps_max_sub_layers_minus1 = max_sub_layer_minus1 ;
sps_ptr - > sps_temporal_id_nesting_flag = sps_temporal_id_nesting_flag ;
memcpy ( & sps_ptr - > profile_tier_level , & ptl , sizeof ( ptl ) ) ;
sps_ptr - > sps_seq_parameter_set_id = sps_id ;
sps_ptr - > chroma_format_idc = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " chroma_format_idc " , sps_ptr - > chroma_format_idc , 0 , 3 ) ;
2023-10-24 16:20:56 -04:00
if ( sps_ptr - > chroma_format_idc = = 3 ) {
sps_ptr - > separate_colour_plane_flag = Parser : : GetBit ( nalu , offset ) ;
}
2025-03-26 08:16:36 -04:00
switch ( sps_ptr - > chroma_format_idc ) {
case 0 : {
sub_width_c_ = 1 ;
sub_height_c_ = 1 ;
break ;
}
case 1 : {
sub_width_c_ = 2 ;
sub_height_c_ = 2 ;
break ;
}
case 2 : {
sub_width_c_ = 2 ;
sub_height_c_ = 1 ;
break ;
}
case 3 : {
sub_width_c_ = 1 ;
sub_height_c_ = 1 ;
break ;
}
}
2023-10-24 16:20:56 -04:00
sps_ptr - > pic_width_in_luma_samples = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
sps_ptr - > pic_height_in_luma_samples = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
sps_ptr - > conformance_window_flag = Parser : : GetBit ( nalu , offset ) ;
if ( sps_ptr - > conformance_window_flag ) {
sps_ptr - > conf_win_left_offset = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
sps_ptr - > conf_win_right_offset = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
sps_ptr - > conf_win_top_offset = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
sps_ptr - > conf_win_bottom_offset = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_MAX ( " SubWidthC * (conf_win_left_offset + conf_win_right_offset) " , sub_width_c_ * ( sps_ptr - > conf_win_left_offset + sps_ptr - > conf_win_right_offset ) , sps_ptr - > pic_width_in_luma_samples - 1 ) ;
CHECK_ALLOWED_MAX ( " SubHeightC * (conf_win_top_offset + conf_win_bottom_offset) " , sub_height_c_ * ( sps_ptr - > conf_win_top_offset + sps_ptr - > conf_win_bottom_offset ) , sps_ptr - > pic_width_in_luma_samples - 1 ) ;
2023-10-24 16:20:56 -04:00
}
sps_ptr - > bit_depth_luma_minus8 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
if ( sps_ptr - > bit_depth_luma_minus8 ! = 0 & & sps_ptr - > bit_depth_luma_minus8 ! = 2 ) {
ERR ( " bit_depth_luma_minus8 = " + TOSTR ( sps_ptr - > bit_depth_luma_minus8 ) + " is not supported " ) ;
return PARSER_OUT_OF_RANGE ;
}
2023-10-24 16:20:56 -04:00
sps_ptr - > bit_depth_chroma_minus8 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
if ( sps_ptr - > bit_depth_chroma_minus8 ! = 0 & & sps_ptr - > bit_depth_chroma_minus8 ! = 2 ) {
ERR ( " bit_depth_chroma_minus8 = " + TOSTR ( sps_ptr - > bit_depth_chroma_minus8 ) + " is not supported " ) ;
return PARSER_OUT_OF_RANGE ;
}
2023-10-24 16:20:56 -04:00
sps_ptr - > log2_max_pic_order_cnt_lsb_minus4 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " log2_max_pic_order_cnt_lsb_minus4 " , sps_ptr - > log2_max_pic_order_cnt_lsb_minus4 , 0 , 12 ) ;
2023-10-24 16:20:56 -04:00
sps_ptr - > sps_sub_layer_ordering_info_present_flag = Parser : : GetBit ( nalu , offset ) ;
for ( int i = 0 ; i < = sps_ptr - > sps_max_sub_layers_minus1 ; i + + ) {
if ( sps_ptr - > sps_sub_layer_ordering_info_present_flag | | ( i = = 0 ) ) {
sps_ptr - > sps_max_dec_pic_buffering_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " sps_max_dec_pic_buffering_minus1 " , sps_ptr - > sps_max_dec_pic_buffering_minus1 [ i ] , 0 , HEVC_MAX_DPB_FRAMES - 1 ) ;
2023-10-24 16:20:56 -04:00
sps_ptr - > sps_max_num_reorder_pics [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " sps_max_num_reorder_pics " , sps_ptr - > sps_max_num_reorder_pics [ i ] , 0 , sps_ptr - > sps_max_dec_pic_buffering_minus1 [ i ] ) ;
2023-10-24 16:20:56 -04:00
sps_ptr - > sps_max_latency_increase_plus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-10-24 16:20:56 -04:00
sps_ptr - > sps_max_dec_pic_buffering_minus1 [ i ] = sps_ptr - > sps_max_dec_pic_buffering_minus1 [ 0 ] ;
sps_ptr - > sps_max_num_reorder_pics [ i ] = sps_ptr - > sps_max_num_reorder_pics [ 0 ] ;
sps_ptr - > sps_max_latency_increase_plus1 [ i ] = sps_ptr - > sps_max_latency_increase_plus1 [ 0 ] ;
2023-10-18 06:01:44 -07:00
}
}
2023-10-24 16:20:56 -04:00
sps_ptr - > log2_min_luma_coding_block_size_minus3 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
int min_cb_log2_size_y = sps_ptr - > log2_min_luma_coding_block_size_minus3 + 3 ; // MinCbLog2SizeY
2023-10-24 16:20:56 -04:00
sps_ptr - > log2_diff_max_min_luma_coding_block_size = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
int max_cu_depth_delta = sps_ptr - > log2_diff_max_min_luma_coding_block_size ;
2025-03-26 08:16:36 -04:00
sps_ptr - > max_cu_width = ( 1 < < ( min_cb_log2_size_y + max_cu_depth_delta ) ) ;
sps_ptr - > max_cu_height = ( 1 < < ( min_cb_log2_size_y + max_cu_depth_delta ) ) ;
sps_ptr - > log2_min_luma_transform_block_size_minus2 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
uint32_t min_tb_log2_size_y = sps_ptr - > log2_min_luma_transform_block_size_minus2 + 2 ; // MinTbLog2SizeY
CHECK_ALLOWED_MAX ( " min_tb_log2_size_y " , min_tb_log2_size_y , min_cb_log2_size_y - 1 ) ;
int add_cu_depth = std : : max ( 0 , min_cb_log2_size_y - ( int ) min_tb_log2_size_y ) ;
2023-10-24 16:20:56 -04:00
sps_ptr - > max_cu_depth = ( max_cu_depth_delta + add_cu_depth ) ;
2025-03-26 08:16:36 -04:00
sps_ptr - > log2_diff_max_min_luma_transform_block_size = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
max_tb_log2_size_y_ = sps_ptr - > log2_min_luma_transform_block_size_minus2 + 2 + sps_ptr - > log2_diff_max_min_luma_transform_block_size ; // MaxTbLog2SizeY
ctb_log2_size_y_ = min_cb_log2_size_y + sps_ptr - > log2_diff_max_min_luma_coding_block_size ; // CtbLog2SizeY
CHECK_ALLOWED_MAX ( " max_tb_log2_size_y_ " , max_tb_log2_size_y_ , std : : min ( ctb_log2_size_y_ , 5 ) ) ;
2023-10-24 16:20:56 -04:00
sps_ptr - > max_transform_hierarchy_depth_inter = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " max_transform_hierarchy_depth_inter " , sps_ptr - > max_transform_hierarchy_depth_inter , 0 , ctb_log2_size_y_ - min_tb_log2_size_y ) ;
2023-10-24 16:20:56 -04:00
sps_ptr - > max_transform_hierarchy_depth_intra = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " max_transform_hierarchy_depth_intra " , sps_ptr - > max_transform_hierarchy_depth_intra , 0 , ctb_log2_size_y_ - min_tb_log2_size_y ) ;
2023-10-24 16:20:56 -04:00
2023-11-09 13:52:02 -05:00
// Infer dimensional variables
2025-03-26 08:16:36 -04:00
int ctb_size_y = 1 < < ctb_log2_size_y_ ; // CtbSizeY
2023-11-09 13:52:02 -05:00
pic_width_in_ctbs_y_ = ( sps_ptr - > pic_width_in_luma_samples + ctb_size_y - 1 ) / ctb_size_y ; // PicWidthInCtbsY
pic_height_in_ctbs_y_ = ( sps_ptr - > pic_height_in_luma_samples + ctb_size_y - 1 ) / ctb_size_y ; // PicHeightInCtbsY
pic_size_in_ctbs_y_ = pic_width_in_ctbs_y_ * pic_height_in_ctbs_y_ ; // PicSizeInCtbsY
2023-10-24 16:20:56 -04:00
sps_ptr - > scaling_list_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
if ( sps_ptr - > scaling_list_enabled_flag ) {
// Set up default values first
SetDefaultScalingList ( & sps_ptr - > scaling_list_data ) ;
sps_ptr - > sps_scaling_list_data_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( sps_ptr - > sps_scaling_list_data_present_flag ) {
2025-03-26 08:16:36 -04:00
if ( ( ret = ParseScalingList ( & sps_ptr - > scaling_list_data , nalu , size , offset , sps_ptr ) ) ! = PARSER_OK ) {
return ret ;
}
2023-10-24 16:20:56 -04:00
}
}
sps_ptr - > amp_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
sps_ptr - > sample_adaptive_offset_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
sps_ptr - > pcm_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
if ( sps_ptr - > pcm_enabled_flag ) {
sps_ptr - > pcm_sample_bit_depth_luma_minus1 = Parser : : ReadBits ( nalu , offset , 4 ) ;
sps_ptr - > pcm_sample_bit_depth_chroma_minus1 = Parser : : ReadBits ( nalu , offset , 4 ) ;
sps_ptr - > log2_min_pcm_luma_coding_block_size_minus3 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
//CHECK_ALLOWED_RANGE("log2_min_pcm_luma_coding_block_size", sps_ptr->log2_min_pcm_luma_coding_block_size_minus3 + 3, std::min(min_cb_log2_size_y, 5), std::min(ctb_log2_size_y_, 5));
if ( ( sps_ptr - > log2_min_pcm_luma_coding_block_size_minus3 + 3 ) < std : : min ( min_cb_log2_size_y , 5 ) | | ( sps_ptr - > log2_min_pcm_luma_coding_block_size_minus3 + 3 ) > std : : min ( ctb_log2_size_y_ , 5 ) ) {
ERR ( " log2_min_pcm_luma_coding_block_size = " + TOSTR ( sps_ptr - > log2_min_pcm_luma_coding_block_size_minus3 + 3 ) + " not in allowd range: " + TOSTR ( std : : min ( min_cb_log2_size_y , 5 ) ) + " , " + TOSTR ( std : : min ( ctb_log2_size_y_ , 5 ) ) ) ;
}
2023-10-24 16:20:56 -04:00
sps_ptr - > log2_diff_max_min_pcm_luma_coding_block_size = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_MAX ( " log2_max_ipcm_cb_size_y " , sps_ptr - > log2_diff_max_min_pcm_luma_coding_block_size + sps_ptr - > log2_min_pcm_luma_coding_block_size_minus3 + 3 , std : : min ( ctb_log2_size_y_ , 5 ) ) ;
2023-10-24 16:20:56 -04:00
sps_ptr - > pcm_loop_filter_disabled_flag = Parser : : GetBit ( nalu , offset ) ;
}
sps_ptr - > num_short_term_ref_pic_sets = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " num_short_term_ref_pic_sets " , sps_ptr - > num_short_term_ref_pic_sets , 0 , 64 ) ;
for ( int i = 0 ; i < sps_ptr - > num_short_term_ref_pic_sets ; i + + ) {
2023-10-18 06:01:44 -07:00
//short_term_ref_pic_set( i )
2025-03-26 08:16:36 -04:00
if ( ( ret = ParseShortTermRefPicSet ( sps_ptr , & sps_ptr - > st_rps [ i ] , i , sps_ptr - > num_short_term_ref_pic_sets , sps_ptr - > st_rps , nalu , size , offset ) ) ! = PARSER_OK ) {
return ret ;
2025-01-22 12:47:01 -05:00
}
2023-10-05 08:20:07 -07:00
}
2023-10-24 16:20:56 -04:00
sps_ptr - > long_term_ref_pics_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( sps_ptr - > long_term_ref_pics_present_flag ) {
2025-03-26 08:16:36 -04:00
sps_ptr - > num_long_term_ref_pics_sps = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
CHECK_ALLOWED_RANGE ( " num_long_term_ref_pics_sps " , sps_ptr - > num_long_term_ref_pics_sps , 0 , 32 ) ;
2023-10-24 16:20:56 -04:00
sps_ptr - > lt_rps . num_of_pics = sps_ptr - > num_long_term_ref_pics_sps ;
for ( int i = 0 ; i < sps_ptr - > num_long_term_ref_pics_sps ; i + + ) {
2023-10-18 06:01:44 -07:00
//The number of bits used to represent lt_ref_pic_poc_lsb_sps[ i ] is equal to log2_max_pic_order_cnt_lsb_minus4 + 4.
2023-10-24 16:20:56 -04:00
sps_ptr - > lt_ref_pic_poc_lsb_sps [ i ] = Parser : : ReadBits ( nalu , offset , ( sps_ptr - > log2_max_pic_order_cnt_lsb_minus4 + 4 ) ) ;
sps_ptr - > used_by_curr_pic_lt_sps_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
sps_ptr - > lt_rps . pocs [ i ] = sps_ptr - > lt_ref_pic_poc_lsb_sps [ i ] ;
sps_ptr - > lt_rps . used_by_curr_pic [ i ] = sps_ptr - > used_by_curr_pic_lt_sps_flag [ i ] ;
2023-10-18 06:01:44 -07:00
}
2023-10-05 08:20:07 -07:00
}
2023-10-24 16:20:56 -04:00
sps_ptr - > sps_temporal_mvp_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
sps_ptr - > strong_intra_smoothing_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
sps_ptr - > vui_parameters_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( sps_ptr - > vui_parameters_present_flag ) {
2023-10-18 06:01:44 -07:00
//vui_parameters()
2025-03-26 08:16:36 -04:00
if ( ( ret = ParseVui ( sps_ptr , nalu , size , offset ) ) ! = PARSER_OK ) {
return ret ;
}
2023-10-18 06:01:44 -07:00
}
2023-10-24 16:20:56 -04:00
sps_ptr - > sps_extension_flag = Parser : : GetBit ( nalu , offset ) ;
2024-05-03 15:18:08 -04:00
sps_ptr - > is_received = 1 ;
2023-10-20 10:39:21 -04:00
# if DBGINFO
2023-10-24 16:20:56 -04:00
PrintSps ( sps_ptr ) ;
2023-10-20 10:39:21 -04:00
# endif // DBGINFO
2025-03-26 08:16:36 -04:00
return PARSER_OK ;
2023-10-18 06:01:44 -07:00
}
2025-03-26 08:16:36 -04:00
ParserResult HevcVideoParser : : ParsePps ( uint8_t * nalu , size_t size ) {
2023-11-09 13:52:02 -05:00
int i ;
2023-10-18 06:01:44 -07:00
size_t offset = 0 ;
uint32_t pps_id = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " pps_pic_parameter_set_id " , pps_id , 0 , 63 ) ;
2024-11-19 15:10:35 -05:00
HevcPicParamSet * pps_ptr = & pps_list_ [ pps_id ] ;
2024-01-10 11:44:07 -05:00
memset ( pps_ptr , 0 , sizeof ( HevcPicParamSet ) ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > pps_pic_parameter_set_id = pps_id ;
pps_ptr - > pps_seq_parameter_set_id = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " pps_seq_parameter_set_id " , pps_ptr - > pps_seq_parameter_set_id , 0 , 15 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > dependent_slice_segments_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > output_flag_present_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > num_extra_slice_header_bits = Parser : : ReadBits ( nalu , offset , 3 ) ;
pps_ptr - > sign_data_hiding_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > cabac_init_present_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > num_ref_idx_l0_default_active_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " num_ref_idx_l0_default_active_minus1 " , pps_ptr - > num_ref_idx_l0_default_active_minus1 , 0 , 14 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > num_ref_idx_l1_default_active_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " num_ref_idx_l1_default_active_minus1 " , pps_ptr - > num_ref_idx_l1_default_active_minus1 , 0 , 14 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > init_qp_minus26 = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " init_qp_minus26 " , pps_ptr - > init_qp_minus26 , static_cast < int > ( - ( 26 + 6 * sps_list_ [ pps_ptr - > pps_seq_parameter_set_id ] . bit_depth_luma_minus8 ) ) , 25 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > constrained_intra_pred_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > transform_skip_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > cu_qp_delta_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
if ( pps_ptr - > cu_qp_delta_enabled_flag ) {
pps_ptr - > diff_cu_qp_delta_depth = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " diff_cu_qp_delta_depth " , pps_ptr - > diff_cu_qp_delta_depth , 0 , sps_list_ [ pps_ptr - > pps_seq_parameter_set_id ] . log2_diff_max_min_luma_coding_block_size ) ;
2023-10-24 16:20:56 -04:00
}
pps_ptr - > pps_cb_qp_offset = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " pps_cb_qp_offset " , pps_ptr - > pps_cb_qp_offset , - 12 , 12 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > pps_cr_qp_offset = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " pps_cr_qp_offset " , pps_ptr - > pps_cr_qp_offset , - 12 , 12 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > pps_slice_chroma_qp_offsets_present_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > weighted_pred_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > weighted_bipred_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > transquant_bypass_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > tiles_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > entropy_coding_sync_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
if ( pps_ptr - > tiles_enabled_flag ) {
pps_ptr - > num_tile_columns_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " num_tile_columns_minus1 " , pps_ptr - > num_tile_columns_minus1 , 0 , pic_width_in_ctbs_y_ - 1 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > num_tile_rows_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " num_tile_rows_minus1 " , pps_ptr - > num_tile_rows_minus1 , 0 , pic_height_in_ctbs_y_ - 1 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > uniform_spacing_flag = Parser : : GetBit ( nalu , offset ) ;
if ( ! pps_ptr - > uniform_spacing_flag ) {
2023-11-09 13:52:02 -05:00
int temp_size = pic_width_in_ctbs_y_ ; // PicWidthInCtbsY
for ( i = 0 ; i < pps_ptr - > num_tile_columns_minus1 ; i + + ) {
2023-10-24 16:20:56 -04:00
pps_ptr - > column_width_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " column_width_minus1 " , pps_ptr - > column_width_minus1 [ i ] , 0 , pic_width_in_ctbs_y_ - 1 ) ;
2023-11-09 13:52:02 -05:00
temp_size - = pps_ptr - > column_width_minus1 [ i ] + 1 ;
2023-10-18 06:01:44 -07:00
}
2023-11-09 13:52:02 -05:00
pps_ptr - > column_width_minus1 [ i ] = temp_size - 1 ; // last column at num_tile_columns_minus1
temp_size = pic_height_in_ctbs_y_ ; // PicHeightInCtbsY
for ( i = 0 ; i < pps_ptr - > num_tile_rows_minus1 ; i + + ) {
2023-10-24 16:20:56 -04:00
pps_ptr - > row_height_minus1 [ i ] = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " row_height_minus1 " , pps_ptr - > row_height_minus1 [ i ] , 0 , pic_height_in_ctbs_y_ - 1 ) ;
2023-11-09 13:52:02 -05:00
temp_size - = pps_ptr - > row_height_minus1 [ i ] + 1 ;
}
pps_ptr - > row_height_minus1 [ i ] = temp_size - 1 ; // last row at num_tile_rows_minus1
2024-01-05 09:15:33 -05:00
} else {
2023-11-09 13:52:02 -05:00
for ( i = 0 ; i < = pps_ptr - > num_tile_columns_minus1 ; i + + ) {
pps_ptr - > column_width_minus1 [ i ] = ( ( i + 1 ) * pic_width_in_ctbs_y_ ) / ( pps_ptr - > num_tile_columns_minus1 + 1 ) - ( i * pic_width_in_ctbs_y_ ) / ( pps_ptr - > num_tile_columns_minus1 + 1 ) - 1 ;
}
for ( i = 0 ; i < = pps_ptr - > num_tile_rows_minus1 ; i + + ) {
pps_ptr - > row_height_minus1 [ i ] = ( ( i + 1 ) * pic_height_in_ctbs_y_ ) / ( pps_ptr - > num_tile_rows_minus1 + 1 ) - ( i * pic_height_in_ctbs_y_ ) / ( pps_ptr - > num_tile_rows_minus1 + 1 ) - 1 ;
2023-10-18 06:01:44 -07:00
}
}
2023-10-24 16:20:56 -04:00
pps_ptr - > loop_filter_across_tiles_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-10-24 16:20:56 -04:00
pps_ptr - > loop_filter_across_tiles_enabled_flag = 1 ;
pps_ptr - > uniform_spacing_flag = 1 ;
2023-11-09 13:52:02 -05:00
pps_ptr - > num_tile_columns_minus1 = 0 ;
pps_ptr - > num_tile_rows_minus1 = 0 ;
2023-10-18 06:01:44 -07:00
}
2023-10-24 16:20:56 -04:00
pps_ptr - > pps_loop_filter_across_slices_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > deblocking_filter_control_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( pps_ptr - > deblocking_filter_control_present_flag ) {
pps_ptr - > deblocking_filter_override_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > pps_deblocking_filter_disabled_flag = Parser : : GetBit ( nalu , offset ) ;
if ( ! pps_ptr - > pps_deblocking_filter_disabled_flag ) {
pps_ptr - > pps_beta_offset_div2 = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " pps_beta_offset_div2 " , pps_ptr - > pps_beta_offset_div2 , - 6 , 6 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > pps_tc_offset_div2 = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " pps_tc_offset_div2 " , pps_ptr - > pps_tc_offset_div2 , - 6 , 6 ) ;
2023-10-18 06:01:44 -07:00
}
}
2023-10-24 16:20:56 -04:00
pps_ptr - > pps_scaling_list_data_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( pps_ptr - > pps_scaling_list_data_present_flag ) {
// Set up default values first
SetDefaultScalingList ( & pps_ptr - > scaling_list_data ) ;
2025-03-26 08:16:36 -04:00
ParserResult ret ;
if ( ( ret = ParseScalingList ( & pps_ptr - > scaling_list_data , nalu , size , offset , & sps_list_ [ pps_ptr - > pps_seq_parameter_set_id ] ) ) ! = PARSER_OK ) {
return ret ;
}
2024-01-05 09:15:33 -05:00
} else {
2024-11-19 15:10:35 -05:00
pps_ptr - > scaling_list_data = sps_list_ [ pps_ptr - > pps_seq_parameter_set_id ] . scaling_list_data ;
2023-10-24 16:20:56 -04:00
}
pps_ptr - > lists_modification_present_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > log2_parallel_merge_level_minus2 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " log2_parallel_merge_level_minus2 " , pps_ptr - > log2_parallel_merge_level_minus2 , 0 , ctb_log2_size_y_ - 2 ) ;
2023-10-24 16:20:56 -04:00
pps_ptr - > slice_segment_header_extension_present_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
pps_ptr - > pps_extension_present_flag = Parser : : GetBit ( nalu , offset ) ;
if ( pps_ptr - > pps_extension_present_flag ) {
pps_ptr - > pps_range_extension_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > pps_multilayer_extension_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > pps_extension_6bits = Parser : : ReadBits ( nalu , offset , 6 ) ;
}
// pps_range_extension()
if ( pps_ptr - > pps_range_extension_flag ) {
if ( pps_ptr - > transform_skip_enabled_flag ) {
pps_ptr - > log2_max_transform_skip_block_size_minus2 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_MAX ( " log2_max_transform_skip_block_size_minus2 " , pps_ptr - > log2_max_transform_skip_block_size_minus2 , max_tb_log2_size_y_ - 2 ) ;
2023-10-26 11:38:46 -04:00
}
pps_ptr - > cross_component_prediction_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
pps_ptr - > chroma_qp_offset_list_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
if ( pps_ptr - > chroma_qp_offset_list_enabled_flag ) {
pps_ptr - > diff_cu_chroma_qp_offset_depth = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " diff_cu_chroma_qp_offset_depth " , pps_ptr - > diff_cu_chroma_qp_offset_depth , 0 , sps_list_ [ pps_ptr - > pps_seq_parameter_set_id ] . log2_diff_max_min_luma_coding_block_size ) ;
2023-10-26 11:38:46 -04:00
pps_ptr - > chroma_qp_offset_list_len_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " chroma_qp_offset_list_len_minus1 " , pps_ptr - > chroma_qp_offset_list_len_minus1 , 0 , 5 ) ;
2023-10-26 11:38:46 -04:00
for ( int i = 0 ; i < = pps_ptr - > chroma_qp_offset_list_len_minus1 ; i + + ) {
pps_ptr - > cb_qp_offset_list [ i ] = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " cb_qp_offset_list " , pps_ptr - > cb_qp_offset_list [ i ] , - 12 , 12 ) ;
2023-10-26 11:38:46 -04:00
pps_ptr - > cr_qp_offset_list [ i ] = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " cr_qp_offset_list " , pps_ptr - > cr_qp_offset_list [ i ] , - 12 , 12 ) ;
2023-10-26 11:38:46 -04:00
}
}
pps_ptr - > log2_sao_offset_scale_luma = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " log2_sao_offset_scale_luma " , pps_ptr - > log2_sao_offset_scale_luma , 0 , std : : max ( 0 , static_cast < int > ( sps_list_ [ pps_ptr - > pps_seq_parameter_set_id ] . bit_depth_luma_minus8 - 2 ) ) ) ;
CHECK_ALLOWED_RANGE ( " log2_sao_offset_scale_luma " , pps_ptr - > log2_sao_offset_scale_luma , 0 , std : : max ( 0 , static_cast < int > ( sps_list_ [ pps_ptr - > pps_seq_parameter_set_id ] . bit_depth_luma_minus8 - 2 ) ) ) ;
2023-10-26 11:38:46 -04:00
pps_ptr - > log2_sao_offset_scale_chroma = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " log2_sao_offset_scale_chroma " , pps_ptr - > log2_sao_offset_scale_chroma , 0 , std : : max ( 0 , static_cast < int > ( sps_list_ [ pps_ptr - > pps_seq_parameter_set_id ] . bit_depth_chroma_minus8 - 2 ) ) ) ;
2023-10-26 11:38:46 -04:00
}
2023-10-20 10:39:21 -04:00
2024-05-03 15:18:08 -04:00
pps_ptr - > is_received = 1 ;
2023-10-20 10:39:21 -04:00
# if DBGINFO
2023-10-24 16:20:56 -04:00
PrintPps ( pps_ptr ) ;
2023-10-20 10:39:21 -04:00
# endif // DBGINFO
2025-03-26 08:16:36 -04:00
return PARSER_OK ;
2023-10-18 06:01:44 -07:00
}
2023-10-05 08:20:07 -07:00
2024-05-03 15:18:08 -04:00
ParserResult HevcVideoParser : : ParseSliceHeader ( uint8_t * nalu , size_t size , HevcSliceSegHeader * p_slice_header ) {
2024-01-10 11:44:07 -05:00
HevcPicParamSet * pps_ptr = nullptr ;
HevcSeqParamSet * sps_ptr = nullptr ;
2023-10-18 06:01:44 -07:00
size_t offset = 0 ;
2024-01-10 11:44:07 -05:00
HevcSliceSegHeader temp_sh ;
2024-02-09 15:09:49 -05:00
memset ( p_slice_header , 0 , sizeof ( HevcSliceSegHeader ) ) ;
2023-10-18 06:01:44 -07:00
memset ( & temp_sh , 0 , sizeof ( temp_sh ) ) ;
2023-10-05 08:20:07 -07:00
2024-02-09 15:09:49 -05:00
temp_sh . first_slice_segment_in_pic_flag = p_slice_header - > first_slice_segment_in_pic_flag = Parser : : GetBit ( nalu , offset ) ;
2023-11-15 16:07:18 -05:00
if ( IsIrapPic ( & slice_nal_unit_header_ ) ) {
2024-02-09 15:09:49 -05:00
temp_sh . no_output_of_prior_pics_flag = p_slice_header - > no_output_of_prior_pics_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
}
2023-10-05 08:20:07 -07:00
2023-10-19 14:07:36 -04:00
// Set active VPS, SPS and PPS for the current slice
2025-03-12 17:49:52 -04:00
int32_t active_pps_id = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
CHECK_ALLOWED_MAX ( " active_pps_id " , active_pps_id , ( MAX_PPS_COUNT - 1 ) ) ;
2025-03-26 08:16:36 -04:00
if ( pps_list_ [ active_pps_id ] . is_received = = 0 ) {
2024-05-03 15:18:08 -04:00
ERR ( " Empty PPS is referred. " ) ;
return PARSER_WRONG_STATE ;
}
2025-03-26 08:16:36 -04:00
active_pps_id_ = active_pps_id ;
pps_ptr = & pps_list_ [ active_pps_id_ ] ;
temp_sh . slice_pic_parameter_set_id = p_slice_header - > slice_pic_parameter_set_id = active_pps_id_ ;
2025-01-22 12:47:01 -05:00
2025-03-26 08:16:36 -04:00
int32_t active_sps_id = pps_ptr - > pps_seq_parameter_set_id ;
if ( sps_list_ [ active_sps_id ] . is_received = = 0 ) {
2024-05-03 15:18:08 -04:00
ERR ( " Empty SPS is referred. " ) ;
return PARSER_WRONG_STATE ;
}
2025-03-26 08:16:36 -04:00
if ( active_sps_id_ ! = active_sps_id ) {
active_sps_id_ = active_sps_id ;
sps_ptr = & sps_list_ [ active_sps_id_ ] ;
new_seq_activated_ = true ;
}
sps_ptr = & sps_list_ [ active_sps_id_ ] ;
int active_vps_id = sps_ptr - > sps_video_parameter_set_id ;
if ( vps_list_ [ active_vps_id ] . is_received = = 0 ) {
2024-05-03 15:18:08 -04:00
ERR ( " Empty VPS is referred. " ) ;
return PARSER_WRONG_STATE ;
}
2025-03-26 08:16:36 -04:00
active_vps_id_ = active_vps_id ;
2023-10-19 14:07:36 -04:00
// Check video dimension change
2025-03-13 09:29:25 -04:00
if ( pic_width_ ! = sps_ptr - > pic_width_in_luma_samples | | pic_height_ ! = sps_ptr - > pic_height_in_luma_samples ) {
2023-10-19 14:07:36 -04:00
pic_width_ = sps_ptr - > pic_width_in_luma_samples ;
pic_height_ = sps_ptr - > pic_height_in_luma_samples ;
2023-11-30 18:32:25 -05:00
// Take care of the case where a new SPS replaces the old SPS with the same id but with different dimensions
2025-03-18 17:19:01 -04:00
new_seq_activated_ = true ;
2023-10-19 14:07:36 -04:00
}
2024-12-19 17:29:52 -05:00
// Check DPB buffer size change
uint32_t max_dec_pic_buffering = sps_ptr - > sps_max_dec_pic_buffering_minus1 [ sps_ptr - > sps_max_sub_layers_minus1 ] + 1 ;
if ( dpb_buffer_ . dpb_size ! = max_dec_pic_buffering ) {
dpb_buffer_ . dpb_size = max_dec_pic_buffering ;
dpb_buffer_ . dpb_size = dpb_buffer_ . dpb_size > HEVC_MAX_DPB_FRAMES ? HEVC_MAX_DPB_FRAMES : dpb_buffer_ . dpb_size ;
2024-05-31 13:14:02 -04:00
CheckAndAdjustDecBufPoolSize ( dpb_buffer_ . dpb_size ) ;
2025-03-18 17:19:01 -04:00
new_seq_activated_ = true ;
2024-05-31 13:14:02 -04:00
}
2025-03-13 09:29:25 -04:00
// Check bit depth change
if ( bit_depth_luma_minus8_ ! = sps_ptr - > bit_depth_luma_minus8 | | bit_depth_chroma_minus8_ ! = sps_ptr - > bit_depth_chroma_minus8 ) {
bit_depth_luma_minus8_ = sps_ptr - > bit_depth_luma_minus8 ;
bit_depth_chroma_minus8_ = sps_ptr - > bit_depth_chroma_minus8 ;
new_seq_activated_ = true ;
}
2024-05-31 13:14:02 -04:00
2023-12-12 13:47:19 -05:00
// Set frame rate if available
2024-06-26 12:46:11 -04:00
if ( new_seq_activated_ ) {
2025-03-26 08:16:36 -04:00
if ( vps_list_ [ active_vps_id_ ] . vps_timing_info_present_flag ) {
frame_rate_ . numerator = vps_list_ [ active_vps_id_ ] . vps_time_scale ;
frame_rate_ . denominator = vps_list_ [ active_vps_id_ ] . vps_num_units_in_tick ;
2023-12-12 13:47:19 -05:00
} else if ( sps_ptr - > vui_parameters . vui_timing_info_present_flag ) {
frame_rate_ . numerator = sps_ptr - > vui_parameters . vui_time_scale ;
frame_rate_ . denominator = sps_ptr - > vui_parameters . vui_num_units_in_tick ;
} else {
frame_rate_ . numerator = 0 ;
frame_rate_ . denominator = 0 ;
}
}
2024-02-09 15:09:49 -05:00
if ( ! p_slice_header - > first_slice_segment_in_pic_flag ) {
2023-10-19 14:07:36 -04:00
if ( pps_ptr - > dependent_slice_segments_enabled_flag ) {
2024-02-09 15:09:49 -05:00
temp_sh . dependent_slice_segment_flag = p_slice_header - > dependent_slice_segment_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
}
2023-11-09 13:52:02 -05:00
int bits_slice_segment_address = ( int ) ceilf ( log2f ( ( float ) pic_size_in_ctbs_y_ ) ) ;
2024-02-09 15:09:49 -05:00
temp_sh . slice_segment_address = p_slice_header - > slice_segment_address = Parser : : ReadBits ( nalu , offset , bits_slice_segment_address ) ;
2024-11-11 14:33:17 -08:00
//todo:: check for max slice_segment_address and error if exceeds max
2023-10-18 06:01:44 -07:00
}
2023-10-19 14:07:36 -04:00
2024-02-09 15:09:49 -05:00
if ( ! p_slice_header - > dependent_slice_segment_flag ) {
2025-03-28 16:35:03 -04:00
memset ( & slice_header_copy_ , 0 , sizeof ( slice_header_copy_ ) ) ;
2023-10-19 14:07:36 -04:00
for ( int i = 0 ; i < pps_ptr - > num_extra_slice_header_bits ; i + + ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_reserved_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
}
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_type = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_MAX ( " slice_type " , p_slice_header - > slice_type , 2 ) ;
2024-11-11 14:33:17 -08:00
2023-10-19 14:07:36 -04:00
if ( pps_ptr - > output_flag_present_flag ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > pic_output_flag = Parser : : GetBit ( nalu , offset ) ;
2024-01-05 09:15:33 -05:00
} else {
2024-02-09 15:09:49 -05:00
p_slice_header - > pic_output_flag = 1 ; // default value
2023-10-24 16:20:56 -04:00
}
2023-10-19 14:07:36 -04:00
if ( sps_ptr - > separate_colour_plane_flag ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > colour_plane_id = Parser : : ReadBits ( nalu , offset , 2 ) ;
2023-10-18 06:01:44 -07:00
}
2023-11-02 18:08:24 -04:00
2023-11-15 16:07:18 -05:00
if ( slice_nal_unit_header_ . nal_unit_type ! = NAL_UNIT_CODED_SLICE_IDR_W_RADL & & slice_nal_unit_header_ . nal_unit_type ! = NAL_UNIT_CODED_SLICE_IDR_N_LP ) {
2023-10-18 06:01:44 -07:00
//length of slice_pic_order_cnt_lsb is log2_max_pic_order_cnt_lsb_minus4 + 4 bits.
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_pic_order_cnt_lsb = Parser : : ReadBits ( nalu , offset , ( sps_ptr - > log2_max_pic_order_cnt_lsb_minus4 + 4 ) ) ;
2023-10-05 08:20:07 -07:00
2024-02-09 15:09:49 -05:00
p_slice_header - > short_term_ref_pic_set_sps_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
int32_t pos = offset ;
2024-02-09 15:09:49 -05:00
if ( ! p_slice_header - > short_term_ref_pic_set_sps_flag ) {
2025-01-22 12:47:01 -05:00
if ( ParseShortTermRefPicSet ( sps_ptr , & p_slice_header - > st_rps , sps_ptr - > num_short_term_ref_pic_sets , sps_ptr - > num_short_term_ref_pic_sets , sps_ptr - > st_rps , nalu , size , offset ) ! = PARSER_OK ) {
return PARSER_WRONG_STATE ;
}
2024-01-05 09:15:33 -05:00
} else {
2023-11-06 08:22:31 -05:00
if ( sps_ptr - > num_short_term_ref_pic_sets > 1 ) {
int num_bits = 0 ;
while ( ( 1 < < num_bits ) < sps_ptr - > num_short_term_ref_pic_sets ) {
num_bits + + ;
}
if ( num_bits > 0 ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > short_term_ref_pic_set_idx = Parser : : ReadBits ( nalu , offset , num_bits ) ;
2023-11-06 08:22:31 -05:00
}
2024-01-05 09:15:33 -05:00
} else {
2024-02-09 15:09:49 -05:00
p_slice_header - > short_term_ref_pic_set_idx = 0 ;
2023-10-18 06:01:44 -07:00
}
2023-10-26 11:38:46 -04:00
// Copy the SPS RPS to slice RPS
2024-02-09 15:09:49 -05:00
p_slice_header - > st_rps = sps_ptr - > st_rps [ p_slice_header - > short_term_ref_pic_set_idx ] ;
2023-10-18 06:01:44 -07:00
}
2024-02-09 15:09:49 -05:00
p_slice_header - > short_term_ref_pic_set_size = offset - pos ;
2023-10-05 08:20:07 -07:00
2023-10-19 14:07:36 -04:00
if ( sps_ptr - > long_term_ref_pics_present_flag ) {
if ( sps_ptr - > num_long_term_ref_pics_sps > 0 ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > num_long_term_sps = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_RANGE ( " num_long_term_sps " , p_slice_header - > num_long_term_sps , 0 , sps_ptr - > num_long_term_ref_pics_sps ) ;
2023-10-18 06:01:44 -07:00
}
2024-02-09 15:09:49 -05:00
p_slice_header - > num_long_term_pics = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-26 08:16:36 -04:00
CHECK_ALLOWED_MAX ( " num_long_term_pics " , p_slice_header - > num_long_term_pics , HEVC_MAX_DPB_FRAMES - 1 ) ;
2023-10-18 06:01:44 -07:00
int bits_for_ltrp_in_sps = 0 ;
2023-10-19 14:07:36 -04:00
while ( sps_ptr - > num_long_term_ref_pics_sps > ( 1 < < bits_for_ltrp_in_sps ) ) {
2023-10-18 06:01:44 -07:00
bits_for_ltrp_in_sps + + ;
}
2024-02-09 15:09:49 -05:00
p_slice_header - > lt_rps . num_of_pics = p_slice_header - > num_long_term_sps + p_slice_header - > num_long_term_pics ;
for ( int i = 0 ; i < ( p_slice_header - > num_long_term_sps + p_slice_header - > num_long_term_pics ) ; i + + ) {
if ( i < p_slice_header - > num_long_term_sps ) {
2023-10-19 14:07:36 -04:00
if ( sps_ptr - > num_long_term_ref_pics_sps > 1 ) {
2023-10-18 06:01:44 -07:00
if ( bits_for_ltrp_in_sps > 0 ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > lt_idx_sps [ i ] = Parser : : ReadBits ( nalu , offset , bits_for_ltrp_in_sps ) ;
p_slice_header - > lt_rps . pocs [ i ] = sps_ptr - > lt_rps . pocs [ p_slice_header - > lt_idx_sps [ i ] ] ; // PocLsbLt[]
p_slice_header - > lt_rps . used_by_curr_pic [ i ] = sps_ptr - > lt_rps . used_by_curr_pic [ p_slice_header - > lt_idx_sps [ i ] ] ; // UsedByCurrPicLt[]
2023-10-18 06:01:44 -07:00
}
}
2024-01-05 09:15:33 -05:00
} else {
2024-02-09 15:09:49 -05:00
p_slice_header - > poc_lsb_lt [ i ] = Parser : : ReadBits ( nalu , offset , ( sps_ptr - > log2_max_pic_order_cnt_lsb_minus4 + 4 ) ) ;
p_slice_header - > used_by_curr_pic_lt_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
p_slice_header - > lt_rps . pocs [ i ] = p_slice_header - > poc_lsb_lt [ i ] ; // PocLsbLt[]
p_slice_header - > lt_rps . used_by_curr_pic [ i ] = p_slice_header - > used_by_curr_pic_lt_flag [ i ] ; // UsedByCurrPicLt[]
2023-10-18 06:01:44 -07:00
}
2024-01-05 09:15:33 -05:00
int delta_poc_msb_cycle_lt = 0 ;
2024-02-09 15:09:49 -05:00
p_slice_header - > delta_poc_msb_present_flag [ i ] = Parser : : GetBit ( nalu , offset ) ;
if ( p_slice_header - > delta_poc_msb_present_flag [ i ] ) {
2023-11-02 18:08:24 -04:00
// Store DeltaPocMsbCycleLt in delta_poc_msb_cycle_lt for later use
2024-01-05 09:15:33 -05:00
delta_poc_msb_cycle_lt = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
}
2024-02-09 15:09:49 -05:00
if ( i = = 0 | | i = = p_slice_header - > num_long_term_sps ) {
p_slice_header - > delta_poc_msb_cycle_lt [ i ] = delta_poc_msb_cycle_lt ;
2024-01-05 09:15:33 -05:00
} else {
2024-02-09 15:09:49 -05:00
p_slice_header - > delta_poc_msb_cycle_lt [ i ] = delta_poc_msb_cycle_lt + p_slice_header - > delta_poc_msb_cycle_lt [ i - 1 ] ;
2023-10-18 06:01:44 -07:00
}
}
}
2025-03-05 08:44:59 -05:00
if ( p_slice_header - > slice_type ! = HEVC_SLICE_TYPE_I ) {
2025-03-31 19:04:34 -04:00
CHECK_ALLOWED_RANGE ( " num_of_delta_pocs + num_long_term_pics " , p_slice_header - > st_rps . num_of_delta_pocs + p_slice_header - > num_long_term_pics , 1 , dpb_buffer_ . dpb_size - 1 ) ;
2025-03-05 08:44:59 -05:00
}
2023-10-19 14:07:36 -04:00
if ( sps_ptr - > sps_temporal_mvp_enabled_flag ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_temporal_mvp_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-18 06:01:44 -07:00
}
}
2023-10-26 11:38:46 -04:00
int chroma_array_type = sps_ptr - > separate_colour_plane_flag ? 0 : sps_ptr - > chroma_format_idc ; // ChromaArrayType
if ( sps_ptr - > sample_adaptive_offset_enabled_flag ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_sao_luma_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
if ( chroma_array_type )
{
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_sao_chroma_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
}
}
2024-02-09 15:09:49 -05:00
if ( p_slice_header - > slice_type ! = HEVC_SLICE_TYPE_I ) {
p_slice_header - > num_ref_idx_active_override_flag = Parser : : GetBit ( nalu , offset ) ;
if ( p_slice_header - > num_ref_idx_active_override_flag ) {
p_slice_header - > num_ref_idx_l0_active_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_MAX ( " num_ref_idx_l0_active_minus1 " , p_slice_header - > num_ref_idx_l0_active_minus1 , std : : min ( 14 , static_cast < int > ( dpb_buffer_ . dpb_size - 1 ) ) ) ;
2024-02-09 15:09:49 -05:00
if ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) {
p_slice_header - > num_ref_idx_l1_active_minus1 = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_MAX ( " num_ref_idx_l1_active_minus1 " , p_slice_header - > num_ref_idx_l1_active_minus1 , std : : min ( 14 , static_cast < int > ( dpb_buffer_ . dpb_size - 1 ) ) ) ;
2023-10-26 11:38:46 -04:00
}
2024-01-05 09:15:33 -05:00
} else {
2024-02-09 15:09:49 -05:00
p_slice_header - > num_ref_idx_l0_active_minus1 = pps_ptr - > num_ref_idx_l0_default_active_minus1 ;
if ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) {
p_slice_header - > num_ref_idx_l1_active_minus1 = pps_ptr - > num_ref_idx_l1_default_active_minus1 ;
2023-10-26 11:38:46 -04:00
}
}
// 7.3.6.2 Reference picture list modification
// Calculate NumPicTotalCurr
2023-11-02 18:08:24 -04:00
num_pic_total_curr_ = 0 ;
2024-02-09 15:09:49 -05:00
HevcShortTermRps * st_rps_ptr = & p_slice_header - > st_rps ;
2023-12-04 11:53:26 -05:00
for ( int i = 0 ; i < st_rps_ptr - > num_negative_pics ; i + + ) {
if ( st_rps_ptr - > used_by_curr_pic_s0 [ i ] ) {
num_pic_total_curr_ + + ;
}
}
for ( int i = 0 ; i < st_rps_ptr - > num_positive_pics ; i + + ) {
if ( st_rps_ptr - > used_by_curr_pic_s1 [ i ] ) {
2023-11-02 18:08:24 -04:00
num_pic_total_curr_ + + ;
2023-10-26 11:38:46 -04:00
}
}
2024-02-09 15:09:49 -05:00
HevcLongTermRps * lt_rps_ptr = & p_slice_header - > lt_rps ;
2023-10-26 11:38:46 -04:00
// Check the combined list
for ( int i = 0 ; i < lt_rps_ptr - > num_of_pics ; i + + ) {
if ( lt_rps_ptr - > used_by_curr_pic [ i ] ) {
2023-11-02 18:08:24 -04:00
num_pic_total_curr_ + + ;
2023-10-26 11:38:46 -04:00
}
}
2023-11-02 18:08:24 -04:00
if ( pps_ptr - > lists_modification_present_flag & & num_pic_total_curr_ > 1 )
2023-10-26 11:38:46 -04:00
{
int list_entry_bits = 0 ;
2023-11-02 18:08:24 -04:00
while ( ( 1 < < list_entry_bits ) < num_pic_total_curr_ ) {
2023-10-26 11:38:46 -04:00
list_entry_bits + + ;
}
2024-02-09 15:09:49 -05:00
p_slice_header - > ref_pic_list_modification_flag_l0 = Parser : : GetBit ( nalu , offset ) ;
if ( p_slice_header - > ref_pic_list_modification_flag_l0 ) {
for ( int i = 0 ; i < = p_slice_header - > num_ref_idx_l0_active_minus1 ; i + + ) {
p_slice_header - > list_entry_l0 [ i ] = Parser : : ReadBits ( nalu , offset , list_entry_bits ) ;
2024-11-11 14:33:17 -08:00
//todo;; check_max
2023-10-26 11:38:46 -04:00
}
}
2024-02-09 15:09:49 -05:00
if ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) {
p_slice_header - > ref_pic_list_modification_flag_l1 = Parser : : GetBit ( nalu , offset ) ;
if ( p_slice_header - > ref_pic_list_modification_flag_l1 ) {
for ( int i = 0 ; i < = p_slice_header - > num_ref_idx_l1_active_minus1 ; i + + ) {
p_slice_header - > list_entry_l1 [ i ] = Parser : : ReadBits ( nalu , offset , list_entry_bits ) ;
2024-11-11 14:33:17 -08:00
//todo::checkmax
2023-10-26 11:38:46 -04:00
}
}
}
}
2024-02-09 15:09:49 -05:00
if ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) {
p_slice_header - > mvd_l1_zero_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
}
if ( pps_ptr - > cabac_init_present_flag ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > cabac_init_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
}
2024-02-09 15:09:49 -05:00
if ( p_slice_header - > slice_temporal_mvp_enabled_flag ) {
if ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) {
p_slice_header - > collocated_from_l0_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
}
2024-02-09 15:09:49 -05:00
if ( ( p_slice_header - > collocated_from_l0_flag & & p_slice_header - > num_ref_idx_l0_active_minus1 > 0 ) | | ( ! p_slice_header - > collocated_from_l0_flag & & p_slice_header - > num_ref_idx_l1_active_minus1 > 0 ) ) {
p_slice_header - > collocated_ref_idx = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2024-11-11 14:33:17 -08:00
if ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_P | | ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B & & p_slice_header - > collocated_from_l0_flag = = 1 ) ) {
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_MAX ( " collocated_ref_idx " , p_slice_header - > collocated_ref_idx , p_slice_header - > num_ref_idx_l0_active_minus1 ) ;
2024-11-11 14:33:17 -08:00
} else {
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_MAX ( " collocated_ref_idx " , p_slice_header - > collocated_ref_idx , p_slice_header - > num_ref_idx_l1_active_minus1 ) ;
2024-11-11 14:33:17 -08:00
}
2023-10-26 11:38:46 -04:00
}
}
2024-02-09 15:09:49 -05:00
if ( ( pps_ptr - > weighted_pred_flag & & p_slice_header - > slice_type = = HEVC_SLICE_TYPE_P ) | | ( pps_ptr - > weighted_bipred_flag & & p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) ) {
2025-03-26 08:16:36 -04:00
ParserResult ret ;
if ( ( ret = ParsePredWeightTable ( p_slice_header , chroma_array_type , nalu , offset ) ) ! = PARSER_OK ) {
return ret ;
}
2023-10-26 11:38:46 -04:00
}
2024-02-09 15:09:49 -05:00
p_slice_header - > five_minus_max_num_merge_cand = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
}
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_qp_delta = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
if ( pps_ptr - > pps_slice_chroma_qp_offsets_present_flag ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_cb_qp_offset = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " slice_cb_qp_offset " , p_slice_header - > slice_cb_qp_offset , - 12 , 12 ) ;
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_cr_qp_offset = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " slice_cr_qp_offset " , p_slice_header - > slice_cr_qp_offset , - 12 , 12 ) ;
2023-10-26 11:38:46 -04:00
}
if ( pps_ptr - > chroma_qp_offset_list_enabled_flag ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > cu_chroma_qp_offset_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
}
if ( pps_ptr - > deblocking_filter_override_enabled_flag ) {
2024-02-09 15:09:49 -05:00
p_slice_header - > deblocking_filter_override_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
}
2024-02-09 15:09:49 -05:00
if ( p_slice_header - > deblocking_filter_override_flag ) {
p_slice_header - > slice_deblocking_filter_disabled_flag = Parser : : GetBit ( nalu , offset ) ;
if ( ! p_slice_header - > slice_deblocking_filter_disabled_flag ) {
p_slice_header - > slice_beta_offset_div2 = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " slice_beta_offset_div2 " , p_slice_header - > slice_beta_offset_div2 , - 6 , 6 ) ;
2024-02-09 15:09:49 -05:00
p_slice_header - > slice_tc_offset_div2 = Parser : : ExpGolomb : : ReadSe ( nalu , offset ) ;
2025-03-10 09:15:12 -04:00
CHECK_ALLOWED_RANGE ( " slice_tc_offset_div2 " , p_slice_header - > slice_tc_offset_div2 , - 6 , 6 ) ;
2023-10-26 11:38:46 -04:00
}
}
2024-02-09 15:09:49 -05:00
if ( pps_ptr - > pps_loop_filter_across_slices_enabled_flag & & ( p_slice_header - > slice_sao_luma_flag | | p_slice_header - > slice_sao_chroma_flag | |
! p_slice_header - > slice_deblocking_filter_disabled_flag ) ) {
p_slice_header - > slice_loop_filter_across_slices_enabled_flag = Parser : : GetBit ( nalu , offset ) ;
2023-10-26 11:38:46 -04:00
}
2025-03-28 16:35:03 -04:00
p_slice_header - > is_received = 1 ;
2024-11-19 15:10:35 -05:00
memcpy ( & slice_header_copy_ , p_slice_header , sizeof ( HevcSliceSegHeader ) ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-10-18 06:01:44 -07:00
//dependant slice
2025-03-28 16:35:03 -04:00
if ( ! slice_header_copy_ . is_received ) {
return PARSER_WRONG_STATE ;
}
2024-11-19 15:10:35 -05:00
memcpy ( p_slice_header , & slice_header_copy_ , sizeof ( HevcSliceSegHeader ) ) ;
2024-02-09 15:09:49 -05:00
p_slice_header - > first_slice_segment_in_pic_flag = temp_sh . first_slice_segment_in_pic_flag ;
p_slice_header - > no_output_of_prior_pics_flag = temp_sh . no_output_of_prior_pics_flag ;
p_slice_header - > slice_pic_parameter_set_id = temp_sh . slice_pic_parameter_set_id ;
p_slice_header - > dependent_slice_segment_flag = temp_sh . dependent_slice_segment_flag ;
p_slice_header - > slice_segment_address = temp_sh . slice_segment_address ;
2023-10-05 08:20:07 -07:00
}
2023-10-26 11:38:46 -04:00
if ( pps_ptr - > tiles_enabled_flag | | pps_ptr - > entropy_coding_sync_enabled_flag ) {
2023-11-17 12:57:19 -05:00
int max_num_entry_point_offsets ; // 7.4.7.1
if ( ! pps_ptr - > tiles_enabled_flag & & pps_ptr - > entropy_coding_sync_enabled_flag ) {
max_num_entry_point_offsets = pic_height_in_ctbs_y_ - 1 ;
2024-01-05 09:15:33 -05:00
} else if ( pps_ptr - > tiles_enabled_flag & & ! pps_ptr - > entropy_coding_sync_enabled_flag ) {
2023-11-17 12:57:19 -05:00
max_num_entry_point_offsets = ( pps_ptr - > num_tile_columns_minus1 + 1 ) * ( pps_ptr - > num_tile_rows_minus1 + 1 ) - 1 ;
2024-01-05 09:15:33 -05:00
} else {
2023-11-17 12:57:19 -05:00
max_num_entry_point_offsets = ( pps_ptr - > num_tile_columns_minus1 + 1 ) * pic_height_in_ctbs_y_ - 1 ;
}
2024-02-09 15:09:49 -05:00
p_slice_header - > num_entry_point_offsets = Parser : : ExpGolomb : : ReadUe ( nalu , offset ) ;
if ( p_slice_header - > num_entry_point_offsets > max_num_entry_point_offsets ) {
p_slice_header - > num_entry_point_offsets = max_num_entry_point_offsets ;
2023-11-17 12:57:19 -05:00
}
2023-11-17 15:59:29 -05:00
#if 0 // do not parse syntax parameters that are not used by HW decode
2024-02-09 15:09:49 -05:00
if (p_slice_header->num_entry_point_offsets) {
p_slice_header->offset_len_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset);
for (int i = 0; i < p_slice_header->num_entry_point_offsets; i++) {
p_slice_header->entry_point_offset_minus1[i] = Parser::ReadBits(nalu, offset, p_slice_header->offset_len_minus1 + 1);
2023-10-26 11:38:46 -04:00
}
}
2023-11-17 15:59:29 -05:00
#endif
2023-10-26 11:38:46 -04:00
}
2023-11-17 15:59:29 -05:00
#if 0 // do not parse syntax parameters that are not used by HW decode
2023-10-26 11:38:46 -04:00
if (pps_ptr->slice_segment_header_extension_present_flag) {
2024-02-09 15:09:49 -05:00
p_slice_header->slice_segment_header_extension_length = Parser::ExpGolomb::ReadUe(nalu, offset);
for (int i = 0; i < p_slice_header->slice_segment_header_extension_length; i++) {
p_slice_header->slice_segment_header_extension_data_byte[i] = Parser::ReadBits(nalu, offset, 8);
2023-10-26 11:38:46 -04:00
}
}
2023-11-17 15:59:29 -05:00
#endif
2023-10-26 11:38:46 -04:00
2023-10-20 10:39:21 -04:00
# if DBGINFO
2024-02-09 15:09:49 -05:00
PrintSliceSegHeader ( p_slice_header ) ;
2023-10-20 10:39:21 -04:00
# endif // DBGINFO
2024-05-03 15:18:08 -04:00
return PARSER_OK ;
2023-10-05 08:20:07 -07:00
}
2024-01-10 11:44:07 -05:00
bool HevcVideoParser : : IsIdrPic ( HevcNalUnitHeader * nal_header_ptr ) {
2023-11-15 16:07:18 -05:00
return ( nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_IDR_W_RADL | | nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_IDR_N_LP ) ;
}
2024-01-10 11:44:07 -05:00
bool HevcVideoParser : : IsBlaPic ( HevcNalUnitHeader * nal_header_ptr ) {
2023-11-15 16:07:18 -05:00
return ( nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_BLA_W_LP | | nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_BLA_W_RADL | | nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_BLA_N_LP ) ;
}
2024-01-10 11:44:07 -05:00
bool HevcVideoParser : : IsCraPic ( HevcNalUnitHeader * nal_header_ptr ) {
2023-11-15 16:07:18 -05:00
return ( nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_CRA_NUT ) ;
}
2024-01-10 11:44:07 -05:00
bool HevcVideoParser : : IsRaslPic ( HevcNalUnitHeader * nal_header_ptr ) {
2023-11-15 16:07:18 -05:00
return ( nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_RASL_N | | nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_RASL_R ) ;
}
2024-01-10 11:44:07 -05:00
bool HevcVideoParser : : IsRadlPic ( HevcNalUnitHeader * nal_header_ptr ) {
2023-12-18 08:20:55 -05:00
return ( nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_RADL_N | | nal_header_ptr - > nal_unit_type = = NAL_UNIT_CODED_SLICE_RADL_R ) ;
}
2024-01-10 11:44:07 -05:00
bool HevcVideoParser : : IsIrapPic ( HevcNalUnitHeader * nal_header_ptr ) {
2023-11-15 16:07:18 -05:00
return ( nal_header_ptr - > nal_unit_type > = NAL_UNIT_CODED_SLICE_BLA_W_LP & & nal_header_ptr - > nal_unit_type < = NAL_UNIT_RESERVED_IRAP_VCL23 ) ;
}
2024-01-10 11:44:07 -05:00
bool HevcVideoParser : : IsRefPic ( HevcNalUnitHeader * nal_header_ptr ) {
2023-12-18 08:20:55 -05:00
if ( ( ( nal_header_ptr - > nal_unit_type < = NAL_UNIT_RESERVED_VCL_R15 ) & & ( ( nal_header_ptr - > nal_unit_type % 2 ) ! = 0 ) ) | |
( ( nal_header_ptr - > nal_unit_type > = NAL_UNIT_CODED_SLICE_BLA_W_LP ) & & ( nal_header_ptr - > nal_unit_type < = NAL_UNIT_RESERVED_IRAP_VCL23 ) ) ) {
return true ;
} else {
return false ;
}
}
2024-01-29 12:09:36 -05:00
void HevcVideoParser : : CalculateCurrPoc ( ) {
2024-02-09 15:09:49 -05:00
HevcSliceSegHeader * p_slice_header = & slice_info_list_ [ 0 ] . slice_header ;
2024-01-29 12:09:36 -05:00
// Record decode order count
2023-11-27 11:04:01 -05:00
curr_pic_info_ . decode_order_count = pic_count_ ;
2023-11-15 16:07:18 -05:00
if ( IsIdrPic ( & slice_nal_unit_header_ ) ) {
2023-11-02 18:08:24 -04:00
curr_pic_info_ . pic_order_cnt = 0 ;
curr_pic_info_ . prev_poc_lsb = 0 ;
curr_pic_info_ . prev_poc_msb = 0 ;
curr_pic_info_ . slice_pic_order_cnt_lsb = 0 ;
2024-01-05 09:15:33 -05:00
} else {
2025-03-26 08:16:36 -04:00
int max_poc_lsb = 1 < < ( sps_list_ [ active_sps_id_ ] . log2_max_pic_order_cnt_lsb_minus4 + 4 ) ; // MaxPicOrderCntLsb
2023-11-02 18:08:24 -04:00
int poc_msb ; // PicOrderCntMsb
// If the current picture is an IRAP picture with NoRaslOutputFlag equal to 1, PicOrderCntMsb is set equal to 0.
2023-11-15 16:07:18 -05:00
if ( IsIrapPic ( & slice_nal_unit_header_ ) & & no_rasl_output_flag_ = = 1 ) {
2023-11-02 18:08:24 -04:00
poc_msb = 0 ;
2024-01-05 09:15:33 -05:00
} else {
2024-02-09 15:09:49 -05:00
if ( ( p_slice_header - > slice_pic_order_cnt_lsb < curr_pic_info_ . prev_poc_lsb ) & & ( ( curr_pic_info_ . prev_poc_lsb - p_slice_header - > slice_pic_order_cnt_lsb ) > = ( max_poc_lsb / 2 ) ) ) {
2023-11-02 18:08:24 -04:00
poc_msb = curr_pic_info_ . prev_poc_msb + max_poc_lsb ;
2024-02-09 15:09:49 -05:00
} else if ( ( p_slice_header - > slice_pic_order_cnt_lsb > curr_pic_info_ . prev_poc_lsb ) & & ( ( p_slice_header - > slice_pic_order_cnt_lsb - curr_pic_info_ . prev_poc_lsb ) > ( max_poc_lsb / 2 ) ) ) {
2023-11-02 18:08:24 -04:00
poc_msb = curr_pic_info_ . prev_poc_msb - max_poc_lsb ;
2024-01-05 09:15:33 -05:00
} else {
2023-11-02 18:08:24 -04:00
poc_msb = curr_pic_info_ . prev_poc_msb ;
}
}
2024-02-09 15:09:49 -05:00
curr_pic_info_ . pic_order_cnt = poc_msb + p_slice_header - > slice_pic_order_cnt_lsb ;
curr_pic_info_ . slice_pic_order_cnt_lsb = p_slice_header - > slice_pic_order_cnt_lsb ;
2023-12-18 08:20:55 -05:00
if ( ( slice_nal_unit_header_ . nuh_temporal_id_plus1 - 1 ) = = 0 & & IsRefPic ( & slice_nal_unit_header_ ) & & ! IsRaslPic ( & slice_nal_unit_header_ ) & & ! IsRadlPic ( & slice_nal_unit_header_ ) ) {
2024-02-09 15:09:49 -05:00
curr_pic_info_ . prev_poc_lsb = p_slice_header - > slice_pic_order_cnt_lsb ;
2023-12-18 08:20:55 -05:00
curr_pic_info_ . prev_poc_msb = poc_msb ;
}
2023-11-02 18:08:24 -04:00
}
}
2024-01-10 11:44:07 -05:00
void HevcVideoParser : : DecodeRps ( ) {
2023-11-02 18:08:24 -04:00
int i , j , k ;
2024-01-05 09:15:33 -05:00
int curr_delta_poc_msb_present_flag [ HEVC_MAX_NUM_REF_PICS ] = { 0 } ; // CurrDeltaPocMsbPresentFlag
2023-11-02 18:08:24 -04:00
int foll_delta_poc_msb_present_flag [ HEVC_MAX_NUM_REF_PICS ] = { 0 } ; // FollDeltaPocMsbPresentFlag
2025-03-26 08:16:36 -04:00
int max_poc_lsb = 1 < < ( sps_list_ [ active_sps_id_ ] . log2_max_pic_order_cnt_lsb_minus4 + 4 ) ; // MaxPicOrderCntLsb
2024-02-09 15:09:49 -05:00
HevcSliceSegHeader * p_slice_header = & slice_info_list_ [ 0 ] . slice_header ;
2023-11-02 18:08:24 -04:00
// When the current picture is an IRAP picture with NoRaslOutputFlag equal to 1, all reference pictures with
// nuh_layer_id equal to currPicLayerId currently in the DPB (if any) are marked as "unused for reference".
2023-11-15 16:07:18 -05:00
if ( IsIrapPic ( & slice_nal_unit_header_ ) & & no_rasl_output_flag_ = = 1 ) {
2023-11-27 11:04:01 -05:00
for ( i = 0 ; i < HEVC_MAX_DPB_FRAMES ; i + + ) {
2023-11-02 18:08:24 -04:00
dpb_buffer_ . frame_buffer_list [ i ] . is_reference = kUnusedForReference ;
}
}
2023-11-15 16:07:18 -05:00
if ( IsIdrPic ( & slice_nal_unit_header_ ) ) {
2023-11-02 18:08:24 -04:00
num_poc_st_curr_before_ = 0 ;
num_poc_st_curr_after_ = 0 ;
num_poc_st_foll_ = 0 ;
num_poc_lt_curr_ = 0 ;
num_poc_lt_foll_ = 0 ;
memset ( poc_st_curr_before_ , 0 , sizeof ( int32_t ) * HEVC_MAX_NUM_REF_PICS ) ;
memset ( poc_st_curr_after_ , 0 , sizeof ( int32_t ) * HEVC_MAX_NUM_REF_PICS ) ;
memset ( poc_st_foll_ , 0 , sizeof ( int32_t ) * HEVC_MAX_NUM_REF_PICS ) ;
memset ( poc_lt_curr_ , 0 , sizeof ( int32_t ) * HEVC_MAX_NUM_REF_PICS ) ;
memset ( poc_lt_foll_ , 0 , sizeof ( int32_t ) * HEVC_MAX_NUM_REF_PICS ) ;
2024-01-05 09:15:33 -05:00
} else {
2024-02-09 15:09:49 -05:00
HevcShortTermRps * rps_ptr = & p_slice_header - > st_rps ;
2023-11-02 18:08:24 -04:00
for ( i = 0 , j = 0 , k = 0 ; i < rps_ptr - > num_negative_pics ; i + + ) {
2023-12-04 11:53:26 -05:00
if ( rps_ptr - > used_by_curr_pic_s0 [ i ] ) {
poc_st_curr_before_ [ j + + ] = curr_pic_info_ . pic_order_cnt + rps_ptr - > delta_poc_s0 [ i ] ;
2024-01-05 09:15:33 -05:00
} else {
2023-12-04 11:53:26 -05:00
poc_st_foll_ [ k + + ] = curr_pic_info_ . pic_order_cnt + rps_ptr - > delta_poc_s0 [ i ] ;
2023-11-02 18:08:24 -04:00
}
}
num_poc_st_curr_before_ = j ;
2023-12-04 11:53:26 -05:00
for ( i = 0 , j = 0 ; i < rps_ptr - > num_positive_pics ; i + + ) {
if ( rps_ptr - > used_by_curr_pic_s1 [ i ] ) {
poc_st_curr_after_ [ j + + ] = curr_pic_info_ . pic_order_cnt + rps_ptr - > delta_poc_s1 [ i ] ;
2024-01-05 09:15:33 -05:00
} else {
2023-12-04 11:53:26 -05:00
poc_st_foll_ [ k + + ] = curr_pic_info_ . pic_order_cnt + rps_ptr - > delta_poc_s1 [ i ] ;
2023-11-02 18:08:24 -04:00
}
}
num_poc_st_curr_after_ = j ;
num_poc_st_foll_ = k ;
2024-02-09 15:09:49 -05:00
HevcLongTermRps * lt_rps_ptr = & p_slice_header - > lt_rps ;
2023-11-02 18:08:24 -04:00
for ( i = 0 , j = 0 , k = 0 ; i < lt_rps_ptr - > num_of_pics ; i + + ) {
uint32_t poc_lt = lt_rps_ptr - > pocs [ i ] ; // oocLt
2024-02-09 15:09:49 -05:00
if ( p_slice_header - > delta_poc_msb_present_flag [ i ] ) {
poc_lt + = curr_pic_info_ . pic_order_cnt - p_slice_header - > delta_poc_msb_cycle_lt [ i ] * max_poc_lsb - ( curr_pic_info_ . pic_order_cnt & ( max_poc_lsb - 1 ) ) ;
2023-11-02 18:08:24 -04:00
}
if ( lt_rps_ptr - > used_by_curr_pic [ i ] ) {
poc_lt_curr_ [ j ] = poc_lt ;
2024-02-09 15:09:49 -05:00
curr_delta_poc_msb_present_flag [ j + + ] = p_slice_header - > delta_poc_msb_present_flag [ i ] ;
2024-01-05 09:15:33 -05:00
} else {
2023-11-02 18:08:24 -04:00
poc_lt_foll_ [ k ] = poc_lt ;
2024-02-09 15:09:49 -05:00
foll_delta_poc_msb_present_flag [ k + + ] = p_slice_header - > delta_poc_msb_present_flag [ i ] ;
2023-11-02 18:08:24 -04:00
}
}
num_poc_lt_curr_ = j ;
num_poc_lt_foll_ = k ;
/*
* RPS derivation and picture marking
*/
2023-12-15 15:54:43 -05:00
// Init to a valid index value to take care of undecodable RASL pictures, whose reference pictures are emptied after a CRA.
2023-11-02 18:08:24 -04:00
for ( i = 0 ; i < HEVC_MAX_NUM_REF_PICS ; i + + ) {
2023-12-15 15:54:43 -05:00
ref_pic_set_st_curr_before_ [ i ] = 0 ;
ref_pic_set_st_curr_after_ [ i ] = 0 ;
ref_pic_set_st_foll_ [ i ] = 0 ;
ref_pic_set_lt_curr_ [ i ] = 0 ;
ref_pic_set_lt_foll_ [ i ] = 0 ;
2023-11-02 18:08:24 -04:00
}
// Mark all in DPB as unused. We will mark them back while we go through the ref lists. The rest will be actually unused.
2023-11-27 11:04:01 -05:00
for ( i = 0 ; i < HEVC_MAX_DPB_FRAMES ; i + + ) {
2023-11-02 18:08:24 -04:00
dpb_buffer_ . frame_buffer_list [ i ] . is_reference = kUnusedForReference ;
}
/// Short term reference pictures
for ( i = 0 ; i < num_poc_st_curr_before_ ; i + + ) {
2023-11-27 11:04:01 -05:00
for ( j = 0 ; j < HEVC_MAX_DPB_FRAMES ; j + + ) {
2024-11-15 15:41:50 -05:00
if ( poc_st_curr_before_ [ i ] = = dpb_buffer_ . frame_buffer_list [ j ] . pic_order_cnt & & dpb_buffer_ . frame_buffer_list [ j ] . use_status ! = kNotUsed ) {
2023-11-02 18:08:24 -04:00
ref_pic_set_st_curr_before_ [ i ] = j ; // RefPicSetStCurrBefore. Use DPB buffer index for now
dpb_buffer_ . frame_buffer_list [ j ] . is_reference = kUsedForShortTerm ;
break ;
}
}
}
for ( i = 0 ; i < num_poc_st_curr_after_ ; i + + ) {
2023-11-27 11:04:01 -05:00
for ( j = 0 ; j < HEVC_MAX_DPB_FRAMES ; j + + ) {
2024-11-15 15:41:50 -05:00
if ( poc_st_curr_after_ [ i ] = = dpb_buffer_ . frame_buffer_list [ j ] . pic_order_cnt & & dpb_buffer_ . frame_buffer_list [ j ] . use_status ! = kNotUsed ) {
2023-11-02 18:08:24 -04:00
ref_pic_set_st_curr_after_ [ i ] = j ; // RefPicSetStCurrAfter
dpb_buffer_ . frame_buffer_list [ j ] . is_reference = kUsedForShortTerm ;
break ;
}
}
}
for ( i = 0 ; i < num_poc_st_foll_ ; i + + ) {
2023-11-27 11:04:01 -05:00
for ( j = 0 ; j < HEVC_MAX_DPB_FRAMES ; j + + ) {
2024-11-15 15:41:50 -05:00
if ( poc_st_foll_ [ i ] = = dpb_buffer_ . frame_buffer_list [ j ] . pic_order_cnt & & dpb_buffer_ . frame_buffer_list [ j ] . use_status ! = kNotUsed ) {
2023-11-02 18:08:24 -04:00
ref_pic_set_st_foll_ [ i ] = j ; // RefPicSetStFoll
dpb_buffer_ . frame_buffer_list [ j ] . is_reference = kUsedForShortTerm ;
break ;
}
}
}
/// Long term reference pictures
for ( i = 0 ; i < num_poc_lt_curr_ ; i + + ) {
2023-11-27 11:04:01 -05:00
for ( j = 0 ; j < HEVC_MAX_DPB_FRAMES ; j + + ) {
2024-01-05 09:15:33 -05:00
if ( ! curr_delta_poc_msb_present_flag [ i ] ) {
if ( poc_lt_curr_ [ i ] = = ( dpb_buffer_ . frame_buffer_list [ j ] . pic_order_cnt & ( max_poc_lsb - 1 ) ) & & dpb_buffer_ . frame_buffer_list [ j ] . use_status ) {
2023-11-02 18:08:24 -04:00
ref_pic_set_lt_curr_ [ i ] = j ; // RefPicSetLtCurr
dpb_buffer_ . frame_buffer_list [ j ] . is_reference = kUsedForLongTerm ;
break ;
}
2024-01-05 09:15:33 -05:00
} else {
2023-11-02 18:08:24 -04:00
if ( poc_lt_curr_ [ i ] = = dpb_buffer_ . frame_buffer_list [ j ] . pic_order_cnt ) {
ref_pic_set_lt_curr_ [ i ] = j ; // RefPicSetLtCurr
dpb_buffer_ . frame_buffer_list [ j ] . is_reference = kUsedForLongTerm ;
break ;
}
}
}
}
for ( i = 0 ; i < num_poc_lt_foll_ ; i + + ) {
2023-11-27 11:04:01 -05:00
for ( j = 0 ; j < HEVC_MAX_DPB_FRAMES ; j + + ) {
2023-11-02 18:08:24 -04:00
if ( ! foll_delta_poc_msb_present_flag [ i ] ) {
2024-01-05 09:15:33 -05:00
if ( poc_lt_foll_ [ i ] = = ( dpb_buffer_ . frame_buffer_list [ j ] . pic_order_cnt & ( max_poc_lsb - 1 ) ) & & dpb_buffer_ . frame_buffer_list [ j ] . use_status ) {
2023-11-02 18:08:24 -04:00
ref_pic_set_lt_foll_ [ i ] = j ; // RefPicSetLtFoll
dpb_buffer_ . frame_buffer_list [ j ] . is_reference = kUsedForLongTerm ;
break ;
}
2024-01-05 09:15:33 -05:00
} else {
2023-11-02 18:08:24 -04:00
if ( poc_lt_foll_ [ i ] = = dpb_buffer_ . frame_buffer_list [ j ] . pic_order_cnt ) {
ref_pic_set_lt_foll_ [ i ] = j ; // RefPicSetLtFoll
dpb_buffer_ . frame_buffer_list [ j ] . is_reference = kUsedForLongTerm ;
break ;
}
}
}
}
}
}
2024-02-09 15:09:49 -05:00
void HevcVideoParser : : ConstructRefPicLists ( HevcSliceInfo * p_slice_info ) {
HevcSliceSegHeader * p_slice_header = & p_slice_info - > slice_header ;
2023-11-02 18:08:24 -04:00
uint32_t num_rps_curr_temp_list ; // NumRpsCurrTempList0 or NumRpsCurrTempList1;
2025-03-20 06:12:16 -07:00
int i ;
2023-11-02 18:08:24 -04:00
int rIdx ;
2025-03-05 08:44:59 -05:00
uint32_t ref_pic_list_temp [ HEVC_MAX_NUM_REF_PICS ] = { 0 } ; // RefPicListTemp0 or RefPicListTemp1
2023-11-02 18:08:24 -04:00
/// List 0
rIdx = 0 ;
2024-02-09 15:09:49 -05:00
num_rps_curr_temp_list = std : : max ( p_slice_header - > num_ref_idx_l0_active_minus1 + 1 , num_pic_total_curr_ ) ;
2023-11-02 18:08:24 -04:00
2024-11-06 11:41:57 -08:00
while ( ( num_poc_st_curr_before_ | num_poc_st_curr_after_ | num_poc_lt_curr_ ) & & ( rIdx < num_rps_curr_temp_list ) ) {
2023-11-02 18:08:24 -04:00
for ( i = 0 ; i < num_poc_st_curr_before_ & & rIdx < num_rps_curr_temp_list ; rIdx + + , i + + ) {
ref_pic_list_temp [ rIdx ] = ref_pic_set_st_curr_before_ [ i ] ;
}
for ( i = 0 ; i < num_poc_st_curr_after_ & & rIdx < num_rps_curr_temp_list ; rIdx + + , i + + ) {
ref_pic_list_temp [ rIdx ] = ref_pic_set_st_curr_after_ [ i ] ;
}
for ( i = 0 ; i < num_poc_lt_curr_ & & rIdx < num_rps_curr_temp_list ; rIdx + + , i + + ) {
ref_pic_list_temp [ rIdx ] = ref_pic_set_lt_curr_ [ i ] ;
}
}
2024-02-09 15:09:49 -05:00
for ( rIdx = 0 ; rIdx < = p_slice_header - > num_ref_idx_l0_active_minus1 ; rIdx + + ) {
p_slice_info - > ref_pic_list_0_ [ rIdx ] = p_slice_header - > ref_pic_list_modification_flag_l0 ? ref_pic_list_temp [ p_slice_header - > list_entry_l0 [ rIdx ] ] : ref_pic_list_temp [ rIdx ] ;
2023-11-02 18:08:24 -04:00
}
/// List 1
2024-02-09 15:09:49 -05:00
if ( p_slice_header - > slice_type = = HEVC_SLICE_TYPE_B ) {
2023-11-02 18:08:24 -04:00
rIdx = 0 ;
2024-02-09 15:09:49 -05:00
num_rps_curr_temp_list = std : : max ( p_slice_header - > num_ref_idx_l1_active_minus1 + 1 , num_pic_total_curr_ ) ;
2023-11-02 18:08:24 -04:00
2024-11-06 11:41:57 -08:00
while ( ( num_poc_st_curr_after_ | num_poc_st_curr_before_ | num_poc_lt_curr_ ) & & ( rIdx < num_rps_curr_temp_list ) ) {
2023-11-02 18:08:24 -04:00
for ( i = 0 ; i < num_poc_st_curr_after_ & & rIdx < num_rps_curr_temp_list ; rIdx + + , i + + ) {
ref_pic_list_temp [ rIdx ] = ref_pic_set_st_curr_after_ [ i ] ;
}
for ( i = 0 ; i < num_poc_st_curr_before_ & & rIdx < num_rps_curr_temp_list ; rIdx + + , i + + ) {
ref_pic_list_temp [ rIdx ] = ref_pic_set_st_curr_before_ [ i ] ;
}
for ( i = 0 ; i < num_poc_lt_curr_ & & rIdx < num_rps_curr_temp_list ; rIdx + + , i + + ) {
ref_pic_list_temp [ rIdx ] = ref_pic_set_lt_curr_ [ i ] ;
}
}
2024-02-09 15:09:49 -05:00
for ( rIdx = 0 ; rIdx < = p_slice_header - > num_ref_idx_l1_active_minus1 ; rIdx + + ) {
p_slice_info - > ref_pic_list_1_ [ rIdx ] = p_slice_header - > ref_pic_list_modification_flag_l1 ? ref_pic_list_temp [ p_slice_header - > list_entry_l1 [ rIdx ] ] : ref_pic_list_temp [ rIdx ] ;
2023-11-02 18:08:24 -04:00
}
}
}
2024-01-10 11:44:07 -05:00
void HevcVideoParser : : InitDpb ( ) {
2023-11-27 11:04:01 -05:00
memset ( & dpb_buffer_ , 0 , sizeof ( DecodedPictureBuffer ) ) ;
for ( int i = 0 ; i < HEVC_MAX_DPB_FRAMES ; i + + ) {
dpb_buffer_ . frame_buffer_list [ i ] . pic_idx = i ;
dpb_buffer_ . frame_buffer_list [ i ] . is_reference = kUnusedForReference ;
dpb_buffer_ . frame_buffer_list [ i ] . pic_output_flag = 0 ;
2024-05-31 13:14:02 -04:00
dpb_buffer_ . frame_buffer_list [ i ] . use_status = kNotUsed ;
2023-11-27 11:04:01 -05:00
}
dpb_buffer_ . dpb_size = 0 ;
dpb_buffer_ . dpb_fullness = 0 ;
2024-02-14 18:06:43 -05:00
dpb_buffer_ . num_pics_needed_for_output = 0 ;
2023-11-27 11:04:01 -05:00
}
2023-11-02 18:08:24 -04:00
2024-01-10 11:44:07 -05:00
void HevcVideoParser : : EmptyDpb ( ) {
2023-11-27 11:04:01 -05:00
for ( int i = 0 ; i < HEVC_MAX_DPB_FRAMES ; i + + ) {
dpb_buffer_ . frame_buffer_list [ i ] . is_reference = kUnusedForReference ;
dpb_buffer_ . frame_buffer_list [ i ] . pic_output_flag = 0 ;
2024-05-31 13:14:02 -04:00
dpb_buffer_ . frame_buffer_list [ i ] . use_status = kNotUsed ;
decode_buffer_pool_ [ dpb_buffer_ . frame_buffer_list [ i ] . dec_buf_idx ] . use_status = kNotUsed ;
2023-11-27 11:04:01 -05:00
}
2023-11-02 18:08:24 -04:00
dpb_buffer_ . dpb_fullness = 0 ;
2024-02-14 18:06:43 -05:00
dpb_buffer_ . num_pics_needed_for_output = 0 ;
2024-05-31 13:14:02 -04:00
num_output_pics_ = 0 ;
2023-11-27 13:03:26 -05:00
}
2024-01-10 11:44:07 -05:00
int HevcVideoParser : : FlushDpb ( ) {
2024-11-06 11:41:57 -08:00
// Bump the remaining pictures
while ( dpb_buffer_ . num_pics_needed_for_output ) {
if ( BumpPicFromDpb ( ) ! = PARSER_OK ) {
return PARSER_FAIL ;
2023-11-27 13:03:26 -05:00
}
2024-05-31 13:14:02 -04:00
}
if ( pfn_display_picture_cb_ & & num_output_pics_ > 0 ) {
if ( OutputDecodedPictures ( true ) ! = PARSER_OK ) {
return PARSER_FAIL ;
2023-11-27 13:03:26 -05:00
}
}
2024-05-31 13:14:02 -04:00
2023-11-27 13:03:26 -05:00
return PARSER_OK ;
2023-11-27 11:04:01 -05:00
}
2024-01-10 11:44:07 -05:00
int HevcVideoParser : : MarkOutputPictures ( ) {
2023-11-27 11:04:01 -05:00
int i ;
if ( IsIrapPic ( & slice_nal_unit_header_ ) & & no_rasl_output_flag_ = = 1 & & pic_count_ ! = 0 ) {
if ( IsCraPic ( & slice_nal_unit_header_ ) ) {
no_output_of_prior_pics_flag = 1 ;
2024-01-05 09:15:33 -05:00
} else {
2024-02-09 15:09:49 -05:00
no_output_of_prior_pics_flag = slice_info_list_ [ 0 ] . slice_header . no_output_of_prior_pics_flag ;
2023-11-02 18:08:24 -04:00
}
2023-11-27 11:04:01 -05:00
if ( ! no_output_of_prior_pics_flag ) {
// Bump the remaining pictures
2023-11-27 19:54:49 -05:00
if ( FlushDpb ( ) ! = PARSER_OK ) {
return PARSER_FAIL ;
2023-11-27 11:04:01 -05:00
}
}
2024-05-31 13:14:02 -04:00
// We can still have remaining undisplayed frames due to display delay feature
if ( num_output_pics_ ) {
OutputDecodedPictures ( true ) ;
}
2023-11-27 11:04:01 -05:00
EmptyDpb ( ) ;
2024-01-05 09:15:33 -05:00
} else {
2023-11-27 11:04:01 -05:00
for ( i = 0 ; i < HEVC_MAX_DPB_FRAMES ; i + + ) {
if ( dpb_buffer_ . frame_buffer_list [ i ] . is_reference = = kUnusedForReference & & dpb_buffer_ . frame_buffer_list [ i ] . pic_output_flag = = 0 & & dpb_buffer_ . frame_buffer_list [ i ] . use_status ) {
2024-05-31 13:14:02 -04:00
dpb_buffer_ . frame_buffer_list [ i ] . use_status = kNotUsed ;
decode_buffer_pool_ [ dpb_buffer_ . frame_buffer_list [ i ] . dec_buf_idx ] . use_status & = ~ kFrameUsedForDecode ;
2023-11-27 11:04:01 -05:00
if ( dpb_buffer_ . dpb_fullness > 0 ) {
dpb_buffer_ . dpb_fullness - - ;
2024-01-05 09:15:33 -05:00
} else {
2023-11-27 11:04:01 -05:00
ERR ( " Invalid DPB buffer fullness: " + TOSTR ( dpb_buffer_ . dpb_fullness ) ) ;
return PARSER_FAIL ;
}
2023-11-02 18:08:24 -04:00
}
}
2023-11-27 11:04:01 -05:00
2025-03-26 08:16:36 -04:00
HevcSeqParamSet * sps_ptr = & sps_list_ [ active_sps_id_ ] ;
2023-11-27 11:04:01 -05:00
uint32_t highest_tid = sps_ptr - > sps_max_sub_layers_minus1 ; // HighestTid
uint32_t max_num_reorder_pics = sps_ptr - > sps_max_num_reorder_pics [ highest_tid ] ;
uint32_t max_dec_pic_buffering = sps_ptr - > sps_max_dec_pic_buffering_minus1 [ highest_tid ] + 1 ;
2023-12-13 09:48:15 -05:00
while ( dpb_buffer_ . dpb_fullness > = max_dec_pic_buffering ) {
2023-11-27 11:04:01 -05:00
if ( BumpPicFromDpb ( ) ! = PARSER_OK ) {
return PARSER_FAIL ;
}
}
2024-02-14 18:06:43 -05:00
while ( dpb_buffer_ . num_pics_needed_for_output > max_num_reorder_pics ) {
2023-11-27 11:04:01 -05:00
if ( BumpPicFromDpb ( ) ! = PARSER_OK ) {
return PARSER_FAIL ;
}
}
// Skip SpsMaxLatencyPictures check as SpsMaxLatencyPictures >= sps_max_num_reorder_pics.
}
return PARSER_OK ;
}
2024-05-31 13:14:02 -04:00
ParserResult HevcVideoParser : : FindFreeInDecBufPool ( ) {
int dec_buf_index ;
// Find a free buffer in decode buffer pool
for ( dec_buf_index = 0 ; dec_buf_index < dec_buf_pool_size_ ; dec_buf_index + + ) {
if ( decode_buffer_pool_ [ dec_buf_index ] . use_status = = kNotUsed ) {
break ;
}
}
if ( dec_buf_index = = dec_buf_pool_size_ ) {
ERR ( " Could not find a free buffer in decode buffer pool. " ) ;
return PARSER_NOT_FOUND ;
}
curr_pic_info_ . dec_buf_idx = dec_buf_index ;
return PARSER_OK ;
}
ParserResult HevcVideoParser : : FindFreeInDpbAndMark ( ) {
2025-03-20 06:12:16 -07:00
int i ;
2023-11-27 11:04:01 -05:00
2024-05-31 13:14:02 -04:00
// Look for an empty buffer in DPB with longest decode history (lowest decode count)
2023-11-27 11:04:01 -05:00
uint32_t min_decode_order_count = 0xFFFFFFFF ;
int index = dpb_buffer_ . dpb_size ;
for ( i = 0 ; i < dpb_buffer_ . dpb_size ; i + + ) {
2024-05-31 13:14:02 -04:00
if ( dpb_buffer_ . frame_buffer_list [ i ] . use_status = = kNotUsed ) {
2023-11-27 11:04:01 -05:00
if ( dpb_buffer_ . frame_buffer_list [ i ] . decode_order_count < min_decode_order_count ) {
2024-05-31 13:14:02 -04:00
min_decode_order_count = dpb_buffer_ . frame_buffer_list [ i ] . decode_order_count ;
index = i ;
2023-11-27 11:04:01 -05:00
}
}
}
if ( index = = dpb_buffer_ . dpb_size ) {
ERR ( " Error! DPB buffer overflow! Fullness = " + TOSTR ( dpb_buffer_ . dpb_fullness ) ) ;
return PARSER_NOT_FOUND ;
2023-11-02 18:08:24 -04:00
}
2023-11-27 11:04:01 -05:00
curr_pic_info_ . pic_idx = index ;
2023-11-09 13:52:02 -05:00
curr_pic_info_ . is_reference = kUsedForShortTerm ;
2023-11-27 11:04:01 -05:00
// dpb_buffer_.frame_buffer_list[i].pic_idx is already set in InitDpb().
2024-05-31 13:14:02 -04:00
dpb_buffer_ . frame_buffer_list [ index ] . dec_buf_idx = curr_pic_info_ . dec_buf_idx ;
2023-11-27 11:04:01 -05:00
dpb_buffer_ . frame_buffer_list [ index ] . pic_order_cnt = curr_pic_info_ . pic_order_cnt ;
dpb_buffer_ . frame_buffer_list [ index ] . prev_poc_lsb = curr_pic_info_ . prev_poc_lsb ;
dpb_buffer_ . frame_buffer_list [ index ] . prev_poc_msb = curr_pic_info_ . prev_poc_msb ;
dpb_buffer_ . frame_buffer_list [ index ] . slice_pic_order_cnt_lsb = curr_pic_info_ . slice_pic_order_cnt_lsb ;
dpb_buffer_ . frame_buffer_list [ index ] . decode_order_count = curr_pic_info_ . decode_order_count ;
dpb_buffer_ . frame_buffer_list [ index ] . pic_output_flag = curr_pic_info_ . pic_output_flag ;
dpb_buffer_ . frame_buffer_list [ index ] . is_reference = kUsedForShortTerm ;
2024-05-31 13:14:02 -04:00
dpb_buffer_ . frame_buffer_list [ index ] . use_status = kFrameUsedForDecode ;
2023-11-27 11:04:01 -05:00
if ( dpb_buffer_ . frame_buffer_list [ index ] . pic_output_flag ) {
2024-02-14 18:06:43 -05:00
dpb_buffer_ . num_pics_needed_for_output + + ;
2023-11-27 11:04:01 -05:00
}
2023-11-02 18:08:24 -04:00
dpb_buffer_ . dpb_fullness + + ;
2024-05-31 13:14:02 -04:00
// Mark as used in decode buffer pool
decode_buffer_pool_ [ curr_pic_info_ . dec_buf_idx ] . use_status | = kFrameUsedForDecode ;
if ( pfn_display_picture_cb_ & & curr_pic_info_ . pic_output_flag ) {
decode_buffer_pool_ [ curr_pic_info_ . dec_buf_idx ] . use_status | = kFrameUsedForDisplay ;
}
decode_buffer_pool_ [ curr_pic_info_ . dec_buf_idx ] . pic_order_cnt = curr_pic_info_ . pic_order_cnt ;
2024-07-25 16:53:20 -04:00
decode_buffer_pool_ [ curr_pic_info_ . dec_buf_idx ] . pts = curr_pts_ ;
2024-05-31 13:14:02 -04:00
2025-03-26 08:16:36 -04:00
HevcSeqParamSet * sps_ptr = & sps_list_ [ active_sps_id_ ] ;
2023-12-13 09:48:15 -05:00
uint32_t highest_tid = sps_ptr - > sps_max_sub_layers_minus1 ; // HighestTid
uint32_t max_num_reorder_pics = sps_ptr - > sps_max_num_reorder_pics [ highest_tid ] ;
2024-05-31 13:14:02 -04:00
while ( dpb_buffer_ . num_pics_needed_for_output > max_num_reorder_pics ) {
2023-12-13 09:48:15 -05:00
if ( BumpPicFromDpb ( ) ! = PARSER_OK ) {
return PARSER_FAIL ;
}
}
2023-11-27 11:04:01 -05:00
// Skip SpsMaxLatencyPictures check as SpsMaxLatencyPictures >= sps_max_num_reorder_pics.
return PARSER_OK ;
}
2024-01-10 11:44:07 -05:00
int HevcVideoParser : : BumpPicFromDpb ( ) {
2023-11-27 11:04:01 -05:00
int32_t min_poc = 0x7FFFFFFF ; // largest possible POC value 2^31 - 1
int min_poc_pic_idx = HEVC_MAX_DPB_FRAMES ;
int i ;
for ( i = 0 ; i < HEVC_MAX_DPB_FRAMES ; i + + ) {
if ( dpb_buffer_ . frame_buffer_list [ i ] . pic_output_flag & & dpb_buffer_ . frame_buffer_list [ i ] . use_status ) {
if ( dpb_buffer_ . frame_buffer_list [ i ] . pic_order_cnt < min_poc ) {
min_poc = dpb_buffer_ . frame_buffer_list [ i ] . pic_order_cnt ;
min_poc_pic_idx = i ;
}
}
}
if ( min_poc_pic_idx > = HEVC_MAX_DPB_FRAMES ) {
// No picture that is needed for ouput is found
return PARSER_OK ;
}
// Mark as "not needed for output"
dpb_buffer_ . frame_buffer_list [ min_poc_pic_idx ] . pic_output_flag = 0 ;
2024-02-14 18:06:43 -05:00
if ( dpb_buffer_ . num_pics_needed_for_output > 0 ) {
dpb_buffer_ . num_pics_needed_for_output - - ;
2023-11-27 11:04:01 -05:00
}
// If it is not used for reference, empty it.
if ( dpb_buffer_ . frame_buffer_list [ min_poc_pic_idx ] . is_reference = = kUnusedForReference ) {
2024-05-31 13:14:02 -04:00
dpb_buffer_ . frame_buffer_list [ min_poc_pic_idx ] . use_status = kNotUsed ;
decode_buffer_pool_ [ dpb_buffer_ . frame_buffer_list [ min_poc_pic_idx ] . dec_buf_idx ] . use_status & = ~ kFrameUsedForDecode ;
2023-11-27 11:04:01 -05:00
if ( dpb_buffer_ . dpb_fullness > 0 ) {
dpb_buffer_ . dpb_fullness - - ;
}
}
// Insert into output/display picture list
2024-05-31 13:14:02 -04:00
if ( pfn_display_picture_cb_ ) {
if ( num_output_pics_ > = dec_buf_pool_size_ ) {
ERR ( " Error! Decode buffer pool overflow! " ) ;
return PARSER_OUT_OF_RANGE ;
} else {
output_pic_list_ [ num_output_pics_ ] = dpb_buffer_ . frame_buffer_list [ min_poc_pic_idx ] . dec_buf_idx ;
num_output_pics_ + + ;
}
2023-11-27 11:04:01 -05:00
}
2023-11-02 18:08:24 -04:00
return PARSER_OK ;
}
2023-10-20 10:39:21 -04:00
# if DBGINFO
2024-01-16 20:57:40 -05:00
void HevcVideoParser : : PrintVps ( HevcVideoParamSet * vps_ptr ) {
2023-10-20 10:39:21 -04:00
MSG ( " === hevc_video_parameter_set_t === " ) ;
MSG ( " vps_video_parameter_set_id = " < < vps_ptr - > vps_video_parameter_set_id ) ;
MSG ( " vps_base_layer_internal_flag = " < < vps_ptr - > vps_base_layer_internal_flag ) ;
MSG ( " vps_base_layer_available_flag = " < < vps_ptr - > vps_base_layer_available_flag ) ;
MSG ( " vps_max_layers_minus1 = " < < vps_ptr - > vps_max_layers_minus1 ) ;
MSG ( " vps_max_sub_layers_minus1 = " < < vps_ptr - > vps_max_sub_layers_minus1 ) ;
MSG ( " vps_temporal_id_nesting_flag = " < < vps_ptr - > vps_temporal_id_nesting_flag ) ;
MSG ( " vps_reserved_0xffff_16bits = " < < vps_ptr - > vps_reserved_0xffff_16bits ) ;
MSG ( " Profile tier level: " ) ;
MSG ( " general_profile_space = " < < vps_ptr - > profile_tier_level . general_profile_space ) ;
MSG ( " general_tier_flag = " < < vps_ptr - > profile_tier_level . general_tier_flag ) ;
MSG ( " general_profile_idc = " < < vps_ptr - > profile_tier_level . general_profile_idc ) ;
MSG_NO_NEWLINE ( " general_profile_compatibility_flag[32]: " ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
MSG_NO_NEWLINE ( " " < < vps_ptr - > profile_tier_level . general_profile_compatibility_flag [ i ] ) ;
}
MSG ( " " ) ;
MSG ( " general_progressive_source_flag = " < < vps_ptr - > profile_tier_level . general_progressive_source_flag ) ;
MSG ( " general_interlaced_source_flag = " < < vps_ptr - > profile_tier_level . general_interlaced_source_flag ) ;
MSG ( " general_non_packed_constraint_flag = " < < vps_ptr - > profile_tier_level . general_non_packed_constraint_flag ) ;
MSG ( " general_frame_only_constraint_flag = " < < vps_ptr - > profile_tier_level . general_frame_only_constraint_flag ) ;
MSG ( " general_reserved_zero_44bits = " < < vps_ptr - > profile_tier_level . general_reserved_zero_44bits ) ;
MSG ( " general_level_idc = " < < vps_ptr - > profile_tier_level . general_level_idc ) ;
MSG ( " vps_sub_layer_ordering_info_present_flag = " < < vps_ptr - > vps_sub_layer_ordering_info_present_flag ) ;
MSG_NO_NEWLINE ( " vps_max_dec_pic_buffering_minus1[]: " ) ;
for ( int i = 0 ; i < 7 ; i + + ) {
MSG_NO_NEWLINE ( " " < < vps_ptr - > vps_max_dec_pic_buffering_minus1 [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " vps_max_num_reorder_pics[]: " ) ;
for ( int i = 0 ; i < 7 ; i + + ) {
MSG_NO_NEWLINE ( " " < < vps_ptr - > vps_max_num_reorder_pics [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " vps_max_latency_increase_plus1[]: " ) ;
for ( int i = 0 ; i < 7 ; i + + ) {
MSG_NO_NEWLINE ( " " < < vps_ptr - > vps_max_latency_increase_plus1 [ i ] ) ;
}
MSG ( " " ) ;
MSG ( " vps_max_layer_id = " < < vps_ptr - > vps_max_layer_id ) ;
MSG ( " vps_num_layer_sets_minus1 = " < < vps_ptr - > vps_num_layer_sets_minus1 ) ;
MSG ( " vps_timing_info_present_flag = " < < vps_ptr - > vps_timing_info_present_flag ) ;
MSG ( " vps_num_hrd_parameters = " < < vps_ptr - > vps_num_hrd_parameters ) ;
MSG ( " vps_extension_flag = " < < vps_ptr - > vps_extension_flag ) ;
MSG ( " vps_extension_data_flag = " < < vps_ptr - > vps_extension_data_flag ) ;
MSG ( " " ) ;
}
2024-01-16 20:57:40 -05:00
void HevcVideoParser : : PrintSps ( HevcSeqParamSet * sps_ptr ) {
2023-10-20 10:39:21 -04:00
MSG ( " === hevc_sequence_parameter_set_t === " ) ;
MSG ( " sps_video_parameter_set_id = " < < sps_ptr - > sps_video_parameter_set_id ) ;
MSG ( " sps_max_sub_layers_minus1 = " < < sps_ptr - > sps_max_sub_layers_minus1 ) ;
MSG ( " sps_temporal_id_nesting_flag = " < < sps_ptr - > sps_temporal_id_nesting_flag ) ;
MSG ( " Profile tier level: " ) ;
MSG ( " general_profile_space = " < < sps_ptr - > profile_tier_level . general_profile_space ) ;
MSG ( " general_tier_flag = " < < sps_ptr - > profile_tier_level . general_tier_flag ) ;
MSG ( " general_profile_idc = " < < sps_ptr - > profile_tier_level . general_profile_idc ) ;
MSG ( " general_profile_compatibility_flag[32]: " ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
MSG_NO_NEWLINE ( " " < < sps_ptr - > profile_tier_level . general_profile_compatibility_flag [ i ] ) ;
}
MSG ( " " ) ;
MSG ( " general_progressive_source_flag = " < < sps_ptr - > profile_tier_level . general_progressive_source_flag ) ;
MSG ( " general_interlaced_source_flag = " < < sps_ptr - > profile_tier_level . general_interlaced_source_flag ) ;
MSG ( " general_non_packed_constraint_flag = " < < sps_ptr - > profile_tier_level . general_non_packed_constraint_flag ) ;
MSG ( " general_frame_only_constraint_flag = " < < sps_ptr - > profile_tier_level . general_frame_only_constraint_flag ) ;
MSG ( " general_reserved_zero_44bits = " < < sps_ptr - > profile_tier_level . general_reserved_zero_44bits ) ;
MSG ( " general_level_idc = " < < sps_ptr - > profile_tier_level . general_level_idc ) ;
MSG ( " sps_seq_parameter_set_id = " < < sps_ptr - > sps_seq_parameter_set_id ) ;
MSG ( " chroma_format_idc = " < < sps_ptr - > chroma_format_idc ) ;
MSG ( " separate_colour_plane_flag = " < < sps_ptr - > separate_colour_plane_flag ) ;
MSG ( " pic_width_in_luma_samples = " < < sps_ptr - > pic_width_in_luma_samples ) ;
MSG ( " pic_height_in_luma_samples = " < < sps_ptr - > pic_height_in_luma_samples ) ;
MSG ( " conformance_window_flag = " < < sps_ptr - > conformance_window_flag ) ;
MSG ( " conf_win_left_offset = " < < sps_ptr - > conf_win_left_offset ) ;
MSG ( " conf_win_right_offset = " < < sps_ptr - > conf_win_right_offset ) ;
MSG ( " conf_win_top_offset = " < < sps_ptr - > conf_win_top_offset ) ;
MSG ( " conf_win_bottom_offset = " < < sps_ptr - > conf_win_bottom_offset ) ;
MSG ( " bit_depth_luma_minus8 = " < < sps_ptr - > bit_depth_luma_minus8 ) ;
MSG ( " bit_depth_chroma_minus8 = " < < sps_ptr - > bit_depth_chroma_minus8 ) ;
MSG ( " log2_max_pic_order_cnt_lsb_minus4 = " < < sps_ptr - > log2_max_pic_order_cnt_lsb_minus4 ) ;
MSG ( " sps_sub_layer_ordering_info_present_flag = " < < sps_ptr - > sps_sub_layer_ordering_info_present_flag ) ;
MSG_NO_NEWLINE ( " sps_max_dec_pic_buffering_minus1[]: " ) ;
for ( int i = 0 ; i < 7 ; i + + ) {
MSG_NO_NEWLINE ( " " < < sps_ptr - > sps_max_dec_pic_buffering_minus1 [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " sps_max_num_reorder_pics[]: " ) ;
for ( int i = 0 ; i < 7 ; i + + ) {
MSG_NO_NEWLINE ( " " < < sps_ptr - > sps_max_num_reorder_pics [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " sps_max_latency_increase_plus1[]: " ) ;
for ( int i = 0 ; i < 7 ; i + + ) {
MSG_NO_NEWLINE ( " " < < sps_ptr - > sps_max_latency_increase_plus1 [ i ] ) ;
}
MSG ( " " ) ;
MSG ( " log2_min_luma_coding_block_size_minus3 = " < < sps_ptr - > log2_min_luma_coding_block_size_minus3 ) ;
MSG ( " log2_diff_max_min_luma_coding_block_size = " < < sps_ptr - > log2_diff_max_min_luma_coding_block_size ) ;
2025-03-26 08:16:36 -04:00
MSG ( " log2_min_luma_transform_block_size_minus2 = " < < sps_ptr - > log2_min_luma_transform_block_size_minus2 ) ;
MSG ( " log2_diff_max_min_luma_transform_block_size = " < < sps_ptr - > log2_diff_max_min_luma_transform_block_size ) ;
2023-10-20 10:39:21 -04:00
MSG ( " max_transform_hierarchy_depth_inter = " < < sps_ptr - > max_transform_hierarchy_depth_inter ) ;
MSG ( " max_transform_hierarchy_depth_intra = " < < sps_ptr - > max_transform_hierarchy_depth_intra ) ;
MSG ( " scaling_list_enabled_flag = " < < sps_ptr - > scaling_list_enabled_flag ) ;
MSG ( " sps_scaling_list_data_present_flag = " < < sps_ptr - > sps_scaling_list_data_present_flag ) ;
2023-10-24 16:20:56 -04:00
MSG ( " Scaling list: " ) ;
2024-01-10 11:44:07 -05:00
for ( int i = 0 ; i < HEVC_SCALING_LIST_SIZE_NUM ; i + + ) {
for ( int j = 0 ; j < HEVC_SCALING_LIST_NUM ; j + + ) {
2023-10-24 16:20:56 -04:00
MSG_NO_NEWLINE ( " scaling_list[ " < < i < < " ][ " < < j < < " ][]: " )
2024-01-10 11:44:07 -05:00
for ( int k = 0 ; k < HEVC_SCALING_LIST_MAX_INDEX ; k + + ) {
2023-10-24 16:20:56 -04:00
MSG_NO_NEWLINE ( " " < < sps_ptr - > scaling_list_data . scaling_list [ i ] [ j ] [ k ] ) ;
}
MSG ( " " ) ;
}
}
2023-10-20 10:39:21 -04:00
MSG ( " amp_enabled_flag = " < < sps_ptr - > amp_enabled_flag ) ;
MSG ( " sample_adaptive_offset_enabled_flag = " < < sps_ptr - > sample_adaptive_offset_enabled_flag ) ;
MSG ( " pcm_enabled_flag = " < < sps_ptr - > pcm_enabled_flag ) ;
MSG ( " pcm_sample_bit_depth_luma_minus1 = " < < sps_ptr - > pcm_sample_bit_depth_luma_minus1 ) ;
MSG ( " pcm_sample_bit_depth_chroma_minus1 = " < < sps_ptr - > pcm_sample_bit_depth_chroma_minus1 ) ;
MSG ( " log2_min_pcm_luma_coding_block_size_minus3 = " < < sps_ptr - > log2_min_pcm_luma_coding_block_size_minus3 ) ;
MSG ( " log2_diff_max_min_pcm_luma_coding_block_size = " < < sps_ptr - > log2_diff_max_min_pcm_luma_coding_block_size ) ;
MSG ( " pcm_loop_filter_disabled_flag = " < < sps_ptr - > pcm_loop_filter_disabled_flag ) ;
MSG ( " num_short_term_ref_pic_sets = " < < sps_ptr - > num_short_term_ref_pic_sets ) ;
if ( sps_ptr - > num_short_term_ref_pic_sets ) {
for ( int i = 0 ; i < sps_ptr - > num_short_term_ref_pic_sets ; i + + ) {
2023-10-26 11:38:46 -04:00
PrintStRps ( & sps_ptr - > st_rps [ i ] ) ;
2023-10-20 10:39:21 -04:00
}
}
MSG ( " long_term_ref_pics_present_flag = " < < sps_ptr - > long_term_ref_pics_present_flag ) ;
MSG ( " num_long_term_ref_pics_sps = " < < sps_ptr - > num_long_term_ref_pics_sps ) ;
if ( sps_ptr - > num_long_term_ref_pics_sps ) {
MSG ( " lt_ref_pic_poc_lsb_sps[%u]: " < < sps_ptr - > num_long_term_ref_pics_sps ) ;
for ( int i = 0 ; i < sps_ptr - > num_long_term_ref_pics_sps ; i + + ) {
MSG_NO_NEWLINE ( " " < < sps_ptr - > lt_ref_pic_poc_lsb_sps [ i ] ) ;
}
MSG ( " " ) ;
MSG ( " used_by_curr_pic_lt_sps_flag[%u]: " < < sps_ptr - > num_long_term_ref_pics_sps ) ;
for ( int i = 0 ; i < sps_ptr - > num_long_term_ref_pics_sps ; i + + ) {
MSG_NO_NEWLINE ( " " < < sps_ptr - > used_by_curr_pic_lt_sps_flag [ i ] ) ;
}
MSG ( " " ) ;
}
2023-10-26 11:38:46 -04:00
PrintLtRefInfo ( & sps_ptr - > lt_rps ) ;
2023-10-20 10:39:21 -04:00
MSG ( " sps_temporal_mvp_enabled_flag = " < < sps_ptr - > sps_temporal_mvp_enabled_flag ) ;
MSG ( " strong_intra_smoothing_enabled_flag = " < < sps_ptr - > strong_intra_smoothing_enabled_flag ) ;
MSG ( " vui_parameters_present_flag = " < < sps_ptr - > vui_parameters_present_flag ) ;
MSG ( " sps_extension_present_flag = " < < sps_ptr - > sps_extension_flag ) ;
MSG ( " " ) ;
}
2024-01-16 20:57:40 -05:00
void HevcVideoParser : : PrintPps ( HevcPicParamSet * pps_ptr ) {
2023-10-20 10:39:21 -04:00
MSG ( " === hevc_picture_parameter_set_t === " ) ;
MSG ( " pps_pic_parameter_set_id = " < < pps_ptr - > pps_pic_parameter_set_id ) ;
MSG ( " pps_seq_parameter_set_id = " < < pps_ptr - > pps_seq_parameter_set_id ) ;
MSG ( " dependent_slice_segments_enabled_flag = " < < pps_ptr - > dependent_slice_segments_enabled_flag ) ;
MSG ( " output_flag_present_flag = " < < pps_ptr - > output_flag_present_flag ) ;
MSG ( " num_extra_slice_header_bits = " < < pps_ptr - > num_extra_slice_header_bits ) ;
MSG ( " sign_data_hiding_enabled_flag = " < < pps_ptr - > sign_data_hiding_enabled_flag ) ;
MSG ( " cabac_init_present_flag = " < < pps_ptr - > cabac_init_present_flag ) ;
MSG ( " num_ref_idx_l0_default_active_minus1 = " < < pps_ptr - > num_ref_idx_l0_default_active_minus1 ) ;
MSG ( " num_ref_idx_l1_default_active_minus1 = " < < pps_ptr - > num_ref_idx_l1_default_active_minus1 ) ;
MSG ( " init_qp_minus26 = " < < pps_ptr - > init_qp_minus26 ) ;
MSG ( " constrained_intra_pred_flag = " < < pps_ptr - > constrained_intra_pred_flag ) ;
MSG ( " transform_skip_enabled_flag = " < < pps_ptr - > transform_skip_enabled_flag ) ;
MSG ( " cu_qp_delta_enabled_flag = " < < pps_ptr - > cu_qp_delta_enabled_flag ) ;
MSG ( " diff_cu_qp_delta_depth = " < < pps_ptr - > diff_cu_qp_delta_depth ) ;
MSG ( " pps_cb_qp_offset = " < < pps_ptr - > pps_cb_qp_offset ) ;
MSG ( " pps_cr_qp_offset = " < < pps_ptr - > pps_cr_qp_offset ) ;
MSG ( " pps_slice_chroma_qp_offsets_present_flag = " < < pps_ptr - > pps_slice_chroma_qp_offsets_present_flag ) ;
MSG ( " weighted_pred_flag = " < < pps_ptr - > weighted_pred_flag ) ;
MSG ( " weighted_bipred_flag = " < < pps_ptr - > weighted_bipred_flag ) ;
MSG ( " transquant_bypass_enabled_flag = " < < pps_ptr - > transquant_bypass_enabled_flag ) ;
MSG ( " tiles_enabled_flag = " < < pps_ptr - > tiles_enabled_flag ) ;
MSG ( " entropy_coding_sync_enabled_flag = " < < pps_ptr - > entropy_coding_sync_enabled_flag ) ;
MSG ( " num_tile_columns_minus1 = " < < pps_ptr - > num_tile_columns_minus1 ) ;
MSG ( " num_tile_rows_minus1 = " < < pps_ptr - > num_tile_rows_minus1 ) ;
MSG ( " uniform_spacing_flag = " < < pps_ptr - > uniform_spacing_flag ) ;
if ( ! pps_ptr - > uniform_spacing_flag ) {
MSG_NO_NEWLINE ( " column_width_minus1[ " < < pps_ptr - > num_tile_columns_minus1 < < " ] " ) ;
for ( int i = 0 ; i < pps_ptr - > num_tile_columns_minus1 ; i + + ) {
MSG_NO_NEWLINE ( " " < < pps_ptr - > column_width_minus1 [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " row_height_minus1[ " < < pps_ptr - > num_tile_rows_minus1 < < " ] " ) ;
for ( int i = 0 ; i < pps_ptr - > num_tile_rows_minus1 ; i + + ) {
MSG_NO_NEWLINE ( " " < < pps_ptr - > row_height_minus1 [ i ] ) ;
}
MSG ( " " ) ;
}
MSG ( " loop_filter_across_tiles_enabled_flag = " < < pps_ptr - > loop_filter_across_tiles_enabled_flag ) ;
MSG ( " pps_loop_filter_across_slices_enabled_flag = " < < pps_ptr - > pps_loop_filter_across_slices_enabled_flag ) ;
MSG ( " deblocking_filter_control_present_flag = " < < pps_ptr - > deblocking_filter_control_present_flag ) ;
MSG ( " deblocking_filter_override_enabled_flag = " < < pps_ptr - > deblocking_filter_override_enabled_flag ) ;
MSG ( " pps_deblocking_filter_disabled_flag = " < < pps_ptr - > pps_deblocking_filter_disabled_flag ) ;
MSG ( " pps_beta_offset_div2 = " < < pps_ptr - > pps_beta_offset_div2 ) ;
MSG ( " pps_tc_offset_div2 = " < < pps_ptr - > pps_tc_offset_div2 ) ;
MSG ( " pps_scaling_list_data_present_flag = " < < pps_ptr - > pps_scaling_list_data_present_flag ) ;
2023-10-24 16:20:56 -04:00
MSG ( " Scaling list: " ) ;
2024-01-10 11:44:07 -05:00
for ( int i = 0 ; i < HEVC_SCALING_LIST_SIZE_NUM ; i + + ) {
for ( int j = 0 ; j < HEVC_SCALING_LIST_NUM ; j + + ) {
2023-10-24 16:20:56 -04:00
MSG_NO_NEWLINE ( " scaling_list[ " < < i < < " ][ " < < j < < " ][]: " )
2024-01-10 11:44:07 -05:00
for ( int k = 0 ; k < HEVC_SCALING_LIST_MAX_INDEX ; k + + ) {
2023-10-24 16:20:56 -04:00
MSG_NO_NEWLINE ( " " < < pps_ptr - > scaling_list_data . scaling_list [ i ] [ j ] [ k ] ) ;
}
MSG ( " " ) ;
}
}
2023-10-20 10:39:21 -04:00
MSG ( " lists_modification_present_flag = " < < pps_ptr - > lists_modification_present_flag ) ;
MSG ( " log2_parallel_merge_level_minus2 = " < < pps_ptr - > log2_parallel_merge_level_minus2 ) ;
MSG ( " slice_segment_header_extension_present_flag = " < < pps_ptr - > slice_segment_header_extension_present_flag ) ;
2023-10-26 11:38:46 -04:00
MSG ( " pps_extension_present_flag = " < < pps_ptr - > pps_extension_present_flag ) ;
2023-10-20 10:39:21 -04:00
MSG ( " " ) ;
}
2024-01-10 11:44:07 -05:00
void HevcVideoParser : : PrintSliceSegHeader ( HevcSliceSegHeader * slice_header_ptr ) {
2023-10-20 10:39:21 -04:00
MSG ( " === hevc_slice_segment_header_t === " ) ;
MSG ( " first_slice_segment_in_pic_flag = " < < slice_header_ptr - > first_slice_segment_in_pic_flag ) ;
MSG ( " no_output_of_prior_pics_flag = " < < slice_header_ptr - > no_output_of_prior_pics_flag ) ;
MSG ( " slice_pic_parameter_set_id = " < < slice_header_ptr - > slice_pic_parameter_set_id ) ;
MSG ( " dependent_slice_segment_flag = " < < slice_header_ptr - > dependent_slice_segment_flag ) ;
MSG ( " slice_segment_address = " < < slice_header_ptr - > slice_segment_address ) ;
MSG ( " slice_type = " < < slice_header_ptr - > slice_type ) ;
MSG ( " pic_output_flag = " < < slice_header_ptr - > pic_output_flag ) ;
MSG ( " colour_plane_id = " < < slice_header_ptr - > colour_plane_id ) ;
MSG ( " slice_pic_order_cnt_lsb = " < < slice_header_ptr - > slice_pic_order_cnt_lsb ) ;
MSG ( " short_term_ref_pic_set_sps_flag = " < < slice_header_ptr - > short_term_ref_pic_set_sps_flag ) ;
MSG ( " short_term_ref_pic_set_idx = " < < slice_header_ptr - > short_term_ref_pic_set_idx ) ;
2023-10-26 11:38:46 -04:00
PrintStRps ( & slice_header_ptr - > st_rps ) ;
2023-10-20 10:39:21 -04:00
MSG ( " num_long_term_sps = " < < slice_header_ptr - > num_long_term_sps ) ;
MSG ( " num_long_term_pics = " < < slice_header_ptr - > num_long_term_pics ) ;
MSG_NO_NEWLINE ( " lt_idx_sps[]: " ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
MSG_NO_NEWLINE ( " " < < slice_header_ptr - > lt_idx_sps [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " poc_lsb_lt[]: " ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
MSG_NO_NEWLINE ( " " < < slice_header_ptr - > poc_lsb_lt [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " used_by_curr_pic_lt_flag[]: " ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
MSG_NO_NEWLINE ( " " < < slice_header_ptr - > used_by_curr_pic_lt_flag [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " delta_poc_msb_present_flag[]: " ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
MSG_NO_NEWLINE ( " " < < slice_header_ptr - > delta_poc_msb_present_flag [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " delta_poc_msb_cycle_lt[]: " ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
MSG_NO_NEWLINE ( " " < < slice_header_ptr - > delta_poc_msb_cycle_lt [ i ] ) ;
}
MSG ( " " ) ;
2023-10-26 11:38:46 -04:00
PrintLtRefInfo ( & slice_header_ptr - > lt_rps ) ;
2023-10-20 10:39:21 -04:00
MSG ( " slice_temporal_mvp_enabled_flag = " < < slice_header_ptr - > slice_temporal_mvp_enabled_flag ) ;
MSG ( " slice_sao_luma_flag = " < < slice_header_ptr - > slice_sao_luma_flag ) ;
MSG ( " slice_sao_chroma_flag = " < < slice_header_ptr - > slice_sao_chroma_flag ) ;
2023-10-26 11:38:46 -04:00
MSG ( " num_ref_idx_active_override_flag = " < < slice_header_ptr - > num_ref_idx_active_override_flag ) ;
MSG ( " num_ref_idx_l0_active_minus1 = " < < slice_header_ptr - > num_ref_idx_l0_active_minus1 ) ;
MSG ( " num_ref_idx_l1_active_minus1 = " < < slice_header_ptr - > num_ref_idx_l1_active_minus1 ) ;
2023-10-20 10:39:21 -04:00
MSG ( " ref_pic_list_modification_flag_l0 = " < < slice_header_ptr - > ref_pic_list_modification_flag_l0 ) ;
MSG ( " ref_pic_list_modification_flag_l1 = " < < slice_header_ptr - > ref_pic_list_modification_flag_l1 ) ;
MSG_NO_NEWLINE ( " list_entry_l0[]: " ) ;
2023-10-26 11:38:46 -04:00
for ( int i = 0 ; i < 16 ; i + + ) {
2023-10-20 10:39:21 -04:00
MSG_NO_NEWLINE ( " " < < slice_header_ptr - > list_entry_l0 [ i ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " list_entry_l1[]: " ) ;
2023-10-26 11:38:46 -04:00
for ( int i = 0 ; i < 16 ; i + + ) {
2023-10-20 10:39:21 -04:00
MSG_NO_NEWLINE ( " " < < slice_header_ptr - > list_entry_l1 [ i ] ) ;
}
MSG ( " " ) ;
MSG ( " mvd_l1_zero_flag = " < < slice_header_ptr - > mvd_l1_zero_flag ) ;
MSG ( " cabac_init_flag = " < < slice_header_ptr - > cabac_init_flag ) ;
MSG ( " collocated_from_l0_flag = " < < slice_header_ptr - > collocated_from_l0_flag ) ;
MSG ( " collocated_ref_idx = " < < slice_header_ptr - > collocated_ref_idx ) ;
2023-10-26 11:38:46 -04:00
MSG ( " five_minus_max_num_merge_cand = " < < slice_header_ptr - > five_minus_max_num_merge_cand ) ;
MSG ( " slice_qp_delta = " < < slice_header_ptr - > slice_qp_delta ) ;
MSG ( " slice_cb_qp_offset = " < < slice_header_ptr - > slice_cb_qp_offset ) ;
MSG ( " slice_cr_qp_offset = " < < slice_header_ptr - > slice_cr_qp_offset ) ;
2024-05-31 13:14:02 -04:00
MSG ( " cu_chroma_qp_offset_enabled_flag = " < < static_cast < uint32_t > ( slice_header_ptr - > cu_chroma_qp_offset_enabled_flag ) ) ;
2023-10-26 11:38:46 -04:00
MSG ( " deblocking_filter_override_flag = " < < slice_header_ptr - > deblocking_filter_override_flag ) ;
MSG ( " slice_deblocking_filter_disabled_flag = " < < slice_header_ptr - > slice_deblocking_filter_disabled_flag ) ;
MSG ( " slice_beta_offset_div2 = " < < slice_header_ptr - > slice_beta_offset_div2 ) ;
MSG ( " slice_tc_offset_div2 = " < < slice_header_ptr - > slice_tc_offset_div2 ) ;
MSG ( " slice_loop_filter_across_slices_enabled_flag = " < < slice_header_ptr - > slice_loop_filter_across_slices_enabled_flag ) ;
MSG ( " num_entry_point_offsets = " < < slice_header_ptr - > num_entry_point_offsets ) ;
MSG ( " offset_len_minus1 = " < < slice_header_ptr - > offset_len_minus1 ) ;
MSG ( " slice_segment_header_extension_length = " < < slice_header_ptr - > slice_segment_header_extension_length ) ;
2023-10-20 10:39:21 -04:00
MSG ( " " ) ;
}
2023-10-24 16:20:56 -04:00
2024-01-16 20:57:40 -05:00
void HevcVideoParser : : PrintStRps ( HevcShortTermRps * rps_ptr ) {
2023-10-24 16:20:56 -04:00
MSG ( " ==== Short-term reference picture set ===== " )
2024-05-31 13:14:02 -04:00
MSG ( " inter_ref_pic_set_prediction_flag = " < < static_cast < uint32_t > ( rps_ptr - > inter_ref_pic_set_prediction_flag ) ) ;
2023-10-24 16:20:56 -04:00
MSG ( " delta_idx_minus1 = " < < rps_ptr - > delta_idx_minus1 ) ;
2024-05-31 13:14:02 -04:00
MSG ( " delta_rps_sign = " < < static_cast < uint32_t > ( rps_ptr - > delta_rps_sign ) ) ;
2023-10-24 16:20:56 -04:00
MSG ( " abs_delta_rps_minus1 = " < < rps_ptr - > abs_delta_rps_minus1 ) ;
MSG_NO_NEWLINE ( " rps->used_by_curr_pic_flag[]: " ) ;
for ( int j = 0 ; j < 16 ; j + + ) {
2024-05-31 13:14:02 -04:00
MSG_NO_NEWLINE ( " " < < static_cast < uint32_t > ( rps_ptr - > used_by_curr_pic_flag [ j ] ) ) ;
2023-10-24 16:20:56 -04:00
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " use_delta_flag[]: " ) ;
for ( int j = 0 ; j < 16 ; j + + ) {
2024-05-31 13:14:02 -04:00
MSG_NO_NEWLINE ( " " < < static_cast < uint32_t > ( rps_ptr - > use_delta_flag [ j ] ) ) ;
2023-10-24 16:20:56 -04:00
}
MSG ( " " ) ;
MSG ( " num_negative_pics = " < < rps_ptr - > num_negative_pics ) ;
MSG ( " num_positive_pics = " < < rps_ptr - > num_positive_pics ) ;
2023-12-04 11:53:26 -05:00
MSG ( " num_of_delta_pocs = " < < rps_ptr - > num_of_delta_pocs ) ;
2023-10-24 16:20:56 -04:00
MSG_NO_NEWLINE ( " delta_poc_s0_minus1[]: " ) ;
for ( int j = 0 ; j < 16 ; j + + ) {
MSG_NO_NEWLINE ( " " < < rps_ptr - > delta_poc_s0_minus1 [ j ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " used_by_curr_pic_s0_flag[]: " ) ;
for ( int j = 0 ; j < 16 ; j + + ) {
2024-05-31 13:14:02 -04:00
MSG_NO_NEWLINE ( " " < < static_cast < uint32_t > ( rps_ptr - > used_by_curr_pic_s0_flag [ j ] ) ) ;
2023-10-24 16:20:56 -04:00
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " delta_poc_s1_minus1[]: " ) ;
for ( int j = 0 ; j < 16 ; j + + ) {
MSG_NO_NEWLINE ( " " < < rps_ptr - > delta_poc_s1_minus1 [ j ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " used_by_curr_pic_s1_flag[]: " ) ;
for ( int j = 0 ; j < 16 ; j + + ) {
2024-05-31 13:14:02 -04:00
MSG_NO_NEWLINE ( " " < < static_cast < uint32_t > ( rps_ptr - > used_by_curr_pic_s1_flag [ j ] ) ) ;
2023-10-24 16:20:56 -04:00
}
MSG ( " " ) ;
2023-12-04 11:53:26 -05:00
MSG_NO_NEWLINE ( " delta_poc_s0[16]: " ) ;
2023-10-24 16:20:56 -04:00
for ( int j = 0 ; j < 16 ; j + + ) {
2023-12-04 11:53:26 -05:00
MSG_NO_NEWLINE ( " " < < rps_ptr - > delta_poc_s0 [ j ] ) ;
2023-10-24 16:20:56 -04:00
}
MSG ( " " ) ;
2023-12-04 11:53:26 -05:00
MSG_NO_NEWLINE ( " delta_poc_s1[16]: " ) ;
2023-10-24 16:20:56 -04:00
for ( int j = 0 ; j < 16 ; j + + ) {
2023-12-04 11:53:26 -05:00
MSG_NO_NEWLINE ( " " < < rps_ptr - > delta_poc_s1 [ j ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " used_by_curr_pic_s0[16]: " ) ;
for ( int j = 0 ; j < 16 ; j + + ) {
2024-05-31 13:14:02 -04:00
MSG_NO_NEWLINE ( " " < < static_cast < uint32_t > ( rps_ptr - > used_by_curr_pic_s0 [ j ] ) ) ;
2023-12-04 11:53:26 -05:00
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " used_by_curr_pic_s1[16]: " ) ;
for ( int j = 0 ; j < 16 ; j + + ) {
2024-05-31 13:14:02 -04:00
MSG_NO_NEWLINE ( " " < < static_cast < uint32_t > ( rps_ptr - > used_by_curr_pic_s1 [ j ] ) ) ;
2023-10-24 16:20:56 -04:00
}
MSG ( " " ) ;
}
2023-10-26 11:38:46 -04:00
2024-01-16 20:57:40 -05:00
void HevcVideoParser : : PrintLtRefInfo ( HevcLongTermRps * lt_info_ptr ) {
2023-10-26 11:38:46 -04:00
MSG ( " ==== Long-term reference picture info ===== " ) ;
MSG ( " num_of_pics = " < < lt_info_ptr - > num_of_pics ) ;
MSG_NO_NEWLINE ( " pocs[]: " ) ;
for ( int j = 0 ; j < 32 ; j + + ) {
MSG_NO_NEWLINE ( " " < < lt_info_ptr - > pocs [ j ] ) ;
}
MSG ( " " ) ;
MSG_NO_NEWLINE ( " used_by_curr_pic[]: " ) ;
for ( int j = 0 ; j < 32 ; j + + ) {
MSG_NO_NEWLINE ( " " < < lt_info_ptr - > used_by_curr_pic [ j ] ) ;
}
MSG ( " " ) ;
}
2024-05-31 13:14:02 -04:00
void HevcVideoParser : : PrintDpb ( ) {
uint32_t i ;
MSG ( " ======================= " ) ;
MSG ( " DPB buffer content: " ) ;
MSG ( " ======================= " ) ;
MSG ( " dpb_size = " < < dpb_buffer_ . dpb_size ) ;
MSG ( " num_pics_needed_for_output = " < < dpb_buffer_ . num_pics_needed_for_output ) ;
MSG ( " dpb_fullness = " < < dpb_buffer_ . dpb_fullness ) ;
MSG ( " Frame buffer store: " ) ;
for ( i = 0 ; i < HEVC_MAX_DPB_FRAMES ; i + + ) {
HevcPicInfo * p_buf = & dpb_buffer_ . frame_buffer_list [ i ] ;
MSG ( " Frame buffer " < < i < < " : pic_idx = " < < p_buf - > pic_idx < < " , dec_buf_idx = " < < p_buf - > dec_buf_idx < < " , pic_order_cnt = " < < p_buf - > pic_order_cnt < < " , slice_pic_order_cnt_lsb = " < < p_buf - > slice_pic_order_cnt_lsb < < " , decode_order_count = " < < p_buf - > decode_order_count < < " , is_reference = " < < p_buf - > is_reference < < " , use_status = " < < p_buf - > use_status < < " , pic_output_flag = " < < p_buf - > pic_output_flag ) ;
}
MSG ( " " ) ;
MSG ( " Decode buffer pool: " ) ;
for ( i = 0 ; i < dec_buf_pool_size_ ; i + + ) {
DecodeFrameBuffer * p_dec_buf = & decode_buffer_pool_ [ i ] ;
2024-07-25 16:53:20 -04:00
MSG ( " Decode buffer " < < i < < " : use_status = " < < p_dec_buf - > use_status < < " , pic_order_cnt = " < < p_dec_buf - > pic_order_cnt < < " , pts = " < < p_dec_buf - > pts ) ;
2024-05-31 13:14:02 -04:00
}
MSG ( " num_output_pics_ = " < < num_output_pics_ ) ;
if ( num_output_pics_ ) {
MSG ( " output_pic_list: " ) ;
for ( i = 0 ; i < num_output_pics_ ; i + + ) {
MSG_NO_NEWLINE ( output_pic_list_ [ i ] < < " , " ) ;
}
MSG ( " " ) ;
}
}
void HevcVideoParser : : PrintVappiBufInfo ( ) {
RocdecHevcPicParams * p_pic_param = & dec_pic_params_ . pic_params . hevc ;
MSG ( " ======================= " ) ;
MSG ( " VAAPI Buffer Info: " ) ;
MSG ( " ======================= " ) ;
MSG ( " Current buffer: " ) ;
MSG_NO_NEWLINE ( " pic_idx = " < < p_pic_param - > curr_pic . pic_idx < < " , poc = " < < p_pic_param - > curr_pic . poc ) ;
MSG ( " , flags = 0x " < < std : : hex < < p_pic_param - > curr_pic . flags ) ;
MSG ( std : : dec ) ;
MSG ( " Reference pictures: " ) ;
for ( int i = 0 ; i < 15 ; i + + ) {
RocdecHevcPicture * p_ref_pic = & p_pic_param - > ref_frames [ i ] ;
MSG_NO_NEWLINE ( " Ref pic " < < i < < " : " < < " pic_idx = " < < p_ref_pic - > pic_idx < < " , poc = " < < p_ref_pic - > poc ) ;
MSG ( " , flags = 0x " < < std : : hex < < p_ref_pic - > flags ) ;
MSG_NO_NEWLINE ( std : : dec ) ;
}
MSG ( " Slice ref lists: " )
for ( int slice_index = 0 ; slice_index < num_slices_ ; slice_index + + ) {
RocdecHevcSliceParams * p_slice_param = & slice_param_list_ [ slice_index ] ;
HevcSliceInfo * p_slice_info = & slice_info_list_ [ slice_index ] ;
MSG ( " Slice " < < slice_index < < " ref list 0: " ) ;
for ( int i = 0 ; i < = p_slice_info - > slice_header . num_ref_idx_l0_active_minus1 ; i + + ) {
MSG ( " Index " < < i < < " : " < < static_cast < uint32_t > ( p_slice_param - > ref_pic_list [ 0 ] [ i ] ) ) ;
}
if ( p_slice_info - > slice_header . slice_type = = HEVC_SLICE_TYPE_B ) {
MSG ( " Slice " < < slice_index < < " ref list 1: " ) ;
for ( int i = 0 ; i < = p_slice_info - > slice_header . num_ref_idx_l1_active_minus1 ; i + + ) {
MSG ( " Index " < < i < < " : " < < static_cast < uint32_t > ( p_slice_param - > ref_pic_list [ 1 ] [ i ] ) ) ;
}
}
MSG ( " " ) ;
}
}
2023-10-20 10:39:21 -04:00
# endif // DBGINFO