From 368687a74f989aa98663554c387ea131e3d69ce9 Mon Sep 17 00:00:00 2001 From: Zaggy1024 Date: Fri, 25 Nov 2022 05:05:00 -0600 Subject: [PATCH] LibVideo/VP9: Store tile counts in FrameContext The log2 of tile counts in the horizontal and vertical dimensions are now stored in the FrameContext struct to be kept only as long as they are needed. --- Userland/Libraries/LibVideo/VP9/Context.h | 1 + Userland/Libraries/LibVideo/VP9/Parser.cpp | 59 ++++++++++++---------- Userland/Libraries/LibVideo/VP9/Parser.h | 6 +-- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Userland/Libraries/LibVideo/VP9/Context.h b/Userland/Libraries/LibVideo/VP9/Context.h index d0d3cbfebf..1f2da18938 100644 --- a/Userland/Libraries/LibVideo/VP9/Context.h +++ b/Userland/Libraries/LibVideo/VP9/Context.h @@ -298,6 +298,7 @@ public: Vector2D const& block_contexts() const { return m_block_contexts; } Gfx::Size render_size { 0, 0 }; + Gfx::Size log2_of_tile_counts { 0, 0 }; // This group of fields is only needed for inter-predicted frames. Array reference_frame_indices; diff --git a/Userland/Libraries/LibVideo/VP9/Parser.cpp b/Userland/Libraries/LibVideo/VP9/Parser.cpp index 5e7874bebe..88d375361f 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.cpp +++ b/Userland/Libraries/LibVideo/VP9/Parser.cpp @@ -263,7 +263,7 @@ DecoderErrorOr Parser::uncompressed_header() TRY(loop_filter_params(frame_context)); TRY(quantization_params(frame_context)); TRY(segmentation_params()); - TRY(tile_info(frame_context)); + TRY(parse_tile_counts(frame_context)); frame_context.header_size_in_bytes = TRY_READ(m_bit_stream->read_f16()); @@ -482,26 +482,7 @@ DecoderErrorOr Parser::read_prob() return 255; } -DecoderErrorOr Parser::tile_info(FrameContext& frame_context) -{ - auto superblock_columns = frame_context.superblock_columns(); - auto min_log2_tile_cols = calc_min_log2_tile_cols(superblock_columns); - auto max_log2_tile_cols = calc_max_log2_tile_cols(superblock_columns); - m_tile_cols_log2 = min_log2_tile_cols; - while (m_tile_cols_log2 < max_log2_tile_cols) { - if (TRY_READ(m_bit_stream->read_bit())) - m_tile_cols_log2++; - else - break; - } - m_tile_rows_log2 = TRY_READ(m_bit_stream->read_bit()); - if (m_tile_rows_log2) { - m_tile_rows_log2 += TRY_READ(m_bit_stream->read_bit()); - } - return {}; -} - -u16 Parser::calc_min_log2_tile_cols(u32 superblock_columns) +static u16 calc_min_log2_of_tile_columns(u32 superblock_columns) { auto min_log_2 = 0u; while ((u32)(MAX_TILE_WIDTH_B64 << min_log_2) < superblock_columns) @@ -509,7 +490,7 @@ u16 Parser::calc_min_log2_tile_cols(u32 superblock_columns) return min_log_2; } -u16 Parser::calc_max_log2_tile_cols(u32 superblock_columns) +static u16 calc_max_log2_tile_cols(u32 superblock_columns) { u16 max_log_2 = 1; while ((superblock_columns >> max_log_2) >= MIN_TILE_WIDTH_B64) @@ -517,6 +498,27 @@ u16 Parser::calc_max_log2_tile_cols(u32 superblock_columns) return max_log_2 - 1; } +DecoderErrorOr Parser::parse_tile_counts(FrameContext& frame_context) +{ + auto superblock_columns = frame_context.superblock_columns(); + + auto log2_of_tile_columns = calc_min_log2_of_tile_columns(superblock_columns); + auto log2_of_tile_columns_maximum = calc_max_log2_tile_cols(superblock_columns); + while (log2_of_tile_columns < log2_of_tile_columns_maximum) { + if (TRY_READ(m_bit_stream->read_bit())) + log2_of_tile_columns++; + else + break; + } + + u16 log2_of_tile_rows = TRY_READ(m_bit_stream->read_bit()); + if (log2_of_tile_rows > 0) { + log2_of_tile_rows += TRY_READ(m_bit_stream->read_bit()); + } + frame_context.log2_of_tile_counts = Gfx::Size(log2_of_tile_columns, log2_of_tile_rows); + return {}; +} + void Parser::setup_past_independence() { for (auto i = 0; i < 8; i++) { @@ -833,8 +835,9 @@ void Parser::setup_compound_reference_mode(FrameContext& frame_context) DecoderErrorOr Parser::decode_tiles(FrameContext& frame_context) { - auto tile_cols = 1 << m_tile_cols_log2; - auto tile_rows = 1 << m_tile_rows_log2; + 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); for (auto tile_row = 0; tile_row < tile_rows; tile_row++) { @@ -846,10 +849,10 @@ DecoderErrorOr Parser::decode_tiles(FrameContext& frame_context) else tile_size = TRY_READ(m_bit_stream->read_bits(32)); - auto rows_start = get_tile_offset(tile_row, frame_context.rows(), m_tile_rows_log2); - auto rows_end = get_tile_offset(tile_row + 1, frame_context.rows(), m_tile_rows_log2); - auto columns_start = get_tile_offset(tile_col, frame_context.columns(), m_tile_cols_log2); - auto columns_end = get_tile_offset(tile_col + 1, frame_context.columns(), m_tile_cols_log2); + auto rows_start = get_tile_offset(tile_row, frame_context.rows(), log2_dimensions.height()); + auto rows_end = get_tile_offset(tile_row + 1, frame_context.rows(), log2_dimensions.height()); + 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 = TileContext(frame_context, rows_start, rows_end, columns_start, columns_end); diff --git a/Userland/Libraries/LibVideo/VP9/Parser.h b/Userland/Libraries/LibVideo/VP9/Parser.h index 91cdf7851c..21273714c1 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.h +++ b/Userland/Libraries/LibVideo/VP9/Parser.h @@ -69,9 +69,7 @@ private: DecoderErrorOr read_delta_q(); DecoderErrorOr segmentation_params(); DecoderErrorOr read_prob(); - DecoderErrorOr tile_info(FrameContext&); - u16 calc_min_log2_tile_cols(u32 superblock_columns); - u16 calc_max_log2_tile_cols(u32 superblock_columns); + DecoderErrorOr parse_tile_counts(FrameContext&); void setup_past_independence(); /* (6.3) Compressed Header Syntax */ @@ -156,8 +154,6 @@ private: bool m_segmentation_update_map { false }; bool m_segmentation_temporal_update { false }; bool m_segmentation_abs_or_delta_update { false }; - u16 m_tile_cols_log2 { 0 }; - u16 m_tile_rows_log2 { 0 }; // FIXME: Move above and left contexts to structs Array, 3> m_above_nonzero_context;