123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- /*
- * 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 }
- {
- }
- }
|