From 2f043a0bd470f182aeb5df0991bacd4ae2375694 Mon Sep 17 00:00:00 2001 From: Zaggy1024 Date: Mon, 28 Nov 2022 01:01:11 -0600 Subject: [PATCH] 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. --- Userland/Libraries/LibVideo/VP9/Context.h | 17 +++++++++++++---- Userland/Libraries/LibVideo/VP9/Parser.cpp | 19 ++++++++++--------- Userland/Libraries/LibVideo/VP9/Parser.h | 1 - .../Libraries/LibVideo/VP9/TreeParser.cpp | 8 +++----- Userland/Libraries/LibVideo/VP9/TreeParser.h | 2 +- 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Userland/Libraries/LibVideo/VP9/Context.h b/Userland/Libraries/LibVideo/VP9/Context.h index 5fb3e2414f..520a810cc6 100644 --- a/Userland/Libraries/LibVideo/VP9/Context.h +++ b/Userland/Libraries/LibVideo/VP9/Context.h @@ -150,12 +150,12 @@ static ErrorOr create_non_zero_tokens(u32 size_in_sub_blocks, boo } template -static Span safe_slice(FixedArray& array, u32 start, u32 size) +static Span safe_slice(Span 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 try_create(FrameContext& frame_context, u32 rows_start, u32 rows_end, u32 columns_start, u32 columns_end) + static ErrorOr 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 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 mode_context {}; + NonZeroTokensView above_non_zero_tokens; NonZeroTokensView left_non_zero_tokens; }; diff --git a/Userland/Libraries/LibVideo/VP9/Parser.cpp b/Userland/Libraries/LibVideo/VP9/Parser.cpp index 1300b66afc..451385e0f9 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.cpp +++ b/Userland/Libraries/LibVideo/VP9/Parser.cpp @@ -848,7 +848,9 @@ DecoderErrorOr 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 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>& 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 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 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); diff --git a/Userland/Libraries/LibVideo/VP9/Parser.h b/Userland/Libraries/LibVideo/VP9/Parser.h index 07460190f3..1c59e61d4a 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.h +++ b/Userland/Libraries/LibVideo/VP9/Parser.h @@ -147,7 +147,6 @@ private: Array, MAX_SEGMENTS> m_previous_segmentation_features; // FIXME: Move above and left contexts to structs - Array, 3> m_above_nonzero_context; Vector m_above_seg_pred_context; Vector m_left_seg_pred_context; Vector m_above_partition_context; diff --git a/Userland/Libraries/LibVideo/VP9/TreeParser.cpp b/Userland/Libraries/LibVideo/VP9/TreeParser.cpp index be3b5c3bd8..401ecfe1b3 100644 --- a/Userland/Libraries/LibVideo/VP9/TreeParser.cpp +++ b/Userland/Libraries/LibVideo/VP9/TreeParser.cpp @@ -626,14 +626,12 @@ ErrorOr TreeParser::parse_motion_vector_hp(BitStream& bit_stream, Probabil return value; } -TokensContext TreeParser::get_context_for_first_token(BlockContext const& block_context, Array, 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; } diff --git a/Userland/Libraries/LibVideo/VP9/TreeParser.h b/Userland/Libraries/LibVideo/VP9/TreeParser.h index 82fa9f6b11..5fe49b843a 100644 --- a/Userland/Libraries/LibVideo/VP9/TreeParser.h +++ b/Userland/Libraries/LibVideo/VP9/TreeParser.h @@ -87,7 +87,7 @@ public: static ErrorOr parse_motion_vector_fr(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, u8 component); static ErrorOr 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, 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 token_cache, TransformSize transform_size, TransformSet transform_set, u8 plane, u16 token_position, bool is_inter, u8 band); static ErrorOr parse_more_coefficients(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, TokensContext const& context); static ErrorOr parse_token(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, TokensContext const& context);