mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 01:47:35 +00:00
LibVideo/VP9: Begin creating a tree parser to parse syntax elements
This commit is contained in:
parent
cfd65eafa9
commit
7ff6315246
7 changed files with 457 additions and 20 deletions
192
Userland/Libraries/LibVideo/VP9/TreeParser.cpp
Normal file
192
Userland/Libraries/LibVideo/VP9/TreeParser.cpp
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "TreeParser.h"
|
||||
#include "LookupTables.h"
|
||||
|
||||
namespace Video::VP9 {
|
||||
|
||||
int TreeParser::parse_tree(SyntaxElementType type)
|
||||
{
|
||||
auto tree_selection = select_tree(type);
|
||||
if (tree_selection.is_single_value())
|
||||
return tree_selection.get_single_value();
|
||||
auto tree = tree_selection.get_tree_value();
|
||||
int n = 0;
|
||||
do {
|
||||
n = tree[n + m_bit_stream->read_bool(select_tree_probability(type, n >> 1))];
|
||||
} while (n > 0);
|
||||
return -n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select a tree value based on the type of syntax element being parsed, as well as some parser state, as specified in section 9.3.1
|
||||
*/
|
||||
TreeParser::TreeSelection TreeParser::select_tree(SyntaxElementType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SyntaxElementType::Partition:
|
||||
if (m_has_rows && m_has_cols)
|
||||
return { partition_tree };
|
||||
if (m_has_cols)
|
||||
return { cols_partition_tree };
|
||||
if (m_has_rows)
|
||||
return { rows_partition_tree };
|
||||
return { PartitionSplit };
|
||||
case SyntaxElementType::DefaultIntraMode:
|
||||
case SyntaxElementType::DefaultUVMode:
|
||||
case SyntaxElementType::IntraMode:
|
||||
case SyntaxElementType::SubIntraMode:
|
||||
case SyntaxElementType::UVMode:
|
||||
return { intra_mode_tree };
|
||||
case SyntaxElementType::SegmentID:
|
||||
return { segment_tree };
|
||||
case SyntaxElementType::Skip:
|
||||
case SyntaxElementType::SegIDPredicted:
|
||||
case SyntaxElementType::IsInter:
|
||||
case SyntaxElementType::CompMode:
|
||||
case SyntaxElementType::CompRef:
|
||||
case SyntaxElementType::SingleRefP1:
|
||||
case SyntaxElementType::SingleRefP2:
|
||||
case SyntaxElementType::MVSign:
|
||||
case SyntaxElementType::MVClass0Bit:
|
||||
case SyntaxElementType::MVBit:
|
||||
case SyntaxElementType::MoreCoefs:
|
||||
return { binary_tree };
|
||||
case SyntaxElementType::TXSize:
|
||||
if (m_max_tx_size == TX_32x32)
|
||||
return { tx_size_32_tree };
|
||||
if (m_max_tx_size == TX_16x16)
|
||||
return { tx_size_16_tree };
|
||||
return { tx_size_8_tree };
|
||||
case SyntaxElementType::InterMode:
|
||||
return { inter_mode_tree };
|
||||
case SyntaxElementType::InterpFilter:
|
||||
return { interp_filter_tree };
|
||||
case SyntaxElementType::MVJoint:
|
||||
return { mv_joint_tree };
|
||||
case SyntaxElementType::MVClass:
|
||||
return { mv_class_tree };
|
||||
case SyntaxElementType::MVClass0FR:
|
||||
case SyntaxElementType::MVFR:
|
||||
return { mv_fr_tree };
|
||||
case SyntaxElementType::MVClass0HP:
|
||||
case SyntaxElementType::MVHP:
|
||||
if (m_use_hp)
|
||||
return { binary_tree };
|
||||
return { 1 };
|
||||
case SyntaxElementType::Token:
|
||||
return { token_tree };
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
/*
|
||||
* Select a probability with which to read a boolean when decoding a tree, as specified in section 9.3.2
|
||||
*/
|
||||
u8 TreeParser::select_tree_probability(SyntaxElementType type, u8 node)
|
||||
{
|
||||
switch (type) {
|
||||
case SyntaxElementType::Partition:
|
||||
return calculate_partition_probability(node);
|
||||
case SyntaxElementType::DefaultIntraMode:
|
||||
break;
|
||||
case SyntaxElementType::DefaultUVMode:
|
||||
break;
|
||||
case SyntaxElementType::IntraMode:
|
||||
break;
|
||||
case SyntaxElementType::SubIntraMode:
|
||||
break;
|
||||
case SyntaxElementType::UVMode:
|
||||
break;
|
||||
case SyntaxElementType::SegmentID:
|
||||
break;
|
||||
case SyntaxElementType::Skip:
|
||||
break;
|
||||
case SyntaxElementType::SegIDPredicted:
|
||||
break;
|
||||
case SyntaxElementType::IsInter:
|
||||
break;
|
||||
case SyntaxElementType::CompMode:
|
||||
break;
|
||||
case SyntaxElementType::CompRef:
|
||||
break;
|
||||
case SyntaxElementType::SingleRefP1:
|
||||
break;
|
||||
case SyntaxElementType::SingleRefP2:
|
||||
break;
|
||||
case SyntaxElementType::MVSign:
|
||||
break;
|
||||
case SyntaxElementType::MVClass0Bit:
|
||||
break;
|
||||
case SyntaxElementType::MVBit:
|
||||
break;
|
||||
case SyntaxElementType::TXSize:
|
||||
break;
|
||||
case SyntaxElementType::InterMode:
|
||||
break;
|
||||
case SyntaxElementType::InterpFilter:
|
||||
break;
|
||||
case SyntaxElementType::MVJoint:
|
||||
break;
|
||||
case SyntaxElementType::MVClass:
|
||||
break;
|
||||
case SyntaxElementType::MVClass0FR:
|
||||
break;
|
||||
case SyntaxElementType::MVClass0HP:
|
||||
break;
|
||||
case SyntaxElementType::MVFR:
|
||||
break;
|
||||
case SyntaxElementType::MVHP:
|
||||
break;
|
||||
case SyntaxElementType::Token:
|
||||
break;
|
||||
case SyntaxElementType::MoreCoefs:
|
||||
break;
|
||||
}
|
||||
TODO();
|
||||
}
|
||||
|
||||
u8 TreeParser::calculate_partition_probability(u8 node)
|
||||
{
|
||||
int node2;
|
||||
if (m_has_rows && m_has_cols) {
|
||||
node2 = node;
|
||||
} else if (m_has_cols) {
|
||||
node2 = 1;
|
||||
} else {
|
||||
node2 = 2;
|
||||
}
|
||||
|
||||
u32 above = 0;
|
||||
u32 left = 0;
|
||||
auto bsl = mi_width_log2_lookup[m_block_subsize];
|
||||
auto block_offset = mi_width_log2_lookup[Block_64x64] - bsl;
|
||||
for (auto i = 0; i < m_num_8x8; i++) {
|
||||
above |= m_above_partition_context[m_col + i];
|
||||
left |= m_left_partition_context[m_row + i];
|
||||
}
|
||||
above = (above & (1 << block_offset)) > 0;
|
||||
left = (left & (1 << block_offset)) > 0;
|
||||
auto ctx = bsl * 4 + left * 2 + above;
|
||||
if (m_frame_is_intra)
|
||||
return m_probability_tables.kf_partition_probs()[ctx][node2];
|
||||
return m_probability_tables.partition_probs()[ctx][node2];
|
||||
}
|
||||
|
||||
TreeParser::TreeSelection::TreeSelection(const int* values)
|
||||
: m_is_single_value(false)
|
||||
, m_value { .m_tree = values }
|
||||
{
|
||||
}
|
||||
|
||||
TreeParser::TreeSelection::TreeSelection(int value)
|
||||
: m_is_single_value(true)
|
||||
, m_value { .m_value = value }
|
||||
{
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue