mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-30 00:31:14 +00:00
LibVideo/VP9: Move the above non-zero tokens context into decode_tiles
We can store this context in the stack of Parser::decode_tiles and use spans to give access to the sections of the context for each tile and subsequently each block.
This commit is contained in:
parent
4e7e9d8479
commit
2f043a0bd4
Notes:
sideshowbarker
2024-07-17 22:41:14 +09:00
Author: https://github.com/Zaggy1024 Commit: https://github.com/SerenityOS/serenity/commit/2f043a0bd4 Pull-request: https://github.com/SerenityOS/serenity/pull/16238
|
@ -150,12 +150,12 @@ static ErrorOr<NonZeroTokens> create_non_zero_tokens(u32 size_in_sub_blocks, boo
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
static Span<T> safe_slice(FixedArray<T>& array, u32 start, u32 size)
|
||||
static Span<T> safe_slice(Span<T> span, u32 start, u32 size)
|
||||
{
|
||||
return array.span().slice(start, min(size, array.size() - start));
|
||||
return span.slice(start, min(size, span.size() - start));
|
||||
}
|
||||
|
||||
static NonZeroTokensView create_non_zero_tokens_view(NonZeroTokens& non_zero_tokens, u32 start_in_sub_blocks, u32 size_in_sub_blocks, bool subsampling)
|
||||
static NonZeroTokensView create_non_zero_tokens_view(NonZeroTokensView non_zero_tokens, u32 start_in_sub_blocks, u32 size_in_sub_blocks, bool subsampling)
|
||||
{
|
||||
NonZeroTokensView result;
|
||||
// Y plane
|
||||
|
@ -168,9 +168,14 @@ static NonZeroTokensView create_non_zero_tokens_view(NonZeroTokens& non_zero_tok
|
|||
return result;
|
||||
}
|
||||
|
||||
static NonZeroTokensView create_non_zero_tokens_view(NonZeroTokens& non_zero_tokens, u32 start_in_sub_blocks, u32 size_in_sub_blocks, bool subsampling)
|
||||
{
|
||||
return create_non_zero_tokens_view({ non_zero_tokens[0].span(), non_zero_tokens[1].span(), non_zero_tokens[2].span() }, start_in_sub_blocks, size_in_sub_blocks, subsampling);
|
||||
}
|
||||
|
||||
struct TileContext {
|
||||
public:
|
||||
static ErrorOr<TileContext> try_create(FrameContext& frame_context, u32 rows_start, u32 rows_end, u32 columns_start, u32 columns_end)
|
||||
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)
|
||||
{
|
||||
auto context_view = frame_context.m_block_contexts.view(rows_start, columns_start, rows_end - rows_start, columns_end - columns_start);
|
||||
|
||||
|
@ -181,6 +186,7 @@ public:
|
|||
columns_start,
|
||||
columns_end,
|
||||
context_view,
|
||||
above_non_zero_tokens,
|
||||
TRY(create_non_zero_tokens(blocks_to_sub_blocks(rows_end - rows_start), frame_context.color_config.subsampling_y)),
|
||||
};
|
||||
}
|
||||
|
@ -196,6 +202,7 @@ public:
|
|||
u32 columns() const { return columns_end - columns_start; }
|
||||
Vector2DView<FrameBlockContext> block_contexts_view;
|
||||
|
||||
NonZeroTokensView above_non_zero_tokens;
|
||||
NonZeroTokens left_non_zero_tokens;
|
||||
};
|
||||
|
||||
|
@ -217,6 +224,7 @@ struct BlockContext {
|
|||
.column = column,
|
||||
.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),
|
||||
.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),
|
||||
};
|
||||
}
|
||||
|
@ -257,6 +265,7 @@ struct BlockContext {
|
|||
// Indexed by ReferenceFrame enum.
|
||||
Array<u8, 4> mode_context {};
|
||||
|
||||
NonZeroTokensView above_non_zero_tokens;
|
||||
NonZeroTokensView left_non_zero_tokens;
|
||||
};
|
||||
|
||||
|
|
|
@ -848,7 +848,9 @@ DecoderErrorOr<void> Parser::decode_tiles(FrameContext& frame_context)
|
|||
auto log2_dimensions = frame_context.log2_of_tile_counts;
|
||||
auto tile_cols = 1 << log2_dimensions.width();
|
||||
auto tile_rows = 1 << log2_dimensions.height();
|
||||
|
||||
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));
|
||||
|
||||
for (auto tile_row = 0; tile_row < tile_rows; tile_row++) {
|
||||
for (auto tile_col = 0; tile_col < tile_cols; tile_col++) {
|
||||
|
@ -864,7 +866,9 @@ DecoderErrorOr<void> Parser::decode_tiles(FrameContext& frame_context)
|
|||
auto columns_start = get_tile_offset(tile_col, frame_context.columns(), log2_dimensions.width());
|
||||
auto columns_end = get_tile_offset(tile_col + 1, frame_context.columns(), log2_dimensions.width());
|
||||
|
||||
auto tile_context = DECODER_TRY_ALLOC(TileContext::try_create(frame_context, rows_start, rows_end, columns_start, columns_end));
|
||||
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 tile_context = DECODER_TRY_ALLOC(TileContext::try_create(frame_context, rows_start, rows_end, columns_start, columns_end, above_non_zero_tokens_view));
|
||||
|
||||
TRY_READ(m_bit_stream->init_bool(tile_size));
|
||||
TRY(decode_tile(tile_context));
|
||||
|
@ -892,8 +896,6 @@ void Parser::clear_context(Vector<Vector<T>>& context, size_t outer_size, size_t
|
|||
|
||||
void Parser::clear_above_context(FrameContext& frame_context)
|
||||
{
|
||||
for (auto i = 0u; i < m_above_nonzero_context.size(); i++)
|
||||
clear_context(m_above_nonzero_context[i], 2 * frame_context.columns());
|
||||
clear_context(m_above_seg_pred_context, frame_context.columns());
|
||||
clear_context(m_above_partition_context, frame_context.superblock_columns() * 8);
|
||||
}
|
||||
|
@ -1397,11 +1399,10 @@ DecoderErrorOr<bool> Parser::residual(BlockContext& block_context, bool has_bloc
|
|||
}
|
||||
}
|
||||
|
||||
auto& above_sub_block_context = m_above_nonzero_context[plane];
|
||||
auto above_sub_block_context_index = pixels_to_sub_blocks(transform_x_in_px);
|
||||
auto above_sub_block_context_end = min(above_sub_block_context_index + transform_size_in_sub_blocks, above_sub_block_context.size());
|
||||
for (; above_sub_block_context_index < above_sub_block_context_end; above_sub_block_context_index++)
|
||||
above_sub_block_context[above_sub_block_context_index] = sub_block_had_non_zero_tokens;
|
||||
auto& above_sub_block_tokens = block_context.above_non_zero_tokens[plane];
|
||||
auto transform_right_in_sub_blocks = min(x + transform_size_in_sub_blocks, above_sub_block_tokens.size());
|
||||
for (size_t inside_x = x; inside_x < transform_right_in_sub_blocks; inside_x++)
|
||||
above_sub_block_tokens[inside_x] = sub_block_had_non_zero_tokens;
|
||||
|
||||
auto& left_sub_block_context = block_context.left_non_zero_tokens[plane];
|
||||
auto transform_bottom_in_sub_blocks = min(y + transform_size_in_sub_blocks, left_sub_block_context.size());
|
||||
|
@ -1458,7 +1459,7 @@ DecoderErrorOr<bool> Parser::tokens(BlockContext& block_context, size_t plane, u
|
|||
auto token_position = scan[coef_index];
|
||||
TokensContext tokens_context;
|
||||
if (coef_index == 0)
|
||||
tokens_context = TreeParser::get_context_for_first_token(block_context, m_above_nonzero_context, block_context.left_non_zero_tokens, transform_size, plane, sub_block_column, sub_block_row, block_context.is_inter_predicted(), band);
|
||||
tokens_context = TreeParser::get_context_for_first_token(block_context.above_non_zero_tokens, block_context.left_non_zero_tokens, transform_size, plane, sub_block_column, sub_block_row, block_context.is_inter_predicted(), band);
|
||||
else
|
||||
tokens_context = TreeParser::get_context_for_other_tokens(token_cache, transform_size, transform_set, plane, token_position, block_context.is_inter_predicted(), band);
|
||||
|
||||
|
|
|
@ -147,7 +147,6 @@ private:
|
|||
Array<Array<SegmentFeature, SEG_LVL_MAX>, MAX_SEGMENTS> m_previous_segmentation_features;
|
||||
|
||||
// FIXME: Move above and left contexts to structs
|
||||
Array<Vector<bool>, 3> m_above_nonzero_context;
|
||||
Vector<u8> m_above_seg_pred_context;
|
||||
Vector<u8> m_left_seg_pred_context;
|
||||
Vector<u8> m_above_partition_context;
|
||||
|
|
|
@ -626,14 +626,12 @@ ErrorOr<bool> TreeParser::parse_motion_vector_hp(BitStream& bit_stream, Probabil
|
|||
return value;
|
||||
}
|
||||
|
||||
TokensContext TreeParser::get_context_for_first_token(BlockContext const& block_context, Array<Vector<bool>, 3> const& above_non_zero_tokens, NonZeroTokensView left_non_zero_tokens_in_block, TransformSize transform_size, u8 plane, u32 sub_block_column, u32 sub_block_row, bool is_inter, u8 band)
|
||||
TokensContext TreeParser::get_context_for_first_token(NonZeroTokensView above_non_zero_tokens, NonZeroTokensView left_non_zero_tokens_in_block, TransformSize transform_size, u8 plane, u32 sub_block_column, u32 sub_block_row, bool is_inter, u8 band)
|
||||
{
|
||||
auto subsampling_x = plane > 0 ? block_context.frame_context.color_config.subsampling_x : false;
|
||||
auto transform_left_in_sub_blocks = (blocks_to_sub_blocks(block_context.column) >> subsampling_x) + sub_block_column;
|
||||
u8 transform_size_in_sub_blocks = transform_size_to_sub_blocks(transform_size);
|
||||
bool above_has_non_zero_tokens = false;
|
||||
for (u8 x = 0; x < transform_size_in_sub_blocks && x < above_non_zero_tokens[plane].size() - transform_left_in_sub_blocks; x++) {
|
||||
if (above_non_zero_tokens[plane][transform_left_in_sub_blocks + x]) {
|
||||
for (u8 x = 0; x < transform_size_in_sub_blocks && x < above_non_zero_tokens[plane].size() - sub_block_column; x++) {
|
||||
if (above_non_zero_tokens[plane][sub_block_column + x]) {
|
||||
above_has_non_zero_tokens = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
static ErrorOr<u8> parse_motion_vector_fr(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, u8 component);
|
||||
static ErrorOr<bool> parse_motion_vector_hp(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, u8 component, bool use_hp);
|
||||
|
||||
static TokensContext get_context_for_first_token(BlockContext const& block_context, Array<Vector<bool>, 3> const& above_non_zero_tokens, NonZeroTokensView left_non_zero_tokens, TransformSize transform_size, u8 plane, u32 sub_block_column, u32 sub_block_row, bool is_inter, u8 band);
|
||||
static TokensContext get_context_for_first_token(NonZeroTokensView above_non_zero_tokens, NonZeroTokensView left_non_zero_tokens, TransformSize transform_size, u8 plane, u32 sub_block_column, u32 sub_block_row, bool is_inter, u8 band);
|
||||
static TokensContext get_context_for_other_tokens(Array<u8, 1024> token_cache, TransformSize transform_size, TransformSet transform_set, u8 plane, u16 token_position, bool is_inter, u8 band);
|
||||
static ErrorOr<bool> parse_more_coefficients(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, TokensContext const& context);
|
||||
static ErrorOr<Token> parse_token(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, TokensContext const& context);
|
||||
|
|
Loading…
Reference in a new issue