Coverage Report

Created: 2026-02-16 07:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibMedia/Video/VP9/TreeParser.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
3
 * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
4
 *
5
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#include <AK/Function.h>
9
10
#include "Context.h"
11
#include "Enums.h"
12
#include "LookupTables.h"
13
#include "Parser.h"
14
#include "TreeParser.h"
15
#include "Utilities.h"
16
17
namespace Media::Video::VP9 {
18
19
// Parsing of binary trees is handled here, as defined in sections 9.3.
20
// Each syntax element is defined in its own section for each overarching section listed here:
21
// - 9.3.1: Selection of the binary tree to be used.
22
// - 9.3.2: Probability selection based on context and often the node of the tree.
23
// - 9.3.4: Counting each syntax element when it is read.
24
25
class TreeSelection {
26
public:
27
    union TreeSelectionValue {
28
        int const* m_tree;
29
        int m_value;
30
    };
31
32
    constexpr TreeSelection(int const* values)
33
28.3M
        : m_is_single_value(false)
34
28.3M
        , m_value { .m_tree = values }
35
28.3M
    {
36
28.3M
    }
37
38
    constexpr TreeSelection(int value)
39
457k
        : m_is_single_value(true)
40
457k
        , m_value { .m_value = value }
41
457k
    {
42
457k
    }
43
44
28.3M
    bool is_single_value() const { return m_is_single_value; }
45
19.2k
    int single_value() const { return m_value.m_value; }
46
28.3M
    int const* tree() const { return m_value.m_tree; }
47
48
private:
49
    bool m_is_single_value;
50
    TreeSelectionValue m_value;
51
};
52
53
template<typename OutputType>
54
inline OutputType parse_tree(BooleanDecoder& decoder, TreeSelection tree_selection, Function<u8(u8)> const& probability_getter)
55
28.4M
{
56
    // 9.3.3: The tree decoding function.
57
28.4M
    if (tree_selection.is_single_value())
58
19.2k
        return static_cast<OutputType>(tree_selection.single_value());
59
60
28.3M
    int const* tree = tree_selection.tree();
61
28.3M
    int n = 0;
62
40.1M
    do {
63
40.1M
        u8 node = n >> 1;
64
40.1M
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
40.1M
    } while (n > 0);
66
67
28.3M
    return static_cast<OutputType>(-n);
68
28.4M
}
Media::Video::VP9::Partition Media::Video::VP9::parse_tree<Media::Video::VP9::Partition>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
432k
{
56
    // 9.3.3: The tree decoding function.
57
432k
    if (tree_selection.is_single_value())
58
1.96k
        return static_cast<OutputType>(tree_selection.single_value());
59
60
431k
    int const* tree = tree_selection.tree();
61
431k
    int n = 0;
62
638k
    do {
63
638k
        u8 node = n >> 1;
64
638k
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
638k
    } while (n > 0);
66
67
431k
    return static_cast<OutputType>(-n);
68
432k
}
Media::Video::VP9::PredictionMode Media::Video::VP9::parse_tree<Media::Video::VP9::PredictionMode>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
754k
{
56
    // 9.3.3: The tree decoding function.
57
754k
    if (tree_selection.is_single_value())
58
0
        return static_cast<OutputType>(tree_selection.single_value());
59
60
754k
    int const* tree = tree_selection.tree();
61
754k
    int n = 0;
62
2.06M
    do {
63
2.06M
        u8 node = n >> 1;
64
2.06M
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
2.06M
    } while (n > 0);
66
67
754k
    return static_cast<OutputType>(-n);
68
754k
}
unsigned char Media::Video::VP9::parse_tree<unsigned char>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
16.6M
{
56
    // 9.3.3: The tree decoding function.
57
16.6M
    if (tree_selection.is_single_value())
58
3.28k
        return static_cast<OutputType>(tree_selection.single_value());
59
60
16.6M
    int const* tree = tree_selection.tree();
61
16.6M
    int n = 0;
62
16.8M
    do {
63
16.8M
        u8 node = n >> 1;
64
16.8M
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
16.8M
    } while (n > 0);
66
67
16.6M
    return static_cast<OutputType>(-n);
68
16.6M
}
bool Media::Video::VP9::parse_tree<bool>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
405k
{
56
    // 9.3.3: The tree decoding function.
57
405k
    if (tree_selection.is_single_value())
58
13.9k
        return static_cast<OutputType>(tree_selection.single_value());
59
60
391k
    int const* tree = tree_selection.tree();
61
391k
    int n = 0;
62
391k
    do {
63
391k
        u8 node = n >> 1;
64
391k
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
391k
    } while (n > 0);
66
67
391k
    return static_cast<OutputType>(-n);
68
405k
}
Media::Video::VP9::InterpolationFilter Media::Video::VP9::parse_tree<Media::Video::VP9::InterpolationFilter>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
16.4k
{
56
    // 9.3.3: The tree decoding function.
57
16.4k
    if (tree_selection.is_single_value())
58
0
        return static_cast<OutputType>(tree_selection.single_value());
59
60
16.4k
    int const* tree = tree_selection.tree();
61
16.4k
    int n = 0;
62
22.9k
    do {
63
22.9k
        u8 node = n >> 1;
64
22.9k
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
22.9k
    } while (n > 0);
66
67
16.4k
    return static_cast<OutputType>(-n);
68
16.4k
}
Media::Video::VP9::TransformSize Media::Video::VP9::parse_tree<Media::Video::VP9::TransformSize>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
23.0k
{
56
    // 9.3.3: The tree decoding function.
57
23.0k
    if (tree_selection.is_single_value())
58
0
        return static_cast<OutputType>(tree_selection.single_value());
59
60
23.0k
    int const* tree = tree_selection.tree();
61
23.0k
    int n = 0;
62
28.3k
    do {
63
28.3k
        u8 node = n >> 1;
64
28.3k
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
28.3k
    } while (n > 0);
66
67
23.0k
    return static_cast<OutputType>(-n);
68
23.0k
}
Media::Video::VP9::ReferenceMode Media::Video::VP9::parse_tree<Media::Video::VP9::ReferenceMode>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
18.0k
{
56
    // 9.3.3: The tree decoding function.
57
18.0k
    if (tree_selection.is_single_value())
58
0
        return static_cast<OutputType>(tree_selection.single_value());
59
60
18.0k
    int const* tree = tree_selection.tree();
61
18.0k
    int n = 0;
62
18.0k
    do {
63
18.0k
        u8 node = n >> 1;
64
18.0k
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
18.0k
    } while (n > 0);
66
67
18.0k
    return static_cast<OutputType>(-n);
68
18.0k
}
Media::Video::VP9::ReferenceIndex Media::Video::VP9::parse_tree<Media::Video::VP9::ReferenceIndex>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
15.1k
{
56
    // 9.3.3: The tree decoding function.
57
15.1k
    if (tree_selection.is_single_value())
58
0
        return static_cast<OutputType>(tree_selection.single_value());
59
60
15.1k
    int const* tree = tree_selection.tree();
61
15.1k
    int n = 0;
62
15.1k
    do {
63
15.1k
        u8 node = n >> 1;
64
15.1k
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
15.1k
    } while (n > 0);
66
67
15.1k
    return static_cast<OutputType>(-n);
68
15.1k
}
Media::Video::VP9::MvJoint Media::Video::VP9::parse_tree<Media::Video::VP9::MvJoint>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
25.9k
{
56
    // 9.3.3: The tree decoding function.
57
25.9k
    if (tree_selection.is_single_value())
58
0
        return static_cast<OutputType>(tree_selection.single_value());
59
60
25.9k
    int const* tree = tree_selection.tree();
61
25.9k
    int n = 0;
62
55.0k
    do {
63
55.0k
        u8 node = n >> 1;
64
55.0k
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
55.0k
    } while (n > 0);
66
67
25.9k
    return static_cast<OutputType>(-n);
68
25.9k
}
Media::Video::VP9::MvClass Media::Video::VP9::parse_tree<Media::Video::VP9::MvClass>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
24.8k
{
56
    // 9.3.3: The tree decoding function.
57
24.8k
    if (tree_selection.is_single_value())
58
0
        return static_cast<OutputType>(tree_selection.single_value());
59
60
24.8k
    int const* tree = tree_selection.tree();
61
24.8k
    int n = 0;
62
37.8k
    do {
63
37.8k
        u8 node = n >> 1;
64
37.8k
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
37.8k
    } while (n > 0);
66
67
24.8k
    return static_cast<OutputType>(-n);
68
24.8k
}
Media::Video::VP9::Token Media::Video::VP9::parse_tree<Media::Video::VP9::Token>(Gfx::BooleanDecoder&, Media::Video::VP9::TreeSelection, AK::Function<unsigned char (unsigned char)> const&)
Line
Count
Source
55
10.0M
{
56
    // 9.3.3: The tree decoding function.
57
10.0M
    if (tree_selection.is_single_value())
58
0
        return static_cast<OutputType>(tree_selection.single_value());
59
60
10.0M
    int const* tree = tree_selection.tree();
61
10.0M
    int n = 0;
62
20.0M
    do {
63
20.0M
        u8 node = n >> 1;
64
20.0M
        n = tree[n + decoder.read_bool(probability_getter(node))];
65
20.0M
    } while (n > 0);
66
67
10.0M
    return static_cast<OutputType>(-n);
68
10.0M
}
69
70
Partition TreeParser::parse_partition(BooleanDecoder& decoder, 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)
71
432k
{
72
    // Tree array
73
432k
    TreeSelection tree = { PartitionSplit };
74
432k
    if (has_rows && has_columns)
75
338k
        tree = { partition_tree };
76
94.2k
    else if (has_rows)
77
51.3k
        tree = { rows_partition_tree };
78
42.8k
    else if (has_columns)
79
40.8k
        tree = { cols_partition_tree };
80
81
    // Probability array
82
432k
    u32 above = 0;
83
432k
    u32 left = 0;
84
432k
    auto bsl = mi_width_log2_lookup[block_subsize];
85
432k
    auto block_offset = mi_width_log2_lookup[Block_64x64] - bsl;
86
2.28M
    for (auto i = 0; i < num_8x8; i++) {
87
1.85M
        above |= above_partition_context[column + i];
88
1.85M
        left |= left_partition_context[row + i];
89
1.85M
    }
90
432k
    above = (above & (1 << block_offset)) > 0;
91
432k
    left = (left & (1 << block_offset)) > 0;
92
432k
    auto context = bsl * 4 + left * 2 + above;
93
432k
    u8 const* probabilities = frame_is_intra ? probability_table.kf_partition_probs()[context] : probability_table.partition_probs()[context];
94
95
638k
    Function<u8(u8)> probability_getter = [&](u8 node) {
96
638k
        if (has_rows && has_columns)
97
545k
            return probabilities[node];
98
92.2k
        if (has_columns)
99
40.8k
            return probabilities[1];
100
51.3k
        return probabilities[2];
101
92.2k
    };
102
103
432k
    auto value = parse_tree<Partition>(decoder, tree, probability_getter);
104
432k
    counter.m_counts_partition[context][value]++;
105
432k
    return value;
106
432k
}
107
108
PredictionMode TreeParser::parse_default_intra_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, BlockSubsize mi_size, FrameBlockContext above, FrameBlockContext left, Array<PredictionMode, 4> const& block_sub_modes, u8 index_x, u8 index_y)
109
425k
{
110
    // FIXME: This should use a struct for the above and left contexts.
111
112
    // Tree
113
425k
    TreeSelection tree = { intra_mode_tree };
114
115
    // Probabilities
116
425k
    PredictionMode above_mode, left_mode;
117
425k
    if (mi_size >= Block_8x8) {
118
247k
        above_mode = above.sub_modes[2];
119
247k
        left_mode = left.sub_modes[1];
120
247k
    } else {
121
177k
        if (index_y > 0)
122
78.4k
            above_mode = block_sub_modes[index_x];
123
99.2k
        else
124
99.2k
            above_mode = above.sub_modes[2 + index_x];
125
126
177k
        if (index_x > 0)
127
73.0k
            left_mode = block_sub_modes[index_y << 1];
128
104k
        else
129
104k
            left_mode = left.sub_modes[1 + (index_y << 1)];
130
177k
    }
131
425k
    u8 const* probabilities = probability_table.kf_y_mode_probs()[to_underlying(above_mode)][to_underlying(left_mode)];
132
133
1.32M
    auto value = parse_tree<PredictionMode>(decoder, tree, [&](u8 node) { return probabilities[node]; });
134
    // Default intra mode is not counted.
135
425k
    return value;
136
425k
}
137
138
PredictionMode TreeParser::parse_default_uv_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, PredictionMode y_mode)
139
304k
{
140
    // Tree
141
304k
    TreeSelection tree = { intra_mode_tree };
142
143
    // Probabilities
144
304k
    u8 const* probabilities = probability_table.kf_uv_mode_prob()[to_underlying(y_mode)];
145
146
682k
    auto value = parse_tree<PredictionMode>(decoder, tree, [&](u8 node) { return probabilities[node]; });
147
    // Default UV mode is not counted.
148
304k
    return value;
149
304k
}
150
151
PredictionMode TreeParser::parse_intra_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, BlockSubsize mi_size)
152
10.2k
{
153
    // Tree
154
10.2k
    TreeSelection tree = { intra_mode_tree };
155
156
    // Probabilities
157
10.2k
    auto context = size_group_lookup[mi_size];
158
10.2k
    u8 const* probabilities = probability_table.y_mode_probs()[context];
159
160
18.5k
    auto value = parse_tree<PredictionMode>(decoder, tree, [&](u8 node) { return probabilities[node]; });
161
10.2k
    counter.m_counts_intra_mode[context][to_underlying(value)]++;
162
10.2k
    return value;
163
10.2k
}
164
165
PredictionMode TreeParser::parse_sub_intra_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter)
166
3.20k
{
167
    // Tree
168
3.20k
    TreeSelection tree = { intra_mode_tree };
169
170
    // Probabilities
171
3.20k
    u8 const* probabilities = probability_table.y_mode_probs()[0];
172
173
13.0k
    auto value = parse_tree<PredictionMode>(decoder, tree, [&](u8 node) { return probabilities[node]; });
174
3.20k
    counter.m_counts_intra_mode[0][to_underlying(value)]++;
175
3.20k
    return value;
176
3.20k
}
177
178
PredictionMode TreeParser::parse_uv_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, PredictionMode y_mode)
179
11.5k
{
180
    // Tree
181
11.5k
    TreeSelection tree = { intra_mode_tree };
182
183
    // Probabilities
184
11.5k
    u8 const* probabilities = probability_table.uv_mode_probs()[to_underlying(y_mode)];
185
186
27.2k
    auto value = parse_tree<PredictionMode>(decoder, tree, [&](u8 node) { return probabilities[node]; });
187
11.5k
    counter.m_counts_uv_mode[to_underlying(y_mode)][to_underlying(value)]++;
188
11.5k
    return value;
189
11.5k
}
190
191
u8 TreeParser::parse_segment_id(BooleanDecoder& decoder, Array<u8, 7> const& probabilities)
192
63.3k
{
193
189k
    auto value = parse_tree<u8>(decoder, { segment_tree }, [&](u8 node) { return probabilities[node]; });
194
    // Segment ID is not counted.
195
63.3k
    return value;
196
63.3k
}
197
198
bool TreeParser::parse_segment_id_predicted(BooleanDecoder& decoder, Array<u8, 3> const& probabilities, u8 above_seg_pred_context, u8 left_seg_pred_context)
199
1
{
200
1
    auto context = left_seg_pred_context + above_seg_pred_context;
201
1
    auto value = parse_tree<bool>(decoder, { binary_tree }, [&](u8) { return probabilities[context]; });
202
    // Segment ID prediction is not counted.
203
1
    return value;
204
1
}
205
206
PredictionMode TreeParser::parse_inter_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 mode_context_for_ref_frame_0)
207
46.5k
{
208
    // Tree
209
46.5k
    TreeSelection tree = { inter_mode_tree };
210
211
    // Probabilities
212
46.5k
    u8 const* probabilities = probability_table.inter_mode_probs()[mode_context_for_ref_frame_0];
213
214
112k
    auto value = parse_tree<u8>(decoder, tree, [&](u8 node) { return probabilities[node]; });
215
46.5k
    counter.m_counts_inter_mode[mode_context_for_ref_frame_0][value]++;
216
46.5k
    return static_cast<PredictionMode>(value + to_underlying(PredictionMode::NearestMv));
217
46.5k
}
218
219
InterpolationFilter TreeParser::parse_interpolation_filter(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left)
220
16.4k
{
221
    // FIXME: Above and left context should be provided by a struct.
222
223
    // Tree
224
16.4k
    TreeSelection tree = { interp_filter_tree };
225
226
    // Probabilities
227
    // NOTE: SWITCHABLE_FILTERS is not used in the spec for this function. Therefore, the number
228
    //       was demystified by referencing the reference codec libvpx:
229
    //       https://github.com/webmproject/libvpx/blob/705bf9de8c96cfe5301451f1d7e5c90a41c64e5f/vp9/common/vp9_pred_common.h#L69
230
16.4k
    u8 left_interp = !left.is_intra_predicted() ? left.interpolation_filter : SWITCHABLE_FILTERS;
231
16.4k
    u8 above_interp = !above.is_intra_predicted() ? above.interpolation_filter : SWITCHABLE_FILTERS;
232
16.4k
    u8 context = SWITCHABLE_FILTERS;
233
16.4k
    if (above_interp == left_interp || above_interp == SWITCHABLE_FILTERS)
234
9.44k
        context = left_interp;
235
7.00k
    else if (left_interp == SWITCHABLE_FILTERS)
236
5.98k
        context = above_interp;
237
16.4k
    u8 const* probabilities = probability_table.interp_filter_probs()[context];
238
239
22.9k
    auto value = parse_tree<InterpolationFilter>(decoder, tree, [&](u8 node) { return probabilities[node]; });
240
16.4k
    counter.m_counts_interp_filter[context][to_underlying(value)]++;
241
16.4k
    return value;
242
16.4k
}
243
244
bool TreeParser::parse_skip(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left)
245
252k
{
246
    // Probabilities
247
252k
    u8 context = 0;
248
252k
    context += static_cast<u8>(above.skip_coefficients);
249
252k
    context += static_cast<u8>(left.skip_coefficients);
250
252k
    u8 probability = probability_table.skip_prob()[context];
251
252
252k
    auto value = parse_tree<bool>(decoder, { binary_tree }, [&](u8) { return probability; });
253
252k
    counter.m_counts_skip[context][value]++;
254
252k
    return value;
255
252k
}
256
257
TransformSize TreeParser::parse_tx_size(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, TransformSize max_tx_size, FrameBlockContext above, FrameBlockContext left)
258
23.0k
{
259
    // FIXME: Above and left contexts should be in structs.
260
261
    // Tree
262
23.0k
    TreeSelection tree { tx_size_8_tree };
263
23.0k
    if (max_tx_size == Transform_16x16)
264
3.70k
        tree = { tx_size_16_tree };
265
23.0k
    if (max_tx_size == Transform_32x32)
266
9.21k
        tree = { tx_size_32_tree };
267
268
    // Probabilities
269
23.0k
    auto above_context = max_tx_size;
270
23.0k
    auto left_context = max_tx_size;
271
23.0k
    if (above.is_available && !above.skip_coefficients)
272
4.46k
        above_context = above.transform_size;
273
23.0k
    if (left.is_available && !left.skip_coefficients)
274
3.44k
        left_context = left.transform_size;
275
23.0k
    if (!left.is_available)
276
1.98k
        left_context = above_context;
277
23.0k
    if (!above.is_available)
278
11.2k
        above_context = left_context;
279
23.0k
    auto context = (above_context + left_context) > max_tx_size;
280
281
23.0k
    u8 const* probabilities = probability_table.tx_probs()[max_tx_size][context];
282
283
28.3k
    auto value = parse_tree<TransformSize>(decoder, tree, [&](u8 node) { return probabilities[node]; });
284
23.0k
    counter.m_counts_tx_size[max_tx_size][context][value]++;
285
23.0k
    return value;
286
23.0k
}
287
288
bool TreeParser::parse_block_is_inter_predicted(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left)
289
45.0k
{
290
    // FIXME: Above and left contexts should be in structs.
291
292
    // Probabilities
293
45.0k
    u8 context = 0;
294
45.0k
    if (above.is_available && left.is_available)
295
11.0k
        context = (left.is_intra_predicted() && above.is_intra_predicted()) ? 3 : static_cast<u8>(above.is_intra_predicted() || left.is_intra_predicted());
296
34.0k
    else if (above.is_available || left.is_available)
297
32.7k
        context = 2 * static_cast<u8>(above.is_available ? above.is_intra_predicted() : left.is_intra_predicted());
298
45.0k
    u8 probability = probability_table.is_inter_prob()[context];
299
300
45.0k
    auto value = parse_tree<bool>(decoder, { binary_tree }, [&](u8) { return probability; });
301
45.0k
    counter.m_counts_is_inter[context][value]++;
302
45.0k
    return value;
303
45.0k
}
304
305
ReferenceMode TreeParser::parse_comp_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, ReferenceFrameType comp_fixed_ref, FrameBlockContext above, FrameBlockContext left)
306
18.0k
{
307
    // FIXME: Above and left contexts should be in structs.
308
309
    // Probabilities
310
18.0k
    u8 context;
311
18.0k
    if (above.is_available && left.is_available) {
312
2.94k
        if (above.is_single_reference() && left.is_single_reference()) {
313
1.28k
            auto is_above_fixed = above.ref_frames.primary == comp_fixed_ref;
314
1.28k
            auto is_left_fixed = left.ref_frames.primary == comp_fixed_ref;
315
1.28k
            context = is_above_fixed ^ is_left_fixed;
316
1.66k
        } else if (above.is_single_reference()) {
317
557
            auto is_above_fixed = above.ref_frames.primary == comp_fixed_ref;
318
557
            context = 2 + static_cast<u8>(is_above_fixed || above.is_intra_predicted());
319
1.11k
        } else if (left.is_single_reference()) {
320
496
            auto is_left_fixed = left.ref_frames.primary == comp_fixed_ref;
321
496
            context = 2 + static_cast<u8>(is_left_fixed || left.is_intra_predicted());
322
614
        } else {
323
614
            context = 4;
324
614
        }
325
15.0k
    } else if (above.is_available) {
326
4.12k
        if (above.is_single_reference())
327
3.02k
            context = above.ref_frames.primary == comp_fixed_ref;
328
1.09k
        else
329
1.09k
            context = 3;
330
10.9k
    } else if (left.is_available) {
331
10.3k
        if (left.is_single_reference())
332
6.76k
            context = static_cast<u8>(left.ref_frames.primary == comp_fixed_ref);
333
3.56k
        else
334
3.56k
            context = 3;
335
10.3k
    } else {
336
621
        context = 1;
337
621
    }
338
18.0k
    u8 probability = probability_table.comp_mode_prob()[context];
339
340
18.0k
    auto value = parse_tree<ReferenceMode>(decoder, { binary_tree }, [&](u8) { return probability; });
341
18.0k
    counter.m_counts_comp_mode[context][value]++;
342
18.0k
    return value;
343
18.0k
}
344
345
ReferenceIndex TreeParser::parse_comp_ref(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, ReferenceFrameType comp_fixed_ref, ReferenceFramePair comp_var_ref, ReferenceIndex variable_reference_index, FrameBlockContext above, FrameBlockContext left)
346
15.1k
{
347
    // FIXME: Above and left contexts should be in structs.
348
349
    // Probabilities
350
15.1k
    u8 context;
351
352
15.1k
    if (above.is_available && left.is_available) {
353
1.55k
        if (above.is_intra_predicted() && left.is_intra_predicted()) {
354
61
            context = 2;
355
1.49k
        } else if (left.is_intra_predicted()) {
356
113
            if (above.is_single_reference()) {
357
39
                context = 1 + 2 * (above.ref_frames.primary != comp_var_ref.secondary);
358
74
            } else {
359
74
                context = 1 + 2 * (above.ref_frames[variable_reference_index] != comp_var_ref.secondary);
360
74
            }
361
1.38k
        } else if (above.is_intra_predicted()) {
362
62
            if (left.is_single_reference()) {
363
37
                context = 1 + 2 * (left.ref_frames.primary != comp_var_ref.secondary);
364
37
            } else {
365
25
                context = 1 + 2 * (left.ref_frames[variable_reference_index] != comp_var_ref.secondary);
366
25
            }
367
1.32k
        } else {
368
1.32k
            auto var_ref_above = above.is_single_reference() ? above.ref_frames.primary : above.ref_frames[variable_reference_index];
369
1.32k
            auto var_ref_left = left.is_single_reference() ? left.ref_frames.primary : left.ref_frames[variable_reference_index];
370
1.32k
            if (var_ref_above == var_ref_left && comp_var_ref.secondary == var_ref_above) {
371
165
                context = 0;
372
1.15k
            } else if (left.is_single_reference() && above.is_single_reference()) {
373
173
                if ((var_ref_above == comp_fixed_ref && var_ref_left == comp_var_ref.primary)
374
162
                    || (var_ref_left == comp_fixed_ref && var_ref_above == comp_var_ref.primary)) {
375
27
                    context = 4;
376
146
                } else if (var_ref_above == var_ref_left) {
377
61
                    context = 3;
378
85
                } else {
379
85
                    context = 1;
380
85
                }
381
982
            } else if (left.is_single_reference() || above.is_single_reference()) {
382
462
                auto vrfc = left.is_single_reference() ? var_ref_above : var_ref_left;
383
462
                auto rfs = above.is_single_reference() ? var_ref_above : var_ref_left;
384
462
                if (vrfc == comp_var_ref.secondary && rfs != comp_var_ref.secondary) {
385
89
                    context = 1;
386
373
                } else if (rfs == comp_var_ref.secondary && vrfc != comp_var_ref.secondary) {
387
47
                    context = 2;
388
326
                } else {
389
326
                    context = 4;
390
326
                }
391
520
            } else if (var_ref_above == var_ref_left) {
392
328
                context = 4;
393
328
            } else {
394
192
                context = 2;
395
192
            }
396
1.32k
        }
397
13.5k
    } else if (above.is_available) {
398
2.75k
        if (above.is_intra_predicted()) {
399
363
            context = 2;
400
2.39k
        } else {
401
2.39k
            if (above.is_single_reference()) {
402
427
                context = 3 * static_cast<u8>(above.ref_frames.primary != comp_var_ref.secondary);
403
1.96k
            } else {
404
1.96k
                context = 4 * static_cast<u8>(above.ref_frames[variable_reference_index] != comp_var_ref.secondary);
405
1.96k
            }
406
2.39k
        }
407
10.8k
    } else if (left.is_available) {
408
10.4k
        if (left.is_intra_predicted()) {
409
863
            context = 2;
410
9.61k
        } else {
411
9.61k
            if (left.is_single_reference()) {
412
1.37k
                context = 3 * static_cast<u8>(left.ref_frames.primary != comp_var_ref.secondary);
413
8.24k
            } else {
414
8.24k
                context = 4 * static_cast<u8>(left.ref_frames[variable_reference_index] != comp_var_ref.secondary);
415
8.24k
            }
416
9.61k
        }
417
10.4k
    } else {
418
343
        context = 2;
419
343
    }
420
421
15.1k
    u8 probability = probability_table.comp_ref_prob()[context];
422
423
15.1k
    auto value = parse_tree<ReferenceIndex>(decoder, { binary_tree }, [&](u8) { return probability; });
424
15.1k
    counter.m_counts_comp_ref[context][to_underlying(value)]++;
425
15.1k
    return value;
426
15.1k
}
427
428
bool TreeParser::parse_single_ref_part_1(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left)
429
19.2k
{
430
    // FIXME: Above and left contexts should be in structs.
431
432
    // Probabilities
433
19.2k
    u8 context;
434
19.2k
    if (above.is_available && left.is_available) {
435
5.39k
        if (above.is_intra_predicted() && left.is_intra_predicted()) {
436
195
            context = 2;
437
5.20k
        } else if (left.is_intra_predicted()) {
438
279
            if (above.is_single_reference()) {
439
263
                context = 4 * (above.ref_frames.primary == ReferenceFrameType::LastFrame);
440
263
            } else {
441
16
                context = 1 + (above.ref_frames.primary == ReferenceFrameType::LastFrame || above.ref_frames.secondary == ReferenceFrameType::LastFrame);
442
16
            }
443
4.92k
        } else if (above.is_intra_predicted()) {
444
503
            if (left.is_single_reference()) {
445
467
                context = 4 * (left.ref_frames.primary == ReferenceFrameType::LastFrame);
446
467
            } else {
447
36
                context = 1 + (left.ref_frames.primary == ReferenceFrameType::LastFrame || left.ref_frames.secondary == ReferenceFrameType::LastFrame);
448
36
            }
449
4.42k
        } else {
450
4.42k
            if (left.is_single_reference() && above.is_single_reference()) {
451
3.83k
                context = 2 * (above.ref_frames.primary == ReferenceFrameType::LastFrame) + 2 * (left.ref_frames.primary == ReferenceFrameType::LastFrame);
452
3.83k
            } else if (!left.is_single_reference() && !above.is_single_reference()) {
453
139
                auto above_used_last_frame = above.ref_frames.primary == ReferenceFrameType::LastFrame || above.ref_frames.secondary == ReferenceFrameType::LastFrame;
454
139
                auto left_used_last_frame = left.ref_frames.primary == ReferenceFrameType::LastFrame || left.ref_frames.secondary == ReferenceFrameType::LastFrame;
455
139
                context = 1 + (above_used_last_frame || left_used_last_frame);
456
447
            } else {
457
447
                auto single_reference_type = above.is_single_reference() ? above.ref_frames.primary : left.ref_frames.primary;
458
447
                auto compound_reference_a_type = above.is_single_reference() ? left.ref_frames.primary : above.ref_frames.primary;
459
447
                auto compound_reference_b_type = above.is_single_reference() ? left.ref_frames.secondary : above.ref_frames.secondary;
460
447
                context = compound_reference_a_type == ReferenceFrameType::LastFrame || compound_reference_b_type == ReferenceFrameType::LastFrame;
461
447
                if (single_reference_type == ReferenceFrameType::LastFrame)
462
256
                    context += 3;
463
447
            }
464
4.42k
        }
465
13.8k
    } else if (above.is_available) {
466
4.44k
        if (above.is_intra_predicted()) {
467
429
            context = 2;
468
4.01k
        } else {
469
4.01k
            if (above.is_single_reference()) {
470
3.58k
                context = 4 * (above.ref_frames.primary == ReferenceFrameType::LastFrame);
471
3.58k
            } else {
472
432
                context = 1 + (above.ref_frames.primary == ReferenceFrameType::LastFrame || above.ref_frames.secondary == ReferenceFrameType::LastFrame);
473
432
            }
474
4.01k
        }
475
9.38k
    } else if (left.is_available) {
476
8.67k
        if (left.is_intra_predicted()) {
477
555
            context = 2;
478
8.11k
        } else {
479
8.11k
            if (left.is_single_reference()) {
480
6.77k
                context = 4 * (left.ref_frames.primary == ReferenceFrameType::LastFrame);
481
6.77k
            } else {
482
1.33k
                context = 1 + (left.ref_frames.primary == ReferenceFrameType::LastFrame || left.ref_frames.secondary == ReferenceFrameType::LastFrame);
483
1.33k
            }
484
8.11k
        }
485
8.67k
    } else {
486
708
        context = 2;
487
708
    }
488
19.2k
    u8 probability = probability_table.single_ref_prob()[context][0];
489
490
19.2k
    auto value = parse_tree<bool>(decoder, { binary_tree }, [&](u8) { return probability; });
491
19.2k
    counter.m_counts_single_ref[context][0][value]++;
492
19.2k
    return value;
493
19.2k
}
494
495
bool TreeParser::parse_single_ref_part_2(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left)
496
7.23k
{
497
    // FIXME: Above and left contexts should be in structs.
498
499
    // Probabilities
500
7.23k
    u8 context;
501
7.23k
    if (above.is_available && left.is_available) {
502
1.62k
        if (above.is_intra_predicted() && left.is_intra_predicted()) {
503
96
            context = 2;
504
1.52k
        } else if (left.is_intra_predicted()) {
505
69
            if (above.is_single_reference()) {
506
63
                if (above.ref_frames.primary == ReferenceFrameType::LastFrame) {
507
4
                    context = 3;
508
59
                } else {
509
59
                    context = 4 * (above.ref_frames.primary == ReferenceFrameType::GoldenFrame);
510
59
                }
511
63
            } else {
512
6
                context = 1 + 2 * (above.ref_frames.primary == ReferenceFrameType::GoldenFrame || above.ref_frames.secondary == ReferenceFrameType::GoldenFrame);
513
6
            }
514
1.45k
        } else if (above.is_intra_predicted()) {
515
167
            if (left.is_single_reference()) {
516
137
                if (left.ref_frames.primary == ReferenceFrameType::LastFrame) {
517
40
                    context = 3;
518
97
                } else {
519
97
                    context = 4 * (left.ref_frames.primary == ReferenceFrameType::GoldenFrame);
520
97
                }
521
137
            } else {
522
30
                context = 1 + 2 * (left.ref_frames.primary == ReferenceFrameType::GoldenFrame || left.ref_frames.secondary == ReferenceFrameType::GoldenFrame);
523
30
            }
524
1.28k
        } else {
525
1.28k
            if (left.is_single_reference() && above.is_single_reference()) {
526
1.06k
                auto above_last = above.ref_frames.primary == ReferenceFrameType::LastFrame;
527
1.06k
                auto left_last = left.ref_frames.primary == ReferenceFrameType::LastFrame;
528
1.06k
                if (above_last && left_last) {
529
246
                    context = 3;
530
823
                } else if (above_last) {
531
188
                    context = 4 * (left.ref_frames.primary == ReferenceFrameType::GoldenFrame);
532
635
                } else if (left_last) {
533
180
                    context = 4 * (above.ref_frames.primary == ReferenceFrameType::GoldenFrame);
534
455
                } else {
535
455
                    context = 2 * (above.ref_frames.primary == ReferenceFrameType::GoldenFrame) + 2 * (left.ref_frames.primary == ReferenceFrameType::GoldenFrame);
536
455
                }
537
1.06k
            } else if (!left.is_single_reference() && !above.is_single_reference()) {
538
57
                if (above.ref_frames.primary == left.ref_frames.primary && above.ref_frames.secondary == left.ref_frames.secondary) {
539
42
                    context = 3 * (above.ref_frames.primary == ReferenceFrameType::GoldenFrame || above.ref_frames.secondary == ReferenceFrameType::GoldenFrame);
540
42
                } else {
541
15
                    context = 2;
542
15
                }
543
163
            } else {
544
163
                auto single_reference_type = above.is_single_reference() ? above.ref_frames.primary : left.ref_frames.primary;
545
163
                auto compound_reference_a_type = above.is_single_reference() ? left.ref_frames.primary : above.ref_frames.primary;
546
163
                auto compound_reference_b_type = above.is_single_reference() ? left.ref_frames.secondary : above.ref_frames.secondary;
547
163
                context = compound_reference_a_type == ReferenceFrameType::GoldenFrame || compound_reference_b_type == ReferenceFrameType::GoldenFrame;
548
163
                if (single_reference_type == ReferenceFrameType::GoldenFrame) {
549
62
                    context += 3;
550
101
                } else if (single_reference_type != ReferenceFrameType::AltRefFrame) {
551
24
                    context = 1 + (2 * context);
552
24
                }
553
163
            }
554
1.28k
        }
555
5.61k
    } else if (above.is_available) {
556
1.61k
        if (above.is_intra_predicted() || (above.ref_frames.primary == ReferenceFrameType::LastFrame && above.is_single_reference())) {
557
336
            context = 2;
558
1.27k
        } else if (above.is_single_reference()) {
559
1.11k
            context = 4 * (above.ref_frames.primary == ReferenceFrameType::GoldenFrame);
560
1.11k
        } else {
561
163
            context = 3 * (above.ref_frames.primary == ReferenceFrameType::GoldenFrame || above.ref_frames.secondary == ReferenceFrameType::GoldenFrame);
562
163
        }
563
4.00k
    } else if (left.is_available) {
564
3.75k
        if (left.is_intra_predicted() || (left.ref_frames.primary == ReferenceFrameType::LastFrame && left.is_single_reference())) {
565
632
            context = 2;
566
3.11k
        } else if (left.is_single_reference()) {
567
2.51k
            context = 4 * (left.ref_frames.primary == ReferenceFrameType::GoldenFrame);
568
2.51k
        } else {
569
602
            context = 3 * (left.ref_frames.primary == ReferenceFrameType::GoldenFrame || left.ref_frames.secondary == ReferenceFrameType::GoldenFrame);
570
602
        }
571
3.75k
    } else {
572
250
        context = 2;
573
250
    }
574
7.23k
    u8 probability = probability_table.single_ref_prob()[context][1];
575
576
7.23k
    auto value = parse_tree<bool>(decoder, { binary_tree }, [&](u8) { return probability; });
577
7.23k
    counter.m_counts_single_ref[context][1][value]++;
578
7.23k
    return value;
579
7.23k
}
580
581
MvJoint TreeParser::parse_motion_vector_joint(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter)
582
25.9k
{
583
55.0k
    auto value = parse_tree<MvJoint>(decoder, { mv_joint_tree }, [&](u8 node) { return probability_table.mv_joint_probs()[node]; });
584
25.9k
    counter.m_counts_mv_joint[value]++;
585
25.9k
    return value;
586
25.9k
}
587
588
bool TreeParser::parse_motion_vector_sign(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component)
589
24.8k
{
590
24.8k
    auto value = parse_tree<bool>(decoder, { binary_tree }, [&](u8) { return probability_table.mv_sign_prob()[component]; });
591
24.8k
    counter.m_counts_mv_sign[component][value]++;
592
24.8k
    return value;
593
24.8k
}
594
595
MvClass TreeParser::parse_motion_vector_class(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component)
596
24.8k
{
597
    // Spec doesn't mention node, but the probabilities table has an extra dimension
598
    // so we will use node for that.
599
37.8k
    auto value = parse_tree<MvClass>(decoder, { mv_class_tree }, [&](u8 node) { return probability_table.mv_class_probs()[component][node]; });
600
24.8k
    counter.m_counts_mv_class[component][value]++;
601
24.8k
    return value;
602
24.8k
}
603
604
bool TreeParser::parse_motion_vector_class0_bit(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component)
605
20.4k
{
606
20.4k
    auto value = parse_tree<bool>(decoder, { binary_tree }, [&](u8) { return probability_table.mv_class0_bit_prob()[component]; });
607
20.4k
    counter.m_counts_mv_class0_bit[component][value]++;
608
20.4k
    return value;
609
20.4k
}
610
611
u8 TreeParser::parse_motion_vector_class0_fr(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, bool class_0_bit)
612
20.4k
{
613
36.0k
    auto value = parse_tree<u8>(decoder, { mv_fr_tree }, [&](u8 node) { return probability_table.mv_class0_fr_probs()[component][class_0_bit][node]; });
614
20.4k
    counter.m_counts_mv_class0_fr[component][class_0_bit][value]++;
615
20.4k
    return value;
616
20.4k
}
617
618
bool TreeParser::parse_motion_vector_class0_hp(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, bool use_hp)
619
20.4k
{
620
20.4k
    TreeSelection tree { 1 };
621
20.4k
    if (use_hp)
622
6.43k
        tree = { binary_tree };
623
20.4k
    auto value = parse_tree<bool>(decoder, tree, [&](u8) { return probability_table.mv_class0_hp_prob()[component]; });
624
20.4k
    counter.m_counts_mv_class0_hp[component][value]++;
625
20.4k
    return value;
626
20.4k
}
627
628
bool TreeParser::parse_motion_vector_bit(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, u8 bit_index)
629
15.7k
{
630
15.7k
    auto value = parse_tree<bool>(decoder, { binary_tree }, [&](u8) { return probability_table.mv_bits_prob()[component][bit_index]; });
631
15.7k
    counter.m_counts_mv_bits[component][bit_index][value]++;
632
15.7k
    return value;
633
15.7k
}
634
635
u8 TreeParser::parse_motion_vector_fr(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component)
636
4.47k
{
637
10.3k
    auto value = parse_tree<u8>(decoder, { mv_fr_tree }, [&](u8 node) { return probability_table.mv_fr_probs()[component][node]; });
638
4.47k
    counter.m_counts_mv_fr[component][value]++;
639
4.47k
    return value;
640
4.47k
}
641
642
bool TreeParser::parse_motion_vector_hp(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, bool use_hp)
643
4.47k
{
644
4.47k
    TreeSelection tree { 1 };
645
4.47k
    if (use_hp)
646
1.18k
        tree = { binary_tree };
647
4.47k
    auto value = parse_tree<u8>(decoder, tree, [&](u8) { return probability_table.mv_hp_prob()[component]; });
648
4.47k
    counter.m_counts_mv_hp[component][value]++;
649
4.47k
    return value;
650
4.47k
}
651
652
TokensContext TreeParser::get_context_for_first_token(NonZeroTokensView above_non_zero_tokens, NonZeroTokensView left_non_zero_tokens_in_block, TransformSize transform_size, u8 plane, u32 sub_block_column, u32 sub_block_row, bool is_inter, u8 band)
653
11.2M
{
654
11.2M
    u8 transform_size_in_sub_blocks = transform_size_to_sub_blocks(transform_size);
655
11.2M
    bool above_has_non_zero_tokens = false;
656
23.8M
    for (u8 x = 0; x < transform_size_in_sub_blocks && x < above_non_zero_tokens[plane].size() - sub_block_column; x++) {
657
13.5M
        if (above_non_zero_tokens[plane][sub_block_column + x]) {
658
887k
            above_has_non_zero_tokens = true;
659
887k
            break;
660
887k
        }
661
13.5M
    }
662
11.2M
    bool left_has_non_zero_tokens = false;
663
24.1M
    for (u8 y = 0; y < transform_size_in_sub_blocks && y < left_non_zero_tokens_in_block[plane].size() - sub_block_row; y++) {
664
13.7M
        if (left_non_zero_tokens_in_block[plane][sub_block_row + y]) {
665
839k
            left_has_non_zero_tokens = true;
666
839k
            break;
667
839k
        }
668
13.7M
    }
669
670
11.2M
    u8 context = above_has_non_zero_tokens + left_has_non_zero_tokens;
671
11.2M
    return TokensContext { transform_size, plane > 0, is_inter, band, context };
672
11.2M
}
673
674
TokensContext TreeParser::get_context_for_other_tokens(Array<u8, 1024> token_cache, TransformSize transform_size, TransformSet transform_set, u8 plane, u16 token_position, bool is_inter, u8 band)
675
9.96M
{
676
9.96M
    auto transform_size_in_pixels = sub_blocks_to_pixels(transform_size_to_sub_blocks(transform_size));
677
9.96M
    auto log2_of_transform_size = transform_size + 2;
678
9.96M
    auto pixel_y = token_position >> log2_of_transform_size;
679
9.96M
    auto pixel_x = token_position - (pixel_y << log2_of_transform_size);
680
9.96M
    auto above_token_energy = pixel_y > 0 ? (pixel_y - 1) * transform_size_in_pixels + pixel_x : 0;
681
9.96M
    auto left_token_energy = pixel_y * transform_size_in_pixels + pixel_x - 1;
682
683
9.96M
    u32 neighbor_a, neighbor_b;
684
9.96M
    if (pixel_y > 0 && pixel_x > 0) {
685
5.25M
        if (transform_set == TransformSet { TransformType::DCT, TransformType::ADST }) {
686
876k
            neighbor_a = above_token_energy;
687
876k
            neighbor_b = above_token_energy;
688
4.37M
        } else if (transform_set == TransformSet { TransformType::ADST, TransformType::DCT }) {
689
455k
            neighbor_a = left_token_energy;
690
455k
            neighbor_b = left_token_energy;
691
3.92M
        } else {
692
3.92M
            neighbor_a = above_token_energy;
693
3.92M
            neighbor_b = left_token_energy;
694
3.92M
        }
695
5.25M
    } else if (pixel_y > 0) {
696
2.55M
        neighbor_a = above_token_energy;
697
2.55M
        neighbor_b = above_token_energy;
698
2.55M
    } else {
699
2.15M
        neighbor_a = left_token_energy;
700
2.15M
        neighbor_b = left_token_energy;
701
2.15M
    }
702
703
9.96M
    u8 context = (1 + token_cache[neighbor_a] + token_cache[neighbor_b]) >> 1;
704
9.96M
    return TokensContext { transform_size, plane > 0, is_inter, band, context };
705
9.96M
}
706
707
bool TreeParser::parse_more_coefficients(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, TokensContext const& context)
708
16.5M
{
709
16.5M
    auto probability = probability_table.coef_probs()[context.m_tx_size][context.m_is_uv_plane][context.m_is_inter][context.m_band][context.m_context_index][0];
710
16.5M
    auto value = parse_tree<u8>(decoder, { binary_tree }, [&](u8) { return probability; });
711
16.5M
    counter.m_counts_more_coefs[context.m_tx_size][context.m_is_uv_plane][context.m_is_inter][context.m_band][context.m_context_index][value]++;
712
16.5M
    return value;
713
16.5M
}
714
715
Token TreeParser::parse_token(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, TokensContext const& context)
716
10.0M
{
717
20.0M
    Function<u8(u8)> probability_getter = [&](u8 node) -> u8 {
718
20.0M
        auto prob = probability_table.coef_probs()[context.m_tx_size][context.m_is_uv_plane][context.m_is_inter][context.m_band][context.m_context_index][min(2, 1 + node)];
719
20.0M
        if (node < 2)
720
15.3M
            return prob;
721
4.70M
        auto x = (prob - 1) / 2;
722
4.70M
        auto const& pareto_table = probability_table.pareto_table();
723
4.70M
        if ((prob & 1) != 0)
724
2.90M
            return pareto_table[x][node - 2];
725
1.80M
        return (pareto_table[x][node - 2] + pareto_table[x + 1][node - 2]) >> 1;
726
4.70M
    };
727
728
10.0M
    auto value = parse_tree<Token>(decoder, { token_tree }, probability_getter);
729
10.0M
    counter.m_counts_token[context.m_tx_size][context.m_is_uv_plane][context.m_is_inter][context.m_band][context.m_context_index][min(2, value)]++;
730
10.0M
    return value;
731
10.0M
}
732
733
}