1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 18:28:12 +00:00

LibVideo/VP9: Move segmentation parameters to FrameContext

Note that some of the previous segmentation feature settings must be
preserved when a frame is decoded that doesn't use segmentation.

This change also allowed a few functions in Decoder to be made static.
This commit is contained in:
Zaggy1024 2022-11-25 17:20:07 -06:00 committed by Andreas Kling
parent d82dc14bd9
commit fedbc12c4d
7 changed files with 74 additions and 64 deletions

View file

@ -110,6 +110,11 @@ DecoderErrorOr<FrameContext> Parser::parse_frame(ReadonlyBytes frame_data)
m_previous_loop_filter_ref_deltas = frame_context.loop_filter_reference_deltas;
m_previous_loop_filter_mode_deltas = frame_context.loop_filter_mode_deltas;
if (frame_context.segmentation_enabled) {
m_previous_should_use_absolute_segment_base_quantizer = frame_context.should_use_absolute_segment_base_quantizer;
m_previous_segmentation_features = frame_context.segmentation_features;
}
return frame_context;
}
@ -265,7 +270,7 @@ DecoderErrorOr<FrameContext> Parser::uncompressed_header()
TRY(loop_filter_params(frame_context));
TRY(quantization_params(frame_context));
TRY(segmentation_params());
TRY(segmentation_params(frame_context));
TRY(parse_tile_counts(frame_context));
frame_context.header_size_in_bytes = TRY_READ(m_bit_stream->read_f16());
@ -437,19 +442,25 @@ DecoderErrorOr<i8> Parser::read_delta_q()
return 0;
}
DecoderErrorOr<void> Parser::segmentation_params()
DecoderErrorOr<void> Parser::segmentation_params(FrameContext& frame_context)
{
m_segmentation_enabled = TRY_READ(m_bit_stream->read_bit());
if (!m_segmentation_enabled)
frame_context.segmentation_enabled = TRY_READ(m_bit_stream->read_bit());
if (!frame_context.segmentation_enabled)
return {};
m_segmentation_update_map = TRY_READ(m_bit_stream->read_bit());
if (m_segmentation_update_map) {
for (auto& segmentation_tree_prob : m_segmentation_tree_probs)
frame_context.should_use_absolute_segment_base_quantizer = m_previous_should_use_absolute_segment_base_quantizer;
frame_context.segmentation_features = m_previous_segmentation_features;
if (TRY_READ(m_bit_stream->read_bit())) {
frame_context.use_full_segment_id_tree = true;
for (auto& segmentation_tree_prob : frame_context.full_segment_id_tree_probabilities)
segmentation_tree_prob = TRY(read_prob());
m_segmentation_temporal_update = TRY_READ(m_bit_stream->read_bit());
for (auto& segmentation_pred_prob : m_segmentation_pred_prob)
segmentation_pred_prob = m_segmentation_temporal_update ? TRY(read_prob()) : 255;
if (TRY_READ(m_bit_stream->read_bit())) {
frame_context.use_predicted_segment_id_tree = true;
for (auto& segmentation_pred_prob : frame_context.predicted_segment_id_tree_probabilities)
segmentation_pred_prob = TRY(read_prob());
}
}
auto segmentation_update_data = (TRY_READ(m_bit_stream->read_bit()));
@ -457,21 +468,19 @@ DecoderErrorOr<void> Parser::segmentation_params()
if (!segmentation_update_data)
return {};
m_segmentation_abs_or_delta_update = TRY_READ(m_bit_stream->read_bit());
frame_context.should_use_absolute_segment_base_quantizer = TRY_READ(m_bit_stream->read_bit());
for (auto i = 0; i < MAX_SEGMENTS; i++) {
for (auto j = 0; j < SEG_LVL_MAX; j++) {
auto feature_value = 0;
auto feature_enabled = TRY_READ(m_bit_stream->read_bit());
m_feature_enabled[i][j] = feature_enabled;
if (feature_enabled) {
auto& feature = frame_context.segmentation_features[i][j];
feature.enabled = TRY_READ(m_bit_stream->read_bit());
if (feature.enabled) {
auto bits_to_read = segmentation_feature_bits[j];
feature_value = TRY_READ(m_bit_stream->read_bits(bits_to_read));
feature.value = TRY_READ(m_bit_stream->read_bits(bits_to_read));
if (segmentation_feature_signed[j]) {
if (TRY_READ(m_bit_stream->read_bit()))
feature_value = -feature_value;
feature.value = -feature.value;
}
}
m_feature_data[i][j] = feature_value;
}
}
@ -524,19 +533,15 @@ DecoderErrorOr<void> Parser::parse_tile_counts(FrameContext& frame_context)
void Parser::setup_past_independence()
{
for (auto i = 0; i < 8; i++) {
for (auto j = 0; j < 4; j++) {
m_feature_data[i][j] = 0;
m_feature_enabled[i][j] = false;
}
}
m_previous_block_contexts.reset();
m_segmentation_abs_or_delta_update = false;
m_previous_loop_filter_ref_deltas[IntraFrame] = 1;
m_previous_loop_filter_ref_deltas[LastFrame] = 0;
m_previous_loop_filter_ref_deltas[GoldenFrame] = -1;
m_previous_loop_filter_ref_deltas[AltRefFrame] = -1;
m_previous_loop_filter_mode_deltas.fill(0);
m_previous_should_use_absolute_segment_base_quantizer = false;
for (auto& segment_levels : m_previous_segmentation_features)
segment_levels.fill({ false, 0 });
m_probability_tables->reset_probs();
}
@ -1026,8 +1031,8 @@ DecoderErrorOr<void> Parser::intra_frame_mode_info(BlockContext& block_context,
DecoderErrorOr<void> Parser::set_intra_segment_id(BlockContext& block_context)
{
if (m_segmentation_enabled && m_segmentation_update_map)
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, m_segmentation_tree_probs));
if (block_context.frame_context.segmentation_enabled && block_context.frame_context.use_full_segment_id_tree)
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, block_context.frame_context.full_segment_id_tree_probabilities));
else
block_context.segment_id = 0;
return {};
@ -1042,7 +1047,7 @@ DecoderErrorOr<bool> Parser::read_should_skip_residuals(BlockContext& block_cont
bool Parser::seg_feature_active(BlockContext const& block_context, u8 feature)
{
return m_segmentation_enabled && m_feature_enabled[block_context.segment_id][feature];
return block_context.frame_context.segmentation_features[block_context.segment_id][feature].enabled;
}
DecoderErrorOr<TXSize> Parser::read_tx_size(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select)
@ -1069,25 +1074,25 @@ DecoderErrorOr<void> Parser::inter_frame_mode_info(BlockContext& block_context,
DecoderErrorOr<void> Parser::set_inter_segment_id(BlockContext& block_context)
{
if (!m_segmentation_enabled) {
if (!block_context.frame_context.segmentation_enabled) {
block_context.segment_id = 0;
return {};
}
auto predicted_segment_id = get_segment_id(block_context);
if (!m_segmentation_update_map) {
if (!block_context.frame_context.use_full_segment_id_tree) {
block_context.segment_id = predicted_segment_id;
return {};
}
if (!m_segmentation_temporal_update) {
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, m_segmentation_tree_probs));
if (!block_context.frame_context.use_predicted_segment_id_tree) {
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, block_context.frame_context.full_segment_id_tree_probabilities));
return {};
}
auto seg_id_predicted = TRY_READ(TreeParser::parse_segment_id_predicted(*m_bit_stream, m_segmentation_pred_prob, m_left_seg_pred_context[block_context.row], m_above_seg_pred_context[block_context.column]));
auto seg_id_predicted = TRY_READ(TreeParser::parse_segment_id_predicted(*m_bit_stream, block_context.frame_context.predicted_segment_id_tree_probabilities, m_left_seg_pred_context[block_context.row], m_above_seg_pred_context[block_context.column]));
if (seg_id_predicted)
block_context.segment_id = predicted_segment_id;
else
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, m_segmentation_tree_probs));
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, block_context.frame_context.full_segment_id_tree_probabilities));
for (size_t i = 0; i < num_8x8_blocks_wide_lookup[block_context.size]; i++) {
auto index = block_context.column + i;
@ -1122,7 +1127,7 @@ u8 Parser::get_segment_id(BlockContext const& block_context)
DecoderErrorOr<bool> Parser::read_is_inter(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
{
if (seg_feature_active(block_context, SEG_LVL_REF_FRAME))
return m_feature_data[block_context.segment_id][SEG_LVL_REF_FRAME] != IntraFrame;
return block_context.frame_context.segmentation_features[block_context.segment_id][SEG_LVL_REF_FRAME].value != IntraFrame;
return TRY_READ(TreeParser::parse_block_is_inter_predicted(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
}
@ -1205,7 +1210,7 @@ DecoderErrorOr<void> Parser::inter_block_mode_info(BlockContext& block_context,
DecoderErrorOr<void> Parser::read_ref_frames(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
{
if (seg_feature_active(block_context, SEG_LVL_REF_FRAME)) {
block_context.reference_frame_types = { static_cast<ReferenceFrameType>(m_feature_data[block_context.segment_id][SEG_LVL_REF_FRAME]), None };
block_context.reference_frame_types = { static_cast<ReferenceFrameType>(block_context.frame_context.segmentation_features[block_context.segment_id][SEG_LVL_REF_FRAME].value), None };
return {};
}