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;