mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 05:27:43 +00:00
LibVideo/VP9: Move partitioning contexts to TileContext
Like the non-zero tokens and segmentation IDs, these can be moved into the tile decoding loop for above context and allocated by TileContext for left context.
This commit is contained in:
parent
720fc5a853
commit
71aac25635
7 changed files with 38 additions and 25 deletions
|
@ -75,8 +75,8 @@ public:
|
||||||
}
|
}
|
||||||
u32 rows() const { return m_rows; }
|
u32 rows() const { return m_rows; }
|
||||||
u32 columns() const { return m_columns; }
|
u32 columns() const { return m_columns; }
|
||||||
u32 superblock_rows() const { return blocks_to_superblocks(rows() + 7u); }
|
u32 superblock_rows() const { return blocks_ceiled_to_superblocks(rows()); }
|
||||||
u32 superblock_columns() const { return blocks_to_superblocks(columns() + 7u); }
|
u32 superblock_columns() const { return blocks_ceiled_to_superblocks(columns()); }
|
||||||
|
|
||||||
Vector2D<FrameBlockContext> const& block_contexts() const { return m_block_contexts; }
|
Vector2D<FrameBlockContext> const& block_contexts() const { return m_block_contexts; }
|
||||||
|
|
||||||
|
@ -175,9 +175,11 @@ static NonZeroTokensView create_non_zero_tokens_view(NonZeroTokens& non_zero_tok
|
||||||
|
|
||||||
struct TileContext {
|
struct TileContext {
|
||||||
public:
|
public:
|
||||||
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, SegmentationPredictionContextView above_segmentation_ids)
|
static ErrorOr<TileContext> try_create(FrameContext& frame_context, u32 rows_start, u32 rows_end, u32 columns_start, u32 columns_end, PartitionContextView above_partition_context, 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);
|
auto width = columns_end - columns_start;
|
||||||
|
auto height = rows_end - rows_start;
|
||||||
|
auto context_view = frame_context.m_block_contexts.view(rows_start, columns_start, height, width);
|
||||||
|
|
||||||
return TileContext {
|
return TileContext {
|
||||||
frame_context,
|
frame_context,
|
||||||
|
@ -186,10 +188,12 @@ public:
|
||||||
columns_start,
|
columns_start,
|
||||||
columns_end,
|
columns_end,
|
||||||
context_view,
|
context_view,
|
||||||
|
above_partition_context,
|
||||||
above_non_zero_tokens,
|
above_non_zero_tokens,
|
||||||
above_segmentation_ids,
|
above_segmentation_ids,
|
||||||
TRY(create_non_zero_tokens(blocks_to_sub_blocks(rows_end - rows_start), frame_context.color_config.subsampling_y)),
|
TRY(PartitionContext::try_create(superblocks_to_blocks(blocks_ceiled_to_superblocks(height)))),
|
||||||
TRY(SegmentationPredictionContext::try_create(rows_end - rows_start)),
|
TRY(create_non_zero_tokens(blocks_to_sub_blocks(height), frame_context.color_config.subsampling_y)),
|
||||||
|
TRY(SegmentationPredictionContext::try_create(height)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,8 +208,10 @@ public:
|
||||||
u32 columns() const { return columns_end - columns_start; }
|
u32 columns() const { return columns_end - columns_start; }
|
||||||
Vector2DView<FrameBlockContext> block_contexts_view;
|
Vector2DView<FrameBlockContext> block_contexts_view;
|
||||||
|
|
||||||
|
PartitionContextView above_partition_context;
|
||||||
NonZeroTokensView above_non_zero_tokens;
|
NonZeroTokensView above_non_zero_tokens;
|
||||||
SegmentationPredictionContextView above_segmentation_ids;
|
SegmentationPredictionContextView above_segmentation_ids;
|
||||||
|
PartitionContext left_partition_context;
|
||||||
NonZeroTokens left_non_zero_tokens;
|
NonZeroTokens left_non_zero_tokens;
|
||||||
SegmentationPredictionContext left_segmentation_ids;
|
SegmentationPredictionContext left_segmentation_ids;
|
||||||
};
|
};
|
||||||
|
|
|
@ -254,4 +254,7 @@ using NonZeroTokensView = Array<Span<bool>, 3>;
|
||||||
using SegmentationPredictionContext = FixedArray<u8>;
|
using SegmentationPredictionContext = FixedArray<u8>;
|
||||||
using SegmentationPredictionContextView = Span<u8>;
|
using SegmentationPredictionContextView = Span<u8>;
|
||||||
|
|
||||||
|
using PartitionContext = FixedArray<u8>;
|
||||||
|
using PartitionContextView = Span<u8>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -849,7 +849,7 @@ DecoderErrorOr<void> Parser::decode_tiles(FrameContext& frame_context)
|
||||||
auto tile_cols = 1 << log2_dimensions.width();
|
auto tile_cols = 1 << log2_dimensions.width();
|
||||||
auto tile_rows = 1 << log2_dimensions.height();
|
auto tile_rows = 1 << log2_dimensions.height();
|
||||||
|
|
||||||
clear_above_context(frame_context);
|
PartitionContext above_partition_context = DECODER_TRY_ALLOC(PartitionContext::try_create(superblocks_to_blocks(frame_context.superblock_columns())));
|
||||||
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));
|
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()));
|
SegmentationPredictionContext above_segmentation_ids = DECODER_TRY_ALLOC(SegmentationPredictionContext::try_create(frame_context.columns()));
|
||||||
|
|
||||||
|
@ -860,7 +860,7 @@ DecoderErrorOr<void> Parser::decode_tiles(FrameContext& frame_context)
|
||||||
for (auto tile_row = 0; tile_row < tile_rows; tile_row++) {
|
for (auto tile_row = 0; tile_row < tile_rows; tile_row++) {
|
||||||
for (auto tile_col = 0; tile_col < tile_cols; tile_col++) {
|
for (auto tile_col = 0; tile_col < tile_cols; tile_col++) {
|
||||||
auto last_tile = (tile_row == tile_rows - 1) && (tile_col == tile_cols - 1);
|
auto last_tile = (tile_row == tile_rows - 1) && (tile_col == tile_cols - 1);
|
||||||
u64 tile_size;
|
size_t tile_size;
|
||||||
if (last_tile)
|
if (last_tile)
|
||||||
tile_size = m_bit_stream->bytes_remaining();
|
tile_size = m_bit_stream->bytes_remaining();
|
||||||
else
|
else
|
||||||
|
@ -871,10 +871,12 @@ DecoderErrorOr<void> Parser::decode_tiles(FrameContext& frame_context)
|
||||||
auto columns_start = get_tile_offset(tile_col, frame_context.columns(), log2_dimensions.width());
|
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 columns_end = get_tile_offset(tile_col + 1, frame_context.columns(), log2_dimensions.width());
|
||||||
|
|
||||||
|
auto width = columns_end - columns_start;
|
||||||
|
auto above_partition_context_for_tile = above_partition_context.span().slice(columns_start, superblocks_to_blocks(blocks_ceiled_to_superblocks(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_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 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, above_segmentation_ids_for_tile));
|
auto tile_context = DECODER_TRY_ALLOC(TileContext::try_create(frame_context, rows_start, rows_end, columns_start, columns_end, above_partition_context_for_tile, above_non_zero_tokens_view, above_segmentation_ids_for_tile));
|
||||||
|
|
||||||
TRY_READ(m_bit_stream->init_bool(tile_size));
|
TRY_READ(m_bit_stream->init_bool(tile_size));
|
||||||
TRY(decode_tile(tile_context));
|
TRY(decode_tile(tile_context));
|
||||||
|
@ -900,11 +902,6 @@ void Parser::clear_context(Vector<Vector<T>>& context, size_t outer_size, size_t
|
||||||
clear_context(sub_vector, inner_size);
|
clear_context(sub_vector, inner_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::clear_above_context(FrameContext& frame_context)
|
|
||||||
{
|
|
||||||
clear_context(m_above_partition_context, frame_context.superblock_columns() * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 Parser::get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2)
|
u32 Parser::get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2)
|
||||||
{
|
{
|
||||||
u32 super_blocks = (mis + 7) >> 3u;
|
u32 super_blocks = (mis + 7) >> 3u;
|
||||||
|
@ -928,7 +925,7 @@ void Parser::clear_left_context(TileContext& tile_context)
|
||||||
for (auto& context_for_plane : tile_context.left_non_zero_tokens)
|
for (auto& context_for_plane : tile_context.left_non_zero_tokens)
|
||||||
context_for_plane.fill_with(false);
|
context_for_plane.fill_with(false);
|
||||||
tile_context.left_segmentation_ids.fill_with(0);
|
tile_context.left_segmentation_ids.fill_with(0);
|
||||||
clear_context(m_left_partition_context, tile_context.frame_context.superblock_rows() * 8);
|
tile_context.left_partition_context.fill_with(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderErrorOr<void> Parser::decode_partition(TileContext& tile_context, u32 row, u32 column, BlockSubsize subsize)
|
DecoderErrorOr<void> Parser::decode_partition(TileContext& tile_context, u32 row, u32 column, BlockSubsize subsize)
|
||||||
|
@ -939,7 +936,9 @@ DecoderErrorOr<void> Parser::decode_partition(TileContext& tile_context, u32 row
|
||||||
auto half_block_8x8 = num_8x8 >> 1;
|
auto half_block_8x8 = num_8x8 >> 1;
|
||||||
bool has_rows = (row + half_block_8x8) < tile_context.frame_context.rows();
|
bool has_rows = (row + half_block_8x8) < tile_context.frame_context.rows();
|
||||||
bool has_cols = (column + half_block_8x8) < tile_context.frame_context.columns();
|
bool has_cols = (column + half_block_8x8) < tile_context.frame_context.columns();
|
||||||
auto partition = TRY_READ(TreeParser::parse_partition(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, has_rows, has_cols, subsize, num_8x8, m_above_partition_context, m_left_partition_context, row, column, !tile_context.frame_context.is_inter_predicted()));
|
u32 row_in_tile = row - tile_context.rows_start;
|
||||||
|
u32 column_in_tile = column - tile_context.columns_start;
|
||||||
|
auto partition = TRY_READ(TreeParser::parse_partition(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, has_rows, has_cols, subsize, num_8x8, tile_context.above_partition_context, tile_context.left_partition_context.span(), row_in_tile, column_in_tile, !tile_context.frame_context.is_inter_predicted()));
|
||||||
|
|
||||||
auto child_subsize = subsize_lookup[partition][subsize];
|
auto child_subsize = subsize_lookup[partition][subsize];
|
||||||
if (child_subsize < Block_8x8 || partition == PartitionNone) {
|
if (child_subsize < Block_8x8 || partition == PartitionNone) {
|
||||||
|
@ -962,8 +961,8 @@ DecoderErrorOr<void> Parser::decode_partition(TileContext& tile_context, u32 row
|
||||||
auto above_context = 15 >> b_width_log2_lookup[child_subsize];
|
auto above_context = 15 >> b_width_log2_lookup[child_subsize];
|
||||||
auto left_context = 15 >> b_height_log2_lookup[child_subsize];
|
auto left_context = 15 >> b_height_log2_lookup[child_subsize];
|
||||||
for (size_t i = 0; i < num_8x8; i++) {
|
for (size_t i = 0; i < num_8x8; i++) {
|
||||||
m_above_partition_context[column + i] = above_context;
|
tile_context.above_partition_context[column_in_tile + i] = above_context;
|
||||||
m_left_partition_context[row + i] = left_context;
|
tile_context.left_partition_context[row_in_tile + i] = left_context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -99,7 +99,6 @@ private:
|
||||||
|
|
||||||
/* (6.4) Decode Tiles Syntax */
|
/* (6.4) Decode Tiles Syntax */
|
||||||
DecoderErrorOr<void> decode_tiles(FrameContext&);
|
DecoderErrorOr<void> decode_tiles(FrameContext&);
|
||||||
void clear_above_context(FrameContext&);
|
|
||||||
u32 get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2);
|
u32 get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2);
|
||||||
DecoderErrorOr<void> decode_tile(TileContext&);
|
DecoderErrorOr<void> decode_tile(TileContext&);
|
||||||
void clear_left_context(TileContext&);
|
void clear_left_context(TileContext&);
|
||||||
|
@ -146,10 +145,6 @@ private:
|
||||||
bool m_previous_should_use_absolute_segment_base_quantizer;
|
bool m_previous_should_use_absolute_segment_base_quantizer;
|
||||||
Array<Array<SegmentFeature, SEG_LVL_MAX>, MAX_SEGMENTS> m_previous_segmentation_features;
|
Array<Array<SegmentFeature, SEG_LVL_MAX>, MAX_SEGMENTS> m_previous_segmentation_features;
|
||||||
|
|
||||||
// FIXME: Move above and left contexts to structs
|
|
||||||
Vector<u8> m_above_partition_context;
|
|
||||||
Vector<u8> m_left_partition_context;
|
|
||||||
|
|
||||||
// FIXME: Move these to a struct to store together in one array.
|
// FIXME: Move these to a struct to store together in one array.
|
||||||
Gfx::Size<u32> m_ref_frame_size[NUM_REF_FRAMES];
|
Gfx::Size<u32> m_ref_frame_size[NUM_REF_FRAMES];
|
||||||
bool m_ref_subsampling_x[NUM_REF_FRAMES];
|
bool m_ref_subsampling_x[NUM_REF_FRAMES];
|
||||||
|
|
|
@ -44,7 +44,7 @@ inline void increment_counter(u8& counter)
|
||||||
counter = min(static_cast<u32>(counter) + 1, 255);
|
counter = min(static_cast<u32>(counter) + 1, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<Partition> TreeParser::parse_partition(BitStream& bit_stream, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, bool has_rows, bool has_columns, BlockSubsize block_subsize, u8 num_8x8, Vector<u8> const& above_partition_context, Vector<u8> const& left_partition_context, u32 row, u32 column, bool frame_is_intra)
|
ErrorOr<Partition> TreeParser::parse_partition(BitStream& bit_stream, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, bool has_rows, bool has_columns, BlockSubsize block_subsize, u8 num_8x8, PartitionContextView above_partition_context, PartitionContextView left_partition_context, u32 row, u32 column, bool frame_is_intra)
|
||||||
{
|
{
|
||||||
// Tree array
|
// Tree array
|
||||||
TreeParser::TreeSelection tree = { PartitionSplit };
|
TreeParser::TreeSelection tree = { PartitionSplit };
|
||||||
|
@ -61,7 +61,11 @@ ErrorOr<Partition> TreeParser::parse_partition(BitStream& bit_stream, Probabilit
|
||||||
auto bsl = mi_width_log2_lookup[block_subsize];
|
auto bsl = mi_width_log2_lookup[block_subsize];
|
||||||
auto block_offset = mi_width_log2_lookup[Block_64x64] - bsl;
|
auto block_offset = mi_width_log2_lookup[Block_64x64] - bsl;
|
||||||
for (auto i = 0; i < num_8x8; i++) {
|
for (auto i = 0; i < num_8x8; i++) {
|
||||||
|
if (column + i >= above_partition_context.size())
|
||||||
|
dbgln("column={}, i={}, size={}", column, i, above_partition_context.size());
|
||||||
above |= above_partition_context[column + i];
|
above |= above_partition_context[column + i];
|
||||||
|
if (row + i >= left_partition_context.size())
|
||||||
|
dbgln("row={}, i={}, size={}", row, i, left_partition_context.size());
|
||||||
left |= left_partition_context[row + i];
|
left |= left_partition_context[row + i];
|
||||||
}
|
}
|
||||||
above = (above & (1 << block_offset)) > 0;
|
above = (above & (1 << block_offset)) > 0;
|
||||||
|
|
|
@ -59,7 +59,7 @@ public:
|
||||||
TreeSelectionValue m_value;
|
TreeSelectionValue m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ErrorOr<Partition> parse_partition(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, bool has_rows, bool has_columns, BlockSubsize block_subsize, u8 num_8x8, Vector<u8> const& above_partition_context, Vector<u8> const& left_partition_context, u32 row, u32 column, bool frame_is_intra);
|
static ErrorOr<Partition> parse_partition(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, bool has_rows, bool has_columns, BlockSubsize block_subsize, u8 num_8x8, PartitionContextView above_partition_context, PartitionContextView left_partition_context, u32 row, u32 column, bool frame_is_intra);
|
||||||
static ErrorOr<PredictionMode> parse_default_intra_mode(BitStream&, ProbabilityTables const&, BlockSubsize mi_size, FrameBlockContext above, FrameBlockContext left, Array<PredictionMode, 4> const& block_sub_modes, u8 index_x, u8 index_y);
|
static ErrorOr<PredictionMode> parse_default_intra_mode(BitStream&, ProbabilityTables const&, BlockSubsize mi_size, FrameBlockContext above, FrameBlockContext left, Array<PredictionMode, 4> const& block_sub_modes, u8 index_x, u8 index_y);
|
||||||
static ErrorOr<PredictionMode> parse_default_uv_mode(BitStream&, ProbabilityTables const&, PredictionMode y_mode);
|
static ErrorOr<PredictionMode> parse_default_uv_mode(BitStream&, ProbabilityTables const&, PredictionMode y_mode);
|
||||||
static ErrorOr<PredictionMode> parse_intra_mode(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, BlockSubsize mi_size);
|
static ErrorOr<PredictionMode> parse_intra_mode(BitStream&, ProbabilityTables const&, SyntaxElementCounter&, BlockSubsize mi_size);
|
||||||
|
|
|
@ -72,6 +72,12 @@ inline T superblocks_to_blocks(T superblocks)
|
||||||
return superblocks << 3;
|
return superblocks << 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<Integral T>
|
||||||
|
inline T blocks_ceiled_to_superblocks(T blocks)
|
||||||
|
{
|
||||||
|
return blocks_to_superblocks(blocks + 7);
|
||||||
|
}
|
||||||
|
|
||||||
template<Integral T>
|
template<Integral T>
|
||||||
inline T blocks_to_sub_blocks(T blocks)
|
inline T blocks_to_sub_blocks(T blocks)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue