mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:47:35 +00:00
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.
This commit is contained in:
parent
6e6cc1ddb2
commit
094b0d8a78
8 changed files with 46 additions and 29 deletions
|
@ -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 {
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {};
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue