From 094b0d8a7836ac08a759c1efbbe5e1b0c668df11 Mon Sep 17 00:00:00 2001 From: Zaggy1024 Date: Sun, 16 Apr 2023 23:29:48 -0500 Subject: LibVideo/VP9: Use an enum to select segment features This throws out some ugly `#define`s we had that were taking the role of an enum anyway. We now have some nice getters in the contexts that take the place of the combo of `seg_feature_active()` and then doing a lookup in `FrameContext::m_segmentation_features` directly. --- Userland/Libraries/LibVideo/VP9/Context.h | 11 ++++++++- Userland/Libraries/LibVideo/VP9/ContextStorage.h | 5 +++- Userland/Libraries/LibVideo/VP9/Decoder.cpp | 5 ++-- Userland/Libraries/LibVideo/VP9/Enums.h | 13 +++++++++++ Userland/Libraries/LibVideo/VP9/LookupTables.h | 4 ++-- Userland/Libraries/LibVideo/VP9/Parser.cpp | 29 +++++++++++------------- Userland/Libraries/LibVideo/VP9/Parser.h | 3 +-- Userland/Libraries/LibVideo/VP9/Symbols.h | 5 ---- 8 files changed, 46 insertions(+), 29 deletions(-) (limited to 'Userland/Libraries/LibVideo/VP9') diff --git a/Userland/Libraries/LibVideo/VP9/Context.h b/Userland/Libraries/LibVideo/VP9/Context.h index dffc0ad6d1..7e2477d9cc 100644 --- a/Userland/Libraries/LibVideo/VP9/Context.h +++ b/Userland/Libraries/LibVideo/VP9/Context.h @@ -143,7 +143,11 @@ public: bool use_predicted_segment_id_tree { false }; Array predicted_segment_id_tree_probabilities; bool should_use_absolute_segment_base_quantizer { false }; - Array, MAX_SEGMENTS> segmentation_features; + SegmentationFeatures segmentation_features; + SegmentFeatureStatus get_segment_feature(u8 segment_id, SegmentFeature feature) const + { + return segmentation_features[segment_id][to_underlying(feature)]; + } u16 header_size_in_bytes { 0 }; @@ -334,6 +338,11 @@ struct BlockContext { SegmentationPredictionContextView above_segmentation_ids; NonZeroTokensView left_non_zero_tokens; SegmentationPredictionContextView left_segmentation_ids; + + SegmentFeatureStatus get_segment_feature(SegmentFeature feature) const + { + return frame_context.get_segment_feature(segment_id, feature); + } }; struct BlockMotionVectorCandidateSet { diff --git a/Userland/Libraries/LibVideo/VP9/ContextStorage.h b/Userland/Libraries/LibVideo/VP9/ContextStorage.h index a91175fc14..b6539f0a72 100644 --- a/Userland/Libraries/LibVideo/VP9/ContextStorage.h +++ b/Userland/Libraries/LibVideo/VP9/ContextStorage.h @@ -243,11 +243,14 @@ struct PersistentBlockContext { u8 segment_id { 0 }; }; -struct SegmentFeature { +struct SegmentFeatureStatus { bool enabled { false }; u8 value { 0 }; }; +using SegmentFeatures = Array; +using SegmentationFeatures = Array; + struct ColorConfig { u8 bit_depth { 8 }; ColorSpace color_space { ColorSpace::Bt601 }; diff --git a/Userland/Libraries/LibVideo/VP9/Decoder.cpp b/Userland/Libraries/LibVideo/VP9/Decoder.cpp index 1a88774f22..3756e12404 100644 --- a/Userland/Libraries/LibVideo/VP9/Decoder.cpp +++ b/Userland/Libraries/LibVideo/VP9/Decoder.cpp @@ -1173,9 +1173,10 @@ u8 Decoder::get_base_quantizer_index(BlockContext const& block_context) { // The function get_qindex( ) returns the quantizer index for the current block and is specified by the following: // − If seg_feature_active( SEG_LVL_ALT_Q ) is equal to 1 the following ordered steps apply: - if (Parser::seg_feature_active(block_context, SEG_LVL_ALT_Q)) { + auto alternative_quantizer_feature = block_context.get_segment_feature(SegmentFeature::UseAlternativeQuantizerBase); + if (alternative_quantizer_feature.enabled) { // 1. Set the variable data equal to FeatureData[ segment_id ][ SEG_LVL_ALT_Q ]. - auto data = block_context.frame_context.segmentation_features[block_context.segment_id][SEG_LVL_ALT_Q].value; + auto data = alternative_quantizer_feature.value; // 2. If segmentation_abs_or_delta_update is equal to 0, set data equal to base_q_idx + data if (!block_context.frame_context.should_use_absolute_segment_base_quantizer) { diff --git a/Userland/Libraries/LibVideo/VP9/Enums.h b/Userland/Libraries/LibVideo/VP9/Enums.h index 5c57513986..e444803db5 100644 --- a/Userland/Libraries/LibVideo/VP9/Enums.h +++ b/Userland/Libraries/LibVideo/VP9/Enums.h @@ -161,4 +161,17 @@ enum Token : u8 { DctValCat6 = 10, }; +enum class SegmentFeature : u8 { + // SEG_LVL_ALT_Q + UseAlternativeQuantizerBase, + // SEG_LVL_ALT_L + UseAlternativeLoopFilterBase, + // SEG_LVL_REF_FRAME + ReferenceFrameOverride, + // SEG_LVL_SKIP + SkipResidualsOverride, + // SEG_LVL_MAX + Sentinel, +}; + } diff --git a/Userland/Libraries/LibVideo/VP9/LookupTables.h b/Userland/Libraries/LibVideo/VP9/LookupTables.h index 1f523d94a3..8d4ac6a8d0 100644 --- a/Userland/Libraries/LibVideo/VP9/LookupTables.h +++ b/Userland/Libraries/LibVideo/VP9/LookupTables.h @@ -15,8 +15,8 @@ namespace Video::VP9 { static constexpr InterpolationFilter literal_to_type[4] = { EightTapSmooth, EightTap, EightTapSharp, Bilinear }; static constexpr TransformSize tx_mode_to_biggest_tx_size[TX_MODES] = { Transform_4x4, Transform_8x8, Transform_16x16, Transform_32x32, Transform_32x32 }; -static constexpr u8 segmentation_feature_bits[SEG_LVL_MAX] = { 8, 6, 2, 0 }; -static constexpr bool segmentation_feature_signed[SEG_LVL_MAX] = { true, true, false, false }; +static constexpr u8 segmentation_feature_bits[to_underlying(SegmentFeature::Sentinel)] = { 8, 6, 2, 0 }; +static constexpr bool segmentation_feature_signed[to_underlying(SegmentFeature::Sentinel)] = { true, true, false, false }; static constexpr u8 inv_map_table[MAX_PROB] = { 7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176, 189, 202, 215, 228, 241, 254, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, diff --git a/Userland/Libraries/LibVideo/VP9/Parser.cpp b/Userland/Libraries/LibVideo/VP9/Parser.cpp index 0843873582..25b25c14ed 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.cpp +++ b/Userland/Libraries/LibVideo/VP9/Parser.cpp @@ -476,14 +476,14 @@ DecoderErrorOr Parser::segmentation_params(FrameContext& frame_context) return {}; frame_context.should_use_absolute_segment_base_quantizer = TRY_READ(frame_context.bit_stream.read_bit()); - for (auto i = 0; i < MAX_SEGMENTS; i++) { - for (auto j = 0; j < SEG_LVL_MAX; j++) { - auto& feature = frame_context.segmentation_features[i][j]; + for (auto segment_id = 0; segment_id < MAX_SEGMENTS; segment_id++) { + for (auto feature_id = 0; feature_id < to_underlying(SegmentFeature::Sentinel); feature_id++) { + auto& feature = frame_context.segmentation_features[segment_id][feature_id]; feature.enabled = TRY_READ(frame_context.bit_stream.read_bit()); if (feature.enabled) { - auto bits_to_read = segmentation_feature_bits[j]; + auto bits_to_read = segmentation_feature_bits[feature_id]; feature.value = TRY_READ(frame_context.bit_stream.read_bits(bits_to_read)); - if (segmentation_feature_signed[j]) { + if (segmentation_feature_signed[feature_id]) { if (TRY_READ(frame_context.bit_stream.read_bit())) feature.value = -feature.value; } @@ -1094,16 +1094,11 @@ DecoderErrorOr Parser::set_intra_segment_id(BlockContext& block_context) DecoderErrorOr Parser::read_should_skip_residuals(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) { - if (seg_feature_active(block_context, SEG_LVL_SKIP)) + if (block_context.get_segment_feature(SegmentFeature::SkipResidualsOverride).enabled) return true; return TRY_READ(TreeParser::parse_skip(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context)); } -bool Parser::seg_feature_active(BlockContext const& block_context, u8 feature) -{ - return block_context.frame_context.segmentation_features[block_context.segment_id][feature].enabled; -} - DecoderErrorOr Parser::read_tx_size(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select) { auto max_tx_size = max_txsize_lookup[block_context.size]; @@ -1176,8 +1171,9 @@ u8 Parser::get_segment_id(BlockContext const& block_context) DecoderErrorOr Parser::read_is_inter(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) { - if (seg_feature_active(block_context, SEG_LVL_REF_FRAME)) - return block_context.frame_context.segmentation_features[block_context.segment_id][SEG_LVL_REF_FRAME].value != ReferenceFrameType::None; + auto reference_frame_override_feature = block_context.get_segment_feature(SegmentFeature::ReferenceFrameOverride); + if (reference_frame_override_feature.enabled) + return reference_frame_override_feature.value != ReferenceFrameType::None; return TRY_READ(TreeParser::parse_block_is_inter_predicted(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context)); } @@ -1221,7 +1217,7 @@ DecoderErrorOr Parser::inter_block_mode_info(BlockContext& block_context, select_best_reference_motion_vectors(block_context, reference_motion_vectors, motion_vector_candidates, ReferenceIndex::Secondary); } - if (seg_feature_active(block_context, SEG_LVL_SKIP)) { + if (block_context.get_segment_feature(SegmentFeature::SkipResidualsOverride).enabled) { block_context.y_prediction_mode() = PredictionMode::ZeroMv; } else if (block_context.size >= Block_8x8) { block_context.y_prediction_mode() = TRY_READ(TreeParser::parse_inter_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.mode_context[block_context.reference_frame_types.primary])); @@ -1259,8 +1255,9 @@ DecoderErrorOr Parser::inter_block_mode_info(BlockContext& block_context, DecoderErrorOr 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(block_context.frame_context.segmentation_features[block_context.segment_id][SEG_LVL_REF_FRAME].value), ReferenceFrameType::None }; + auto reference_frame_override_feature = block_context.get_segment_feature(SegmentFeature::ReferenceFrameOverride); + if (reference_frame_override_feature.enabled) { + block_context.reference_frame_types = { static_cast(reference_frame_override_feature.value), ReferenceFrameType::None }; return {}; } diff --git a/Userland/Libraries/LibVideo/VP9/Parser.h b/Userland/Libraries/LibVideo/VP9/Parser.h index c3e7f8de3d..c29540fbe5 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.h +++ b/Userland/Libraries/LibVideo/VP9/Parser.h @@ -98,7 +98,6 @@ private: DecoderErrorOr intra_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); DecoderErrorOr set_intra_segment_id(BlockContext&); DecoderErrorOr read_should_skip_residuals(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); - static bool seg_feature_active(BlockContext const&, u8 feature); DecoderErrorOr read_tx_size(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select); DecoderErrorOr inter_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); DecoderErrorOr set_inter_segment_id(BlockContext&); @@ -130,7 +129,7 @@ private: Array m_previous_loop_filter_ref_deltas; Array m_previous_loop_filter_mode_deltas; bool m_previous_should_use_absolute_segment_base_quantizer; - Array, MAX_SEGMENTS> m_previous_segmentation_features; + SegmentationFeatures m_previous_segmentation_features; ReferenceFrame m_reference_frames[NUM_REF_FRAMES]; diff --git a/Userland/Libraries/LibVideo/VP9/Symbols.h b/Userland/Libraries/LibVideo/VP9/Symbols.h index 434b3a186c..c367d5cb65 100644 --- a/Userland/Libraries/LibVideo/VP9/Symbols.h +++ b/Userland/Libraries/LibVideo/VP9/Symbols.h @@ -33,11 +33,6 @@ namespace Video::VP9 { #define COMP_MODE_CONTEXTS 5 #define REF_CONTEXTS 5 #define MAX_SEGMENTS 8 -#define SEG_LVL_ALT_Q 0 -#define SEG_LVL_ALT_L 1 -#define SEG_LVL_REF_FRAME 2 -#define SEG_LVL_SKIP 3 -#define SEG_LVL_MAX 4 #define BLOCK_TYPES 2 #define REF_TYPES 2 #define COEF_BANDS 6 -- cgit v1.2.3