/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 | | } |