LibVideo/VP9: Move segmentation id prediction context to TileContext

These can also be stored in the same places as the non-zero tokens
contexts.
This commit is contained in:
Zaggy1024 2022-11-28 04:56:04 -06:00 committed by Andreas Kling
parent 9df72080a1
commit 1fe22f2141
Notes: sideshowbarker 2024-07-17 03:53:08 +09:00
5 changed files with 31 additions and 19 deletions

View file

@ -175,7 +175,7 @@ static NonZeroTokensView create_non_zero_tokens_view(NonZeroTokens& non_zero_tok
struct TileContext {
public:
static ErrorOr<TileContext> try_create(FrameContext& frame_context, u32 rows_start, u32 rows_end, u32 columns_start, u32 columns_end, NonZeroTokensView above_non_zero_tokens)
static ErrorOr<TileContext> try_create(FrameContext& frame_context, u32 rows_start, u32 rows_end, u32 columns_start, u32 columns_end, NonZeroTokensView above_non_zero_tokens, SegmentationPredictionContextView above_segmentation_ids)
{
auto context_view = frame_context.m_block_contexts.view(rows_start, columns_start, rows_end - rows_start, columns_end - columns_start);
@ -187,7 +187,9 @@ public:
columns_end,
context_view,
above_non_zero_tokens,
above_segmentation_ids,
TRY(create_non_zero_tokens(blocks_to_sub_blocks(rows_end - rows_start), frame_context.color_config.subsampling_y)),
TRY(SegmentationPredictionContext::try_create(rows_end - rows_start)),
};
}
@ -203,7 +205,9 @@ public:
Vector2DView<FrameBlockContext> block_contexts_view;
NonZeroTokensView above_non_zero_tokens;
SegmentationPredictionContextView above_segmentation_ids;
NonZeroTokens left_non_zero_tokens;
SegmentationPredictionContext left_segmentation_ids;
};
struct BlockContext {
@ -215,6 +219,7 @@ struct BlockContext {
min<u32>(num_8x8_blocks_high_lookup[size], tile_context.frame_context.rows() - row),
min<u32>(num_8x8_blocks_wide_lookup[size], tile_context.frame_context.columns() - column));
auto size_in_blocks = block_size_to_blocks(size);
auto size_in_sub_blocks = block_size_to_sub_blocks(get_subsampled_block_size(size, false, false));
return BlockContext {
@ -225,7 +230,9 @@ struct BlockContext {
.size = size,
.contexts_view = contexts_view,
.above_non_zero_tokens = create_non_zero_tokens_view(tile_context.above_non_zero_tokens, blocks_to_sub_blocks(column - tile_context.columns_start), size_in_sub_blocks.width(), tile_context.frame_context.color_config.subsampling_x),
.above_segmentation_ids = safe_slice(tile_context.above_segmentation_ids, column - tile_context.columns_start, size_in_blocks.width()),
.left_non_zero_tokens = create_non_zero_tokens_view(tile_context.left_non_zero_tokens, blocks_to_sub_blocks(row - tile_context.rows_start), size_in_sub_blocks.height(), tile_context.frame_context.color_config.subsampling_y),
.left_segmentation_ids = safe_slice(tile_context.left_segmentation_ids.span(), row - tile_context.rows_start, size_in_blocks.height()),
};
}
@ -266,7 +273,9 @@ struct BlockContext {
Array<u8, 4> mode_context {};
NonZeroTokensView above_non_zero_tokens;
SegmentationPredictionContextView above_segmentation_ids;
NonZeroTokensView left_non_zero_tokens;
SegmentationPredictionContextView left_segmentation_ids;
};
struct BlockMotionVectorCandidateSet {

View file

@ -251,4 +251,7 @@ using BlockMotionVectorCandidates = ReferencePair<BlockMotionVectorCandidateSet>
using NonZeroTokens = Array<FixedArray<bool>, 3>;
using NonZeroTokensView = Array<Span<bool>, 3>;
using SegmentationPredictionContext = FixedArray<u8>;
using SegmentationPredictionContextView = Span<u8>;
}

View file

@ -851,6 +851,7 @@ DecoderErrorOr<void> Parser::decode_tiles(FrameContext& frame_context)
clear_above_context(frame_context);
NonZeroTokens above_non_zero_tokens = DECODER_TRY_ALLOC(create_non_zero_tokens(blocks_to_sub_blocks(frame_context.columns()), frame_context.color_config.subsampling_x));
SegmentationPredictionContext above_segmentation_ids = DECODER_TRY_ALLOC(SegmentationPredictionContext::try_create(frame_context.columns()));
// FIXME: To implement tiled decoding, we'll need to pre-parse the tile positions and sizes into a 2D vector of ReadonlyBytes,
// then run through each column of tiles in top to bottom order afterward. Each column can be sent to a worker thread
@ -871,8 +872,9 @@ DecoderErrorOr<void> Parser::decode_tiles(FrameContext& frame_context)
auto columns_end = get_tile_offset(tile_col + 1, frame_context.columns(), log2_dimensions.width());
auto above_non_zero_tokens_view = create_non_zero_tokens_view(above_non_zero_tokens, blocks_to_sub_blocks(columns_start), blocks_to_sub_blocks(columns_end - columns_start), frame_context.color_config.subsampling_x);
auto above_segmentation_ids_for_tile = safe_slice(above_segmentation_ids.span(), columns_start, columns_end - columns_start);
auto tile_context = DECODER_TRY_ALLOC(TileContext::try_create(frame_context, rows_start, rows_end, columns_start, columns_end, above_non_zero_tokens_view));
auto tile_context = DECODER_TRY_ALLOC(TileContext::try_create(frame_context, rows_start, rows_end, columns_start, columns_end, above_non_zero_tokens_view, above_segmentation_ids_for_tile));
TRY_READ(m_bit_stream->init_bool(tile_size));
TRY(decode_tile(tile_context));
@ -900,7 +902,6 @@ void Parser::clear_context(Vector<Vector<T>>& context, size_t outer_size, size_t
void Parser::clear_above_context(FrameContext& frame_context)
{
clear_context(m_above_seg_pred_context, frame_context.columns());
clear_context(m_above_partition_context, frame_context.superblock_columns() * 8);
}
@ -926,7 +927,7 @@ void Parser::clear_left_context(TileContext& tile_context)
{
for (auto& context_for_plane : tile_context.left_non_zero_tokens)
context_for_plane.fill_with(false);
clear_context(m_left_seg_pred_context, tile_context.frame_context.rows());
tile_context.left_segmentation_ids.fill_with(0);
clear_context(m_left_partition_context, tile_context.frame_context.superblock_rows() * 8);
}
@ -1095,24 +1096,20 @@ DecoderErrorOr<void> Parser::set_inter_segment_id(BlockContext& block_context)
return {};
}
auto seg_id_predicted = TRY_READ(TreeParser::parse_segment_id_predicted(*m_bit_stream, block_context.frame_context.predicted_segment_id_tree_probabilities, m_left_seg_pred_context[block_context.row], m_above_seg_pred_context[block_context.column]));
auto above_segmentation_id = block_context.tile_context.above_segmentation_ids[block_context.row - block_context.tile_context.rows_start];
auto left_segmentation_id = block_context.tile_context.left_segmentation_ids[block_context.column - block_context.tile_context.columns_start];
auto seg_id_predicted = TRY_READ(TreeParser::parse_segment_id_predicted(*m_bit_stream, block_context.frame_context.predicted_segment_id_tree_probabilities, above_segmentation_id, left_segmentation_id));
if (seg_id_predicted)
block_context.segment_id = predicted_segment_id;
else
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, block_context.frame_context.full_segment_id_tree_probabilities));
for (size_t i = 0; i < num_8x8_blocks_wide_lookup[block_context.size]; i++) {
auto index = block_context.column + i;
// (7.4.1) AboveSegPredContext[ i ] only needs to be set to 0 for i = 0..MiCols-1.
if (index < m_above_seg_pred_context.size())
m_above_seg_pred_context[index] = seg_id_predicted;
}
for (size_t i = 0; i < num_8x8_blocks_high_lookup[block_context.size]; i++) {
auto index = block_context.row + i;
// (7.4.1) LeftSegPredContext[ i ] only needs to be set to 0 for i = 0..MiRows-1.
if (index < m_above_seg_pred_context.size())
m_left_seg_pred_context[block_context.row + i] = seg_id_predicted;
}
// (7.4.1) AboveSegPredContext[ i ] only needs to be set to 0 for i = 0..MiCols-1.
// This is taken care of by the slicing in BlockContext.
block_context.above_segmentation_ids.fill(seg_id_predicted);
// (7.4.1) LeftSegPredContext[ i ] only needs to be set to 0 for i = 0..MiRows-1.
// This is taken care of by the slicing in BlockContext.
block_context.left_segmentation_ids.fill(seg_id_predicted);
return {};
}

View file

@ -147,8 +147,6 @@ private:
Array<Array<SegmentFeature, SEG_LVL_MAX>, MAX_SEGMENTS> m_previous_segmentation_features;
// FIXME: Move above and left contexts to structs
Vector<u8> m_above_seg_pred_context;
Vector<u8> m_left_seg_pred_context;
Vector<u8> m_above_partition_context;
Vector<u8> m_left_partition_context;

View file

@ -50,6 +50,11 @@ inline BlockSubsize get_subsampled_block_size(BlockSubsize size, bool subsamplin
return ss_size_lookup[size < Block_8x8 ? Block_8x8 : size][subsampling_x][subsampling_y];
}
inline Gfx::Size<u8> block_size_to_blocks(BlockSubsize size)
{
return Gfx::Size<u8>(num_8x8_blocks_wide_lookup[size], num_8x8_blocks_high_lookup[size]);
}
inline Gfx::Size<u8> block_size_to_sub_blocks(BlockSubsize size)
{
return Gfx::Size<u8>(num_4x4_blocks_wide_lookup[size], num_4x4_blocks_high_lookup[size]);