summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibVideo/VP9
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibVideo/VP9')
-rw-r--r--Userland/Libraries/LibVideo/VP9/Context.h11
-rw-r--r--Userland/Libraries/LibVideo/VP9/ContextStorage.h5
-rw-r--r--Userland/Libraries/LibVideo/VP9/Decoder.cpp5
-rw-r--r--Userland/Libraries/LibVideo/VP9/Enums.h13
-rw-r--r--Userland/Libraries/LibVideo/VP9/LookupTables.h4
-rw-r--r--Userland/Libraries/LibVideo/VP9/Parser.cpp29
-rw-r--r--Userland/Libraries/LibVideo/VP9/Parser.h3
-rw-r--r--Userland/Libraries/LibVideo/VP9/Symbols.h5
8 files changed, 46 insertions, 29 deletions
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<u8, 3> predicted_segment_id_tree_probabilities;
bool should_use_absolute_segment_base_quantizer { false };
- Array<Array<SegmentFeature, SEG_LVL_MAX>, 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<SegmentFeatureStatus, to_underlying(SegmentFeature::Sentinel)>;
+using SegmentationFeatures = Array<SegmentFeatures, MAX_SEGMENTS>;
+
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<void> 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<void> Parser::set_intra_segment_id(BlockContext& block_context)
DecoderErrorOr<bool> 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<TransformSize> 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<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 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<void> 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<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>(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<ReferenceFrameType>(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<void> intra_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
DecoderErrorOr<void> set_intra_segment_id(BlockContext&);
DecoderErrorOr<bool> read_should_skip_residuals(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
- static bool seg_feature_active(BlockContext const&, u8 feature);
DecoderErrorOr<TransformSize> read_tx_size(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select);
DecoderErrorOr<void> inter_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
DecoderErrorOr<void> set_inter_segment_id(BlockContext&);
@@ -130,7 +129,7 @@ private:
Array<i8, MAX_REF_FRAMES> m_previous_loop_filter_ref_deltas;
Array<i8, 2> m_previous_loop_filter_mode_deltas;
bool m_previous_should_use_absolute_segment_base_quantizer;
- Array<Array<SegmentFeature, SEG_LVL_MAX>, 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