1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-17 21:15:06 +00:00
serenity/Userland/Libraries/LibVideo/VP9/TreeParser.cpp

257 lines
7.2 KiB
C++

/*
* 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);
int value;
if (tree_selection.is_single_value()) {
value = tree_selection.get_single_value();
} else {
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);
value = -n;
}
count_syntax_element(type, value);
return value;
}
/*
* 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;
m_ctx = bsl * 4 + left * 2 + above;
if (m_frame_is_intra)
return m_probability_tables.kf_partition_probs()[m_ctx][node2];
return m_probability_tables.partition_probs()[m_ctx][node2];
}
void TreeParser::count_syntax_element(SyntaxElementType type, int value)
{
switch (type) {
case SyntaxElementType::Partition:
m_syntax_element_counter->m_counts_partition[m_ctx][value]++;
break;
case SyntaxElementType::IntraMode:
break;
case SyntaxElementType::SubIntraMode:
break;
case SyntaxElementType::UVMode:
break;
case SyntaxElementType::Skip:
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;
case SyntaxElementType::DefaultIntraMode:
case SyntaxElementType::DefaultUVMode:
case SyntaxElementType::SegmentID:
case SyntaxElementType::SegIDPredicted:
break;
}
}
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 }
{
}
}