2024-03-26 15:59:15 -07:00
/*
Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
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 <algorithm>
# include "av1_parser.h"
Av1VideoParser : : Av1VideoParser ( ) {
2024-06-10 12:07:23 -04:00
seen_frame_header_ = 0 ;
2024-03-26 15:59:15 -07:00
}
Av1VideoParser : : ~ Av1VideoParser ( ) {
}
rocDecStatus Av1VideoParser : : Initialize ( RocdecParserParams * p_params ) {
return RocVideoParser : : Initialize ( p_params ) ;
}
rocDecStatus Av1VideoParser : : UnInitialize ( ) {
return ROCDEC_SUCCESS ;
}
rocDecStatus Av1VideoParser : : ParseVideoData ( RocdecSourceDataPacket * p_data ) {
2024-06-10 12:07:23 -04:00
if ( p_data - > payload & & p_data - > payload_size ) {
if ( ParsePictureData ( p_data - > payload , p_data - > payload_size ) ! = PARSER_OK ) {
ERR ( STR ( " Parser failed! " ) ) ;
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 ;
}
return ROCDEC_SUCCESS ;
2024-04-03 15:04:18 -04:00
}
2024-06-10 12:07:23 -04:00
ParserResult Av1VideoParser : : ParsePictureData ( const uint8_t * p_stream , uint32_t pic_data_size ) {
ParserResult ret = PARSER_OK ;
pic_data_buffer_ptr_ = ( uint8_t * ) p_stream ;
pic_data_size_ = pic_data_size ;
curr_byte_offset_ = 0 ;
while ( ReadObuHeaderAndSize ( ) ! = PARSER_EOF ) {
switch ( obu_header_ . obu_type ) {
case kObuTemporalDelimiter : {
seen_frame_header_ = 0 ;
break ;
}
case kObuSequenceHeader : {
ParseSequenceHeaderObu ( pic_data_buffer_ptr_ + obu_byte_offset_ , obu_size_ ) ;
break ;
}
case kObuFrameHeader : {
if ( seen_frame_header_ ! = 0 ) {
ERR ( " If obu_type is equal to OBU_FRAME_HEADER, it is a requirement of bitstream conformance that SeenFrameHeader is equal to 0. " ) ;
return PARSER_INVALID_ARG ;
}
int bytes_parsed ;
if ( ( ret = ParseFrameHeaderObu ( pic_data_buffer_ptr_ + obu_byte_offset_ , obu_size_ , & bytes_parsed ) ) ! = PARSER_OK ) {
return ret ;
}
break ;
}
case kObuRedundantFrameHeader : {
if ( seen_frame_header_ ! = 1 ) {
ERR ( " If obu_type is equal to OBU_REDUNDANT_FRAME_HEADER, it is a requirement of bitstream conformance that SeenFrameHeader is equal to 1. " ) ;
return PARSER_INVALID_ARG ;
}
int bytes_parsed ;
if ( ( ret = ParseFrameHeaderObu ( pic_data_buffer_ptr_ + obu_byte_offset_ , obu_size_ , & bytes_parsed ) ) ! = PARSER_OK ) {
return ret ;
}
break ;
}
case kObuFrame : {
int bytes_parsed ;
if ( ( ret = ParseFrameHeaderObu ( pic_data_buffer_ptr_ + obu_byte_offset_ , obu_size_ , & bytes_parsed ) ) ! = PARSER_OK ) {
return ret ;
}
obu_byte_offset_ + = bytes_parsed ;
if ( obu_size_ > bytes_parsed ) {
obu_size_ - = bytes_parsed ;
ParseTileGroupObu ( pic_data_buffer_ptr_ + obu_byte_offset_ , obu_size_ ) ;
} else {
ERR ( " Frame OBU size error. " ) ;
return PARSER_OUT_OF_RANGE ;
}
break ;
}
case kObuTileGroup : {
ParseTileGroupObu ( pic_data_buffer_ptr_ + obu_byte_offset_ , obu_size_ ) ;
break ;
}
default :
break ;
}
} ;
return PARSER_OK ;
}
ParserResult Av1VideoParser : : ParseObuHeader ( const uint8_t * p_stream ) {
size_t offset = 0 ;
obu_header_ . size = 1 ;
if ( Parser : : GetBit ( p_stream , offset ) ! = 0 ) {
ERR ( " Syntax error: obu_forbidden_bit must be set to 0. " ) ;
return PARSER_INVALID_ARG ;
}
obu_header_ . obu_type = Parser : : ReadBits ( p_stream , offset , 4 ) ;
obu_header_ . obu_extension_flag = Parser : : GetBit ( p_stream , offset ) ;
obu_header_ . obu_has_size_field = Parser : : GetBit ( p_stream , offset ) ;
if ( ! obu_header_ . obu_has_size_field ) {
ERR ( " Syntax error: Section 5.2: obu_has_size_field must be equal to 1. " ) ;
return PARSER_INVALID_ARG ;
}
if ( Parser : : GetBit ( p_stream , offset ) ! = 0 ) {
ERR ( " Syntax error: obu_reserved_1bit must be set to 0. " ) ;
return PARSER_INVALID_ARG ;
}
if ( obu_header_ . obu_extension_flag ) {
obu_header_ . size + = 1 ;
obu_header_ . temporal_id = Parser : : ReadBits ( p_stream , offset , 3 ) ;
obu_header_ . spatial_id = Parser : : ReadBits ( p_stream , offset , 2 ) ;
if ( Parser : : ReadBits ( p_stream , offset , 3 ) ! = 0 ) {
ERR ( " Syntax error: extension_header_reserved_3bits must be set to 0. \n " ) ;
return PARSER_INVALID_ARG ;
}
}
return PARSER_OK ;
}
ParserResult Av1VideoParser : : ReadObuHeaderAndSize ( ) {
ParserResult ret = PARSER_OK ;
if ( curr_byte_offset_ > = pic_data_size_ ) {
return PARSER_EOF ;
}
uint8_t * p_stream = pic_data_buffer_ptr_ + curr_byte_offset_ ;
if ( ( ret = ParseObuHeader ( p_stream ) ) ! = PARSER_OK ) {
return ret ;
}
curr_byte_offset_ + = obu_header_ . size ;
p_stream + = obu_header_ . size ;
uint32_t bytes_read ;
obu_size_ = ReadLeb128 ( p_stream , & bytes_read ) ;
obu_byte_offset_ = curr_byte_offset_ + bytes_read ;
curr_byte_offset_ = obu_byte_offset_ + obu_size_ ;
return PARSER_OK ;
}
void Av1VideoParser : : ParseSequenceHeaderObu ( uint8_t * p_stream , size_t size ) {
2024-04-03 15:04:18 -04:00
Av1SequenceHeader * p_seq_header = & seq_header_ ;
size_t offset = 0 ; // current bit offset
memset ( p_seq_header , 0 , sizeof ( Av1SequenceHeader ) ) ;
p_seq_header - > seq_profile = Parser : : ReadBits ( p_stream , offset , 3 ) ;
p_seq_header - > still_picture = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > reduced_still_picture_header = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > reduced_still_picture_header ) {
p_seq_header - > timing_info_present_flag = 0 ;
p_seq_header - > decoder_model_info_present_flag = 0 ;
p_seq_header - > initial_display_delay_present_flag = 0 ;
p_seq_header - > operating_points_cnt_minus_1 = 0 ;
p_seq_header - > operating_point_idc [ 0 ] = 0 ;
p_seq_header - > seq_level_idx [ 0 ] = Parser : : ReadBits ( p_stream , offset , 5 ) ;
p_seq_header - > seq_tier [ 0 ] = 0 ;
p_seq_header - > decoder_model_present_for_this_op [ 0 ] = 0 ;
p_seq_header - > initial_display_delay_present_for_this_op [ 0 ] = 0 ;
} else {
p_seq_header - > timing_info_present_flag = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > timing_info_present_flag ) {
// timing_info()
p_seq_header - > timing_info . num_units_in_display_tick = Parser : : ReadBits ( p_stream , offset , 32 ) ;
p_seq_header - > timing_info . time_scale = Parser : : ReadBits ( p_stream , offset , 32 ) ;
p_seq_header - > timing_info . equal_picture_interval = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > timing_info . equal_picture_interval ) {
p_seq_header - > timing_info . num_ticks_per_picture_minus_1 = ReadUVLC ( p_stream , offset ) ;
}
p_seq_header - > decoder_model_info_present_flag = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > decoder_model_info_present_flag ) {
p_seq_header - > decoder_model_info . buffer_delay_length_minus_1 = Parser : : ReadBits ( p_stream , offset , 5 ) ;
p_seq_header - > decoder_model_info . num_units_in_decoding_tick = Parser : : ReadBits ( p_stream , offset , 32 ) ;
p_seq_header - > decoder_model_info . buffer_removal_time_length_minus_1 = Parser : : ReadBits ( p_stream , offset , 5 ) ;
p_seq_header - > decoder_model_info . frame_presentation_time_length_minus_1 = Parser : : ReadBits ( p_stream , offset , 5 ) ;
}
} else {
p_seq_header - > decoder_model_info_present_flag = 0 ;
}
p_seq_header - > initial_display_delay_present_flag = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > operating_points_cnt_minus_1 = Parser : : ReadBits ( p_stream , offset , 5 ) ;
for ( int i = 0 ; i < p_seq_header - > operating_points_cnt_minus_1 + 1 ; i + + ) {
p_seq_header - > operating_point_idc [ i ] = Parser : : ReadBits ( p_stream , offset , 12 ) ;
p_seq_header - > seq_level_idx [ i ] = Parser : : ReadBits ( p_stream , offset , 5 ) ;
if ( p_seq_header - > seq_level_idx [ i ] > 7 ) {
p_seq_header - > seq_tier [ i ] = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_seq_header - > seq_tier [ i ] = 0 ;
}
if ( p_seq_header - > decoder_model_info_present_flag ) {
p_seq_header - > decoder_model_present_for_this_op [ i ] = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > decoder_model_present_for_this_op [ i ] ) {
p_seq_header - > operating_parameters_info [ i ] . decoder_buffer_delay = Parser : : ReadBits ( p_stream , offset , p_seq_header - > decoder_model_info . buffer_delay_length_minus_1 + 1 ) ;
p_seq_header - > operating_parameters_info [ i ] . encoder_buffer_delay = Parser : : ReadBits ( p_stream , offset , p_seq_header - > decoder_model_info . buffer_delay_length_minus_1 + 1 ) ;
p_seq_header - > operating_parameters_info [ i ] . low_delay_mode_flag = Parser : : GetBit ( p_stream , offset ) ;
}
} else {
p_seq_header - > decoder_model_present_for_this_op [ i ] = 0 ;
}
if ( p_seq_header - > initial_display_delay_present_flag ) {
p_seq_header - > initial_display_delay_present_for_this_op [ i ] = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > initial_display_delay_present_for_this_op [ i ] ) {
p_seq_header - > initial_display_delay_minus_1 [ i ] = Parser : : ReadBits ( p_stream , offset , 4 ) ;
}
}
}
}
// Todo: Choose operating point.
p_seq_header - > frame_width_bits_minus_1 = Parser : : ReadBits ( p_stream , offset , 4 ) ;
p_seq_header - > frame_height_bits_minus_1 = Parser : : ReadBits ( p_stream , offset , 4 ) ;
p_seq_header - > max_frame_width_minus_1 = Parser : : ReadBits ( p_stream , offset , p_seq_header - > frame_width_bits_minus_1 + 1 ) ;
p_seq_header - > max_frame_height_minus_1 = Parser : : ReadBits ( p_stream , offset , p_seq_header - > frame_height_bits_minus_1 + 1 ) ;
if ( p_seq_header - > reduced_still_picture_header ) {
p_seq_header - > frame_id_numbers_present_flag = 0 ;
} else {
p_seq_header - > frame_id_numbers_present_flag = Parser : : GetBit ( p_stream , offset ) ;
}
if ( p_seq_header - > frame_id_numbers_present_flag ) {
p_seq_header - > delta_frame_id_length_minus_2 = Parser : : ReadBits ( p_stream , offset , 4 ) ;
p_seq_header - > additional_frame_id_length_minus_1 = Parser : : ReadBits ( p_stream , offset , 3 ) ;
}
p_seq_header - > use_128x128_superblock = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > enable_filter_intra = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > enable_intra_edge_filter = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > reduced_still_picture_header ) {
p_seq_header - > enable_interintra_compound = 0 ;
p_seq_header - > enable_masked_compound = 0 ;
p_seq_header - > enable_warped_motion = 0 ;
p_seq_header - > enable_dual_filter = 0 ;
p_seq_header - > enable_order_hint = 0 ;
p_seq_header - > enable_jnt_comp = 0 ;
p_seq_header - > enable_ref_frame_mvs = 0 ;
p_seq_header - > seq_force_screen_content_tools = SELECT_SCREEN_CONTENT_TOOLS ;
p_seq_header - > seq_force_integer_mv = SELECT_INTEGER_MV ;
p_seq_header - > order_hint_bits = 0 ;
} else {
p_seq_header - > enable_interintra_compound = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > enable_masked_compound = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > enable_warped_motion = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > enable_dual_filter = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > enable_order_hint = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > enable_order_hint ) {
p_seq_header - > enable_jnt_comp = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > enable_ref_frame_mvs = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_seq_header - > enable_jnt_comp = 0 ;
p_seq_header - > enable_ref_frame_mvs = 0 ;
}
p_seq_header - > seq_choose_screen_content_tools = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > seq_choose_screen_content_tools ) {
p_seq_header - > seq_force_screen_content_tools = SELECT_SCREEN_CONTENT_TOOLS ;
} else {
p_seq_header - > seq_force_screen_content_tools = Parser : : GetBit ( p_stream , offset ) ;
}
if ( p_seq_header - > seq_force_screen_content_tools > 0 ) {
p_seq_header - > seq_choose_integer_mv = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > seq_choose_integer_mv ) {
p_seq_header - > seq_force_integer_mv = SELECT_INTEGER_MV ;
} else {
p_seq_header - > seq_force_integer_mv = Parser : : GetBit ( p_stream , offset ) ;
}
} else {
p_seq_header - > seq_force_integer_mv = SELECT_INTEGER_MV ;
}
if ( p_seq_header - > enable_order_hint ) {
p_seq_header - > order_hint_bits_minus_1 = Parser : : ReadBits ( p_stream , offset , 3 ) ;
p_seq_header - > order_hint_bits = p_seq_header - > order_hint_bits_minus_1 + 1 ;
} else {
p_seq_header - > order_hint_bits = 0 ;
}
}
p_seq_header - > enable_superres = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > enable_cdef = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > enable_restoration = Parser : : GetBit ( p_stream , offset ) ;
ParseColorConfig ( p_stream , offset , p_seq_header ) ;
p_seq_header - > film_grain_params_present = Parser : : GetBit ( p_stream , offset ) ;
}
2024-06-10 12:07:23 -04:00
ParserResult Av1VideoParser : : ParseFrameHeaderObu ( uint8_t * p_stream , size_t size , int * p_bytes_parsed ) {
if ( seen_frame_header_ = = 1 ) {
// frame_header_copy(). Use the existing frame_header_obu
} else {
seen_frame_header_ = 1 ;
ParserResult ret ;
if ( ( ret = ParseUncompressedHeader ( p_stream , size , p_bytes_parsed ) ) ! = PARSER_OK ) {
return ret ;
}
if ( frame_header_ . show_existing_frame ) {
// decode_frame_wrapup()
seen_frame_header_ = 0 ;
} else {
tile_num_ = 0 ;
seen_frame_header_ = 1 ;
}
}
return PARSER_OK ;
}
ParserResult Av1VideoParser : : ParseUncompressedHeader ( uint8_t * p_stream , size_t size , int * p_bytes_parsed ) {
2024-04-11 09:01:54 -04:00
size_t offset = 0 ; // current bit offset
Av1SequenceHeader * p_seq_header = & seq_header_ ;
Av1FrameHeader * p_frame_header = & frame_header_ ;
uint32_t frame_id_len = 0 ;
uint32_t all_frames = ( 1 < < NUM_REF_FRAMES ) - 1 ;
int i ;
memset ( p_frame_header , 0 , sizeof ( Av1FrameHeader ) ) ;
if ( p_seq_header - > frame_id_numbers_present_flag ) {
frame_id_len = p_seq_header - > additional_frame_id_length_minus_1 + p_seq_header - > delta_frame_id_length_minus_2 + 3 ;
}
if ( p_seq_header - > reduced_still_picture_header ) {
p_frame_header - > show_existing_frame = 0 ;
p_frame_header - > frame_type = kKeyFrame ;
p_frame_header - > frame_is_intra = 1 ;
p_frame_header - > show_frame = 1 ;
p_frame_header - > showable_frame = 0 ;
} else {
p_frame_header - > show_existing_frame = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > show_existing_frame = = 1 ) {
p_frame_header - > frame_to_show_map_idx = Parser : : ReadBits ( p_stream , offset , 3 ) ;
if ( p_seq_header - > decoder_model_info_present_flag & & ! p_seq_header - > timing_info . equal_picture_interval ) {
// temporal_point_info()
p_frame_header - > temporal_point_info . frame_presentation_time = Parser : : ReadBits ( p_stream , offset , p_seq_header - > decoder_model_info . frame_presentation_time_length_minus_1 + 1 ) ;
}
p_frame_header - > refresh_frame_flags = 0 ;
if ( p_seq_header - > frame_id_numbers_present_flag ) {
p_frame_header - > display_frame_id = Parser : : ReadBits ( p_stream , offset , frame_id_len ) ;
}
p_frame_header - > frame_type = ref_frame_type_ [ p_frame_header - > frame_to_show_map_idx ] ;
if ( p_frame_header - > frame_type = = kKeyFrame ) {
p_frame_header - > refresh_frame_flags = all_frames ;
}
if ( p_seq_header - > film_grain_params_present ) {
// Todo
ERR ( " Film grain param loading not implemented. \n " ) ;
// load_grain_params(p_frame_header->frame_to_show_map_idx);
return PARSER_NOT_IMPLEMENTED ;
}
return PARSER_OK ;
}
p_frame_header - > frame_type = Parser : : ReadBits ( p_stream , offset , 2 ) ;
p_frame_header - > frame_is_intra = ( p_frame_header - > frame_type = = kIntraOnlyFrame ) | | ( p_frame_header - > frame_type = = kKeyFrame ) ;
p_frame_header - > show_frame = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > show_frame & & p_seq_header - > decoder_model_info_present_flag & & ! p_seq_header - > timing_info . equal_picture_interval ) {
// temporal_point_info()
p_frame_header - > temporal_point_info . frame_presentation_time = Parser : : ReadBits ( p_stream , offset , p_seq_header - > decoder_model_info . frame_presentation_time_length_minus_1 + 1 ) ;
}
if ( p_frame_header - > show_frame ) {
p_frame_header - > showable_frame = p_frame_header - > frame_type ! = kKeyFrame ;
} else {
p_frame_header - > showable_frame = Parser : : GetBit ( p_stream , offset ) ;
}
if ( p_frame_header - > frame_type = = kSwitchFrame | | ( p_frame_header - > frame_type = = kKeyFrame & & p_frame_header - > show_frame ) ) {
p_frame_header - > error_resilient_mode = 1 ;
} else {
p_frame_header - > error_resilient_mode = Parser : : GetBit ( p_stream , offset ) ;
}
}
if ( p_frame_header - > frame_type = = kKeyFrame & & p_frame_header - > show_frame ) {
for ( i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
ref_valid_ [ i ] = 0 ;
ref_order_hint_ [ i ] = 0 ;
}
for ( i = 0 ; i < REFS_PER_FRAME ; i + + ) {
p_frame_header - > order_hints [ kLastFrame + i ] = 0 ;
}
}
p_frame_header - > disable_cdf_update = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > seq_force_screen_content_tools = = SELECT_SCREEN_CONTENT_TOOLS ) {
p_frame_header - > allow_screen_content_tools = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_frame_header - > allow_screen_content_tools = p_seq_header - > seq_force_screen_content_tools ;
}
if ( p_frame_header - > allow_screen_content_tools ) {
if ( p_seq_header - > seq_force_integer_mv = = SELECT_INTEGER_MV ) {
p_frame_header - > force_integer_mv = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_frame_header - > force_integer_mv = p_seq_header - > seq_force_integer_mv ;
}
} else {
p_frame_header - > force_integer_mv = 0 ;
}
if ( p_frame_header - > frame_is_intra ) {
p_frame_header - > force_integer_mv = 1 ;
}
if ( p_seq_header - > frame_id_numbers_present_flag ) {
p_frame_header - > prev_frame_id = p_frame_header - > current_frame_id ;
p_frame_header - > current_frame_id = Parser : : ReadBits ( p_stream , offset , frame_id_len ) ;
MarkRefFrames ( p_seq_header , p_frame_header , frame_id_len ) ;
} else {
p_frame_header - > current_frame_id = 0 ;
}
if ( p_frame_header - > frame_type = = kSwitchFrame ) {
p_frame_header - > frame_size_override_flag = 1 ;
} else if ( p_seq_header - > reduced_still_picture_header ) {
p_frame_header - > frame_size_override_flag = 0 ;
} else {
p_frame_header - > frame_size_override_flag = Parser : : GetBit ( p_stream , offset ) ;
}
p_frame_header - > order_hint = Parser : : ReadBits ( p_stream , offset , p_seq_header - > order_hint_bits ) ;
if ( p_frame_header - > frame_is_intra | | p_frame_header - > error_resilient_mode ) {
p_frame_header - > primary_ref_frame = PRIMARY_REF_NONE ;
} else {
p_frame_header - > primary_ref_frame = Parser : : ReadBits ( p_stream , offset , 3 ) ;
}
if ( p_seq_header - > decoder_model_info_present_flag ) {
p_frame_header - > buffer_removal_time_present_flag = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > buffer_removal_time_present_flag ) {
for ( int op_num = 0 ; op_num < = p_seq_header - > operating_points_cnt_minus_1 ; op_num + + ) {
if ( p_seq_header - > decoder_model_present_for_this_op [ op_num ] ) {
uint32_t op_pt_idc = p_seq_header - > operating_point_idc [ op_num ] ;
uint32_t in_temporal_layer = ( op_pt_idc > > temporal_id_ ) & 1 ;
uint32_t in_spatial_layer = ( op_pt_idc > > ( spatial_id_ + 8 ) ) & 1 ;
if ( op_pt_idc = = 0 | | ( in_temporal_layer & & in_spatial_layer ) ) {
p_frame_header - > buffer_removal_time [ op_num ] = Parser : : ReadBits ( p_stream , offset , p_seq_header - > decoder_model_info . buffer_removal_time_length_minus_1 + 1 ) ;
}
}
}
}
}
p_frame_header - > allow_high_precision_mv = 0 ;
p_frame_header - > use_ref_frame_mvs = 0 ;
p_frame_header - > allow_intrabc = 0 ;
if ( p_frame_header - > frame_type = = kSwitchFrame | | ( p_frame_header - > frame_type = = kKeyFrame & & p_frame_header - > show_frame ) ) {
p_frame_header - > refresh_frame_flags = all_frames ;
} else {
p_frame_header - > refresh_frame_flags = Parser : : ReadBits ( p_stream , offset , 8 ) ;
}
// Clear reference list for kKeyFrame
if ( p_frame_header - > frame_type = = kKeyFrame ) {
for ( i = 0 ; i < REFS_PER_FRAME ; i + + ) {
ref_pictures_ [ i ] . index = INVALID_INDEX ;
}
}
if ( ! p_frame_header - > frame_is_intra | | p_frame_header - > refresh_frame_flags ! = all_frames ) {
if ( p_frame_header - > error_resilient_mode & & p_seq_header - > enable_order_hint ) {
for ( i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
p_frame_header - > ref_order_hint [ i ] = Parser : : ReadBits ( p_stream , offset , p_seq_header - > order_hint_bits ) ;
if ( p_frame_header - > ref_order_hint [ i ] ! = ref_order_hint_ [ i ] ) {
ref_valid_ [ i ] = 0 ;
}
}
}
}
if ( p_frame_header - > frame_is_intra ) {
FrameSize ( p_stream , offset , p_seq_header , p_frame_header ) ;
RenderSize ( p_stream , offset , p_frame_header ) ;
if ( p_frame_header - > allow_screen_content_tools & & p_frame_header - > frame_size . upscaled_width = = p_frame_header - > frame_size . frame_width ) {
p_frame_header - > allow_intrabc = Parser : : GetBit ( p_stream , offset ) ;
}
} else {
if ( ! p_seq_header - > enable_order_hint ) {
p_frame_header - > frame_refs_short_signaling = 0 ;
} else {
p_frame_header - > frame_refs_short_signaling = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > frame_refs_short_signaling ) {
p_frame_header - > last_frame_idx = Parser : : ReadBits ( p_stream , offset , 3 ) ;
p_frame_header - > gold_frame_idx = Parser : : ReadBits ( p_stream , offset , 3 ) ;
// 7.8. Set frame refs process
SetFrameRefs ( p_seq_header , p_frame_header ) ;
}
}
for ( int i = 0 ; i < REFS_PER_FRAME ; i + + ) {
if ( ! p_frame_header - > frame_refs_short_signaling ) {
p_frame_header - > ref_frame_idx [ i ] = Parser : : ReadBits ( p_stream , offset , 3 ) ;
}
if ( p_seq_header - > frame_id_numbers_present_flag ) {
p_frame_header - > delta_frame_id_minus_1 = Parser : : ReadBits ( p_stream , offset , p_seq_header - > delta_frame_id_length_minus_2 + 2 ) ;
uint32_t delta_frame_id = p_frame_header - > delta_frame_id_minus_1 + 1 ;
p_frame_header - > expected_frame_id [ i ] = ( ( p_frame_header - > current_frame_id + ( 1 < < frame_id_len ) - delta_frame_id ) % ( 1 < < frame_id_len ) ) ;
if ( p_frame_header - > expected_frame_id [ i ] ! = ref_frame_id_ [ p_frame_header - > ref_frame_idx [ i ] ] | | ref_valid_ [ p_frame_header - > ref_frame_idx [ i ] ] = = 0 ) {
ERR ( " Syntax Error: Reference buffer frame ID mismatch. \n " ) ;
return PARSER_INVALID_ARG ;
}
}
}
if ( p_frame_header - > frame_size_override_flag & & ! p_frame_header - > error_resilient_mode ) {
FrameSizeWithRefs ( p_stream , offset , p_seq_header , p_frame_header ) ;
} else {
FrameSize ( p_stream , offset , p_seq_header , p_frame_header ) ;
RenderSize ( p_stream , offset , p_frame_header ) ;
}
if ( p_frame_header - > force_integer_mv ) {
p_frame_header - > allow_high_precision_mv = 0 ;
} else {
p_frame_header - > allow_high_precision_mv = Parser : : GetBit ( p_stream , offset ) ;
}
// read_interpolation_filter()
p_frame_header - > is_filter_switchable = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > is_filter_switchable = = 1 ) {
p_frame_header - > interpolation_filter = kSwitchable ;
} else {
p_frame_header - > interpolation_filter = Parser : : ReadBits ( p_stream , offset , 2 ) ;
}
p_frame_header - > is_motion_mode_switchable = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > error_resilient_mode | | ! p_seq_header - > enable_ref_frame_mvs ) {
p_frame_header - > use_ref_frame_mvs = 0 ;
} else {
p_frame_header - > use_ref_frame_mvs = Parser : : GetBit ( p_stream , offset ) ;
}
for ( i = 0 ; i < REFS_PER_FRAME ; i + + ) {
uint32_t ref_frame = kLastFrame + i ;
uint32_t hint = ref_order_hint_ [ p_frame_header - > ref_frame_idx [ i ] ] ;
p_frame_header - > order_hints [ ref_frame ] = hint ;
if ( ! p_seq_header - > enable_order_hint ) {
p_frame_header - > ref_frame_sign_bias [ ref_frame ] = 0 ;
} else {
p_frame_header - > ref_frame_sign_bias [ ref_frame ] = GetRelativeDist ( p_seq_header , hint , p_frame_header - > order_hint ) > 0 ;
}
}
}
// Generate reference map for the next picture
int ref_index = 0 ;
for ( int mask = p_frame_header - > refresh_frame_flags ; mask ; mask > > = 1 ) {
if ( mask & 1 ) {
ref_pic_map_next_ [ ref_index ] = new_fb_index_ ;
} else {
ref_pic_map_next_ [ ref_index ] = ref_pic_map_ [ ref_index ] ;
}
+ + ref_index ;
}
for ( ; ref_index < NUM_REF_FRAMES ; + + ref_index ) {
ref_pic_map_next_ [ ref_index ] = ref_pic_map_ [ ref_index ] ;
}
if ( p_seq_header - > reduced_still_picture_header | | p_frame_header - > disable_cdf_update ) {
p_frame_header - > disable_frame_end_update_cdf = 1 ;
} else {
p_frame_header - > disable_frame_end_update_cdf = Parser : : GetBit ( p_stream , offset ) ;
}
if ( p_frame_header - > primary_ref_frame = = PRIMARY_REF_NONE ) {
2024-06-10 12:07:23 -04:00
// Todo: check need for implementation
//init_non_coeff_cdfs();
2024-04-11 09:01:54 -04:00
SetupPastIndependence ( p_frame_header ) ;
} else {
2024-06-10 12:07:23 -04:00
// Todo: check need for implementation
//load_cdfs();
//load_previous();
2024-04-11 09:01:54 -04:00
}
if ( p_frame_header - > use_ref_frame_mvs = = 1 ) {
2024-06-10 12:07:23 -04:00
// Todo: check need for implementation
//motion_field_estimation());
2024-04-11 09:01:54 -04:00
}
TileInfo ( p_stream , offset , p_seq_header , p_frame_header ) ;
QuantizationParams ( p_stream , offset , p_seq_header , p_frame_header ) ;
SegmentationParams ( p_stream , offset , p_frame_header ) ;
DeltaQParams ( p_stream , offset , p_frame_header ) ;
DeltaLFParams ( p_stream , offset , p_frame_header ) ;
if ( p_frame_header - > primary_ref_frame = = PRIMARY_REF_NONE ) {
2024-06-10 12:07:23 -04:00
// Todo: check need for implementation
// init_coeff_cdfs();
2024-04-11 09:01:54 -04:00
} else {
2024-06-10 12:07:23 -04:00
// Todo: check need for implementation
//load_previous_segment_ids();
2024-04-11 09:01:54 -04:00
}
p_frame_header - > coded_lossless = 1 ;
for ( int segment_id = 0 ; segment_id < MAX_SEGMENTS ; segment_id + + ) {
2024-06-10 12:07:23 -04:00
int qindex = GetQIndex ( p_frame_header , 1 , segment_id ) ;
2024-04-11 09:01:54 -04:00
p_frame_header - > lossless_array [ segment_id ] = qindex = = 0 & & p_frame_header - > quantization_params . delta_q_y_dc = = 0 & & p_frame_header - > quantization_params . delta_q_u_ac = = 0 & & p_frame_header - > quantization_params . delta_q_u_dc = = 0 & & p_frame_header - > quantization_params . delta_q_v_ac = = 0 & & p_frame_header - > quantization_params . delta_q_v_dc = = 0 ;
if ( ! p_frame_header - > lossless_array [ segment_id ] ) {
p_frame_header - > coded_lossless = 0 ;
}
if ( p_frame_header - > quantization_params . using_qmatrix ) {
if ( p_frame_header - > lossless_array [ segment_id ] ) {
p_frame_header - > seg_qm_level [ 0 ] [ segment_id ] = 15 ;
p_frame_header - > seg_qm_level [ 1 ] [ segment_id ] = 15 ;
p_frame_header - > seg_qm_level [ 2 ] [ segment_id ] = 15 ;
} else {
p_frame_header - > seg_qm_level [ 0 ] [ segment_id ] = p_frame_header - > quantization_params . qm_y ;
p_frame_header - > seg_qm_level [ 1 ] [ segment_id ] = p_frame_header - > quantization_params . qm_u ;
p_frame_header - > seg_qm_level [ 2 ] [ segment_id ] = p_frame_header - > quantization_params . qm_v ;
}
}
}
p_frame_header - > all_lossless = p_frame_header - > coded_lossless & & ( p_frame_header - > frame_size . frame_width = = p_frame_header - > frame_size . upscaled_width ) ;
LoopFilterParams ( p_stream , offset , p_seq_header , p_frame_header ) ;
CdefParams ( p_stream , offset , p_seq_header , p_frame_header ) ;
LrParams ( p_stream , offset , p_seq_header , p_frame_header ) ;
ReadTxMode ( p_stream , offset , p_frame_header ) ;
// frame_reference_mode()
if ( p_frame_header - > frame_is_intra ) {
p_frame_header - > frame_reference_mode . reference_select = 0 ;
} else {
p_frame_header - > frame_reference_mode . reference_select = Parser : : GetBit ( p_stream , offset ) ;
}
SkipModeParams ( p_stream , offset , p_seq_header , p_frame_header ) ;
if ( p_frame_header - > frame_is_intra | | p_frame_header - > error_resilient_mode | | ! p_seq_header - > enable_warped_motion ) {
p_frame_header - > allow_warped_motion = 0 ;
} else {
p_frame_header - > allow_warped_motion = Parser : : GetBit ( p_stream , offset ) ;
}
p_frame_header - > reduced_tx_set = Parser : : GetBit ( p_stream , offset ) ;
GlobalMotionParams ( p_stream , offset , p_frame_header ) ;
FilmGrainParams ( p_stream , offset , p_seq_header , p_frame_header ) ;
2024-06-10 12:07:23 -04:00
// Update reference frames
for ( i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
if ( ( p_frame_header - > refresh_frame_flags > > i ) & 1 ) {
ref_order_hint_ [ i ] = p_frame_header - > order_hint ;
}
}
* p_bytes_parsed = ( offset + 7 ) > > 3 ;
2024-04-11 09:01:54 -04:00
return PARSER_OK ;
}
2024-06-10 12:07:23 -04:00
void Av1VideoParser : : ParseTileGroupObu ( uint8_t * p_stream , size_t size ) {
2024-04-11 09:01:54 -04:00
size_t offset = 0 ; // current bit offset
Av1SequenceHeader * p_seq_header = & seq_header_ ;
Av1FrameHeader * p_frame_header = & frame_header_ ;
Av1TileGroupDataInfo * p_tile_group = & tile_group_data_ ;
uint32_t num_tiles ;
uint32_t tile_start_and_end_present_flag = 0 ;
uint32_t tg_start , tg_end ;
uint32_t header_types = 0 ;
uint32_t tile_cols = p_frame_header - > tile_info . tile_cols ;
uint32_t tile_rows = p_frame_header - > tile_info . tile_rows ;
uint8_t * p_tg_buf = p_stream ;
uint32_t tg_size = size ;
memset ( p_tile_group , 0 , sizeof ( Av1TileGroupDataInfo ) ) ;
p_tile_group - > buffer_ptr = p_tg_buf ;
p_tile_group - > buffer_size = tg_size ;
// First parse the header
num_tiles = tile_cols * tile_rows ;
if ( num_tiles > 1 ) {
tile_start_and_end_present_flag = Parser : : GetBit ( p_stream , offset ) ;
}
if ( num_tiles = = 1 | | ! tile_start_and_end_present_flag ) {
tg_start = 0 ;
tg_end = num_tiles - 1 ;
} else {
uint32_t tile_bits = p_frame_header - > tile_info . tile_cols_log2 + p_frame_header - > tile_info . tile_rows_log2 ;
tg_start = Parser : : ReadBits ( p_stream , offset , tile_bits ) ;
tg_end = Parser : : ReadBits ( p_stream , offset , tile_bits ) ;
}
header_types = ( ( offset + 7 ) > > 3 ) ;
p_tg_buf + = header_types ;
tg_size - = header_types ;
for ( int tile_num = tg_start ; tile_num < = tg_end ; tile_num + + ) {
int tile_row = tile_num / tile_cols ;
int tile_col = tile_num % tile_cols ;
int last_tile = tile_num = = tg_end ;
if ( last_tile ) {
p_tile_group - > tile_data_info [ tile_row ] [ tile_col ] . size = tg_size ;
p_tile_group - > tile_data_info [ tile_row ] [ tile_col ] . offset = p_tg_buf - p_tile_group - > buffer_ptr ;
} else {
uint32_t tile_size_bytes = p_frame_header - > tile_info . tile_size_bytes_minus_1 + 1 ;
uint32_t tile_size = ReadLeBytes ( p_tg_buf , tile_size_bytes ) + 1 ;
p_tile_group - > tile_data_info [ tile_row ] [ tile_col ] . size = tile_size ;
p_tile_group - > tile_data_info [ tile_row ] [ tile_col ] . offset = p_tg_buf + tile_size_bytes - p_tile_group - > buffer_ptr ;
tg_size - = tile_size + tile_size_bytes ;
p_tg_buf + = tile_size + tile_size_bytes ;
}
}
2024-06-10 12:07:23 -04:00
if ( tg_end = = num_tiles - 1 ) {
if ( ! frame_header_ . disable_frame_end_update_cdf ) {
//frame_end_update_cdf();
}
//decode_frame_wrapup();
seen_frame_header_ = 0 ;
}
2024-04-11 09:01:54 -04:00
}
2024-04-03 15:04:18 -04:00
void Av1VideoParser : : ParseColorConfig ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header ) {
p_seq_header - > color_config . bit_depth = 8 ;
p_seq_header - > color_config . high_bitdepth = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > seq_profile = = 2 & & p_seq_header - > color_config . high_bitdepth ) {
p_seq_header - > color_config . twelve_bit = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > color_config . bit_depth = p_seq_header - > color_config . twelve_bit ? 12 : 10 ;
} else if ( p_seq_header - > seq_profile < = 2 ) {
p_seq_header - > color_config . bit_depth = p_seq_header - > color_config . high_bitdepth ? 10 : 8 ;
}
if ( p_seq_header - > seq_profile = = 1 ) {
p_seq_header - > color_config . mono_chrome = 0 ;
} else {
p_seq_header - > color_config . mono_chrome = Parser : : GetBit ( p_stream , offset ) ;
}
p_seq_header - > color_config . num_planes = p_seq_header - > color_config . mono_chrome ? 1 : 3 ;
p_seq_header - > color_config . color_description_present_flag = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > color_config . color_description_present_flag ) {
p_seq_header - > color_config . color_primaries = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_seq_header - > color_config . transfer_characteristics = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_seq_header - > color_config . matrix_coefficients = Parser : : ReadBits ( p_stream , offset , 8 ) ;
} else {
p_seq_header - > color_config . color_primaries = CP_UNSPECIFIED ;
p_seq_header - > color_config . transfer_characteristics = TC_UNSPECIFIED ;
p_seq_header - > color_config . matrix_coefficients = MC_UNSPECIFIED ;
}
if ( p_seq_header - > color_config . mono_chrome ) {
p_seq_header - > color_config . color_range = Parser : : GetBit ( p_stream , offset ) ;
p_seq_header - > color_config . subsampling_x = 1 ;
p_seq_header - > color_config . subsampling_y = 1 ;
p_seq_header - > color_config . chroma_sample_position = CSP_UNKNOWN ;
p_seq_header - > color_config . separate_uv_delta_q = 0 ;
return ;
} else if ( p_seq_header - > color_config . color_primaries = = CP_BT_709 & & p_seq_header - > color_config . transfer_characteristics = = TC_SRGB & & p_seq_header - > color_config . matrix_coefficients = = MC_IDENTITY ) {
p_seq_header - > color_config . color_range = 1 ;
p_seq_header - > color_config . subsampling_x = 0 ;
p_seq_header - > color_config . subsampling_y = 0 ;
} else {
p_seq_header - > color_config . color_range = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > seq_profile = = 0 ) {
p_seq_header - > color_config . subsampling_x = 1 ;
p_seq_header - > color_config . subsampling_y = 1 ;
} else if ( p_seq_header - > seq_profile = = 1 ) {
p_seq_header - > color_config . subsampling_x = 0 ;
p_seq_header - > color_config . subsampling_y = 0 ;
} else {
if ( p_seq_header - > color_config . bit_depth = = 12 ) {
p_seq_header - > color_config . subsampling_x = Parser : : GetBit ( p_stream , offset ) ;
if ( p_seq_header - > color_config . subsampling_x ) {
p_seq_header - > color_config . subsampling_y = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_seq_header - > color_config . subsampling_y = 0 ;
}
} else {
p_seq_header - > color_config . subsampling_x = 1 ;
p_seq_header - > color_config . subsampling_y = 0 ;
}
}
if ( p_seq_header - > color_config . subsampling_x & & p_seq_header - > color_config . subsampling_y ) {
p_seq_header - > color_config . chroma_sample_position = Parser : : ReadBits ( p_stream , offset , 2 ) ;
}
}
p_seq_header - > color_config . separate_uv_delta_q = Parser : : GetBit ( p_stream , offset ) ;
}
2024-04-11 09:01:54 -04:00
void Av1VideoParser : : MarkRefFrames ( Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header , uint32_t id_len ) {
int diff_len = p_seq_header - > delta_frame_id_length_minus_2 + 2 ;
for ( int i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
if ( p_frame_header - > frame_type = = kKeyFrame & & p_frame_header - > show_frame ) {
ref_valid_ [ i ] = 0 ;
} else if ( p_frame_header - > current_frame_id > ( 1 < < diff_len ) ) {
if ( ref_frame_id_ [ i ] > p_frame_header - > current_frame_id | | ref_frame_id_ [ i ] < ( p_frame_header - > current_frame_id - ( 1 < < diff_len ) ) ) {
ref_valid_ [ i ] = 0 ;
}
} else {
if ( ref_frame_id_ [ i ] > p_frame_header - > current_frame_id & & ref_frame_id_ [ i ] < ( ( 1 < < id_len ) + p_frame_header - > current_frame_id - ( 1 < < diff_len ) ) ) {
ref_valid_ [ i ] = 0 ;
}
}
}
}
void Av1VideoParser : : FrameSize ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
if ( p_frame_header - > frame_size_override_flag ) {
p_frame_header - > frame_size . frame_width_minus_1 = Parser : : ReadBits ( p_stream , offset , p_seq_header - > frame_width_bits_minus_1 + 1 ) ;
p_frame_header - > frame_size . frame_width = p_frame_header - > frame_size . frame_width_minus_1 + 1 ;
p_frame_header - > frame_size . frame_height_minus_1 = Parser : : ReadBits ( p_stream , offset , p_seq_header - > frame_height_bits_minus_1 + 1 ) ;
p_frame_header - > frame_size . frame_height = p_frame_header - > frame_size . frame_height_minus_1 + 1 ;
} else {
p_frame_header - > frame_size . frame_width = p_seq_header - > max_frame_width_minus_1 + 1 ;
p_frame_header - > frame_size . frame_height = p_seq_header - > max_frame_height_minus_1 + 1 ;
}
SuperResParams ( p_stream , offset , p_seq_header , p_frame_header ) ;
ComputeImageSize ( p_frame_header ) ;
}
void Av1VideoParser : : SuperResParams ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
uint32_t super_res_denom ;
if ( p_seq_header - > enable_superres ) {
p_frame_header - > frame_size . superres_params . use_superres = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_frame_header - > frame_size . superres_params . use_superres = 0 ;
}
if ( p_frame_header - > frame_size . superres_params . use_superres ) {
p_frame_header - > frame_size . superres_params . coded_denom = Parser : : ReadBits ( p_stream , offset , SUPERRES_DENOM_BITS ) ;
super_res_denom = p_frame_header - > frame_size . superres_params . coded_denom + SUPERRES_DENOM_MIN ;
} else {
super_res_denom = SUPERRES_NUM ;
}
p_frame_header - > frame_size . upscaled_width = p_frame_header - > frame_size . frame_width ;
p_frame_header - > frame_size . frame_width = ( p_frame_header - > frame_size . upscaled_width * SUPERRES_NUM + ( super_res_denom / 2 ) ) / super_res_denom ;
}
void Av1VideoParser : : ComputeImageSize ( Av1FrameHeader * p_frame_header ) {
p_frame_header - > frame_size . mi_cols = 2 * ( ( p_frame_header - > frame_size . frame_width + 7 ) > > 3 ) ;
p_frame_header - > frame_size . mi_rows = 2 * ( ( p_frame_header - > frame_size . frame_height + 7 ) > > 3 ) ;
}
void Av1VideoParser : : RenderSize ( const uint8_t * p_stream , size_t & offset , Av1FrameHeader * p_frame_header ) {
p_frame_header - > render_size . render_and_frame_size_different = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > render_size . render_and_frame_size_different ) {
p_frame_header - > render_size . render_width_minus_1 = Parser : : ReadBits ( p_stream , offset , 16 ) ;
p_frame_header - > render_size . render_height_minus_1 = Parser : : ReadBits ( p_stream , offset , 16 ) ;
p_frame_header - > render_size . render_width = p_frame_header - > render_size . render_width_minus_1 + 1 ;
p_frame_header - > render_size . render_height = p_frame_header - > render_size . render_height_minus_1 + 1 ;
} else {
p_frame_header - > render_size . render_width = p_frame_header - > frame_size . upscaled_width ;
p_frame_header - > render_size . render_height = p_frame_header - > frame_size . frame_height ;
}
}
void Av1VideoParser : : SetFrameRefs ( Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
int i ;
int used_frame [ NUM_REF_FRAMES ] ;
int curr_frame_hint ;
int shifted_order_hints [ NUM_REF_FRAMES ] ;
int ref ;
for ( i = 0 ; i < REFS_PER_FRAME ; i + + ) {
p_frame_header - > ref_frame_idx [ i ] = - 1 ;
}
p_frame_header - > ref_frame_idx [ kLastFrame - kLastFrame ] = p_frame_header - > last_frame_idx ;
p_frame_header - > ref_frame_idx [ kGoldenFrame - kLastFrame ] = p_frame_header - > gold_frame_idx ;
for ( i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
used_frame [ i ] = 0 ;
}
used_frame [ p_frame_header - > last_frame_idx ] = 1 ;
used_frame [ p_frame_header - > gold_frame_idx ] = 1 ;
curr_frame_hint = 1 < < ( p_seq_header - > order_hint_bits - 1 ) ;
for ( i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
shifted_order_hints [ i ] = curr_frame_hint + GetRelativeDist ( p_seq_header , ref_order_hint_ [ i ] , p_frame_header - > order_hint ) ;
}
// The kAltRefFrame reference is set to be a backward reference to the frame with highest output order.
ref = FindLatestBackward ( shifted_order_hints , used_frame , curr_frame_hint ) ;
if ( ref > = 0 ) {
p_frame_header - > ref_frame_idx [ kAltRefFrame - kLastFrame ] = ref ;
used_frame [ ref ] = 1 ;
}
// The kBwdRefFrame reference is set to be a backward reference to the closest frame.
ref = FindEarliestBackward ( shifted_order_hints , used_frame , curr_frame_hint ) ;
if ( ref > = 0 )
{
p_frame_header - > ref_frame_idx [ kBwdRefFrame - kLastFrame ] = ref ;
used_frame [ ref ] = 1 ;
}
// The kAltRef2Frame reference is set to the next closest backward reference.
ref = FindEarliestBackward ( shifted_order_hints , used_frame , curr_frame_hint ) ;
if ( ref > = 0 )
{
p_frame_header - > ref_frame_idx [ kAltRef2Frame - kLastFrame ] = ref ;
used_frame [ ref ] = 1 ;
}
// The remaining references are set to be forward references in anti-chronological order.
int ref_frame_list [ REFS_PER_FRAME - 2 ] = { kLast2Frame , kLast3Frame , kBwdRefFrame , kAltRef2Frame , kAltRefFrame } ;
for ( i = 0 ; i < REFS_PER_FRAME - 2 ; i + + ) {
int refFrame = ref_frame_list [ i ] ;
if ( p_frame_header - > ref_frame_idx [ refFrame - kLastFrame ] < 0 ) {
ref = FindLatestForward ( shifted_order_hints , used_frame , curr_frame_hint ) ;
if ( ref > = 0 ) {
p_frame_header - > ref_frame_idx [ refFrame - kLastFrame ] = ref ;
used_frame [ ref ] = 1 ;
}
}
}
// Finally, any remaining references are set to the reference frame with smallest output order.
ref = - 1 ;
for ( i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
int earliest_order_hint = 9999 ;
int hint = shifted_order_hints [ i ] ;
if ( ref < 0 | | hint < earliest_order_hint ) {
ref = i ;
earliest_order_hint = hint ;
}
}
for ( i = 0 ; i < REFS_PER_FRAME ; i + + ) {
if ( p_frame_header - > ref_frame_idx [ i ] < 0 ) {
p_frame_header - > ref_frame_idx [ i ] = ref ;
}
}
}
int Av1VideoParser : : GetRelativeDist ( Av1SequenceHeader * p_seq_header , int a , int b ) {
if ( ! p_seq_header - > enable_order_hint ) {
return 0 ;
}
int diff = a - b ;
int m = 1 < < ( p_seq_header - > order_hint_bits - 1 ) ;
diff = ( diff & ( m - 1 ) ) - ( diff & m ) ;
return diff ;
}
int Av1VideoParser : : FindLatestBackward ( int * shifted_order_hints , int * used_frame , int curr_frame_hint ) {
int ref = - 1 ;
int hint ;
int latest_order_hint = - 9999 ;
for ( int i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
hint = shifted_order_hints [ i ] ;
if ( ! used_frame [ i ] & & hint > = curr_frame_hint & & ( ref < 0 | | hint > = latest_order_hint ) ) {
ref = i ;
latest_order_hint = hint ;
}
}
return ref ;
}
int Av1VideoParser : : FindEarliestBackward ( int * shifted_order_hints , int * used_frame , int curr_frame_hint ) {
int ref = - 1 ;
int hint ;
int earliest_order_hint = 9999 ;
for ( int i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
hint = shifted_order_hints [ i ] ;
if ( ! used_frame [ i ] & & hint > = curr_frame_hint & & ( ref < 0 | | hint < earliest_order_hint ) ) {
ref = i ;
earliest_order_hint = hint ;
}
}
return ref ;
}
int Av1VideoParser : : FindLatestForward ( int * shifted_order_hints , int * used_frame , int curr_frame_hint ) {
int ref = - 1 ;
int hint ;
int latest_order_hint = - 9999 ;
for ( int i = 0 ; i < NUM_REF_FRAMES ; i + + ) {
hint = shifted_order_hints [ i ] ;
if ( ! used_frame [ i ] & & hint < curr_frame_hint & & ( ref < 0 | | hint > = latest_order_hint ) ) {
ref = i ;
latest_order_hint = hint ;
}
}
return ref ;
}
void Av1VideoParser : : FrameSizeWithRefs ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
for ( int i = 0 ; i < REFS_PER_FRAME ; i + + ) {
p_frame_header - > found_ref = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > found_ref ) {
// Todo
ERR ( " Warning: Need to implement! found_ref == 1 case. \n " ) ;
#if 0
UpscaledWidth = RefUpscaledWidth[ ref_frame_idx[ i ] ]
FrameWidth = UpscaledWidth
FrameHeight = RefFrameHeight[ ref_frame_idx[ i ] ]
RenderWidth = RefRenderWidth[ ref_frame_idx[ i ] ]
RenderHeight = RefRenderHeight[ ref_frame_idx[ i ] ]
#endif
break ;
}
}
if ( p_frame_header - > found_ref = = 0 ) {
FrameSize ( p_stream , offset , p_seq_header , p_frame_header ) ;
RenderSize ( p_stream , offset , p_frame_header ) ;
} else {
SuperResParams ( p_stream , offset , p_seq_header , p_frame_header ) ;
ComputeImageSize ( p_frame_header ) ;
}
}
void Av1VideoParser : : SetupPastIndependence ( Av1FrameHeader * p_frame_header ) {
2024-06-10 12:07:23 -04:00
for ( int i = 0 ; i < MAX_SEGMENTS ; i + + ) {
for ( int j = 0 ; j < SEG_LVL_MAX ; j + + ) {
p_frame_header - > segmentation_params . feature_data [ i ] [ j ] = 0 ;
p_frame_header - > segmentation_params . feature_enabled_flags [ i ] [ j ] = 0 ;
}
}
// Block level: PrevSegmentIds[ row ][ col ] is set equal to 0 for row = 0..MiRows-1 and col = 0..MiCols-1.
for ( int ref = kLastFrame ; ref < = kAltRefFrame ; ref + + ) {
p_frame_header - > global_motion_params . gm_type [ ref ] = kIdentity ;
for ( int i = 0 ; i < 6 ; i + + ) {
prev_gm_params_ [ ref ] [ i ] = ( i % 3 = = 2 ) ? 1 < < WARPEDMODEL_PREC_BITS : 0 ;
}
}
2024-04-11 09:01:54 -04:00
2024-06-10 12:07:23 -04:00
p_frame_header - > loop_filter_params . loop_filter_delta_enabled = 1 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kIntraFrame ] = 1 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kLastFrame ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kLast2Frame ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kLast3Frame ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kBwdRefFrame ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kGoldenFrame ] = - 1 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kAltRefFrame ] = - 1 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kAltRef2Frame ] = - 1 ;
p_frame_header - > loop_filter_params . loop_filter_mode_deltas [ 0 ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_mode_deltas [ 1 ] = 0 ;
2024-04-11 09:01:54 -04:00
}
void Av1VideoParser : : TileInfo ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
int32_t sb_cols ;
int32_t sb_rows ;
int32_t sb_shift ;
int32_t sb_size ;
int32_t max_tile_width_sb ;
int32_t max_tile_height_sb ;
int32_t max_tile_area_sb ;
int32_t min_log2_tile_cols ;
int32_t min_log2_tile_rows ;
int32_t max_log2_tile_cols ;
int32_t max_log2_tile_rows ;
int32_t min_log2_tiles ;
int32_t tile_width_sb ;
int32_t tile_height_sb ;
int32_t max_width ;
int32_t max_height ;
int32_t size_sb ;
int start_sb ;
int i ;
sb_cols = p_seq_header - > use_128x128_superblock ? ( ( p_frame_header - > frame_size . mi_cols + 31 ) > > 5 ) : ( ( p_frame_header - > frame_size . mi_cols + 15 ) > > 4 ) ;
sb_rows = p_seq_header - > use_128x128_superblock ? ( ( p_frame_header - > frame_size . mi_rows + 31 ) > > 5 ) : ( ( p_frame_header - > frame_size . mi_rows + 15 ) > > 4 ) ;
sb_shift = p_seq_header - > use_128x128_superblock ? 5 : 4 ;
sb_size = sb_shift + 2 ;
max_tile_width_sb = MAX_TILE_WIDTH > > sb_size ;
max_tile_area_sb = MAX_TILE_AREA > > ( 2 * sb_size ) ;
min_log2_tile_cols = TileLog2 ( max_tile_width_sb , sb_cols ) ;
max_log2_tile_cols = TileLog2 ( 1 , std : : min ( sb_cols , MAX_TILE_COLS ) ) ;
max_log2_tile_rows = TileLog2 ( 1 , std : : min ( sb_rows , MAX_TILE_ROWS ) ) ;
min_log2_tiles = std : : max ( min_log2_tile_cols , static_cast < int > ( TileLog2 ( max_tile_area_sb , sb_rows * sb_cols ) ) ) ;
p_frame_header - > tile_info . uniform_tile_spacing_flag = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > tile_info . uniform_tile_spacing_flag ) {
p_frame_header - > tile_info . tile_cols_log2 = min_log2_tile_cols ;
while ( p_frame_header - > tile_info . tile_cols_log2 < max_log2_tile_cols ) {
p_frame_header - > tile_info . increment_tile_cols_log2 = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > tile_info . increment_tile_cols_log2 = = 1 ) {
p_frame_header - > tile_info . tile_cols_log2 + + ;
} else {
break ;
}
}
tile_width_sb = ( sb_cols + ( 1 < < p_frame_header - > tile_info . tile_cols_log2 ) - 1 ) > > p_frame_header - > tile_info . tile_cols_log2 ;
i = 0 ;
for ( start_sb = 0 ; start_sb < sb_cols ; start_sb + = tile_width_sb ) {
p_frame_header - > tile_info . mi_col_starts [ i ] = start_sb < < sb_shift ;
i + = 1 ;
}
p_frame_header - > tile_info . mi_col_starts [ i ] = p_frame_header - > frame_size . mi_cols ;
p_frame_header - > tile_info . tile_cols = i ;
min_log2_tile_rows = std : : max ( min_log2_tiles - p_frame_header - > tile_info . tile_cols_log2 , 0 ) ;
p_frame_header - > tile_info . tile_rows_log2 = min_log2_tile_rows ;
while ( p_frame_header - > tile_info . tile_rows_log2 < max_log2_tile_rows ) {
p_frame_header - > tile_info . increment_tile_rows_log2 = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > tile_info . increment_tile_rows_log2 = = 1 ) {
p_frame_header - > tile_info . tile_rows_log2 + + ;
} else {
break ;
}
}
tile_height_sb = ( sb_rows + ( 1 < < p_frame_header - > tile_info . tile_rows_log2 ) - 1 ) > > p_frame_header - > tile_info . tile_rows_log2 ;
i = 0 ;
for ( start_sb = 0 ; start_sb < sb_rows ; start_sb + = tile_height_sb ) {
p_frame_header - > tile_info . mi_row_starts [ i ] = start_sb < < sb_shift ;
i + = 1 ;
}
p_frame_header - > tile_info . mi_row_starts [ i ] = p_frame_header - > frame_size . mi_rows ;
p_frame_header - > tile_info . tile_rows = i ;
} else {
int widest_tile_sb = 0 ;
start_sb = 0 ;
for ( i = 0 ; start_sb < sb_cols ; i + + ) {
p_frame_header - > tile_info . mi_col_starts [ i ] = start_sb < < sb_shift ;
max_width = std : : min ( sb_cols - start_sb , max_tile_width_sb ) ;
p_frame_header - > tile_info . width_in_sbs_minus_1 = ReadUnsignedNonSymmetic ( p_stream , offset , max_width ) ;
size_sb = p_frame_header - > tile_info . width_in_sbs_minus_1 + 1 ;
widest_tile_sb = std : : max ( size_sb , widest_tile_sb ) ;
start_sb + = size_sb ;
}
p_frame_header - > tile_info . mi_col_starts [ i ] = p_frame_header - > frame_size . mi_cols ;
p_frame_header - > tile_info . tile_cols = i ;
p_frame_header - > tile_info . tile_cols_log2 = TileLog2 ( 1 , p_frame_header - > tile_info . tile_cols ) ;
if ( min_log2_tiles > 0 ) {
max_tile_area_sb = ( sb_rows * sb_cols ) > > ( min_log2_tiles + 1 ) ;
} else {
max_tile_area_sb = sb_rows * sb_cols ;
}
max_tile_height_sb = std : : max ( max_tile_area_sb / widest_tile_sb , static_cast < int > ( 1 ) ) ;
start_sb = 0 ;
for ( i = 0 ; start_sb < sb_rows ; i + + ) {
p_frame_header - > tile_info . mi_row_starts [ i ] = start_sb < < sb_shift ;
max_height = std : : min ( sb_rows - start_sb , max_tile_height_sb ) ;
p_frame_header - > tile_info . height_in_sbs_minus_1 = ReadUnsignedNonSymmetic ( p_stream , offset , max_height ) ;
size_sb = p_frame_header - > tile_info . height_in_sbs_minus_1 + 1 ;
start_sb + = size_sb ;
}
p_frame_header - > tile_info . mi_row_starts [ i ] = p_frame_header - > frame_size . mi_rows ;
p_frame_header - > tile_info . tile_rows = i ;
p_frame_header - > tile_info . tile_rows_log2 = TileLog2 ( 1 , p_frame_header - > tile_info . tile_rows ) ;
}
if ( p_frame_header - > tile_info . tile_cols_log2 > 0 | | p_frame_header - > tile_info . tile_rows_log2 > 0 ) {
p_frame_header - > tile_info . context_update_tile_id = Parser : : ReadBits ( p_stream , offset , p_frame_header - > tile_info . tile_rows_log2 + p_frame_header - > tile_info . tile_cols_log2 ) ;
p_frame_header - > tile_info . tile_size_bytes_minus_1 = Parser : : ReadBits ( p_stream , offset , 2 ) ;
} else {
p_frame_header - > tile_info . context_update_tile_id = 0 ;
}
}
uint32_t Av1VideoParser : : TileLog2 ( uint32_t blk_size , uint32_t target ) {
uint32_t k ;
2024-06-10 12:07:23 -04:00
for ( k = 0 ; ( blk_size < < k ) < target ; k + + ) { }
2024-04-11 09:01:54 -04:00
return k ;
}
void Av1VideoParser : : QuantizationParams ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
p_frame_header - > quantization_params . base_q_idx = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_frame_header - > quantization_params . delta_q_y_dc = ReadDeltaQ ( p_stream , offset , p_frame_header ) ;
if ( p_seq_header - > color_config . num_planes > 1 ) {
if ( p_seq_header - > color_config . separate_uv_delta_q ) {
p_frame_header - > quantization_params . diff_uv_delta = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_frame_header - > quantization_params . diff_uv_delta = 0 ;
}
p_frame_header - > quantization_params . delta_q_u_dc = ReadDeltaQ ( p_stream , offset , p_frame_header ) ;
p_frame_header - > quantization_params . delta_q_u_ac = ReadDeltaQ ( p_stream , offset , p_frame_header ) ;
if ( p_frame_header - > quantization_params . diff_uv_delta ) {
p_frame_header - > quantization_params . delta_q_v_dc = ReadDeltaQ ( p_stream , offset , p_frame_header ) ;
p_frame_header - > quantization_params . delta_q_v_ac = ReadDeltaQ ( p_stream , offset , p_frame_header ) ;
} else {
p_frame_header - > quantization_params . delta_q_v_dc = p_frame_header - > quantization_params . delta_q_u_dc ;
p_frame_header - > quantization_params . delta_q_v_ac = p_frame_header - > quantization_params . delta_q_u_ac ;
}
} else {
p_frame_header - > quantization_params . delta_q_u_dc = 0 ;
p_frame_header - > quantization_params . delta_q_u_ac = 0 ;
p_frame_header - > quantization_params . delta_q_v_dc = 0 ;
p_frame_header - > quantization_params . delta_q_v_ac = 0 ;
}
p_frame_header - > quantization_params . using_qmatrix = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > quantization_params . using_qmatrix ) {
p_frame_header - > quantization_params . qm_y = Parser : : ReadBits ( p_stream , offset , 4 ) ;
p_frame_header - > quantization_params . qm_u = Parser : : ReadBits ( p_stream , offset , 4 ) ;
if ( ! p_seq_header - > color_config . separate_uv_delta_q ) {
p_frame_header - > quantization_params . qm_v = p_frame_header - > quantization_params . qm_u ;
} else {
p_frame_header - > quantization_params . qm_v = Parser : : ReadBits ( p_stream , offset , 4 ) ;
}
}
}
uint32_t Av1VideoParser : : ReadDeltaQ ( const uint8_t * p_stream , size_t & offset , Av1FrameHeader * p_frame_header ) {
p_frame_header - > quantization_params . delta_coded = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > quantization_params . delta_coded ) {
p_frame_header - > quantization_params . delta_q = ReadSigned ( p_stream , offset , 1 + 6 ) ;
} else {
p_frame_header - > quantization_params . delta_q = 0 ;
}
return p_frame_header - > quantization_params . delta_q ;
}
void Av1VideoParser : : SegmentationParams ( const uint8_t * p_stream , size_t & offset , Av1FrameHeader * p_frame_header ) {
int i , j ;
int clipped_value ;
uint32_t bits_to_read ;
uint32_t segmentation_feature_bits [ SEG_LVL_MAX ] = { 8 , 6 , 6 , 6 , 6 , 3 , 0 , 0 } ;
uint32_t segmentation_feature_signed [ SEG_LVL_MAX ] = { 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 } ;
uint32_t segmentation_feature_max [ SEG_LVL_MAX ] = { 255 , MAX_LOOP_FILTER , MAX_LOOP_FILTER , MAX_LOOP_FILTER , MAX_LOOP_FILTER , 7 , 0 , 0 } ;
p_frame_header - > segmentation_params . segmentation_enabled = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > segmentation_params . segmentation_enabled = = 1 ) {
if ( p_frame_header - > primary_ref_frame = = PRIMARY_REF_NONE ) {
p_frame_header - > segmentation_params . segmentation_update_map = 1 ;
p_frame_header - > segmentation_params . segmentation_temporal_update = 0 ;
p_frame_header - > segmentation_params . segmentation_update_data = 1 ;
} else {
p_frame_header - > segmentation_params . segmentation_update_map = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > segmentation_params . segmentation_update_map = = 1 ) {
p_frame_header - > segmentation_params . segmentation_temporal_update = Parser : : GetBit ( p_stream , offset ) ;
}
p_frame_header - > segmentation_params . segmentation_update_data = Parser : : GetBit ( p_stream , offset ) ;
}
if ( p_frame_header - > segmentation_params . segmentation_update_data = = 1 ) {
for ( i = 0 ; i < MAX_SEGMENTS ; i + + ) {
for ( j = 0 ; j < SEG_LVL_MAX ; j + + ) {
p_frame_header - > segmentation_params . feature_value = 0 ;
p_frame_header - > segmentation_params . feature_enabled = Parser : : GetBit ( p_stream , offset ) ;
p_frame_header - > segmentation_params . feature_enabled_flags [ i ] [ j ] = p_frame_header - > segmentation_params . feature_enabled ;
clipped_value = 0 ;
if ( p_frame_header - > segmentation_params . feature_enabled = = 1 ) {
bits_to_read = segmentation_feature_bits [ j ] ;
int limit = segmentation_feature_max [ j ] ;
if ( segmentation_feature_signed [ j ] = = 1 ) {
p_frame_header - > segmentation_params . feature_value = ReadSigned ( p_stream , offset , 1 + bits_to_read ) ;
clipped_value = std : : clamp ( static_cast < int > ( p_frame_header - > segmentation_params . feature_value ) , - limit , limit ) ;
} else {
p_frame_header - > segmentation_params . feature_value = Parser : : ReadBits ( p_stream , offset , bits_to_read ) ;
clipped_value = std : : clamp ( static_cast < int > ( p_frame_header - > segmentation_params . feature_value ) , 0 , limit ) ;
}
}
p_frame_header - > segmentation_params . feature_data [ i ] [ j ] = clipped_value ;
}
}
}
} else {
for ( i = 0 ; i < MAX_SEGMENTS ; i + + ) {
for ( j = 0 ; j < SEG_LVL_MAX ; j + + ) {
p_frame_header - > segmentation_params . feature_enabled_flags [ i ] [ j ] = 0 ;
p_frame_header - > segmentation_params . feature_data [ i ] [ j ] = 0 ;
}
}
}
p_frame_header - > segmentation_params . seg_id_pre_skip = 0 ;
p_frame_header - > segmentation_params . last_active_seg_id = 0 ;
for ( i = 0 ; i < MAX_SEGMENTS ; i + + ) {
for ( j = 0 ; j < SEG_LVL_MAX ; j + + ) {
if ( p_frame_header - > segmentation_params . feature_enabled_flags [ i ] [ j ] ) {
p_frame_header - > segmentation_params . last_active_seg_id = i ;
if ( j > = SEG_LVL_REF_FRAME ) {
p_frame_header - > segmentation_params . seg_id_pre_skip = 1 ;
}
}
}
}
}
void Av1VideoParser : : DeltaQParams ( const uint8_t * p_stream , size_t & offset , Av1FrameHeader * p_frame_header ) {
p_frame_header - > delta_q_params . delta_q_res = 0 ;
p_frame_header - > delta_q_params . delta_q_present = 0 ;
2024-06-10 12:07:23 -04:00
if ( p_frame_header - > quantization_params . base_q_idx > 0 ) {
2024-04-11 09:01:54 -04:00
p_frame_header - > delta_q_params . delta_q_present = Parser : : GetBit ( p_stream , offset ) ;
}
2024-06-10 12:07:23 -04:00
if ( p_frame_header - > delta_q_params . delta_q_present ) {
2024-04-11 09:01:54 -04:00
p_frame_header - > delta_q_params . delta_q_res = Parser : : ReadBits ( p_stream , offset , 2 ) ;
}
}
void Av1VideoParser : : DeltaLFParams ( const uint8_t * p_stream , size_t & offset , Av1FrameHeader * p_frame_header ) {
p_frame_header - > delta_lf_params . delta_lf_present = 0 ;
p_frame_header - > delta_lf_params . delta_lf_res = 0 ;
p_frame_header - > delta_lf_params . delta_lf_multi = 0 ;
if ( p_frame_header - > delta_q_params . delta_q_present ) {
if ( ! p_frame_header - > allow_intrabc ) {
p_frame_header - > delta_lf_params . delta_lf_present = Parser : : GetBit ( p_stream , offset ) ;
}
if ( p_frame_header - > delta_lf_params . delta_lf_present ) {
p_frame_header - > delta_lf_params . delta_lf_res = Parser : : ReadBits ( p_stream , offset , 2 ) ;
p_frame_header - > delta_lf_params . delta_lf_multi = Parser : : GetBit ( p_stream , offset ) ;
}
}
}
2024-06-10 12:07:23 -04:00
int Av1VideoParser : : GetQIndex ( Av1FrameHeader * p_frame_header , int ignore_delta_q , int segment_id ) {
// seg_feature_active_idx(segment_id, SEG_LVL_ALT_Q)
int seg_feature_active_idx = p_frame_header - > segmentation_params . segmentation_enabled & & p_frame_header - > segmentation_params . feature_enabled_flags [ segment_id ] [ SEG_LVL_ALT_Q ] ;
if ( seg_feature_active_idx = = 1 ) {
int data = p_frame_header - > segmentation_params . feature_data [ segment_id ] [ SEG_LVL_ALT_Q ] ;
int q_index = p_frame_header - > quantization_params . base_q_idx + data ;
// CurrentQIndex is base_q_idx at tile level: If ignoreDeltaQ is equal to 0 and delta_q_present is equal to 1, set qindex equal to CurrentQIndex + data.
std : : clamp ( q_index , 0 , 255 ) ;
return q_index ;
} else if ( ignore_delta_q = = 0 & & p_frame_header - > delta_q_params . delta_q_present = = 1 ) {
return p_frame_header - > quantization_params . base_q_idx ; // CurrentQIndex is base_q_idx at tile level
} else {
return p_frame_header - > quantization_params . base_q_idx ;
}
}
2024-04-11 09:01:54 -04:00
void Av1VideoParser : : LoopFilterParams ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
int i ;
if ( p_frame_header - > coded_lossless | | p_frame_header - > allow_intrabc ) {
p_frame_header - > loop_filter_params . loop_filter_level [ 0 ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_level [ 1 ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kIntraFrame ] = 1 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kLastFrame ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kLast2Frame ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kLast3Frame ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kBwdRefFrame ] = 0 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kGoldenFrame ] = - 1 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kAltRefFrame ] = - 1 ;
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ kAltRef2Frame ] = - 1 ;
for ( i = 0 ; i < 2 ; i + + ) {
p_frame_header - > loop_filter_params . loop_filter_mode_deltas [ i ] = 0 ;
}
return ;
}
p_frame_header - > loop_filter_params . loop_filter_level [ 0 ] = Parser : : ReadBits ( p_stream , offset , 6 ) ;
p_frame_header - > loop_filter_params . loop_filter_level [ 1 ] = Parser : : ReadBits ( p_stream , offset , 6 ) ;
if ( p_seq_header - > color_config . num_planes > 1 ) {
if ( p_frame_header - > loop_filter_params . loop_filter_level [ 0 ] | | p_frame_header - > loop_filter_params . loop_filter_level [ 1 ] ) {
p_frame_header - > loop_filter_params . loop_filter_level [ 2 ] = Parser : : ReadBits ( p_stream , offset , 6 ) ;
p_frame_header - > loop_filter_params . loop_filter_level [ 3 ] = Parser : : ReadBits ( p_stream , offset , 6 ) ;
}
}
p_frame_header - > loop_filter_params . loop_filter_sharpness = Parser : : ReadBits ( p_stream , offset , 3 ) ;
p_frame_header - > loop_filter_params . loop_filter_delta_enabled = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > loop_filter_params . loop_filter_delta_enabled = = 1 ) {
p_frame_header - > loop_filter_params . loop_filter_delta_update = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > loop_filter_params . loop_filter_delta_update = = 1 ) {
for ( i = 0 ; i < TOTAL_REFS_PER_FRAME ; i + + ) {
p_frame_header - > loop_filter_params . update_ref_delta = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > loop_filter_params . update_ref_delta = = 1 ) {
p_frame_header - > loop_filter_params . loop_filter_ref_deltas [ i ] = ReadSigned ( p_stream , offset , 1 + 6 ) ;
}
}
for ( i = 0 ; i < 2 ; i + + ) {
p_frame_header - > loop_filter_params . update_mode_delta = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > loop_filter_params . update_mode_delta = = 1 )
{
p_frame_header - > loop_filter_params . loop_filter_mode_deltas [ i ] = ReadSigned ( p_stream , offset , 1 + 6 ) ;
}
}
}
}
}
void Av1VideoParser : : CdefParams ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
if ( p_frame_header - > coded_lossless | | p_frame_header - > allow_intrabc | | ! p_seq_header - > enable_cdef ) {
p_frame_header - > cdef_params . cdef_bits = 0 ;
p_frame_header - > cdef_params . cdef_y_pri_strength [ 0 ] = 0 ;
p_frame_header - > cdef_params . cdef_y_sec_strength [ 0 ] = 0 ;
p_frame_header - > cdef_params . cdef_uv_pri_strength [ 0 ] = 0 ;
p_frame_header - > cdef_params . cdef_uv_sec_strength [ 0 ] = 0 ;
p_frame_header - > cdef_params . cdef_damping = 3 ;
return ;
}
p_frame_header - > cdef_params . cdef_damping_minus_3 = Parser : : ReadBits ( p_stream , offset , 2 ) ;
p_frame_header - > cdef_params . cdef_damping = p_frame_header - > cdef_params . cdef_damping_minus_3 + 3 ;
p_frame_header - > cdef_params . cdef_bits = Parser : : ReadBits ( p_stream , offset , 2 ) ;
for ( int i = 0 ; i < ( 1 < < p_frame_header - > cdef_params . cdef_bits ) ; i + + ) {
p_frame_header - > cdef_params . cdef_y_pri_strength [ i ] = Parser : : ReadBits ( p_stream , offset , 4 ) ;
p_frame_header - > cdef_params . cdef_y_sec_strength [ i ] = Parser : : ReadBits ( p_stream , offset , 2 ) ;
if ( p_frame_header - > cdef_params . cdef_y_sec_strength [ i ] = = 3 ) {
p_frame_header - > cdef_params . cdef_y_sec_strength [ i ] + = 1 ;
}
if ( p_seq_header - > color_config . num_planes > 1 ) {
p_frame_header - > cdef_params . cdef_uv_pri_strength [ i ] = Parser : : ReadBits ( p_stream , offset , 4 ) ;
p_frame_header - > cdef_params . cdef_uv_sec_strength [ i ] = Parser : : ReadBits ( p_stream , offset , 2 ) ;
if ( p_frame_header - > cdef_params . cdef_uv_sec_strength [ i ] = = 3 ) {
p_frame_header - > cdef_params . cdef_uv_sec_strength [ i ] + = 1 ;
}
}
}
}
void Av1VideoParser : : LrParams ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
uint32_t remap_lr_type [ 4 ] = { kRestoreNone , kRestoreSwitchable , kRestoreWiener , kRestoreSgrproj } ;
if ( p_frame_header - > all_lossless | | p_frame_header - > allow_intrabc | | ! p_seq_header - > enable_restoration ) {
p_frame_header - > lr_params . frame_restoration_type [ 0 ] = kRestoreNone ;
p_frame_header - > lr_params . frame_restoration_type [ 1 ] = kRestoreNone ;
p_frame_header - > lr_params . frame_restoration_type [ 2 ] = kRestoreNone ;
p_frame_header - > lr_params . uses_lr = 0 ;
return ;
}
p_frame_header - > lr_params . uses_lr = 0 ;
uint32_t uses_chroma_lr = 0 ;
for ( int i = 0 ; i < p_seq_header - > color_config . num_planes ; i + + ) {
2024-06-10 12:07:23 -04:00
p_frame_header - > lr_params . lr_type [ i ] = Parser : : ReadBits ( p_stream , offset , 2 ) ;
p_frame_header - > lr_params . frame_restoration_type [ i ] = remap_lr_type [ p_frame_header - > lr_params . lr_type [ i ] ] ;
2024-04-11 09:01:54 -04:00
if ( p_frame_header - > lr_params . frame_restoration_type [ i ] ! = kRestoreNone ) {
p_frame_header - > lr_params . uses_lr = 1 ;
if ( i > 0 ) {
uses_chroma_lr = 1 ;
}
}
}
if ( p_frame_header - > lr_params . uses_lr ) {
if ( p_seq_header - > use_128x128_superblock ) {
p_frame_header - > lr_params . lr_unit_shift = Parser : : GetBit ( p_stream , offset ) ;
p_frame_header - > lr_params . lr_unit_shift + + ;
} else {
p_frame_header - > lr_params . lr_unit_shift = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > lr_params . lr_unit_shift ) {
p_frame_header - > lr_params . lr_unit_extra_shift = Parser : : GetBit ( p_stream , offset ) ;
p_frame_header - > lr_params . lr_unit_shift + = p_frame_header - > lr_params . lr_unit_extra_shift ;
}
}
p_frame_header - > lr_params . loop_restoration_size [ 0 ] = RESTORATION_TILESIZE_MAX > > ( 2 - p_frame_header - > lr_params . lr_unit_shift ) ;
if ( p_seq_header - > color_config . subsampling_x & & p_seq_header - > color_config . subsampling_y & & uses_chroma_lr ) {
p_frame_header - > lr_params . lr_uv_shift = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_frame_header - > lr_params . lr_uv_shift = 0 ;
}
p_frame_header - > lr_params . loop_restoration_size [ 1 ] = p_frame_header - > lr_params . loop_restoration_size [ 0 ] > > p_frame_header - > lr_params . lr_uv_shift ;
p_frame_header - > lr_params . loop_restoration_size [ 2 ] = p_frame_header - > lr_params . loop_restoration_size [ 0 ] > > p_frame_header - > lr_params . lr_uv_shift ;
}
}
void Av1VideoParser : : ReadTxMode ( const uint8_t * p_stream , size_t & offset , Av1FrameHeader * p_frame_header ) {
if ( p_frame_header - > coded_lossless = = 1 ) {
p_frame_header - > tx_mode . tx_mode = kOnly4x4 ;
} else {
p_frame_header - > tx_mode . tx_mode_select = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > tx_mode . tx_mode_select ) {
p_frame_header - > tx_mode . tx_mode = kTxModeSelect ;
} else {
2024-06-10 12:07:23 -04:00
p_frame_header - > tx_mode . tx_mode = kTxModeLargest ;
2024-04-11 09:01:54 -04:00
}
}
}
void Av1VideoParser : : SkipModeParams ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
uint32_t skip_mode_allowed ;
int forward_idx , backward_idx ;
int forward_hint , backward_hint ;
int second_forward_idx , second_forward_hint ;
uint32_t ref_hint ;
int i ;
if ( p_frame_header - > frame_is_intra | | ! p_frame_header - > frame_reference_mode . reference_select | | ! p_seq_header - > enable_order_hint ) {
skip_mode_allowed = 0 ;
} else {
forward_idx = - 1 ;
backward_idx = - 1 ;
forward_hint = ref_order_hint_ [ 0 ] ; // init value. No effect.
backward_hint = ref_order_hint_ [ 1 ] ; // init value. No effect.
for ( i = 0 ; i < REFS_PER_FRAME ; i + + ) {
ref_hint = ref_order_hint_ [ p_frame_header - > ref_frame_idx [ i ] ] ;
if ( GetRelativeDist ( p_seq_header , ref_hint , p_frame_header - > order_hint ) < 0 ) {
if ( forward_idx < 0 | | GetRelativeDist ( p_seq_header , ref_hint , forward_hint ) > 0 ) {
forward_idx = i ;
forward_hint = ref_hint ;
}
} else if ( GetRelativeDist ( p_seq_header , ref_hint , p_frame_header - > order_hint ) > 0 ) {
if ( backward_idx < 0 | | GetRelativeDist ( p_seq_header , ref_hint , backward_hint ) < 0 ) {
backward_idx = i ;
backward_hint = ref_hint ;
}
}
}
if ( forward_idx < 0 ) {
skip_mode_allowed = 0 ;
} else if ( backward_idx > = 0 ) {
skip_mode_allowed = 1 ;
p_frame_header - > skip_mode_params . skip_mode_frame [ 0 ] = kLastFrame + std : : min ( forward_idx , backward_idx ) ;
p_frame_header - > skip_mode_params . skip_mode_frame [ 1 ] = kLastFrame + std : : max ( forward_idx , backward_idx ) ;
} else {
second_forward_idx = - 1 ;
second_forward_hint = ref_order_hint_ [ 0 ] ; // init value. No effect.
for ( i = 0 ; i < REFS_PER_FRAME ; i + + ) {
ref_hint = ref_order_hint_ [ p_frame_header - > ref_frame_idx [ i ] ] ;
if ( GetRelativeDist ( p_seq_header , ref_hint , forward_hint ) < 0 ) {
if ( second_forward_idx < 0 | | GetRelativeDist ( p_seq_header , ref_hint , second_forward_hint ) > 0 ) {
second_forward_idx = i ;
second_forward_hint = ref_hint ;
}
}
}
if ( second_forward_idx < 0 ) {
skip_mode_allowed = 0 ;
} else {
skip_mode_allowed = 1 ;
p_frame_header - > skip_mode_params . skip_mode_frame [ 0 ] = kLastFrame + std : : min ( forward_idx , second_forward_idx ) ;
p_frame_header - > skip_mode_params . skip_mode_frame [ 1 ] = kLastFrame + std : : max ( forward_idx , second_forward_idx ) ;
}
}
}
if ( skip_mode_allowed ) {
p_frame_header - > skip_mode_params . skip_mode_present = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_frame_header - > skip_mode_params . skip_mode_present = 0 ;
}
}
void Av1VideoParser : : GlobalMotionParams ( const uint8_t * p_stream , size_t & offset , Av1FrameHeader * p_frame_header ) {
int ref ;
int type ;
for ( ref = kLastFrame ; ref < = kAltRefFrame ; ref + + ) {
p_frame_header - > global_motion_params . gm_type [ ref ] = kIdentity ;
for ( int i = 0 ; i < 6 ; i + + ) {
p_frame_header - > global_motion_params . gm_params [ ref ] [ i ] = ( ( i % 3 = = 2 ) ? 1 < < WARPEDMODEL_PREC_BITS : 0 ) ;
}
}
if ( p_frame_header - > frame_is_intra ) {
return ;
}
for ( ref = kLastFrame ; ref < = kAltRefFrame ; ref + + ) {
p_frame_header - > global_motion_params . is_global = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > global_motion_params . is_global ) {
p_frame_header - > global_motion_params . is_rot_zoom = Parser : : GetBit ( p_stream , offset ) ;
if ( p_frame_header - > global_motion_params . is_rot_zoom ) {
type = kRotZoom ;
} else {
p_frame_header - > global_motion_params . is_translation = Parser : : GetBit ( p_stream , offset ) ;
type = p_frame_header - > global_motion_params . is_translation ? kTranslation : kAffine ;
}
} else {
type = kIdentity ;
}
p_frame_header - > global_motion_params . gm_type [ ref ] = type ;
if ( type > = kRotZoom ) {
ReadGlobalParam ( p_stream , offset , p_frame_header , type , ref , 2 ) ;
ReadGlobalParam ( p_stream , offset , p_frame_header , type , ref , 3 ) ;
if ( type = = kAffine ) {
ReadGlobalParam ( p_stream , offset , p_frame_header , type , ref , 4 ) ;
ReadGlobalParam ( p_stream , offset , p_frame_header , type , ref , 5 ) ;
} else {
p_frame_header - > global_motion_params . gm_params [ ref ] [ 4 ] = - p_frame_header - > global_motion_params . gm_params [ ref ] [ 3 ] ;
p_frame_header - > global_motion_params . gm_params [ ref ] [ 5 ] = p_frame_header - > global_motion_params . gm_params [ ref ] [ 2 ] ;
}
}
if ( type > = kTranslation ) {
ReadGlobalParam ( p_stream , offset , p_frame_header , type , ref , 0 ) ;
ReadGlobalParam ( p_stream , offset , p_frame_header , type , ref , 1 ) ;
}
}
}
void Av1VideoParser : : ReadGlobalParam ( const uint8_t * p_stream , size_t & offset , Av1FrameHeader * p_frame_header , int type , int ref , int idx ) {
int abs_bits = GM_ABS_ALPHA_BITS ;
int prec_bits = GM_ALPHA_PREC_BITS ;
if ( idx < 2 ) {
if ( type = = kTranslation ) {
abs_bits = GM_ABS_TRANS_ONLY_BITS - ! p_frame_header - > allow_high_precision_mv ;
prec_bits = GM_TRANS_ONLY_PREC_BITS - ! p_frame_header - > allow_high_precision_mv ;
} else {
abs_bits = GM_ABS_TRANS_BITS ;
prec_bits = GM_TRANS_PREC_BITS ;
}
}
int prec_diff = WARPEDMODEL_PREC_BITS - prec_bits ;
int round = ( idx % 3 ) = = 2 ? ( 1 < < WARPEDMODEL_PREC_BITS ) : 0 ;
int sub = ( idx % 3 ) = = 2 ? ( 1 < < prec_bits ) : 0 ;
int mx = ( 1 < < abs_bits ) ;
2024-06-10 12:07:23 -04:00
int r = ( prev_gm_params_ [ ref ] [ idx ] > > prec_diff ) - sub ;
2024-04-11 09:01:54 -04:00
p_frame_header - > global_motion_params . gm_params [ ref ] [ idx ] = ( DecodeSignedSubexpWithRef ( p_stream , offset , - mx , mx + 1 , r ) < < prec_diff ) + round ;
}
int Av1VideoParser : : DecodeSignedSubexpWithRef ( const uint8_t * p_stream , size_t & offset , int low , int high , int r ) {
int x = DecodeUnsignedSubexpWithRef ( p_stream , offset , high - low , r - low ) ;
return x + low ;
}
int Av1VideoParser : : DecodeUnsignedSubexpWithRef ( const uint8_t * p_stream , size_t & offset , int mx , int r ) {
int v = DecodeSubexp ( p_stream , offset , mx ) ;
if ( ( r < < 1 ) < = mx ) {
return InverseRecenter ( r , v ) ;
} else {
return mx - 1 - InverseRecenter ( mx - 1 - r , v ) ;
}
}
int Av1VideoParser : : DecodeSubexp ( const uint8_t * p_stream , size_t & offset , int num_syms ) {
int i = 0 ;
int mk = 0 ;
int k = 3 ;
while ( 1 ) {
int b2 = i ? k + i - 1 : k ;
int a = 1 < < b2 ;
if ( num_syms < = mk + 3 * a ) {
int subexp_final_bits = ReadUnsignedNonSymmetic ( p_stream , offset , num_syms - mk ) ;
return subexp_final_bits + mk ;
} else {
int subexp_more_bits = Parser : : GetBit ( p_stream , offset ) ;
if ( subexp_more_bits ) {
i + + ;
mk + = a ;
} else {
int subexp_bits = Parser : : ReadBits ( p_stream , offset , b2 ) ;
return subexp_bits + mk ;
}
}
}
}
int Av1VideoParser : : InverseRecenter ( int r , int v ) {
if ( v > 2 * r ) {
return v ;
} else if ( v & 1 ) {
return r - ( ( v + 1 ) > > 1 ) ;
} else {
return r + ( v > > 1 ) ;
}
}
void Av1VideoParser : : FilmGrainParams ( const uint8_t * p_stream , size_t & offset , Av1SequenceHeader * p_seq_header , Av1FrameHeader * p_frame_header ) {
int i ;
if ( ! p_seq_header - > film_grain_params_present | | ( ! p_frame_header - > show_frame & & ! p_frame_header - > showable_frame ) ) {
// reset_grain_params()
memset ( & p_frame_header - > film_grain_params , 0 , sizeof ( Av1FilmGrainParams ) ) ;
return ;
}
p_frame_header - > film_grain_params . apply_grain = Parser : : GetBit ( p_stream , offset ) ;
if ( ! p_frame_header - > film_grain_params . apply_grain )
{
// reset_grain_params()
memset ( & p_frame_header - > film_grain_params , 0 , sizeof ( Av1FilmGrainParams ) ) ;
return ;
}
p_frame_header - > film_grain_params . grain_seed = Parser : : ReadBits ( p_stream , offset , 16 ) ;
if ( p_frame_header - > frame_type = = kInterFrame ) {
p_frame_header - > film_grain_params . update_grain = Parser : : GetBit ( p_stream , offset ) ;
} else {
p_frame_header - > film_grain_params . update_grain = 1 ;
}
if ( ! p_frame_header - > film_grain_params . update_grain ) {
p_frame_header - > film_grain_params . film_grain_params_ref_idx = Parser : : ReadBits ( p_stream , offset , 3 ) ;
int temp_grain_seed = p_frame_header - > film_grain_params . grain_seed ;
//load_grain_params( film_grain_params_ref_idx );
// Todo
ERR ( " Warning: need to implement film grain param loading load_grain_params( film_grain_params_ref_idx ). \n " ) ;
p_frame_header - > film_grain_params . grain_seed = temp_grain_seed ;
return ;
}
p_frame_header - > film_grain_params . num_y_points = Parser : : ReadBits ( p_stream , offset , 4 ) ;
for ( i = 0 ; i < p_frame_header - > film_grain_params . num_y_points ; i + + ) {
p_frame_header - > film_grain_params . point_y_value [ i ] = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_frame_header - > film_grain_params . point_y_scaling [ i ] = Parser : : ReadBits ( p_stream , offset , 8 ) ;
}
if ( p_seq_header - > color_config . mono_chrome ) {
p_frame_header - > film_grain_params . chroma_scaling_from_luma = 0 ;
} else {
p_frame_header - > film_grain_params . chroma_scaling_from_luma = Parser : : GetBit ( p_stream , offset ) ;
}
if ( p_seq_header - > color_config . mono_chrome | | p_frame_header - > film_grain_params . chroma_scaling_from_luma | | ( p_seq_header - > color_config . subsampling_x = = 1 & & p_seq_header - > color_config . subsampling_y = = 1 & & p_frame_header - > film_grain_params . num_y_points = = 0 ) ) {
p_frame_header - > film_grain_params . num_cb_points = 0 ;
p_frame_header - > film_grain_params . num_cr_points = 0 ;
} else {
p_frame_header - > film_grain_params . num_cb_points = Parser : : ReadBits ( p_stream , offset , 4 ) ;
for ( i = 0 ; i < p_frame_header - > film_grain_params . num_cb_points ; i + + ) {
p_frame_header - > film_grain_params . point_cb_value [ i ] = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_frame_header - > film_grain_params . point_cb_scaling [ i ] = Parser : : ReadBits ( p_stream , offset , 8 ) ;
}
p_frame_header - > film_grain_params . num_cr_points = Parser : : ReadBits ( p_stream , offset , 4 ) ;
for ( i = 0 ; i < p_frame_header - > film_grain_params . num_cr_points ; i + + )
{
p_frame_header - > film_grain_params . point_cr_value [ i ] = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_frame_header - > film_grain_params . point_cr_scaling [ i ] = Parser : : ReadBits ( p_stream , offset , 8 ) ;
}
}
p_frame_header - > film_grain_params . grain_scaling_minus_8 = Parser : : ReadBits ( p_stream , offset , 2 ) ;
p_frame_header - > film_grain_params . ar_coeff_lag = Parser : : ReadBits ( p_stream , offset , 2 ) ;
uint32_t num_pos_luma = 2 * p_frame_header - > film_grain_params . ar_coeff_lag * ( p_frame_header - > film_grain_params . ar_coeff_lag + 1 ) ;
uint32_t num_pos_chroma ;
if ( p_frame_header - > film_grain_params . num_y_points ) {
num_pos_chroma = num_pos_luma + 1 ;
for ( i = 0 ; i < num_pos_luma ; i + + ) {
p_frame_header - > film_grain_params . ar_coeffs_y_plus_128 [ i ] = Parser : : ReadBits ( p_stream , offset , 8 ) ;
}
} else {
num_pos_chroma = num_pos_luma ;
}
if ( p_frame_header - > film_grain_params . chroma_scaling_from_luma | | p_frame_header - > film_grain_params . num_cb_points ) {
for ( i = 0 ; i < num_pos_chroma ; i + + ) {
p_frame_header - > film_grain_params . ar_coeffs_cb_plus_128 [ i ] = Parser : : ReadBits ( p_stream , offset , 8 ) ;
}
}
if ( p_frame_header - > film_grain_params . chroma_scaling_from_luma | | p_frame_header - > film_grain_params . num_cr_points ) {
for ( i = 0 ; i < num_pos_chroma ; i + + ) {
p_frame_header - > film_grain_params . ar_coeffs_cr_plus_128 [ i ] = Parser : : ReadBits ( p_stream , offset , 8 ) ;
}
}
p_frame_header - > film_grain_params . ar_coeff_shift_minus_6 = Parser : : ReadBits ( p_stream , offset , 2 ) ;
p_frame_header - > film_grain_params . grain_scale_shift = Parser : : ReadBits ( p_stream , offset , 2 ) ;
if ( p_frame_header - > film_grain_params . num_cb_points ) {
p_frame_header - > film_grain_params . cb_mult = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_frame_header - > film_grain_params . cb_luma_mult = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_frame_header - > film_grain_params . cb_offset = Parser : : ReadBits ( p_stream , offset , 9 ) ;
}
if ( p_frame_header - > film_grain_params . num_cr_points ) {
p_frame_header - > film_grain_params . cr_mult = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_frame_header - > film_grain_params . cr_luma_mult = Parser : : ReadBits ( p_stream , offset , 8 ) ;
p_frame_header - > film_grain_params . cr_offset = Parser : : ReadBits ( p_stream , offset , 9 ) ;
}
p_frame_header - > film_grain_params . overlap_flag = Parser : : GetBit ( p_stream , offset ) ;
p_frame_header - > film_grain_params . clip_to_restricted_range = Parser : : GetBit ( p_stream , offset ) ;
}