From 1fe22f21410509c680700bfe66a83d3021a94804 Mon Sep 17 00:00:00 2001 From: Zaggy1024 Date: Mon, 28 Nov 2022 04:56:04 -0600 Subject: [PATCH] LibVideo/VP9: Move segmentation id prediction context to TileContext These can also be stored in the same places as the non-zero tokens contexts. --- Userland/Libraries/LibVideo/VP9/Context.h | 11 ++++++- .../Libraries/LibVideo/VP9/ContextStorage.h | 3 ++ Userland/Libraries/LibVideo/VP9/Parser.cpp | 29 +++++++++---------- Userland/Libraries/LibVideo/VP9/Parser.h | 2 -- Userland/Libraries/LibVideo/VP9/Utilities.h | 5 ++++ 5 files changed, 31 insertions(+), 19 deletions(-) diff --git a/Userland/Libraries/LibVideo/VP9/Context.h b/Userland/Libraries/LibVideo/VP9/Context.h index 520a810cc62..4d380e2f84b 100644 --- a/Userland/Libraries/LibVideo/VP9/Context.h +++ b/Userland/Libraries/LibVideo/VP9/Context.h @@ -175,7 +175,7 @@ static NonZeroTokensView create_non_zero_tokens_view(NonZeroTokens& non_zero_tok struct TileContext { public: - static ErrorOr try_create(FrameContext& frame_context, u32 rows_start, u32 rows_end, u32 columns_start, u32 columns_end, NonZeroTokensView above_non_zero_tokens) + static ErrorOr 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 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(num_8x8_blocks_high_lookup[size], tile_context.frame_context.rows() - row), min(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 mode_context {}; NonZeroTokensView above_non_zero_tokens; + SegmentationPredictionContextView above_segmentation_ids; NonZeroTokensView left_non_zero_tokens; + SegmentationPredictionContextView left_segmentation_ids; }; struct BlockMotionVectorCandidateSet { diff --git a/Userland/Libraries/LibVideo/VP9/ContextStorage.h b/Userland/Libraries/LibVideo/VP9/ContextStorage.h index aefe3e6f97e..1b77aaf0bf2 100644 --- a/Userland/Libraries/LibVideo/VP9/ContextStorage.h +++ b/Userland/Libraries/LibVideo/VP9/ContextStorage.h @@ -251,4 +251,7 @@ using BlockMotionVectorCandidates = ReferencePair using NonZeroTokens = Array, 3>; using NonZeroTokensView = Array, 3>; +using SegmentationPredictionContext = FixedArray; +using SegmentationPredictionContextView = Span; + } diff --git a/Userland/Libraries/LibVideo/VP9/Parser.cpp b/Userland/Libraries/LibVideo/VP9/Parser.cpp index f2448938f46..b1075f1b41a 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.cpp +++ b/Userland/Libraries/LibVideo/VP9/Parser.cpp @@ -851,6 +851,7 @@ DecoderErrorOr 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 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>& 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 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 {}; } diff --git a/Userland/Libraries/LibVideo/VP9/Parser.h b/Userland/Libraries/LibVideo/VP9/Parser.h index 1c59e61d4ad..71255722c3d 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.h +++ b/Userland/Libraries/LibVideo/VP9/Parser.h @@ -147,8 +147,6 @@ private: Array, MAX_SEGMENTS> m_previous_segmentation_features; // FIXME: Move above and left contexts to structs - Vector m_above_seg_pred_context; - Vector m_left_seg_pred_context; Vector m_above_partition_context; Vector m_left_partition_context; diff --git a/Userland/Libraries/LibVideo/VP9/Utilities.h b/Userland/Libraries/LibVideo/VP9/Utilities.h index ebdab25fe2a..1fd3f891a69 100644 --- a/Userland/Libraries/LibVideo/VP9/Utilities.h +++ b/Userland/Libraries/LibVideo/VP9/Utilities.h @@ -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 block_size_to_blocks(BlockSubsize size) +{ + return Gfx::Size(num_8x8_blocks_wide_lookup[size], num_8x8_blocks_high_lookup[size]); +} + inline Gfx::Size block_size_to_sub_blocks(BlockSubsize size) { return Gfx::Size(num_4x4_blocks_wide_lookup[size], num_4x4_blocks_high_lookup[size]);