diff --git a/Userland/Libraries/LibVideo/VP9/Parser.cpp b/Userland/Libraries/LibVideo/VP9/Parser.cpp index 48e33dac7d..752d1981ab 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.cpp +++ b/Userland/Libraries/LibVideo/VP9/Parser.cpp @@ -1279,10 +1279,17 @@ DecoderErrorOr Parser::read_ref_frames() return {}; } ReferenceMode comp_mode; - if (m_reference_mode == ReferenceModeSelect) - comp_mode = TRY_READ(m_tree_parser->parse_tree(SyntaxElementType::CompMode)); - else + if (m_reference_mode == ReferenceModeSelect) { + Optional above_single = m_available_u ? m_above_single : Optional(); + Optional left_single = m_available_l ? m_left_single : Optional(); + Optional above_intra = m_available_u ? m_above_intra : Optional(); + Optional left_intra = m_available_l ? m_left_intra : Optional(); + Optional above_ref_frame_0 = m_available_u ? m_above_ref_frame[0] : Optional(); + Optional left_ref_frame_0 = m_available_l ? m_left_ref_frame[0] : Optional(); + comp_mode = TRY_READ(TreeParser::parse_comp_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_comp_fixed_ref, above_single, left_single, above_intra, left_intra, above_ref_frame_0, left_ref_frame_0)); + } else { comp_mode = m_reference_mode; + } if (comp_mode == CompoundReference) { auto idx = m_ref_frame_sign_bias[m_comp_fixed_ref]; auto comp_ref = TRY_READ(m_tree_parser->parse_tree(SyntaxElementType::CompRef)); diff --git a/Userland/Libraries/LibVideo/VP9/TreeParser.cpp b/Userland/Libraries/LibVideo/VP9/TreeParser.cpp index 99bfee4ce8..f8e718f7fe 100644 --- a/Userland/Libraries/LibVideo/VP9/TreeParser.cpp +++ b/Userland/Libraries/LibVideo/VP9/TreeParser.cpp @@ -306,13 +306,52 @@ ErrorOr TreeParser::parse_is_inter(BitStream& bit_stream, ProbabilityTable return value; } +ErrorOr TreeParser::parse_comp_mode(BitStream& bit_stream, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, ReferenceFrameType comp_fixed_ref, Optional above_single, Optional left_single, Optional above_intra, Optional left_intra, Optional above_ref_frame_0, Optional left_ref_frame_0) +{ + // FIXME: Above and left contexts should be in structs. + + // Probabilities + u8 context; + if (above_single.has_value() && left_single.has_value()) { + if (above_single.value() && left_single.value()) { + auto is_above_fixed = above_ref_frame_0.value() == comp_fixed_ref; + auto is_left_fixed = left_ref_frame_0.value() == comp_fixed_ref; + context = is_above_fixed ^ is_left_fixed; + } else if (above_single.value()) { + auto is_above_fixed = above_ref_frame_0.value() == comp_fixed_ref; + context = 2 + static_cast(is_above_fixed || above_intra.value()); + } else if (left_single.value()) { + auto is_left_fixed = left_ref_frame_0.value() == comp_fixed_ref; + context = 2 + static_cast(is_left_fixed || left_intra.value()); + } else { + context = 4; + } + } else if (above_single.has_value()) { + if (above_single.value()) + context = above_ref_frame_0.value() == comp_fixed_ref; + else + context = 3; + } else if (left_single.has_value()) { + if (left_single.value()) + context = static_cast(left_ref_frame_0.value() == comp_fixed_ref); + else + context = 3; + } else { + context = 1; + } + u8 probability = probability_table.comp_mode_prob()[context]; + + auto value = TRY(parse_tree_new(bit_stream, { binary_tree }, [&](u8) { return probability; })); + increment_counter(counter.m_counts_comp_mode[context][value]); + return value; +} + /* * Select a tree value based on the type of syntax element being parsed, as well as some parser state, as specified in section 9.3.1 */ TreeParser::TreeSelection TreeParser::select_tree(SyntaxElementType type) { switch (type) { - case SyntaxElementType::CompMode: case SyntaxElementType::CompRef: case SyntaxElementType::SingleRefP1: case SyntaxElementType::SingleRefP2: @@ -347,8 +386,6 @@ TreeParser::TreeSelection TreeParser::select_tree(SyntaxElementType type) u8 TreeParser::select_tree_probability(SyntaxElementType type, u8 node) { switch (type) { - case SyntaxElementType::CompMode: - return calculate_comp_mode_probability(); case SyntaxElementType::CompRef: return calculate_comp_ref_probability(); case SyntaxElementType::SingleRefP1: @@ -398,40 +435,6 @@ u8 TreeParser::select_tree_probability(SyntaxElementType type, u8 node) #define ABOVE_SINGLE m_decoder.m_above_single #define LEFT_SINGLE m_decoder.m_left_single -u8 TreeParser::calculate_comp_mode_probability() -{ - if (AVAIL_U && AVAIL_L) { - if (ABOVE_SINGLE && LEFT_SINGLE) { - auto is_above_fixed = ABOVE_FRAME_0 == m_decoder.m_comp_fixed_ref; - auto is_left_fixed = LEFT_FRAME_0 == m_decoder.m_comp_fixed_ref; - m_ctx = is_above_fixed ^ is_left_fixed; - } else if (ABOVE_SINGLE) { - auto is_above_fixed = ABOVE_FRAME_0 == m_decoder.m_comp_fixed_ref; - m_ctx = 2 + (is_above_fixed || ABOVE_INTRA); - } else if (LEFT_SINGLE) { - auto is_left_fixed = LEFT_FRAME_0 == m_decoder.m_comp_fixed_ref; - m_ctx = 2 + (is_left_fixed || LEFT_INTRA); - } else { - m_ctx = 4; - } - } else if (AVAIL_U) { - if (ABOVE_SINGLE) { - m_ctx = ABOVE_FRAME_0 == m_decoder.m_comp_fixed_ref; - } else { - m_ctx = 3; - } - } else if (AVAIL_L) { - if (LEFT_SINGLE) { - m_ctx = LEFT_FRAME_0 == m_decoder.m_comp_fixed_ref; - } else { - m_ctx = 3; - } - } else { - m_ctx = 1; - } - return m_decoder.m_probability_tables->comp_mode_prob()[m_ctx]; -} - u8 TreeParser::calculate_comp_ref_probability() { auto fix_ref_idx = m_decoder.m_ref_frame_sign_bias[m_decoder.m_comp_fixed_ref]; @@ -722,9 +725,6 @@ void TreeParser::count_syntax_element(SyntaxElementType type, int value) increment_counter(count); }; switch (type) { - case SyntaxElementType::CompMode: - increment(m_decoder.m_syntax_element_counter->m_counts_comp_mode[m_ctx][value]); - return; case SyntaxElementType::CompRef: increment(m_decoder.m_syntax_element_counter->m_counts_comp_ref[m_ctx][value]); return; diff --git a/Userland/Libraries/LibVideo/VP9/TreeParser.h b/Userland/Libraries/LibVideo/VP9/TreeParser.h index fb6a9cfa9c..02add35c23 100644 --- a/Userland/Libraries/LibVideo/VP9/TreeParser.h +++ b/Userland/Libraries/LibVideo/VP9/TreeParser.h @@ -75,6 +75,7 @@ public: static ErrorOr parse_skip(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, Optional const& above_skip, Optional const& left_skip); static ErrorOr parse_tx_size(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, TXSize max_tx_size, Optional above_skip, Optional left_skip, Optional above_tx_size, Optional left_tx_size); static ErrorOr parse_is_inter(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, Optional above_intra, Optional left_intra); + static ErrorOr parse_comp_mode(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, ReferenceFrameType comp_fixed_ref, Optional above_single, Optional left_single, Optional above_intra, Optional left_intra, Optional above_ref_frame_0, Optional left_ref_frame_0); void set_default_intra_mode_variables(u8 idx, u8 idy) { @@ -108,7 +109,6 @@ public: } private: - u8 calculate_comp_mode_probability(); u8 calculate_comp_ref_probability(); u8 calculate_single_ref_p1_probability(); u8 calculate_single_ref_p2_probability();