LibVideo/VP9: Implement token parsing (6.4.24-6.4.26)

Note that this now requires a couple new syntax types to be parsed
in the TreeParser, so a follow-up commit will implement that behavior.
This commit is contained in:
FalseHonesty 2021-06-27 10:58:16 -04:00 committed by Andreas Kling
parent d79c9c262f
commit aa27ca1b16
Notes: sideshowbarker 2024-07-18 09:23:29 +09:00
5 changed files with 171 additions and 4 deletions

File diff suppressed because one or more lines are too long

View file

@ -1191,10 +1191,93 @@ BlockSubsize Parser::get_plane_block_size(u32 subsize, u8 plane)
return ss_size_lookup[subsize][sub_x][sub_y];
}
bool Parser::tokens(size_t, u32, u32, TXSize, u32)
bool Parser::tokens(size_t plane, u32 start_x, u32 start_y, TXSize tx_size, u32 block_index)
{
// TODO: Implement
return true;
m_tree_parser->set_more_coefs_variables(start_x, start_y);
size_t segment_eob = 16 << (tx_size << 1);
auto scan = get_scan(plane, tx_size, block_index);
auto check_eob = true;
size_t c = 0;
for (; c < segment_eob; c++) {
auto pos = scan[c];
auto band = (tx_size == TX_4x4) ? coefband_4x4[c] : coefband_8x8plus[c];
m_tree_parser->set_band(band);
if (check_eob) {
auto more_coefs = m_tree_parser->parse_tree<bool>(SyntaxElementType::MoreCoefs);
if (!more_coefs)
break;
}
auto token = m_tree_parser->parse_tree<Token>(SyntaxElementType::Token);
m_token_cache[pos] = energy_class[token];
if (token == ZeroToken) {
m_tokens[pos] = 0;
check_eob = false;
} else {
i32 coef = static_cast<i32>(read_coef(token));
auto sign_bit = m_bit_stream->read_literal(1);
m_tokens[pos] = sign_bit ? -coef : coef;
check_eob = true;
}
}
auto non_zero = c > 0;
m_eob_total += non_zero;
for (size_t i = c; i < segment_eob; i++)
m_tokens[scan[i]] = 0;
return non_zero;
}
u32 const* Parser::get_scan(size_t plane, TXSize tx_size, u32 block_index)
{
if (plane > 0 || tx_size == TX_32x32) {
m_tx_type = DCT_DCT;
} else if (tx_size == TX_4x4) {
if (m_lossless || m_is_inter)
m_tx_type = DCT_DCT;
else
m_tx_type = mode_to_txfm_map[m_mi_size < Block_8x8 ? m_block_sub_modes[block_index] : m_y_mode];
} else {
m_tx_type = mode_to_txfm_map[m_y_mode];
}
if (tx_size == TX_4x4) {
if (m_tx_type == ADST_DCT)
return row_scan_4x4;
if (m_tx_type == DCT_ADST)
return col_scan_4x4;
return default_scan_4x4;
}
if (tx_size == TX_8x8) {
if (m_tx_type == ADST_DCT)
return row_scan_8x8;
if (m_tx_type == DCT_ADST)
return col_scan_8x8;
return default_scan_8x8;
}
if (tx_size == TX_16x16) {
if (m_tx_type == ADST_DCT)
return row_scan_16x16;
if (m_tx_type == DCT_ADST)
return col_scan_16x16;
return default_scan_16x16;
}
return default_scan_32x32;
}
u32 Parser::read_coef(Token token)
{
auto cat = extra_bits[token][0];
auto num_extra = extra_bits[token][1];
auto coef = extra_bits[token][2];
if (token == DctValCat6) {
for (size_t e = 0; e < (u8)(m_bit_depth - 8); e++) {
auto high_bit = m_bit_stream->read_bool(255);
coef += high_bit << (5 + m_bit_depth - e);
}
}
for (size_t e = 0; e < num_extra; e++) {
auto coef_bit = m_bit_stream->read_bool(cat_probs[cat][e]);
coef += coef_bit << (num_extra - 1 - e);
}
return coef;
}
bool Parser::find_mv_refs(ReferenceFrame, int)

View file

@ -116,7 +116,9 @@ private:
bool residual();
TXSize get_uv_tx_size();
BlockSubsize get_plane_block_size(u32 subsize, u8 plane);
bool tokens(size_t plane, u32 x, u32 y, TXSize size, u32 index);
bool tokens(size_t plane, u32 x, u32 y, TXSize tx_size, u32 block_index);
u32 const* get_scan(size_t plane, TXSize tx_size, u32 block_index);
u32 read_coef(Token token);
/* (6.5) Motion Vector Prediction */
bool find_mv_refs(ReferenceFrame, int block);
@ -220,6 +222,9 @@ private:
u32 m_ref_frame_width[NUM_REF_FRAMES];
u32 m_ref_frame_height[NUM_REF_FRAMES];
u32 m_eob_total { 0 };
u8 m_tx_type { 0 };
u8 m_token_cache[1024];
i32 m_tokens[1024];
bool m_use_hp { false };

View file

@ -36,6 +36,7 @@ template IntraMode TreeParser::parse_tree(SyntaxElementType);
template TXSize TreeParser::parse_tree(SyntaxElementType);
template InterpolationFilter TreeParser::parse_tree(SyntaxElementType);
template ReferenceMode TreeParser::parse_tree(SyntaxElementType);
template Token TreeParser::parse_tree(SyntaxElementType);
/*
* 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

View file

@ -57,6 +57,14 @@ public:
m_idy = idy;
}
void set_band(u8 band) { m_band = band; }
void set_more_coefs_variables(u32 start_x, u32 start_y)
{
m_start_x = start_x;
m_start_y = start_y;
}
private:
u8 calculate_partition_probability(u8 node);
u8 calculate_default_intra_mode_probability(u8 node);
@ -84,6 +92,9 @@ private:
// not stored in the Decoder itself.
u8 m_idx { 0 };
u8 m_idy { 0 };
u8 m_band { 0 };
u32 m_start_x { 0 };
u32 m_start_y { 0 };
};
}