1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 07:07:45 +00:00

LibVideo/VP9: Move reference frame type fields to FrameContext

This commit is contained in:
Zaggy1024 2022-11-24 23:36:38 -06:00 committed by Andreas Kling
parent b966f9d811
commit 3af4deba6d
3 changed files with 49 additions and 45 deletions

View file

@ -331,6 +331,11 @@ public:
TXMode transform_mode;
// This group also is only needed for inter-predicted frames.
ReferenceMode reference_mode;
ReferenceFrameType fixed_reference_type;
ReferenceFramePair variable_reference_types;
private:
friend struct TileContext;

View file

@ -553,7 +553,7 @@ DecoderErrorOr<void> Parser::compressed_header(FrameContext& frame_context)
TRY(read_interp_filter_probs());
TRY(read_is_inter_probs());
TRY(frame_reference_mode(frame_context));
TRY(frame_reference_mode_probs());
TRY(frame_reference_mode_probs(frame_context));
TRY(read_y_mode_probs());
TRY(read_partition_probs());
TRY(mv_probs(frame_context));
@ -690,49 +690,68 @@ DecoderErrorOr<void> Parser::read_is_inter_probs()
return {};
}
static void setup_compound_reference_mode(FrameContext& frame_context)
{
ReferenceFrameType fixed_reference;
ReferenceFramePair variable_references;
if (frame_context.reference_frame_sign_biases[LastFrame] == frame_context.reference_frame_sign_biases[GoldenFrame]) {
fixed_reference = AltRefFrame;
variable_references = { LastFrame, GoldenFrame };
} else if (frame_context.reference_frame_sign_biases[LastFrame] == frame_context.reference_frame_sign_biases[AltRefFrame]) {
fixed_reference = GoldenFrame;
variable_references = { LastFrame, AltRefFrame };
} else {
fixed_reference = LastFrame;
variable_references = { GoldenFrame, AltRefFrame };
}
frame_context.fixed_reference_type = fixed_reference;
frame_context.variable_reference_types = variable_references;
}
DecoderErrorOr<void> Parser::frame_reference_mode(FrameContext& frame_context)
{
// FIXME: These fields and the ones set in setup_compound_reference_mode should probably be contained by a field,
// since they are all used to set the reference frames later in one function (I think).
auto compound_reference_allowed = false;
for (size_t i = 2; i <= REFS_PER_FRAME; i++) {
if (frame_context.reference_frame_sign_biases[i] != frame_context.reference_frame_sign_biases[1])
compound_reference_allowed = true;
}
ReferenceMode reference_mode;
if (compound_reference_allowed) {
auto non_single_reference = TRY_READ(m_bit_stream->read_literal(1));
if (non_single_reference == 0) {
m_reference_mode = SingleReference;
reference_mode = SingleReference;
} else {
auto reference_select = TRY_READ(m_bit_stream->read_literal(1));
if (reference_select == 0)
m_reference_mode = CompoundReference;
reference_mode = CompoundReference;
else
m_reference_mode = ReferenceModeSelect;
setup_compound_reference_mode(frame_context);
reference_mode = ReferenceModeSelect;
}
} else {
m_reference_mode = SingleReference;
reference_mode = SingleReference;
}
frame_context.reference_mode = reference_mode;
if (reference_mode != SingleReference)
setup_compound_reference_mode(frame_context);
return {};
}
DecoderErrorOr<void> Parser::frame_reference_mode_probs()
DecoderErrorOr<void> Parser::frame_reference_mode_probs(FrameContext const& frame_context)
{
if (m_reference_mode == ReferenceModeSelect) {
if (frame_context.reference_mode == ReferenceModeSelect) {
for (auto i = 0; i < COMP_MODE_CONTEXTS; i++) {
auto& comp_mode_prob = m_probability_tables->comp_mode_prob();
comp_mode_prob[i] = TRY(diff_update_prob(comp_mode_prob[i]));
}
}
if (m_reference_mode != CompoundReference) {
if (frame_context.reference_mode != CompoundReference) {
for (auto i = 0; i < REF_CONTEXTS; i++) {
auto& single_ref_prob = m_probability_tables->single_ref_prob();
single_ref_prob[i][0] = TRY(diff_update_prob(single_ref_prob[i][0]));
single_ref_prob[i][1] = TRY(diff_update_prob(single_ref_prob[i][1]));
}
}
if (m_reference_mode != SingleReference) {
if (frame_context.reference_mode != SingleReference) {
for (auto i = 0; i < REF_CONTEXTS; i++) {
auto& comp_ref_prob = m_probability_tables->comp_ref_prob();
comp_ref_prob[i] = TRY(diff_update_prob(comp_ref_prob[i]));
@ -818,23 +837,6 @@ DecoderErrorOr<u8> Parser::update_mv_prob(u8 prob)
return prob;
}
void Parser::setup_compound_reference_mode(FrameContext& frame_context)
{
if (frame_context.reference_frame_sign_biases[LastFrame] == frame_context.reference_frame_sign_biases[GoldenFrame]) {
m_comp_fixed_ref = AltRefFrame;
m_comp_var_ref[0] = LastFrame;
m_comp_var_ref[1] = GoldenFrame;
} else if (frame_context.reference_frame_sign_biases[LastFrame] == frame_context.reference_frame_sign_biases[AltRefFrame]) {
m_comp_fixed_ref = GoldenFrame;
m_comp_var_ref[0] = LastFrame;
m_comp_var_ref[1] = AltRefFrame;
} else {
m_comp_fixed_ref = LastFrame;
m_comp_var_ref[0] = GoldenFrame;
m_comp_var_ref[1] = AltRefFrame;
}
}
DecoderErrorOr<void> Parser::decode_tiles(FrameContext& frame_context)
{
auto log2_dimensions = frame_context.log2_of_tile_counts;
@ -1203,23 +1205,24 @@ DecoderErrorOr<void> Parser::read_ref_frames(BlockContext& block_context, FrameB
block_context.reference_frame_types = { static_cast<ReferenceFrameType>(m_feature_data[block_context.segment_id][SEG_LVL_REF_FRAME]), None };
return {};
}
ReferenceMode comp_mode;
if (m_reference_mode == ReferenceModeSelect)
comp_mode = TRY_READ(TreeParser::parse_comp_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_comp_fixed_ref, above_context, left_context));
else
comp_mode = m_reference_mode;
if (comp_mode == CompoundReference) {
// FIXME: Make reference frame pairs be indexed by an enum of FixedReference or VariableReference?
auto fixed_reference_index = block_context.frame_context.reference_frame_sign_biases[m_comp_fixed_ref];
ReferenceMode compound_mode = block_context.frame_context.reference_mode;
auto fixed_reference = block_context.frame_context.fixed_reference_type;
if (compound_mode == ReferenceModeSelect)
compound_mode = TRY_READ(TreeParser::parse_comp_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, fixed_reference, above_context, left_context));
if (compound_mode == CompoundReference) {
auto secondary_reference = block_context.frame_context.variable_reference_types;
auto fixed_reference_index = block_context.frame_context.reference_frame_sign_biases[fixed_reference];
auto variable_reference_index = !fixed_reference_index;
// FIXME: Create an enum for compound frame references using names Primary and Secondary.
auto comp_ref = TRY_READ(TreeParser::parse_comp_ref(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_comp_fixed_ref, m_comp_var_ref, variable_reference_index, above_context, left_context));
auto secondary_reference_selection = TRY_READ(TreeParser::parse_comp_ref(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, fixed_reference, secondary_reference, variable_reference_index, above_context, left_context));
block_context.reference_frame_types[fixed_reference_index] = m_comp_fixed_ref;
block_context.reference_frame_types[variable_reference_index] = m_comp_var_ref[comp_ref];
block_context.reference_frame_types[fixed_reference_index] = fixed_reference;
block_context.reference_frame_types[variable_reference_index] = secondary_reference[secondary_reference_selection];
return {};
}
// FIXME: Maybe consolidate this into a tree. Context is different between part 1 and 2 but still, it would look nice here.
auto single_ref_p1 = TRY_READ(TreeParser::parse_single_ref_part_1(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
if (single_ref_p1) {

View file

@ -86,12 +86,11 @@ private:
DecoderErrorOr<void> read_interp_filter_probs();
DecoderErrorOr<void> read_is_inter_probs();
DecoderErrorOr<void> frame_reference_mode(FrameContext&);
DecoderErrorOr<void> frame_reference_mode_probs();
DecoderErrorOr<void> frame_reference_mode_probs(FrameContext const&);
DecoderErrorOr<void> read_y_mode_probs();
DecoderErrorOr<void> read_partition_probs();
DecoderErrorOr<void> mv_probs(FrameContext const&);
DecoderErrorOr<u8> update_mv_prob(u8 prob);
void setup_compound_reference_mode(FrameContext&);
/* (6.4) Decode Tiles Syntax */
DecoderErrorOr<void> decode_tiles(FrameContext&);
@ -169,9 +168,6 @@ private:
u8 m_token_cache[1024];
i32 m_tokens[1024];
bool m_use_hp { false };
ReferenceMode m_reference_mode;
ReferenceFrameType m_comp_fixed_ref;
ReferenceFramePair m_comp_var_ref;
bool m_use_prev_frame_mvs;
Vector2D<FrameBlockContext> m_reusable_frame_block_contexts;