Coverage Report

Created: 2025-03-04 07:22

/src/serenity/Userland/Libraries/LibMedia/Video/VP9/Parser.cpp
Line
Count
Source (jump to first uncovered line)
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/MemoryStream.h>
9
#include <LibGfx/Point.h>
10
#include <LibGfx/Size.h>
11
#include <LibThreading/WorkerThread.h>
12
13
#include "Context.h"
14
#include "Decoder.h"
15
#include "Parser.h"
16
#include "Utilities.h"
17
18
#if defined(AK_COMPILER_GCC)
19
#    pragma GCC optimize("O3")
20
#endif
21
22
// Beware, threading is unstable in Serenity with smp=on, and performs worse than with it off.
23
#define VP9_TILE_THREADING
24
25
namespace Media::Video::VP9 {
26
27
109k
#define TRY_READ(expression) DECODER_TRY(DecoderErrorCategory::Corrupted, expression)
28
29
Parser::Parser(Decoder& decoder)
30
783
    : m_decoder(decoder)
31
783
{
32
783
}
33
34
Parser::~Parser()
35
783
{
36
783
}
37
38
Vector<size_t> Parser::parse_superframe_sizes(ReadonlyBytes frame_data)
39
783
{
40
783
    if (frame_data.size() < 1)
41
0
        return {};
42
43
    // The decoder determines the presence of a superframe by:
44
    // 1. parsing the final byte of the chunk and checking that the superframe_marker equals 0b110,
45
46
    // If the checks in steps 1 and 3 both pass, then the chunk is determined to contain a superframe and each
47
    // frame in the superframe is passed to the decoding process in turn.
48
    // Otherwise, the chunk is determined to not contain a superframe, and the whole chunk is passed to the
49
    // decoding process.
50
51
    // NOTE: Reading from span data will be quicker than spinning up a BitStream.
52
783
    u8 superframe_byte = frame_data[frame_data.size() - 1];
53
54
    // NOTE: We have to read out of the byte from the little end first, hence the padding bits in the masks below.
55
783
    u8 superframe_marker = superframe_byte & 0b1110'0000;
56
783
    if (superframe_marker == 0b1100'0000) {
57
538
        u8 bytes_per_framesize = ((superframe_byte >> 3) & 0b11) + 1;
58
538
        u8 frames_in_superframe = (superframe_byte & 0b111) + 1;
59
        // 2. setting the total size of the superframe_index SzIndex equal to 2 + NumFrames * SzBytes,
60
538
        size_t index_size = 2 + bytes_per_framesize * frames_in_superframe;
61
62
538
        if (index_size > frame_data.size())
63
0
            return {};
64
65
538
        auto superframe_header_data = frame_data.data() + frame_data.size() - index_size;
66
67
538
        u8 start_superframe_byte = *(superframe_header_data++);
68
        // 3. checking that the first byte of the superframe_index matches the final byte.
69
538
        if (superframe_byte != start_superframe_byte)
70
42
            return {};
71
72
496
        Vector<size_t> result;
73
4.45k
        for (u8 i = 0; i < frames_in_superframe; i++) {
74
3.96k
            size_t frame_size = 0;
75
7.92k
            for (u8 j = 0; j < bytes_per_framesize; j++)
76
3.96k
                frame_size |= (static_cast<size_t>(*(superframe_header_data++)) << (j * 8));
77
3.96k
            result.append(frame_size);
78
3.96k
        }
79
496
        return result;
80
538
    }
81
82
245
    return {};
83
783
}
84
85
/* (6.1) */
86
DecoderErrorOr<FrameContext> Parser::parse_frame(ReadonlyBytes frame_data)
87
2.25k
{
88
2.25k
    if (!m_probability_tables)
89
783
        m_probability_tables = DECODER_TRY_ALLOC(try_make<ProbabilityTables>());
90
91
    // NOTE: m_reusable_frame_block_contexts does not need to retain any data between frame decodes.
92
    //       This is only stored so that we don't need to allocate a frame's block contexts on each
93
    //       call to this function, since it will rarely change sizes.
94
2.25k
    auto frame_context = DECODER_TRY_ALLOC(FrameContext::create(frame_data, m_reusable_frame_block_contexts));
95
2.25k
    TRY(uncompressed_header(frame_context));
96
    // FIXME: This should not be an error. Spec says that we consume padding bits until the end of the sample.
97
2.19k
    if (frame_context.header_size_in_bytes == 0)
98
12
        return DecoderError::corrupted("Frame header is zero-sized"sv);
99
2.18k
    m_probability_tables->load_probs(frame_context.probability_context_index);
100
2.18k
    m_probability_tables->load_probs2(frame_context.probability_context_index);
101
102
2.18k
    TRY(compressed_header(frame_context));
103
104
2.15k
    TRY(m_decoder.allocate_buffers(frame_context));
105
106
2.15k
    TRY(decode_tiles(frame_context));
107
1.88k
    TRY(refresh_probs(frame_context));
108
109
0
    m_previous_frame_type = frame_context.type;
110
1.88k
    m_previous_frame_size = frame_context.size();
111
1.88k
    m_previous_show_frame = frame_context.shows_a_frame();
112
1.88k
    m_previous_color_config = frame_context.color_config;
113
1.88k
    m_previous_loop_filter_ref_deltas = frame_context.loop_filter_reference_deltas;
114
1.88k
    m_previous_loop_filter_mode_deltas = frame_context.loop_filter_mode_deltas;
115
116
1.88k
    if (frame_context.segmentation_enabled) {
117
646
        m_previous_should_use_absolute_segment_base_quantizer = frame_context.should_use_absolute_segment_base_quantizer;
118
646
        m_previous_segmentation_features = frame_context.segmentation_features;
119
646
    }
120
121
1.88k
    return frame_context;
122
1.88k
}
123
124
DecoderErrorOr<void> Parser::refresh_probs(FrameContext const& frame_context)
125
1.88k
{
126
1.88k
    if (!frame_context.error_resilient_mode && !frame_context.parallel_decoding_mode) {
127
1.06k
        m_probability_tables->load_probs(frame_context.probability_context_index);
128
1.06k
        TRY(m_decoder.adapt_coef_probs(frame_context));
129
1.06k
        if (frame_context.is_inter_predicted()) {
130
741
            m_probability_tables->load_probs2(frame_context.probability_context_index);
131
741
            TRY(m_decoder.adapt_non_coef_probs(frame_context));
132
741
        }
133
1.06k
    }
134
1.88k
    if (frame_context.should_replace_probability_context)
135
472
        m_probability_tables->save_probs(frame_context.probability_context_index);
136
1.88k
    return {};
137
1.88k
}
138
139
DecoderErrorOr<VideoFullRangeFlag> Parser::read_video_full_range_flag(BigEndianInputBitStream& bit_stream)
140
902
{
141
902
    if (TRY_READ(bit_stream.read_bit()))
142
61
        return VideoFullRangeFlag::Full;
143
841
    return VideoFullRangeFlag::Studio;
144
902
}
145
146
template<Signed T = i8>
147
static ErrorOr<T> read_signed(BigEndianInputBitStream& bit_stream, u8 bits)
148
1.87k
{
149
1.87k
    auto value_unsigned = static_cast<T>(TRY(bit_stream.read_bits(bits)));
150
1.87k
    if (TRY(bit_stream.read_bit()))
151
1.42k
        return -value_unsigned;
152
453
    return value_unsigned;
153
1.87k
}
154
155
static DecoderErrorOr<i8> read_delta_q(BigEndianInputBitStream& bit_stream)
156
6.57k
{
157
6.57k
    if (TRY_READ(bit_stream.read_bit()))
158
6.57k
        return TRY_READ(read_signed(bit_stream, 4));
159
5.62k
    return 0;
160
6.57k
}
161
162
struct QuantizationParameters {
163
    u8 base_quantizer_index { 0 };
164
    i8 y_dc_quantizer_index_delta { 0 };
165
    i8 uv_dc_quantizer_index_delta { 0 };
166
    i8 uv_ac_quantizer_index_delta { 0 };
167
};
168
169
static DecoderErrorOr<QuantizationParameters> quantization_params(BigEndianInputBitStream& bit_stream)
170
2.19k
{
171
2.19k
    QuantizationParameters result;
172
2.19k
    result.base_quantizer_index = TRY_READ(bit_stream.read_bits(8));
173
2.19k
    result.y_dc_quantizer_index_delta = TRY(read_delta_q(bit_stream));
174
2.19k
    result.uv_dc_quantizer_index_delta = TRY(read_delta_q(bit_stream));
175
2.19k
    result.uv_ac_quantizer_index_delta = TRY(read_delta_q(bit_stream));
176
0
    return result;
177
2.19k
}
178
179
/* (6.2) */
180
DecoderErrorOr<void> Parser::uncompressed_header(FrameContext& frame_context)
181
2.25k
{
182
2.25k
    frame_context.color_config = m_previous_color_config;
183
184
2.25k
    auto frame_marker = TRY_READ(frame_context.bit_stream.read_bits(2));
185
2.25k
    if (frame_marker != 2)
186
44
        return DecoderError::corrupted("uncompressed_header: Frame marker must be 2"sv);
187
188
2.20k
    auto profile_low_bit = TRY_READ(frame_context.bit_stream.read_bit());
189
2.20k
    auto profile_high_bit = TRY_READ(frame_context.bit_stream.read_bit());
190
0
    frame_context.profile = (profile_high_bit << 1u) + profile_low_bit;
191
2.20k
    if (frame_context.profile == 3 && TRY_READ(frame_context.bit_stream.read_bit()))
192
0
        return DecoderError::corrupted("uncompressed_header: Profile 3 reserved bit was non-zero"sv);
193
194
2.20k
    if (TRY_READ(frame_context.bit_stream.read_bit())) {
195
8
        frame_context.set_existing_frame_to_show(TRY_READ(frame_context.bit_stream.read_bits(3)));
196
0
        return {};
197
8
    }
198
199
2.20k
    bool is_keyframe = !TRY_READ(frame_context.bit_stream.read_bit());
200
201
2.20k
    if (!TRY_READ(frame_context.bit_stream.read_bit()))
202
610
        frame_context.set_frame_hidden();
203
204
2.20k
    frame_context.error_resilient_mode = TRY_READ(frame_context.bit_stream.read_bit());
205
206
0
    FrameType type;
207
208
2.20k
    Gfx::Size<u32> frame_size;
209
2.20k
    Gfx::Size<u32> render_size;
210
2.20k
    u8 reference_frames_to_update_flags = 0xFF; // Save frame to all reference indices by default.
211
212
2.20k
    enum class ResetProbabilities : u8 {
213
2.20k
        No = 0,
214
        // 1 also means No here, but we don't need to do anything with the No case.
215
2.20k
        OnlyCurrent = 2,
216
2.20k
        All = 3,
217
2.20k
    };
218
2.20k
    ResetProbabilities reset_frame_context = ResetProbabilities::All;
219
220
2.20k
    if (is_keyframe) {
221
891
        type = FrameType::KeyFrame;
222
891
        TRY(frame_sync_code(frame_context.bit_stream));
223
888
        frame_context.color_config = TRY(parse_color_config(frame_context.bit_stream, frame_context.profile));
224
888
        frame_size = TRY(parse_frame_size(frame_context.bit_stream));
225
888
        render_size = TRY(parse_render_size(frame_context.bit_stream, frame_size));
226
1.30k
    } else {
227
1.30k
        if (!frame_context.shows_a_frame() && TRY_READ(frame_context.bit_stream.read_bit())) {
228
15
            type = FrameType::IntraOnlyFrame;
229
1.29k
        } else {
230
1.29k
            type = FrameType::InterFrame;
231
1.29k
            reset_frame_context = ResetProbabilities::No;
232
1.29k
        }
233
234
1.30k
        if (!frame_context.error_resilient_mode)
235
842
            reset_frame_context = static_cast<ResetProbabilities>(TRY_READ(frame_context.bit_stream.read_bits(2)));
236
237
1.30k
        if (type == FrameType::IntraOnlyFrame) {
238
15
            TRY(frame_sync_code(frame_context.bit_stream));
239
240
14
            if (frame_context.profile == 0) {
241
0
                frame_context.color_config = ColorConfig();
242
14
            } else {
243
14
                frame_context.color_config = TRY(parse_color_config(frame_context.bit_stream, frame_context.profile));
244
14
            }
245
246
14
            reference_frames_to_update_flags = TRY_READ(frame_context.bit_stream.read_bits(8));
247
14
            frame_size = TRY(parse_frame_size(frame_context.bit_stream));
248
14
            render_size = TRY(parse_render_size(frame_context.bit_stream, frame_size));
249
1.29k
        } else {
250
1.29k
            reference_frames_to_update_flags = TRY_READ(frame_context.bit_stream.read_bits(NUM_REF_FRAMES));
251
5.17k
            for (auto i = 0; i < REFS_PER_FRAME; i++) {
252
3.88k
                frame_context.reference_frame_indices[i] = TRY_READ(frame_context.bit_stream.read_bits(LOG2_OF_NUM_REF_FRAMES));
253
3.88k
                frame_context.reference_frame_sign_biases[ReferenceFrameType::LastFrame + i] = TRY_READ(frame_context.bit_stream.read_bit());
254
3.88k
            }
255
1.29k
            frame_size = TRY(parse_frame_size_with_refs(frame_context.bit_stream, frame_context.reference_frame_indices));
256
1.29k
            render_size = TRY(parse_render_size(frame_context.bit_stream, frame_size));
257
1.29k
            frame_context.high_precision_motion_vectors_allowed = TRY_READ(frame_context.bit_stream.read_bit());
258
1.29k
            frame_context.interpolation_filter = TRY(read_interpolation_filter(frame_context.bit_stream));
259
5.16k
            for (auto i = 0; i < REFS_PER_FRAME; i++) {
260
3.87k
                TRY(m_decoder.prepare_referenced_frame(frame_size, frame_context.reference_frame_indices[i]));
261
3.87k
            }
262
1.29k
        }
263
1.30k
    }
264
265
2.19k
    bool should_replace_probability_context = false;
266
2.19k
    bool parallel_decoding_mode = true;
267
2.19k
    if (!frame_context.error_resilient_mode) {
268
1.63k
        should_replace_probability_context = TRY_READ(frame_context.bit_stream.read_bit());
269
1.63k
        parallel_decoding_mode = TRY_READ(frame_context.bit_stream.read_bit());
270
1.63k
    }
271
272
2.19k
    u8 probability_context_index = TRY_READ(frame_context.bit_stream.read_bits(2));
273
0
    switch (reset_frame_context) {
274
923
    case ResetProbabilities::All:
275
923
        setup_past_independence();
276
4.61k
        for (auto i = 0; i < 4; i++) {
277
3.69k
            m_probability_tables->save_probs(i);
278
3.69k
        }
279
923
        probability_context_index = 0;
280
923
        break;
281
662
    case ResetProbabilities::OnlyCurrent:
282
662
        setup_past_independence();
283
662
        m_probability_tables->save_probs(probability_context_index);
284
662
        probability_context_index = 0;
285
662
        break;
286
608
    default:
287
608
        break;
288
2.19k
    }
289
290
2.19k
    frame_context.type = type;
291
2.19k
    DECODER_TRY_ALLOC(frame_context.set_size(frame_size));
292
0
    frame_context.render_size = render_size;
293
2.19k
    TRY(compute_image_size(frame_context));
294
295
0
    frame_context.reference_frames_to_update_flags = reference_frames_to_update_flags;
296
2.19k
    frame_context.parallel_decoding_mode = parallel_decoding_mode;
297
298
2.19k
    frame_context.should_replace_probability_context = should_replace_probability_context;
299
2.19k
    frame_context.probability_context_index = probability_context_index;
300
301
2.19k
    TRY(loop_filter_params(frame_context));
302
2.19k
    auto quantization_parameters = TRY(quantization_params(frame_context.bit_stream));
303
2.19k
    TRY(segmentation_params(frame_context));
304
0
    precalculate_quantizers(frame_context, quantization_parameters);
305
306
2.19k
    TRY(parse_tile_counts(frame_context));
307
308
2.19k
    frame_context.header_size_in_bytes = TRY_READ(frame_context.bit_stream.read_bits(16));
309
310
0
    frame_context.bit_stream.align_to_byte_boundary();
311
2.19k
    return {};
312
2.19k
}
313
314
DecoderErrorOr<void> Parser::frame_sync_code(BigEndianInputBitStream& bit_stream)
315
906
{
316
1.81k
    if (TRY_READ(bit_stream.read_bits(24)) != 0x498342) {
317
4
        return DecoderError::corrupted("frame sync code was not 0x498342."sv);
318
4
    }
319
902
    return {};
320
906
}
321
322
DecoderErrorOr<ColorConfig> Parser::parse_color_config(BigEndianInputBitStream& bit_stream, u8 profile)
323
902
{
324
    // (6.2.2) color_config( )
325
902
    u8 bit_depth;
326
902
    if (profile >= 2) {
327
96
        bit_depth = TRY_READ(bit_stream.read_bit()) ? 12 : 10;
328
806
    } else {
329
806
        bit_depth = 8;
330
806
    }
331
332
902
    auto color_space = static_cast<ColorSpace>(TRY_READ(bit_stream.read_bits(3)));
333
902
    if (color_space == ColorSpace::Reserved)
334
0
        return DecoderError::corrupted("color_config: Color space reserved value was set"sv);
335
336
902
    VERIFY(color_space <= ColorSpace::RGB);
337
338
902
    VideoFullRangeFlag video_full_range_flag;
339
902
    bool subsampling_x, subsampling_y;
340
341
902
    if (color_space != ColorSpace::RGB) {
342
902
        video_full_range_flag = TRY(read_video_full_range_flag(bit_stream));
343
902
        if (profile == 1 || profile == 3) {
344
109
            subsampling_x = TRY_READ(bit_stream.read_bit());
345
109
            subsampling_y = TRY_READ(bit_stream.read_bit());
346
109
            if (TRY_READ(bit_stream.read_bit()))
347
0
                return DecoderError::corrupted("color_config: Subsampling reserved zero was set"sv);
348
793
        } else {
349
793
            subsampling_x = true;
350
793
            subsampling_y = true;
351
793
        }
352
902
    } else {
353
0
        video_full_range_flag = VideoFullRangeFlag::Full;
354
0
        if (profile == 1 || profile == 3) {
355
0
            subsampling_x = false;
356
0
            subsampling_y = false;
357
0
            if (TRY_READ(bit_stream.read_bit()))
358
0
                return DecoderError::corrupted("color_config: RGB reserved zero was set"sv);
359
0
        } else {
360
            // FIXME: Spec does not specify the subsampling value here. Is this an error or should we set a default?
361
0
            return DecoderError::corrupted("color_config: Invalid subsampling value for profile 0 or 2"sv);
362
0
        }
363
0
    }
364
365
902
    return ColorConfig { bit_depth, color_space, video_full_range_flag, subsampling_x, subsampling_y };
366
902
}
367
368
DecoderErrorOr<Gfx::Size<u32>> Parser::parse_frame_size(BigEndianInputBitStream& bit_stream)
369
1.03k
{
370
1.03k
    return Gfx::Size<u32> { TRY_READ(bit_stream.read_bits(16)) + 1, TRY_READ(bit_stream.read_bits(16)) + 1 };
371
1.03k
}
372
373
DecoderErrorOr<Gfx::Size<u32>> Parser::parse_render_size(BigEndianInputBitStream& bit_stream, Gfx::Size<u32> frame_size)
374
2.19k
{
375
    // FIXME: This function should save this bit as a value in the FrameContext. The bit can be
376
    //        used in files where the pixel aspect ratio changes between samples in the video.
377
    //        If the bit is set, the pixel aspect ratio should be recalculated, whereas if only
378
    //        the frame size has changed and the render size is unadjusted, then the pixel aspect
379
    //        ratio should be retained and the new render size determined based on that.
380
    //        See the Firefox source code here:
381
    //        https://searchfox.org/mozilla-central/source/dom/media/platforms/wrappers/MediaChangeMonitor.cpp#268-276
382
2.19k
    if (!TRY_READ(bit_stream.read_bit()))
383
1.04k
        return frame_size;
384
1.14k
    return Gfx::Size<u32> { TRY_READ(bit_stream.read_bits(16)) + 1, TRY_READ(bit_stream.read_bits(16)) + 1 };
385
1.14k
}
386
387
DecoderErrorOr<Gfx::Size<u32>> Parser::parse_frame_size_with_refs(BigEndianInputBitStream& bit_stream, Array<u8, 3> const& reference_indices)
388
1.29k
{
389
1.29k
    Optional<Gfx::Size<u32>> size;
390
2.37k
    for (auto frame_index : reference_indices) {
391
2.37k
        if (TRY_READ(bit_stream.read_bit())) {
392
1.15k
            if (!m_reference_frames[frame_index].is_valid())
393
0
                return DecoderError::corrupted("Frame size referenced a frame that does not exist"sv);
394
1.15k
            size.emplace(m_reference_frames[frame_index].size);
395
1.15k
            break;
396
1.15k
        }
397
2.37k
    }
398
399
1.29k
    if (size.has_value())
400
1.15k
        return size.value();
401
402
136
    return TRY(parse_frame_size(bit_stream));
403
136
}
404
405
DecoderErrorOr<void> Parser::compute_image_size(FrameContext& frame_context)
406
2.19k
{
407
    // 7.2.6 Compute image size semantics
408
    // When compute_image_size is invoked, the following ordered steps occur:
409
    // 1. If this is the first time compute_image_size is invoked, or if either FrameWidth or FrameHeight have
410
    // changed in value compared to the previous time this function was invoked, then the segmentation map is
411
    // cleared to all zeros by setting SegmentId[ row ][ col ] equal to 0 for row = 0..MiRows-1 and col =
412
    // 0..MiCols-1.
413
    // FIXME: What does this mean? SegmentIds is scoped to one frame, so it will not contain values here. It's
414
    //        also suspicious that spec refers to this as SegmentId rather than SegmentIds (plural). Is this
415
    //        supposed to refer to PrevSegmentIds?
416
2.19k
    bool first_invoke = m_is_first_compute_image_size_invoke;
417
2.19k
    m_is_first_compute_image_size_invoke = false;
418
2.19k
    bool same_size = m_previous_frame_size == frame_context.size();
419
420
    // 2. The variable UsePrevFrameMvs is set equal to 1 if all of the following conditions are true:
421
    // a. This is not the first time compute_image_size is invoked.
422
    // b. Both FrameWidth and FrameHeight have the same value compared to the previous time this function
423
    // was invoked.
424
    // c. show_frame was equal to 1 the previous time this function was invoked.
425
    // d. error_resilient_mode is equal to 0.
426
    // e. FrameIsIntra is equal to 0.
427
    // Otherwise, UsePrevFrameMvs is set equal to 0.
428
2.19k
    frame_context.use_previous_frame_motion_vectors = !first_invoke && same_size && m_previous_show_frame && !frame_context.error_resilient_mode && frame_context.is_inter_predicted();
429
2.19k
    return {};
430
2.19k
}
431
432
DecoderErrorOr<InterpolationFilter> Parser::read_interpolation_filter(BigEndianInputBitStream& bit_stream)
433
1.29k
{
434
1.29k
    if (TRY_READ(bit_stream.read_bit())) {
435
967
        return InterpolationFilter::Switchable;
436
967
    }
437
327
    return literal_to_type[TRY_READ(bit_stream.read_bits(2))];
438
327
}
439
440
DecoderErrorOr<void> Parser::loop_filter_params(FrameContext& frame_context)
441
2.19k
{
442
    // FIXME: These should be moved to their own struct to return here.
443
2.19k
    frame_context.loop_filter_level = TRY_READ(frame_context.bit_stream.read_bits(6));
444
2.19k
    frame_context.loop_filter_sharpness = TRY_READ(frame_context.bit_stream.read_bits(3));
445
2.19k
    frame_context.loop_filter_delta_enabled = TRY_READ(frame_context.bit_stream.read_bit());
446
447
0
    auto reference_deltas = m_previous_loop_filter_ref_deltas;
448
2.19k
    auto mode_deltas = m_previous_loop_filter_mode_deltas;
449
2.19k
    if (frame_context.loop_filter_delta_enabled && TRY_READ(frame_context.bit_stream.read_bit())) {
450
944
        for (auto& loop_filter_ref_delta : reference_deltas) {
451
944
            if (TRY_READ(frame_context.bit_stream.read_bit()))
452
868
                loop_filter_ref_delta = TRY_READ(read_signed(frame_context.bit_stream, 6));
453
944
        }
454
472
        for (auto& loop_filter_mode_delta : mode_deltas) {
455
472
            if (TRY_READ(frame_context.bit_stream.read_bit()))
456
56
                loop_filter_mode_delta = TRY_READ(read_signed(frame_context.bit_stream, 6));
457
472
        }
458
236
    }
459
2.19k
    frame_context.loop_filter_reference_deltas = reference_deltas;
460
2.19k
    frame_context.loop_filter_mode_deltas = mode_deltas;
461
462
2.19k
    return {};
463
2.19k
}
464
465
DecoderErrorOr<void> Parser::segmentation_params(FrameContext& frame_context)
466
2.19k
{
467
2.19k
    frame_context.segmentation_enabled = TRY_READ(frame_context.bit_stream.read_bit());
468
2.19k
    if (!frame_context.segmentation_enabled)
469
1.49k
        return {};
470
471
692
    frame_context.should_use_absolute_segment_base_quantizer = m_previous_should_use_absolute_segment_base_quantizer;
472
692
    frame_context.segmentation_features = m_previous_segmentation_features;
473
474
692
    if (TRY_READ(frame_context.bit_stream.read_bit())) {
475
60
        frame_context.use_full_segment_id_tree = true;
476
60
        for (auto& segmentation_tree_prob : frame_context.full_segment_id_tree_probabilities)
477
420
            segmentation_tree_prob = TRY(read_prob(frame_context.bit_stream));
478
479
60
        if (TRY_READ(frame_context.bit_stream.read_bit())) {
480
13
            frame_context.use_predicted_segment_id_tree = true;
481
13
            for (auto& segmentation_pred_prob : frame_context.predicted_segment_id_tree_probabilities)
482
39
                segmentation_pred_prob = TRY(read_prob(frame_context.bit_stream));
483
13
        }
484
60
    }
485
486
692
    auto segmentation_update_data = (TRY_READ(frame_context.bit_stream.read_bit()));
487
488
692
    if (!segmentation_update_data)
489
52
        return {};
490
491
640
    frame_context.should_use_absolute_segment_base_quantizer = TRY_READ(frame_context.bit_stream.read_bit());
492
5.76k
    for (auto segment_id = 0; segment_id < MAX_SEGMENTS; segment_id++) {
493
25.6k
        for (auto feature_id = 0; feature_id < to_underlying(SegmentFeature::Sentinel); feature_id++) {
494
20.4k
            auto& feature = frame_context.segmentation_features[segment_id][feature_id];
495
20.4k
            feature.enabled = TRY_READ(frame_context.bit_stream.read_bit());
496
20.4k
            if (feature.enabled) {
497
4.64k
                auto bits_to_read = segmentation_feature_bits[feature_id];
498
4.64k
                feature.value = TRY_READ(frame_context.bit_stream.read_bits(bits_to_read));
499
4.64k
                if (segmentation_feature_signed[feature_id]) {
500
2.89k
                    if (TRY_READ(frame_context.bit_stream.read_bit()))
501
1.52k
                        feature.value = -feature.value;
502
2.89k
                }
503
4.64k
            }
504
20.4k
        }
505
5.12k
    }
506
507
640
    return {};
508
640
}
509
510
DecoderErrorOr<u8> Parser::read_prob(BigEndianInputBitStream& bit_stream)
511
459
{
512
459
    if (TRY_READ(bit_stream.read_bit()))
513
459
        return TRY_READ(bit_stream.read_bits(8));
514
281
    return 255;
515
459
}
516
517
void Parser::precalculate_quantizers(FrameContext& frame_context, QuantizationParameters quantization_parameters)
518
2.19k
{
519
2.19k
    frame_context.lossless = quantization_parameters.base_quantizer_index == 0
520
2.19k
        && quantization_parameters.y_dc_quantizer_index_delta == 0
521
2.19k
        && quantization_parameters.uv_dc_quantizer_index_delta == 0
522
2.19k
        && quantization_parameters.uv_ac_quantizer_index_delta == 0;
523
524
    // Pre-calculate the quantizers so that the decoder doesn't have to do it repeatedly.
525
19.7k
    for (u8 segment_id = 0; segment_id < MAX_SEGMENTS; segment_id++) {
526
17.5k
        auto alternative_quantizer_feature = frame_context.get_segment_feature(segment_id, SegmentFeature::AlternativeQuantizerBase);
527
17.5k
        auto base = Decoder::get_base_quantizer_index(alternative_quantizer_feature, frame_context.should_use_absolute_segment_base_quantizer, quantization_parameters.base_quantizer_index);
528
529
        // The function get_ac_quant( plane ) returns the quantizer value for the ac coefficient for a particular plane and
530
        // is derived as follows:
531
        // − If plane is equal to 0, return ac_q( get_qindex( ) ).
532
        // − Otherwise, return ac_q( get_qindex( ) + delta_q_uv_ac ).
533
17.5k
        auto& current_quantizers = frame_context.segment_quantizers[segment_id];
534
17.5k
        current_quantizers.y_ac_quantizer = Decoder::get_ac_quantizer(frame_context.color_config.bit_depth, base, 0);
535
17.5k
        current_quantizers.uv_ac_quantizer = Decoder::get_ac_quantizer(frame_context.color_config.bit_depth, base, quantization_parameters.uv_ac_quantizer_index_delta);
536
537
        // The function get_dc_quant( plane ) returns the quantizer value for the dc coefficient for a particular plane and
538
        // is derived as follows:
539
        // − If plane is equal to 0, return dc_q( get_qindex( ) + delta_q_y_dc ).
540
        // − Otherwise, return dc_q( get_qindex( ) + delta_q_uv_dc ).
541
17.5k
        current_quantizers.y_dc_quantizer = Decoder::get_dc_quantizer(frame_context.color_config.bit_depth, base, quantization_parameters.y_dc_quantizer_index_delta);
542
17.5k
        current_quantizers.uv_dc_quantizer = Decoder::get_dc_quantizer(frame_context.color_config.bit_depth, base, quantization_parameters.uv_dc_quantizer_index_delta);
543
17.5k
    }
544
2.19k
}
545
546
static u16 calc_min_log2_of_tile_columns(u32 superblock_columns)
547
2.19k
{
548
2.19k
    auto min_log_2 = 0u;
549
2.21k
    while ((u32)(MAX_TILE_WIDTH_B64 << min_log_2) < superblock_columns)
550
24
        min_log_2++;
551
2.19k
    return min_log_2;
552
2.19k
}
553
554
static u16 calc_max_log2_tile_cols(u32 superblock_columns)
555
2.19k
{
556
2.19k
    u16 max_log_2 = 1;
557
3.33k
    while ((superblock_columns >> max_log_2) >= MIN_TILE_WIDTH_B64)
558
1.14k
        max_log_2++;
559
2.19k
    return max_log_2 - 1;
560
2.19k
}
561
562
DecoderErrorOr<void> Parser::parse_tile_counts(FrameContext& frame_context)
563
2.19k
{
564
2.19k
    auto superblock_columns = frame_context.superblock_columns();
565
566
2.19k
    auto log2_of_tile_columns = calc_min_log2_of_tile_columns(superblock_columns);
567
2.19k
    auto log2_of_tile_columns_maximum = calc_max_log2_tile_cols(superblock_columns);
568
2.22k
    while (log2_of_tile_columns < log2_of_tile_columns_maximum) {
569
975
        if (TRY_READ(frame_context.bit_stream.read_bit()))
570
29
            log2_of_tile_columns++;
571
946
        else
572
946
            break;
573
975
    }
574
575
2.19k
    u16 log2_of_tile_rows = TRY_READ(frame_context.bit_stream.read_bit());
576
2.19k
    if (log2_of_tile_rows > 0) {
577
16
        log2_of_tile_rows += TRY_READ(frame_context.bit_stream.read_bit());
578
16
    }
579
2.19k
    frame_context.log2_of_tile_counts = Gfx::Size<u16>(log2_of_tile_columns, log2_of_tile_rows);
580
2.19k
    return {};
581
2.19k
}
582
583
void Parser::setup_past_independence()
584
1.58k
{
585
1.58k
    m_previous_block_contexts.reset();
586
1.58k
    m_previous_loop_filter_ref_deltas[ReferenceFrameType::None] = 1;
587
1.58k
    m_previous_loop_filter_ref_deltas[ReferenceFrameType::LastFrame] = 0;
588
1.58k
    m_previous_loop_filter_ref_deltas[ReferenceFrameType::GoldenFrame] = -1;
589
1.58k
    m_previous_loop_filter_ref_deltas[ReferenceFrameType::AltRefFrame] = -1;
590
1.58k
    m_previous_loop_filter_mode_deltas.fill(0);
591
1.58k
    m_previous_should_use_absolute_segment_base_quantizer = false;
592
1.58k
    for (auto& segment_levels : m_previous_segmentation_features)
593
12.6k
        segment_levels.fill({ false, 0 });
594
1.58k
    m_probability_tables->reset_probs();
595
1.58k
}
596
597
DecoderErrorOr<void> Parser::compressed_header(FrameContext& frame_context)
598
2.18k
{
599
2.18k
    auto decoder = TRY(frame_context.create_range_decoder(frame_context.header_size_in_bytes));
600
601
0
    frame_context.transform_mode = read_tx_mode(decoder, frame_context);
602
2.15k
    if (frame_context.transform_mode == TransformMode::Select)
603
387
        tx_mode_probs(decoder);
604
2.15k
    read_coef_probs(decoder, frame_context.transform_mode);
605
2.15k
    read_skip_prob(decoder);
606
2.15k
    if (frame_context.is_inter_predicted()) {
607
1.26k
        read_inter_mode_probs(decoder);
608
1.26k
        if (frame_context.interpolation_filter == Switchable)
609
951
            read_interp_filter_probs(decoder);
610
1.26k
        read_is_inter_probs(decoder);
611
1.26k
        frame_reference_mode(frame_context, decoder);
612
1.26k
        frame_reference_mode_probs(decoder, frame_context);
613
1.26k
        read_y_mode_probs(decoder);
614
1.26k
        read_partition_probs(decoder);
615
1.26k
        mv_probs(decoder, frame_context);
616
1.26k
    }
617
2.15k
    TRY_READ(decoder.finish_decode());
618
0
    return {};
619
2.15k
}
620
621
TransformMode Parser::read_tx_mode(BooleanDecoder& decoder, FrameContext const& frame_context)
622
2.15k
{
623
2.15k
    if (frame_context.lossless) {
624
1.24k
        return TransformMode::Only_4x4;
625
1.24k
    }
626
627
915
    auto tx_mode = decoder.read_literal(2);
628
915
    if (tx_mode == to_underlying(TransformMode::Allow_32x32))
629
465
        tx_mode += decoder.read_literal(1);
630
915
    return static_cast<TransformMode>(tx_mode);
631
2.15k
}
632
633
void Parser::tx_mode_probs(BooleanDecoder& decoder)
634
387
{
635
387
    auto& tx_probs = m_probability_tables->tx_probs();
636
1.16k
    for (auto i = 0; i < TX_SIZE_CONTEXTS; i++) {
637
1.54k
        for (auto j = 0; j < TX_SIZES - 3; j++)
638
774
            tx_probs[Transform_8x8][i][j] = diff_update_prob(decoder, tx_probs[Transform_8x8][i][j]);
639
774
    }
640
1.16k
    for (auto i = 0; i < TX_SIZE_CONTEXTS; i++) {
641
2.32k
        for (auto j = 0; j < TX_SIZES - 2; j++)
642
1.54k
            tx_probs[Transform_16x16][i][j] = diff_update_prob(decoder, tx_probs[Transform_16x16][i][j]);
643
774
    }
644
1.16k
    for (auto i = 0; i < TX_SIZE_CONTEXTS; i++) {
645
3.09k
        for (auto j = 0; j < TX_SIZES - 1; j++)
646
2.32k
            tx_probs[Transform_32x32][i][j] = diff_update_prob(decoder, tx_probs[Transform_32x32][i][j]);
647
774
    }
648
387
}
649
650
u8 Parser::diff_update_prob(BooleanDecoder& decoder, u8 prob)
651
259k
{
652
259k
    auto update_prob = decoder.read_bool(252);
653
259k
    if (update_prob) {
654
13.8k
        auto delta_prob = decode_term_subexp(decoder);
655
13.8k
        prob = inv_remap_prob(delta_prob, prob);
656
13.8k
    }
657
259k
    return prob;
658
259k
}
659
660
u8 Parser::decode_term_subexp(BooleanDecoder& decoder)
661
13.8k
{
662
13.8k
    if (decoder.read_literal(1) == 0)
663
5.25k
        return decoder.read_literal(4);
664
8.57k
    if (decoder.read_literal(1) == 0)
665
2.10k
        return decoder.read_literal(4) + 16;
666
6.46k
    if (decoder.read_literal(1) == 0)
667
812
        return decoder.read_literal(5) + 32;
668
669
5.65k
    auto v = decoder.read_literal(7);
670
5.65k
    if (v < 65)
671
215
        return v + 64;
672
5.43k
    return (v << 1u) - 1 + decoder.read_literal(1);
673
5.65k
}
674
675
u8 Parser::inv_remap_prob(u8 delta_prob, u8 prob)
676
13.8k
{
677
13.8k
    u8 m = prob - 1;
678
13.8k
    auto v = inv_map_table[delta_prob];
679
13.8k
    if ((m << 1u) <= 255)
680
8.89k
        return 1 + inv_recenter_nonneg(v, m);
681
4.92k
    return 255 - inv_recenter_nonneg(v, 254 - m);
682
13.8k
}
683
684
u8 Parser::inv_recenter_nonneg(u8 v, u8 m)
685
13.8k
{
686
13.8k
    if (v > 2 * m)
687
8.40k
        return v;
688
5.41k
    if (v & 1u)
689
2.84k
        return m - ((v + 1u) >> 1u);
690
2.57k
    return m + (v >> 1u);
691
5.41k
}
692
693
void Parser::read_coef_probs(BooleanDecoder& decoder, TransformMode transform_mode)
694
2.15k
{
695
2.15k
    auto max_tx_size = tx_mode_to_biggest_tx_size[to_underlying(transform_mode)];
696
5.87k
    for (u8 transform_size = 0; transform_size <= max_tx_size; transform_size++) {
697
3.71k
        auto update_probs = decoder.read_literal(1);
698
3.71k
        if (update_probs == 1) {
699
639
            for (auto i = 0; i < 2; i++) {
700
1.27k
                for (auto j = 0; j < 2; j++) {
701
5.96k
                    for (auto k = 0; k < 6; k++) {
702
5.11k
                        auto max_l = (k == 0) ? 3 : 6;
703
33.2k
                        for (auto l = 0; l < max_l; l++) {
704
112k
                            for (auto m = 0; m < 3; m++) {
705
84.3k
                                auto& prob = m_probability_tables->coef_probs()[transform_size][i][j][k][l][m];
706
84.3k
                                prob = diff_update_prob(decoder, prob);
707
84.3k
                            }
708
28.1k
                        }
709
5.11k
                    }
710
852
                }
711
426
            }
712
213
        }
713
3.71k
    }
714
2.15k
}
715
716
void Parser::read_skip_prob(BooleanDecoder& decoder)
717
2.15k
{
718
8.63k
    for (auto i = 0; i < SKIP_CONTEXTS; i++)
719
6.47k
        m_probability_tables->skip_prob()[i] = diff_update_prob(decoder, m_probability_tables->skip_prob()[i]);
720
2.15k
}
721
722
void Parser::read_inter_mode_probs(BooleanDecoder& decoder)
723
1.26k
{
724
10.1k
    for (auto i = 0; i < INTER_MODE_CONTEXTS; i++) {
725
35.4k
        for (auto j = 0; j < INTER_MODES - 1; j++)
726
26.6k
            m_probability_tables->inter_mode_probs()[i][j] = diff_update_prob(decoder, m_probability_tables->inter_mode_probs()[i][j]);
727
8.86k
    }
728
1.26k
}
729
730
void Parser::read_interp_filter_probs(BooleanDecoder& decoder)
731
951
{
732
4.75k
    for (auto i = 0; i < INTERP_FILTER_CONTEXTS; i++) {
733
11.4k
        for (auto j = 0; j < SWITCHABLE_FILTERS - 1; j++)
734
7.60k
            m_probability_tables->interp_filter_probs()[i][j] = diff_update_prob(decoder, m_probability_tables->interp_filter_probs()[i][j]);
735
3.80k
    }
736
951
}
737
738
void Parser::read_is_inter_probs(BooleanDecoder& decoder)
739
1.26k
{
740
6.33k
    for (auto i = 0; i < IS_INTER_CONTEXTS; i++)
741
5.06k
        m_probability_tables->is_inter_prob()[i] = diff_update_prob(decoder, m_probability_tables->is_inter_prob()[i]);
742
1.26k
}
743
744
static void setup_compound_reference_mode(FrameContext& frame_context)
745
933
{
746
933
    ReferenceFrameType fixed_reference;
747
933
    ReferenceFramePair variable_references;
748
933
    if (frame_context.reference_frame_sign_biases[ReferenceFrameType::LastFrame] == frame_context.reference_frame_sign_biases[ReferenceFrameType::GoldenFrame]) {
749
690
        fixed_reference = ReferenceFrameType::AltRefFrame;
750
690
        variable_references = { ReferenceFrameType::LastFrame, ReferenceFrameType::GoldenFrame };
751
690
    } else if (frame_context.reference_frame_sign_biases[ReferenceFrameType::LastFrame] == frame_context.reference_frame_sign_biases[ReferenceFrameType::AltRefFrame]) {
752
12
        fixed_reference = ReferenceFrameType::GoldenFrame;
753
12
        variable_references = { ReferenceFrameType::LastFrame, ReferenceFrameType::AltRefFrame };
754
231
    } else {
755
231
        fixed_reference = ReferenceFrameType::LastFrame;
756
231
        variable_references = { ReferenceFrameType::GoldenFrame, ReferenceFrameType::AltRefFrame };
757
231
    }
758
933
    frame_context.fixed_reference_type = fixed_reference;
759
933
    frame_context.variable_reference_types = variable_references;
760
933
}
761
762
void Parser::frame_reference_mode(FrameContext& frame_context, BooleanDecoder& decoder)
763
1.26k
{
764
1.26k
    auto compound_reference_allowed = false;
765
3.80k
    for (size_t i = 2; i <= REFS_PER_FRAME; i++) {
766
2.53k
        if (frame_context.reference_frame_sign_biases[i] != frame_context.reference_frame_sign_biases[1])
767
1.38k
            compound_reference_allowed = true;
768
2.53k
    }
769
1.26k
    ReferenceMode reference_mode;
770
1.26k
    if (compound_reference_allowed) {
771
1.10k
        auto non_single_reference = decoder.read_literal(1);
772
1.10k
        if (non_single_reference == 0) {
773
171
            reference_mode = SingleReference;
774
933
        } else {
775
933
            auto reference_select = decoder.read_literal(1);
776
933
            if (reference_select == 0)
777
227
                reference_mode = CompoundReference;
778
706
            else
779
706
                reference_mode = ReferenceModeSelect;
780
933
        }
781
1.10k
    } else {
782
163
        reference_mode = SingleReference;
783
163
    }
784
1.26k
    frame_context.reference_mode = reference_mode;
785
1.26k
    if (reference_mode != SingleReference)
786
933
        setup_compound_reference_mode(frame_context);
787
1.26k
}
788
789
void Parser::frame_reference_mode_probs(BooleanDecoder& decoder, FrameContext const& frame_context)
790
1.26k
{
791
1.26k
    if (frame_context.reference_mode == ReferenceModeSelect) {
792
4.23k
        for (auto i = 0; i < COMP_MODE_CONTEXTS; i++) {
793
3.53k
            auto& comp_mode_prob = m_probability_tables->comp_mode_prob();
794
3.53k
            comp_mode_prob[i] = diff_update_prob(decoder, comp_mode_prob[i]);
795
3.53k
        }
796
706
    }
797
1.26k
    if (frame_context.reference_mode != CompoundReference) {
798
6.24k
        for (auto i = 0; i < REF_CONTEXTS; i++) {
799
5.20k
            auto& single_ref_prob = m_probability_tables->single_ref_prob();
800
5.20k
            single_ref_prob[i][0] = diff_update_prob(decoder, single_ref_prob[i][0]);
801
5.20k
            single_ref_prob[i][1] = diff_update_prob(decoder, single_ref_prob[i][1]);
802
5.20k
        }
803
1.04k
    }
804
1.26k
    if (frame_context.reference_mode != SingleReference) {
805
5.59k
        for (auto i = 0; i < REF_CONTEXTS; i++) {
806
4.66k
            auto& comp_ref_prob = m_probability_tables->comp_ref_prob();
807
4.66k
            comp_ref_prob[i] = diff_update_prob(decoder, comp_ref_prob[i]);
808
4.66k
        }
809
933
    }
810
1.26k
}
811
812
void Parser::read_y_mode_probs(BooleanDecoder& decoder)
813
1.26k
{
814
6.33k
    for (auto i = 0; i < BLOCK_SIZE_GROUPS; i++) {
815
50.6k
        for (auto j = 0; j < INTRA_MODES - 1; j++) {
816
45.6k
            auto& y_mode_probs = m_probability_tables->y_mode_probs();
817
45.6k
            y_mode_probs[i][j] = diff_update_prob(decoder, y_mode_probs[i][j]);
818
45.6k
        }
819
5.06k
    }
820
1.26k
}
821
822
void Parser::read_partition_probs(BooleanDecoder& decoder)
823
1.26k
{
824
21.5k
    for (auto i = 0; i < PARTITION_CONTEXTS; i++) {
825
81.0k
        for (auto j = 0; j < PARTITION_TYPES - 1; j++) {
826
60.8k
            auto& partition_probs = m_probability_tables->partition_probs();
827
60.8k
            partition_probs[i][j] = diff_update_prob(decoder, partition_probs[i][j]);
828
60.8k
        }
829
20.2k
    }
830
1.26k
}
831
832
void Parser::mv_probs(BooleanDecoder& decoder, FrameContext const& frame_context)
833
1.26k
{
834
5.06k
    for (auto j = 0; j < MV_JOINTS - 1; j++) {
835
3.80k
        auto& mv_joint_probs = m_probability_tables->mv_joint_probs();
836
3.80k
        mv_joint_probs[j] = update_mv_prob(decoder, mv_joint_probs[j]);
837
3.80k
    }
838
839
3.80k
    for (auto i = 0; i < 2; i++) {
840
2.53k
        auto& mv_sign_prob = m_probability_tables->mv_sign_prob();
841
2.53k
        mv_sign_prob[i] = update_mv_prob(decoder, mv_sign_prob[i]);
842
27.8k
        for (auto j = 0; j < MV_CLASSES - 1; j++) {
843
25.3k
            auto& mv_class_probs = m_probability_tables->mv_class_probs();
844
25.3k
            mv_class_probs[i][j] = update_mv_prob(decoder, mv_class_probs[i][j]);
845
25.3k
        }
846
2.53k
        auto& mv_class0_bit_prob = m_probability_tables->mv_class0_bit_prob();
847
2.53k
        mv_class0_bit_prob[i] = update_mv_prob(decoder, mv_class0_bit_prob[i]);
848
27.8k
        for (auto j = 0; j < MV_OFFSET_BITS; j++) {
849
25.3k
            auto& mv_bits_prob = m_probability_tables->mv_bits_prob();
850
25.3k
            mv_bits_prob[i][j] = update_mv_prob(decoder, mv_bits_prob[i][j]);
851
25.3k
        }
852
2.53k
    }
853
854
3.80k
    for (auto i = 0; i < 2; i++) {
855
7.60k
        for (auto j = 0; j < CLASS0_SIZE; j++) {
856
20.2k
            for (auto k = 0; k < MV_FR_SIZE - 1; k++) {
857
15.2k
                auto& mv_class0_fr_probs = m_probability_tables->mv_class0_fr_probs();
858
15.2k
                mv_class0_fr_probs[i][j][k] = update_mv_prob(decoder, mv_class0_fr_probs[i][j][k]);
859
15.2k
            }
860
5.06k
        }
861
10.1k
        for (auto k = 0; k < MV_FR_SIZE - 1; k++) {
862
7.60k
            auto& mv_fr_probs = m_probability_tables->mv_fr_probs();
863
7.60k
            mv_fr_probs[i][k] = update_mv_prob(decoder, mv_fr_probs[i][k]);
864
7.60k
        }
865
2.53k
    }
866
867
1.26k
    if (frame_context.high_precision_motion_vectors_allowed) {
868
2.39k
        for (auto i = 0; i < 2; i++) {
869
1.59k
            auto& mv_class0_hp_prob = m_probability_tables->mv_class0_hp_prob();
870
1.59k
            auto& mv_hp_prob = m_probability_tables->mv_hp_prob();
871
1.59k
            mv_class0_hp_prob[i] = update_mv_prob(decoder, mv_class0_hp_prob[i]);
872
1.59k
            mv_hp_prob[i] = update_mv_prob(decoder, mv_hp_prob[i]);
873
1.59k
        }
874
798
    }
875
1.26k
}
876
877
u8 Parser::update_mv_prob(BooleanDecoder& decoder, u8 prob)
878
85.5k
{
879
85.5k
    if (decoder.read_bool(252)) {
880
2.62k
        return (decoder.read_literal(7) << 1u) | 1u;
881
2.62k
    }
882
82.9k
    return prob;
883
85.5k
}
884
885
static u32 get_tile_offset(u32 tile_start, u32 frame_size_in_blocks, u32 tile_size_log2)
886
8.78k
{
887
8.78k
    u32 superblocks = blocks_ceiled_to_superblocks(frame_size_in_blocks);
888
8.78k
    u32 offset = superblocks_to_blocks((tile_start * superblocks) >> tile_size_log2);
889
8.78k
    return min(offset, frame_size_in_blocks);
890
8.78k
}
891
892
DecoderErrorOr<void> Parser::decode_tiles(FrameContext& frame_context)
893
2.15k
{
894
2.15k
    auto log2_dimensions = frame_context.log2_of_tile_counts;
895
2.15k
    auto tile_cols = 1u << log2_dimensions.width();
896
2.15k
    auto tile_rows = 1u << log2_dimensions.height();
897
898
2.15k
    PartitionContext above_partition_context = DECODER_TRY_ALLOC(PartitionContext::create(superblocks_to_blocks(frame_context.superblock_columns())));
899
2.15k
    NonZeroTokens above_non_zero_tokens = DECODER_TRY_ALLOC(create_non_zero_tokens(blocks_to_sub_blocks(frame_context.columns()), frame_context.color_config.subsampling_x));
900
2.15k
    SegmentationPredictionContext above_segmentation_ids = DECODER_TRY_ALLOC(SegmentationPredictionContext::create(frame_context.columns()));
901
902
    // FIXME: To implement tiled decoding, we'll need to pre-parse the tile positions and sizes into a 2D vector of ReadonlyBytes,
903
    //        then run through each column of tiles in top to bottom order afterward. Each column can be sent to a worker thread
904
    //        for execution. Each worker thread will want to create a set of above contexts sized to its tile width, then provide
905
    //        those to each tile as it decodes them.
906
0
    Vector<Vector<TileContext, 1>, 4> tile_workloads;
907
2.15k
    DECODER_TRY_ALLOC(tile_workloads.try_ensure_capacity(tile_cols));
908
4.34k
    for (auto tile_col = 0u; tile_col < tile_cols; tile_col++) {
909
2.19k
        tile_workloads.append({});
910
2.19k
        DECODER_TRY_ALLOC(tile_workloads[tile_col].try_ensure_capacity(tile_rows));
911
2.19k
    }
912
913
4.26k
    for (auto tile_row = 0u; tile_row < tile_rows; tile_row++) {
914
4.31k
        for (auto tile_col = 0u; tile_col < tile_cols; tile_col++) {
915
2.19k
            auto last_tile = (tile_row == tile_rows - 1) && (tile_col == tile_cols - 1);
916
2.19k
            size_t tile_size;
917
2.19k
            if (last_tile)
918
2.15k
                tile_size = frame_context.stream->remaining();
919
46
            else
920
46
                tile_size = TRY_READ(frame_context.bit_stream.read_bits(32));
921
922
2.19k
            auto rows_start = get_tile_offset(tile_row, frame_context.rows(), log2_dimensions.height());
923
2.19k
            auto rows_end = get_tile_offset(tile_row + 1, frame_context.rows(), log2_dimensions.height());
924
2.19k
            auto columns_start = get_tile_offset(tile_col, frame_context.columns(), log2_dimensions.width());
925
2.19k
            auto columns_end = get_tile_offset(tile_col + 1, frame_context.columns(), log2_dimensions.width());
926
927
2.19k
            auto width = columns_end - columns_start;
928
2.19k
            auto above_partition_context_for_tile = above_partition_context.span().slice(columns_start, superblocks_to_blocks(blocks_ceiled_to_superblocks(width)));
929
2.19k
            auto above_non_zero_tokens_view = create_non_zero_tokens_view(above_non_zero_tokens, blocks_to_sub_blocks(columns_start), blocks_to_sub_blocks(columns_end - columns_start), frame_context.color_config.subsampling_x);
930
2.19k
            auto above_segmentation_ids_for_tile = safe_slice(above_segmentation_ids.span(), columns_start, columns_end - columns_start);
931
932
2.19k
            tile_workloads[tile_col].append(TRY(TileContext::try_create(frame_context, tile_size, rows_start, rows_end, columns_start, columns_end, above_partition_context_for_tile, above_non_zero_tokens_view, above_segmentation_ids_for_tile)));
933
2.16k
        }
934
2.15k
    }
935
936
2.16k
    auto decode_tile_column = [this, tile_rows](auto& column_workloads) -> DecoderErrorOr<void> {
937
2.16k
        VERIFY(column_workloads.size() == tile_rows);
938
4.06k
        for (auto tile_row = 0u; tile_row < tile_rows; tile_row++)
939
2.16k
            TRY(decode_tile(column_workloads[tile_row]));
940
1.90k
        return {};
941
2.16k
    };
942
943
2.11k
#ifdef VP9_TILE_THREADING
944
2.11k
    auto const worker_count = tile_cols - 1;
945
946
2.11k
    if (m_worker_threads.size() < worker_count) {
947
45
        m_worker_threads.clear();
948
45
        m_worker_threads.ensure_capacity(worker_count);
949
90
        for (auto i = 0u; i < worker_count; i++)
950
45
            m_worker_threads.append(DECODER_TRY_ALLOC(Threading::WorkerThread<DecoderError>::create("Decoder Worker"sv)));
951
45
    }
952
2.11k
    VERIFY(m_worker_threads.size() >= worker_count);
953
954
    // Start tile column decoding tasks in thread workers starting from the second column.
955
2.16k
    for (auto tile_col = 1u; tile_col < tile_cols; tile_col++) {
956
45
        auto& column_workload = tile_workloads[tile_col];
957
45
        m_worker_threads[tile_col - 1]->start_task([&decode_tile_column, &column_workload]() -> DecoderErrorOr<void> {
958
45
            return decode_tile_column(column_workload);
959
45
        });
960
45
    }
961
962
    // Decode the first column in this thread.
963
2.11k
    auto result = decode_tile_column(tile_workloads[0]);
964
965
2.11k
    for (auto& worker_thread : m_worker_threads) {
966
45
        auto task_result = worker_thread->wait_until_task_is_finished();
967
45
        if (!result.is_error() && task_result.is_error())
968
8
            result = move(task_result);
969
45
    }
970
971
2.11k
    if (result.is_error())
972
230
        return result;
973
#else
974
    for (auto& column_workloads : tile_workloads)
975
        TRY(decode_tile_column(column_workloads));
976
#endif
977
978
    // Sum up all tile contexts' syntax element counters after all decodes have finished.
979
1.89k
    for (auto& tile_contexts : tile_workloads) {
980
1.89k
        for (auto& tile_context : tile_contexts) {
981
1.89k
            *frame_context.counter += *tile_context.counter;
982
1.89k
        }
983
1.89k
    }
984
985
1.88k
    return {};
986
2.11k
}
987
988
DecoderErrorOr<void> Parser::decode_tile(TileContext& tile_context)
989
2.16k
{
990
75.5k
    for (auto row = tile_context.rows_start; row < tile_context.rows_end; row += 8) {
991
73.3k
        clear_left_context(tile_context);
992
321k
        for (auto col = tile_context.columns_start; col < tile_context.columns_end; col += 8) {
993
247k
            TRY(decode_partition(tile_context, row, col, Block_64x64));
994
247k
        }
995
73.3k
    }
996
2.14k
    TRY_READ(tile_context.decoder.finish_decode());
997
0
    return {};
998
2.14k
}
999
1000
void Parser::clear_left_context(TileContext& tile_context)
1001
73.3k
{
1002
73.3k
    for (auto& context_for_plane : tile_context.left_non_zero_tokens)
1003
220k
        context_for_plane.fill_with(false);
1004
73.3k
    tile_context.left_segmentation_ids.fill_with(0);
1005
73.3k
    tile_context.left_partition_context.fill_with(0);
1006
73.3k
}
1007
1008
DecoderErrorOr<void> Parser::decode_partition(TileContext& tile_context, u32 row, u32 column, BlockSubsize subsize)
1009
897k
{
1010
897k
    if (row >= tile_context.frame_context.rows() || column >= tile_context.frame_context.columns())
1011
127k
        return {};
1012
770k
    u8 num_8x8 = num_8x8_blocks_wide_lookup[subsize];
1013
770k
    auto half_block_8x8 = num_8x8 >> 1;
1014
770k
    bool has_rows = (row + half_block_8x8) < tile_context.frame_context.rows();
1015
770k
    bool has_cols = (column + half_block_8x8) < tile_context.frame_context.columns();
1016
770k
    u32 row_in_tile = row - tile_context.rows_start;
1017
770k
    u32 column_in_tile = column - tile_context.columns_start;
1018
770k
    auto partition = TreeParser::parse_partition(tile_context.decoder, *m_probability_tables, *tile_context.counter, has_rows, has_cols, subsize, num_8x8, tile_context.above_partition_context, tile_context.left_partition_context.span(), row_in_tile, column_in_tile, !tile_context.frame_context.is_inter_predicted());
1019
1020
770k
    auto child_subsize = subsize_lookup[partition][subsize];
1021
770k
    if (child_subsize < Block_8x8 || partition == PartitionNone) {
1022
526k
        TRY(decode_block(tile_context, row, column, child_subsize));
1023
526k
    } else if (partition == PartitionHorizontal) {
1024
21.5k
        TRY(decode_block(tile_context, row, column, child_subsize));
1025
21.5k
        if (has_rows)
1026
11.5k
            TRY(decode_block(tile_context, row + half_block_8x8, column, child_subsize));
1027
222k
    } else if (partition == PartitionVertical) {
1028
60.3k
        TRY(decode_block(tile_context, row, column, child_subsize));
1029
60.3k
        if (has_cols)
1030
10.1k
            TRY(decode_block(tile_context, row, column + half_block_8x8, child_subsize));
1031
162k
    } else {
1032
162k
        TRY(decode_partition(tile_context, row, column, child_subsize));
1033
162k
        TRY(decode_partition(tile_context, row, column + half_block_8x8, child_subsize));
1034
162k
        TRY(decode_partition(tile_context, row + half_block_8x8, column, child_subsize));
1035
162k
        TRY(decode_partition(tile_context, row + half_block_8x8, column + half_block_8x8, child_subsize));
1036
162k
    }
1037
770k
    if (subsize == Block_8x8 || partition != PartitionSplit) {
1038
608k
        auto above_context = 15 >> b_width_log2_lookup[child_subsize];
1039
608k
        auto left_context = 15 >> b_height_log2_lookup[child_subsize];
1040
2.91M
        for (size_t i = 0; i < num_8x8; i++) {
1041
2.30M
            tile_context.above_partition_context[column_in_tile + i] = above_context;
1042
2.30M
            tile_context.left_partition_context[row_in_tile + i] = left_context;
1043
2.30M
        }
1044
608k
    }
1045
770k
    return {};
1046
770k
}
1047
1048
size_t Parser::get_image_index(FrameContext const& frame_context, u32 row, u32 column) const
1049
0
{
1050
0
    VERIFY(row < frame_context.rows() && column < frame_context.columns());
1051
0
    return row * frame_context.columns() + column;
1052
0
}
1053
1054
DecoderErrorOr<void> Parser::decode_block(TileContext& tile_context, u32 row, u32 column, BlockSubsize subsize)
1055
630k
{
1056
630k
    auto above_context = row > 0 ? tile_context.frame_block_contexts().at(row - 1, column) : FrameBlockContext();
1057
630k
    auto left_context = column > tile_context.columns_start ? tile_context.frame_block_contexts().at(row, column - 1) : FrameBlockContext();
1058
630k
    auto block_context = BlockContext::create(tile_context, row, column, subsize);
1059
1060
630k
    mode_info(block_context, above_context, left_context);
1061
630k
    auto had_residual_tokens = TRY(residual(block_context, above_context.is_available, left_context.is_available));
1062
629k
    if (block_context.is_inter_predicted() && subsize >= Block_8x8 && !had_residual_tokens)
1063
18.3k
        block_context.should_skip_residuals = true;
1064
1065
2.92M
    for (size_t y = 0; y < block_context.contexts_view.height(); y++) {
1066
14.7M
        for (size_t x = 0; x < block_context.contexts_view.width(); x++) {
1067
12.4M
            auto sub_block_context = FrameBlockContext { true, block_context.should_skip_residuals, block_context.transform_size, block_context.y_prediction_mode(), block_context.sub_block_prediction_modes, block_context.interpolation_filter, block_context.reference_frame_types, block_context.sub_block_motion_vectors, block_context.segment_id };
1068
12.4M
            block_context.contexts_view.at(y, x) = sub_block_context;
1069
12.4M
            VERIFY(block_context.frame_block_contexts().at(row + y, column + x).transform_size == sub_block_context.transform_size);
1070
12.4M
        }
1071
2.29M
    }
1072
629k
    return {};
1073
629k
}
1074
1075
void Parser::mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
1076
630k
{
1077
630k
    if (block_context.frame_context.is_inter_predicted())
1078
38.1k
        inter_frame_mode_info(block_context, above_context, left_context);
1079
591k
    else
1080
591k
        intra_frame_mode_info(block_context, above_context, left_context);
1081
630k
}
1082
1083
void Parser::intra_frame_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
1084
591k
{
1085
591k
    block_context.reference_frame_types = { ReferenceFrameType::None, ReferenceFrameType::None };
1086
591k
    VERIFY(!block_context.is_inter_predicted());
1087
591k
    set_intra_segment_id(block_context);
1088
591k
    block_context.should_skip_residuals = read_should_skip_residuals(block_context, above_context, left_context);
1089
591k
    block_context.transform_size = read_tx_size(block_context, above_context, left_context, true);
1090
    // FIXME: This if statement is also present in parse_default_intra_mode. The selection of parameters for
1091
    //        the probability table lookup should be inlined here.
1092
591k
    if (block_context.size >= Block_8x8) {
1093
421k
        auto mode = TreeParser::parse_default_intra_mode(block_context.decoder, *m_probability_tables, block_context.size, above_context, left_context, block_context.sub_block_prediction_modes, 0, 0);
1094
421k
        for (auto& block_sub_mode : block_context.sub_block_prediction_modes)
1095
1.68M
            block_sub_mode = mode;
1096
421k
    } else {
1097
169k
        auto size_in_sub_blocks = block_context.get_size_in_sub_blocks();
1098
484k
        for (auto idy = 0; idy < 2; idy += size_in_sub_blocks.height()) {
1099
871k
            for (auto idx = 0; idx < 2; idx += size_in_sub_blocks.width()) {
1100
556k
                auto sub_mode = TreeParser::parse_default_intra_mode(block_context.decoder, *m_probability_tables, block_context.size, above_context, left_context, block_context.sub_block_prediction_modes, idx, idy);
1101
1102
1.16M
                for (auto y = 0; y < size_in_sub_blocks.height(); y++) {
1103
1.28M
                    for (auto x = 0; x < size_in_sub_blocks.width(); x++) {
1104
679k
                        auto index = (idy + y) * 2 + idx + x;
1105
679k
                        block_context.sub_block_prediction_modes[index] = sub_mode;
1106
679k
                    }
1107
606k
                }
1108
556k
            }
1109
314k
        }
1110
169k
    }
1111
591k
    block_context.uv_prediction_mode = TreeParser::parse_default_uv_mode(block_context.decoder, *m_probability_tables, block_context.y_prediction_mode());
1112
591k
}
1113
1114
void Parser::set_intra_segment_id(BlockContext& block_context)
1115
591k
{
1116
591k
    if (block_context.frame_context.segmentation_enabled && block_context.frame_context.use_full_segment_id_tree)
1117
161k
        block_context.segment_id = TreeParser::parse_segment_id(block_context.decoder, block_context.frame_context.full_segment_id_tree_probabilities);
1118
430k
    else
1119
430k
        block_context.segment_id = 0;
1120
591k
}
1121
1122
bool Parser::read_should_skip_residuals(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
1123
630k
{
1124
630k
    if (block_context.get_segment_feature(SegmentFeature::SkipResidualsOverride).enabled)
1125
195k
        return true;
1126
434k
    return TreeParser::parse_skip(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context);
1127
630k
}
1128
1129
TransformSize Parser::read_tx_size(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select)
1130
630k
{
1131
630k
    auto max_tx_size = max_txsize_lookup[block_context.size];
1132
630k
    if (allow_select && block_context.frame_context.transform_mode == TransformMode::Select && block_context.size >= Block_8x8)
1133
23.4k
        return (TreeParser::parse_tx_size(block_context.decoder, *m_probability_tables, block_context.counter, max_tx_size, above_context, left_context));
1134
606k
    return min(max_tx_size, tx_mode_to_biggest_tx_size[to_underlying(block_context.frame_context.transform_mode)]);
1135
630k
}
1136
1137
void Parser::inter_frame_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
1138
38.1k
{
1139
38.1k
    set_inter_segment_id(block_context);
1140
38.1k
    block_context.should_skip_residuals = read_should_skip_residuals(block_context, above_context, left_context);
1141
38.1k
    auto is_inter = read_is_inter(block_context, above_context, left_context);
1142
38.1k
    block_context.transform_size = read_tx_size(block_context, above_context, left_context, !block_context.should_skip_residuals || !is_inter);
1143
38.1k
    if (is_inter) {
1144
28.8k
        inter_block_mode_info(block_context, above_context, left_context);
1145
28.8k
    } else {
1146
9.35k
        intra_block_mode_info(block_context);
1147
9.35k
    }
1148
38.1k
}
1149
1150
void Parser::set_inter_segment_id(BlockContext& block_context)
1151
38.1k
{
1152
38.1k
    if (!block_context.frame_context.segmentation_enabled) {
1153
37.3k
        block_context.segment_id = 0;
1154
37.3k
        return;
1155
37.3k
    }
1156
779
    auto predicted_segment_id = get_segment_id(block_context);
1157
779
    if (!block_context.frame_context.use_full_segment_id_tree) {
1158
23
        block_context.segment_id = predicted_segment_id;
1159
23
        return;
1160
23
    }
1161
756
    if (!block_context.frame_context.use_predicted_segment_id_tree) {
1162
756
        block_context.segment_id = TreeParser::parse_segment_id(block_context.decoder, block_context.frame_context.full_segment_id_tree_probabilities);
1163
756
        return;
1164
756
    }
1165
1166
0
    auto above_segmentation_id = block_context.tile_context.above_segmentation_ids[block_context.row - block_context.tile_context.rows_start];
1167
0
    auto left_segmentation_id = block_context.tile_context.left_segmentation_ids[block_context.column - block_context.tile_context.columns_start];
1168
0
    auto seg_id_predicted = TreeParser::parse_segment_id_predicted(block_context.decoder, block_context.frame_context.predicted_segment_id_tree_probabilities, above_segmentation_id, left_segmentation_id);
1169
0
    if (seg_id_predicted)
1170
0
        block_context.segment_id = predicted_segment_id;
1171
0
    else
1172
0
        block_context.segment_id = TreeParser::parse_segment_id(block_context.decoder, block_context.frame_context.full_segment_id_tree_probabilities);
1173
1174
    // (7.4.1) AboveSegPredContext[ i ] only needs to be set to 0 for i = 0..MiCols-1.
1175
    // This is taken care of by the slicing in BlockContext.
1176
0
    block_context.above_segmentation_ids.fill(seg_id_predicted);
1177
    // (7.4.1) LeftSegPredContext[ i ] only needs to be set to 0 for i = 0..MiRows-1.
1178
    // This is taken care of by the slicing in BlockContext.
1179
0
    block_context.left_segmentation_ids.fill(seg_id_predicted);
1180
0
}
1181
1182
u8 Parser::get_segment_id(BlockContext const& block_context)
1183
779
{
1184
779
    auto bw = num_8x8_blocks_wide_lookup[block_context.size];
1185
779
    auto bh = num_8x8_blocks_high_lookup[block_context.size];
1186
779
    auto xmis = min(block_context.frame_context.columns() - block_context.column, (u32)bw);
1187
779
    auto ymis = min(block_context.frame_context.rows() - block_context.row, (u32)bh);
1188
779
    u8 segment = 7;
1189
2.56k
    for (size_t y = 0; y < ymis; y++) {
1190
9.32k
        for (size_t x = 0; x < xmis; x++) {
1191
7.54k
            segment = min(segment, m_previous_block_contexts.index_at(block_context.row + y, block_context.column + x));
1192
7.54k
        }
1193
1.78k
    }
1194
779
    return segment;
1195
779
}
1196
1197
bool Parser::read_is_inter(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
1198
38.1k
{
1199
38.1k
    auto reference_frame_override_feature = block_context.get_segment_feature(SegmentFeature::ReferenceFrameOverride);
1200
38.1k
    if (reference_frame_override_feature.enabled)
1201
411
        return reference_frame_override_feature.value != ReferenceFrameType::None;
1202
37.7k
    return TreeParser::parse_block_is_inter_predicted(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context);
1203
38.1k
}
1204
1205
void Parser::intra_block_mode_info(BlockContext& block_context)
1206
9.35k
{
1207
9.35k
    block_context.reference_frame_types = { ReferenceFrameType::None, ReferenceFrameType::None };
1208
9.35k
    VERIFY(!block_context.is_inter_predicted());
1209
9.35k
    auto& sub_modes = block_context.sub_block_prediction_modes;
1210
9.35k
    if (block_context.size >= Block_8x8) {
1211
8.48k
        auto mode = TreeParser::parse_intra_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.size);
1212
8.48k
        for (auto& block_sub_mode : sub_modes)
1213
33.9k
            block_sub_mode = mode;
1214
8.48k
    } else {
1215
870
        auto size_in_sub_blocks = block_context.get_size_in_sub_blocks();
1216
2.29k
        for (auto idy = 0; idy < 2; idy += size_in_sub_blocks.height()) {
1217
3.59k
            for (auto idx = 0; idx < 2; idx += size_in_sub_blocks.width()) {
1218
2.17k
                auto sub_intra_mode = TreeParser::parse_sub_intra_mode(block_context.decoder, *m_probability_tables, block_context.counter);
1219
4.97k
                for (auto y = 0; y < size_in_sub_blocks.height(); y++) {
1220
6.28k
                    for (auto x = 0; x < size_in_sub_blocks.width(); x++)
1221
3.48k
                        sub_modes[(idy + y) * 2 + idx + x] = sub_intra_mode;
1222
2.80k
                }
1223
2.17k
            }
1224
1.42k
        }
1225
870
    }
1226
9.35k
    block_context.uv_prediction_mode = TreeParser::parse_uv_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.y_prediction_mode());
1227
9.35k
}
1228
1229
static void select_best_reference_motion_vectors(BlockContext& block_context, MotionVectorPair reference_motion_vectors, BlockMotionVectorCandidates& candidates, ReferenceIndex);
1230
1231
void Parser::inter_block_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
1232
28.8k
{
1233
28.8k
    read_ref_frames(block_context, above_context, left_context);
1234
28.8k
    VERIFY(block_context.is_inter_predicted());
1235
1236
28.8k
    BlockMotionVectorCandidates motion_vector_candidates;
1237
28.8k
    auto reference_motion_vectors = find_reference_motion_vectors(block_context, block_context.reference_frame_types.primary, -1);
1238
28.8k
    select_best_reference_motion_vectors(block_context, reference_motion_vectors, motion_vector_candidates, ReferenceIndex::Primary);
1239
28.8k
    if (block_context.is_compound()) {
1240
11.8k
        auto reference_motion_vectors = find_reference_motion_vectors(block_context, block_context.reference_frame_types.secondary, -1);
1241
11.8k
        select_best_reference_motion_vectors(block_context, reference_motion_vectors, motion_vector_candidates, ReferenceIndex::Secondary);
1242
11.8k
    }
1243
1244
28.8k
    if (block_context.get_segment_feature(SegmentFeature::SkipResidualsOverride).enabled) {
1245
0
        block_context.y_prediction_mode() = PredictionMode::ZeroMv;
1246
28.8k
    } else if (block_context.size >= Block_8x8) {
1247
22.6k
        block_context.y_prediction_mode() = TreeParser::parse_inter_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.mode_context[block_context.reference_frame_types.primary]);
1248
22.6k
    }
1249
28.8k
    if (block_context.frame_context.interpolation_filter == Switchable)
1250
18.3k
        block_context.interpolation_filter = TreeParser::parse_interpolation_filter(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context);
1251
10.4k
    else
1252
10.4k
        block_context.interpolation_filter = block_context.frame_context.interpolation_filter;
1253
28.8k
    if (block_context.size < Block_8x8) {
1254
6.20k
        auto size_in_sub_blocks = block_context.get_size_in_sub_blocks();
1255
16.8k
        for (auto idy = 0; idy < 2; idy += size_in_sub_blocks.height()) {
1256
26.5k
            for (auto idx = 0; idx < 2; idx += size_in_sub_blocks.width()) {
1257
15.9k
                block_context.y_prediction_mode() = TreeParser::parse_inter_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.mode_context[block_context.reference_frame_types.primary]);
1258
15.9k
                if (block_context.y_prediction_mode() == PredictionMode::NearestMv || block_context.y_prediction_mode() == PredictionMode::NearMv) {
1259
8.76k
                    select_best_sub_block_reference_motion_vectors(block_context, motion_vector_candidates, idy * 2 + idx, ReferenceIndex::Primary);
1260
8.76k
                    if (block_context.is_compound())
1261
4.51k
                        select_best_sub_block_reference_motion_vectors(block_context, motion_vector_candidates, idy * 2 + idx, ReferenceIndex::Secondary);
1262
8.76k
                }
1263
15.9k
                auto new_motion_vector_pair = get_motion_vector(block_context, motion_vector_candidates);
1264
35.4k
                for (auto y = 0; y < size_in_sub_blocks.height(); y++) {
1265
44.3k
                    for (auto x = 0; x < size_in_sub_blocks.width(); x++) {
1266
24.8k
                        auto sub_block_index = (idy + y) * 2 + idx + x;
1267
24.8k
                        block_context.sub_block_motion_vectors[sub_block_index] = new_motion_vector_pair;
1268
24.8k
                    }
1269
19.5k
                }
1270
15.9k
            }
1271
10.6k
        }
1272
6.20k
        return;
1273
6.20k
    }
1274
22.6k
    auto new_motion_vector_pair = get_motion_vector(block_context, motion_vector_candidates);
1275
113k
    for (auto block = 0; block < 4; block++)
1276
90.4k
        block_context.sub_block_motion_vectors[block] = new_motion_vector_pair;
1277
22.6k
}
1278
1279
void Parser::read_ref_frames(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
1280
28.8k
{
1281
28.8k
    auto reference_frame_override_feature = block_context.get_segment_feature(SegmentFeature::ReferenceFrameOverride);
1282
28.8k
    if (reference_frame_override_feature.enabled) {
1283
45
        block_context.reference_frame_types = { static_cast<ReferenceFrameType>(reference_frame_override_feature.value), ReferenceFrameType::None };
1284
45
        return;
1285
45
    }
1286
1287
28.7k
    ReferenceMode compound_mode = block_context.frame_context.reference_mode;
1288
28.7k
    auto fixed_reference = block_context.frame_context.fixed_reference_type;
1289
28.7k
    if (compound_mode == ReferenceModeSelect)
1290
13.3k
        compound_mode = TreeParser::parse_comp_mode(block_context.decoder, *m_probability_tables, block_context.counter, fixed_reference, above_context, left_context);
1291
28.7k
    if (compound_mode == CompoundReference) {
1292
11.8k
        auto variable_references = block_context.frame_context.variable_reference_types;
1293
1294
11.8k
        auto fixed_reference_index = ReferenceIndex::Primary;
1295
11.8k
        auto variable_reference_index = ReferenceIndex::Secondary;
1296
11.8k
        if (block_context.frame_context.reference_frame_sign_biases[fixed_reference])
1297
6.69k
            swap(fixed_reference_index, variable_reference_index);
1298
1299
11.8k
        auto variable_reference_selection = TreeParser::parse_comp_ref(block_context.decoder, *m_probability_tables, block_context.counter, fixed_reference, variable_references, variable_reference_index, above_context, left_context);
1300
1301
11.8k
        block_context.reference_frame_types[fixed_reference_index] = fixed_reference;
1302
11.8k
        block_context.reference_frame_types[variable_reference_index] = variable_references[variable_reference_selection];
1303
11.8k
        return;
1304
11.8k
    }
1305
1306
    // FIXME: Maybe consolidate this into a tree. Context is different between part 1 and 2 but still, it would look nice here.
1307
16.9k
    ReferenceFrameType primary_type = ReferenceFrameType::LastFrame;
1308
16.9k
    auto single_ref_p1 = TreeParser::parse_single_ref_part_1(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context);
1309
16.9k
    if (single_ref_p1) {
1310
6.36k
        auto single_ref_p2 = TreeParser::parse_single_ref_part_2(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context);
1311
6.36k
        primary_type = single_ref_p2 ? ReferenceFrameType::AltRefFrame : ReferenceFrameType::GoldenFrame;
1312
6.36k
    }
1313
16.9k
    block_context.reference_frame_types = { primary_type, ReferenceFrameType::None };
1314
16.9k
}
1315
1316
// assign_mv( isCompound ) in the spec.
1317
MotionVectorPair Parser::get_motion_vector(BlockContext const& block_context, BlockMotionVectorCandidates const& candidates)
1318
38.5k
{
1319
38.5k
    MotionVectorPair result;
1320
55.2k
    auto read_one = [&](ReferenceIndex index) -> void {
1321
55.2k
        switch (block_context.y_prediction_mode()) {
1322
19.8k
        case PredictionMode::NewMv:
1323
19.8k
            result[index] = read_motion_vector(block_context, candidates, index);
1324
19.8k
            break;
1325
23.1k
        case PredictionMode::NearestMv:
1326
23.1k
            result[index] = candidates[index].nearest_vector;
1327
23.1k
            break;
1328
7.76k
        case PredictionMode::NearMv:
1329
7.76k
            result[index] = candidates[index].near_vector;
1330
7.76k
            break;
1331
4.46k
        default:
1332
4.46k
            result[index] = {};
1333
4.46k
            break;
1334
55.2k
        }
1335
55.2k
        return;
1336
55.2k
    };
1337
38.5k
    read_one(ReferenceIndex::Primary);
1338
38.5k
    if (block_context.is_compound())
1339
16.7k
        read_one(ReferenceIndex::Secondary);
1340
38.5k
    return result;
1341
38.5k
}
1342
1343
// use_mv_hp( deltaMv ) in the spec.
1344
static bool should_use_high_precision_motion_vector(MotionVector const& delta_vector)
1345
46.2k
{
1346
46.2k
    return (abs(delta_vector.row()) >> 3) < COMPANDED_MVREF_THRESH && (abs(delta_vector.column()) >> 3) < COMPANDED_MVREF_THRESH;
1347
46.2k
}
1348
1349
// read_mv( ref ) in the spec.
1350
MotionVector Parser::read_motion_vector(BlockContext const& block_context, BlockMotionVectorCandidates const& candidates, ReferenceIndex reference_index)
1351
19.8k
{
1352
19.8k
    auto use_high_precision = block_context.frame_context.high_precision_motion_vectors_allowed && should_use_high_precision_motion_vector(candidates[reference_index].best_vector);
1353
19.8k
    MotionVector delta_vector;
1354
19.8k
    auto joint = TreeParser::parse_motion_vector_joint(block_context.decoder, *m_probability_tables, block_context.counter);
1355
19.8k
    if ((joint & MotionVectorNonZeroRow) != 0)
1356
8.96k
        delta_vector.set_row(read_single_motion_vector_component(block_context.decoder, block_context.counter, 0, use_high_precision));
1357
19.8k
    if ((joint & MotionVectorNonZeroColumn) != 0)
1358
11.3k
        delta_vector.set_column(read_single_motion_vector_component(block_context.decoder, block_context.counter, 1, use_high_precision));
1359
1360
19.8k
    return candidates[reference_index].best_vector + delta_vector;
1361
19.8k
}
1362
1363
// read_mv_component( comp ) in the spec.
1364
i32 Parser::read_single_motion_vector_component(BooleanDecoder& decoder, SyntaxElementCounter& counter, u8 component, bool use_high_precision)
1365
20.2k
{
1366
20.2k
    auto mv_sign = TreeParser::parse_motion_vector_sign(decoder, *m_probability_tables, counter, component);
1367
20.2k
    auto mv_class = TreeParser::parse_motion_vector_class(decoder, *m_probability_tables, counter, component);
1368
20.2k
    u32 magnitude;
1369
20.2k
    if (mv_class == MvClass0) {
1370
16.6k
        auto mv_class0_bit = TreeParser::parse_motion_vector_class0_bit(decoder, *m_probability_tables, counter, component);
1371
16.6k
        auto mv_class0_fr = TreeParser::parse_motion_vector_class0_fr(decoder, *m_probability_tables, counter, component, mv_class0_bit);
1372
16.6k
        auto mv_class0_hp = TreeParser::parse_motion_vector_class0_hp(decoder, *m_probability_tables, counter, component, use_high_precision);
1373
16.6k
        magnitude = ((mv_class0_bit << 3) | (mv_class0_fr << 1) | mv_class0_hp) + 1;
1374
16.6k
    } else {
1375
3.64k
        u32 bits = 0;
1376
16.2k
        for (u8 i = 0; i < mv_class; i++) {
1377
12.6k
            auto mv_bit = TreeParser::parse_motion_vector_bit(decoder, *m_probability_tables, counter, component, i);
1378
12.6k
            bits |= mv_bit << i;
1379
12.6k
        }
1380
3.64k
        magnitude = CLASS0_SIZE << (mv_class + 2);
1381
3.64k
        auto mv_fr = TreeParser::parse_motion_vector_fr(decoder, *m_probability_tables, counter, component);
1382
3.64k
        auto mv_hp = TreeParser::parse_motion_vector_hp(decoder, *m_probability_tables, counter, component, use_high_precision);
1383
3.64k
        magnitude += ((bits << 3) | (mv_fr << 1) | mv_hp) + 1;
1384
3.64k
    }
1385
20.2k
    return (mv_sign ? -1 : 1) * static_cast<i32>(magnitude);
1386
20.2k
}
1387
1388
static TransformSize get_uv_transform_size(TransformSize transform_size, BlockSubsize size_for_plane)
1389
1.88M
{
1390
1.88M
    return min(transform_size, max_txsize_lookup[size_for_plane]);
1391
1.88M
}
1392
1393
static TransformSet select_transform_type(BlockContext const& block_context, u8 plane, TransformSize transform_size, u32 block_index)
1394
12.8M
{
1395
12.8M
    if (plane > 0 || transform_size == Transform_32x32)
1396
6.91M
        return TransformSet { TransformType::DCT, TransformType::DCT };
1397
5.88M
    if (transform_size == Transform_4x4) {
1398
5.18M
        if (block_context.frame_context.lossless || block_context.is_inter_predicted())
1399
861k
            return TransformSet { TransformType::DCT, TransformType::DCT };
1400
1401
4.32M
        return mode_to_txfm_map[to_underlying(block_context.size < Block_8x8 ? block_context.sub_block_prediction_modes[block_index] : block_context.y_prediction_mode())];
1402
5.18M
    }
1403
1404
704k
    return mode_to_txfm_map[to_underlying(block_context.y_prediction_mode())];
1405
5.88M
}
1406
1407
DecoderErrorOr<bool> Parser::residual(BlockContext& block_context, bool has_block_above, bool has_block_left)
1408
630k
{
1409
630k
    bool block_had_non_zero_tokens = false;
1410
630k
    Array<u8, 1024> token_cache;
1411
2.52M
    for (u8 plane = 0; plane < 3; plane++) {
1412
1.89M
        auto plane_subsampling_x = (plane > 0) ? block_context.frame_context.color_config.subsampling_x : false;
1413
1.89M
        auto plane_subsampling_y = (plane > 0) ? block_context.frame_context.color_config.subsampling_y : false;
1414
1.89M
        auto plane_size = get_subsampled_block_size(block_context.size, plane_subsampling_x, plane_subsampling_y);
1415
1.89M
        if (plane_size == Block_Invalid) {
1416
20
            return DecoderError::corrupted("Invalid block size"sv);
1417
20
        }
1418
1.88M
        auto transform_size = get_uv_transform_size(block_context.transform_size, plane_size);
1419
1.88M
        auto transform_size_in_sub_blocks = transform_size_to_sub_blocks(transform_size);
1420
1.88M
        auto block_size_in_sub_blocks = block_size_to_sub_blocks(plane_size);
1421
1422
1.88M
        auto base_x_in_pixels = (blocks_to_pixels(block_context.column)) >> plane_subsampling_x;
1423
1.88M
        auto base_y_in_pixels = (blocks_to_pixels(block_context.row)) >> plane_subsampling_y;
1424
1.88M
        if (block_context.is_inter_predicted()) {
1425
86.4k
            if (block_context.size < Block_8x8) {
1426
43.4k
                for (auto y = 0; y < block_size_in_sub_blocks.height(); y++) {
1427
62.0k
                    for (auto x = 0; x < block_size_in_sub_blocks.width(); x++) {
1428
37.2k
                        TRY(m_decoder.predict_inter(plane, block_context, base_x_in_pixels + sub_blocks_to_pixels(x), base_y_in_pixels + sub_blocks_to_pixels(y), sub_blocks_to_pixels(1), sub_blocks_to_pixels(1), (y * block_size_in_sub_blocks.width()) + x));
1429
37.2k
                    }
1430
24.8k
                }
1431
67.8k
            } else {
1432
67.8k
                TRY(m_decoder.predict_inter(plane, block_context, base_x_in_pixels, base_y_in_pixels, sub_blocks_to_pixels(block_size_in_sub_blocks.width()), sub_blocks_to_pixels(block_size_in_sub_blocks.height()), 0));
1433
67.8k
            }
1434
86.4k
        }
1435
1436
1.88M
        auto frame_right_in_pixels = (blocks_to_pixels(block_context.frame_context.columns())) >> plane_subsampling_x;
1437
1.88M
        auto frame_bottom_in_pixels = (blocks_to_pixels(block_context.frame_context.rows())) >> plane_subsampling_y;
1438
1439
1.88M
        auto sub_block_index = 0;
1440
6.26M
        for (u32 y = 0; y < block_size_in_sub_blocks.height(); y += transform_size_in_sub_blocks) {
1441
27.4M
            for (u32 x = 0; x < block_size_in_sub_blocks.width(); x += transform_size_in_sub_blocks) {
1442
23.0M
                auto transform_x_in_px = base_x_in_pixels + sub_blocks_to_pixels(x);
1443
23.0M
                auto transform_y_in_px = base_y_in_pixels + sub_blocks_to_pixels(y);
1444
1445
23.0M
                auto sub_block_had_non_zero_tokens = false;
1446
23.0M
                if (transform_x_in_px < frame_right_in_pixels && transform_y_in_px < frame_bottom_in_pixels) {
1447
20.9M
                    if (!block_context.is_inter_predicted())
1448
20.3M
                        TRY(m_decoder.predict_intra(plane, block_context, transform_x_in_px, transform_y_in_px, has_block_left || x > 0, has_block_above || y > 0, (x + transform_size_in_sub_blocks) < block_size_in_sub_blocks.width(), transform_size, sub_block_index));
1449
20.9M
                    if (!block_context.should_skip_residuals) {
1450
12.8M
                        auto transform_set = select_transform_type(block_context, plane, transform_size, sub_block_index);
1451
12.8M
                        sub_block_had_non_zero_tokens = tokens(block_context, plane, x, y, transform_size, transform_set, token_cache);
1452
12.8M
                        block_had_non_zero_tokens = block_had_non_zero_tokens || sub_block_had_non_zero_tokens;
1453
12.8M
                        TRY(m_decoder.reconstruct(plane, block_context, transform_x_in_px, transform_y_in_px, transform_size, transform_set));
1454
12.8M
                    }
1455
20.9M
                }
1456
1457
23.0M
                auto& above_sub_block_tokens = block_context.above_non_zero_tokens[plane];
1458
23.0M
                auto transform_right_in_sub_blocks = min(x + transform_size_in_sub_blocks, above_sub_block_tokens.size());
1459
53.5M
                for (size_t inside_x = x; inside_x < transform_right_in_sub_blocks; inside_x++)
1460
30.4M
                    above_sub_block_tokens[inside_x] = sub_block_had_non_zero_tokens;
1461
1462
23.0M
                auto& left_sub_block_context = block_context.left_non_zero_tokens[plane];
1463
23.0M
                auto transform_bottom_in_sub_blocks = min(y + transform_size_in_sub_blocks, left_sub_block_context.size());
1464
55.9M
                for (size_t inside_y = y; inside_y < transform_bottom_in_sub_blocks; inside_y++)
1465
32.8M
                    left_sub_block_context[inside_y] = sub_block_had_non_zero_tokens;
1466
1467
23.0M
                sub_block_index++;
1468
23.0M
            }
1469
4.37M
        }
1470
1.88M
    }
1471
629k
    return block_had_non_zero_tokens;
1472
630k
}
1473
1474
static u16 const* get_scan(TransformSize transform_size, TransformSet transform_set)
1475
12.8M
{
1476
12.8M
    constexpr TransformSet adst_dct { TransformType::ADST, TransformType::DCT };
1477
12.8M
    constexpr TransformSet dct_adst { TransformType::DCT, TransformType::ADST };
1478
1479
12.8M
    if (transform_size == Transform_4x4) {
1480
10.9M
        if (transform_set == adst_dct)
1481
90.8k
            return row_scan_4x4;
1482
10.8M
        if (transform_set == dct_adst)
1483
167k
            return col_scan_4x4;
1484
10.6M
        return default_scan_4x4;
1485
10.8M
    }
1486
1.86M
    if (transform_size == Transform_8x8) {
1487
959k
        if (transform_set == adst_dct)
1488
25.1k
            return row_scan_8x8;
1489
934k
        if (transform_set == dct_adst)
1490
39.9k
            return col_scan_8x8;
1491
894k
        return default_scan_8x8;
1492
934k
    }
1493
903k
    if (transform_size == Transform_16x16) {
1494
284k
        if (transform_set == adst_dct)
1495
5.46k
            return row_scan_16x16;
1496
279k
        if (transform_set == dct_adst)
1497
9.86k
            return col_scan_16x16;
1498
269k
        return default_scan_16x16;
1499
279k
    }
1500
618k
    return default_scan_32x32;
1501
903k
}
1502
1503
bool Parser::tokens(BlockContext& block_context, size_t plane, u32 sub_block_column, u32 sub_block_row, TransformSize transform_size, TransformSet transform_set, Array<u8, 1024> token_cache)
1504
12.8M
{
1505
12.8M
    block_context.residual_tokens.fill(0);
1506
1507
12.8M
    auto const* scan = get_scan(transform_size, transform_set);
1508
1509
12.8M
    auto check_for_more_coefficients = true;
1510
12.8M
    u16 coef_index = 0;
1511
12.8M
    u16 transform_pixel_count = 16 << (transform_size << 1);
1512
25.6M
    for (; coef_index < transform_pixel_count; coef_index++) {
1513
25.5M
        auto band = (transform_size == Transform_4x4) ? coefband_4x4[coef_index] : coefband_8x8plus[coef_index];
1514
25.5M
        auto token_position = scan[coef_index];
1515
25.5M
        TokensContext tokens_context;
1516
25.5M
        if (coef_index == 0)
1517
12.8M
            tokens_context = TreeParser::get_context_for_first_token(block_context.above_non_zero_tokens, block_context.left_non_zero_tokens, transform_size, plane, sub_block_column, sub_block_row, block_context.is_inter_predicted(), band);
1518
12.7M
        else
1519
12.7M
            tokens_context = TreeParser::get_context_for_other_tokens(token_cache, transform_size, transform_set, plane, token_position, block_context.is_inter_predicted(), band);
1520
1521
25.5M
        if (check_for_more_coefficients && !TreeParser::parse_more_coefficients(block_context.decoder, *m_probability_tables, block_context.counter, tokens_context))
1522
12.7M
            break;
1523
1524
12.8M
        auto token = TreeParser::parse_token(block_context.decoder, *m_probability_tables, block_context.counter, tokens_context);
1525
12.8M
        token_cache[token_position] = energy_class[token];
1526
1527
12.8M
        i32 coef;
1528
12.8M
        if (token == ZeroToken) {
1529
6.17M
            coef = 0;
1530
6.17M
            check_for_more_coefficients = false;
1531
6.68M
        } else {
1532
6.68M
            coef = read_coef(block_context.decoder, block_context.frame_context.color_config.bit_depth, token);
1533
6.68M
            check_for_more_coefficients = true;
1534
6.68M
        }
1535
12.8M
        block_context.residual_tokens[token_position] = coef;
1536
12.8M
    }
1537
1538
12.8M
    return coef_index > 0;
1539
12.8M
}
1540
1541
i32 Parser::read_coef(BooleanDecoder& decoder, u8 bit_depth, Token token)
1542
6.68M
{
1543
6.68M
    auto cat = extra_bits[token][0];
1544
6.68M
    auto num_extra = extra_bits[token][1];
1545
6.68M
    i32 coef = extra_bits[token][2];
1546
6.68M
    if (token == DctValCat6) {
1547
249k
        for (size_t e = 0; e < (u8)(bit_depth - 8); e++) {
1548
87.5k
            auto high_bit = decoder.read_bool(255);
1549
87.5k
            coef += high_bit << (5 + bit_depth - e);
1550
87.5k
        }
1551
161k
    }
1552
9.91M
    for (size_t e = 0; e < num_extra; e++) {
1553
3.23M
        auto coef_bit = decoder.read_bool(cat_probs[cat][e]);
1554
3.23M
        coef += coef_bit << (num_extra - 1 - e);
1555
3.23M
    }
1556
6.68M
    bool sign_bit = decoder.read_literal(1);
1557
6.68M
    coef = sign_bit ? -coef : coef;
1558
6.68M
    return coef;
1559
6.68M
}
1560
1561
// is_inside( candidateR, candidateC ) in the spec.
1562
static bool motion_vector_is_inside_tile(TileContext const& tile_context, MotionVector vector)
1563
850k
{
1564
850k
    if (vector.row() < 0)
1565
359k
        return false;
1566
490k
    if (vector.column() < 0)
1567
189k
        return false;
1568
300k
    u32 row_positive = vector.row();
1569
300k
    u32 column_positive = vector.column();
1570
300k
    return row_positive < tile_context.frame_context.rows() && column_positive >= tile_context.columns_start && column_positive < tile_context.columns_end;
1571
490k
}
1572
1573
// add_mv_ref_list( refList ) in the spec.
1574
static void add_motion_vector_to_list_deduped(MotionVector const& vector, Vector<MotionVector, 2>& list)
1575
181k
{
1576
181k
    if (list.size() >= 2)
1577
49.4k
        return;
1578
131k
    if (list.size() == 1 && vector == list[0])
1579
55.1k
        return;
1580
1581
76.7k
    list.append(vector);
1582
76.7k
}
1583
1584
// get_block_mv( candidateR, candidateC, refList, usePrev ) in the spec.
1585
MotionVectorCandidate Parser::get_motion_vector_from_current_or_previous_frame(BlockContext const& block_context, MotionVector candidate_vector, ReferenceIndex reference_index, bool use_prev)
1586
500k
{
1587
500k
    if (use_prev) {
1588
78.4k
        auto const& prev_context = m_previous_block_contexts.at(candidate_vector.row(), candidate_vector.column());
1589
78.4k
        return { prev_context.ref_frames[reference_index], prev_context.primary_motion_vector_pair[reference_index] };
1590
78.4k
    }
1591
1592
421k
    auto const& current_context = block_context.frame_block_contexts().at(candidate_vector.row(), candidate_vector.column());
1593
421k
    return { current_context.ref_frames[reference_index], current_context.primary_motion_vector_pair()[reference_index] };
1594
500k
}
1595
1596
// if_same_ref_frame_add_mv( candidateR, candidateC, refFrame, usePrev ) in the spec.
1597
void Parser::add_motion_vector_if_reference_frame_type_is_same(BlockContext const& block_context, MotionVector candidate_vector, ReferenceFrameType ref_frame, Vector<MotionVector, 2>& list, bool use_prev)
1598
106k
{
1599
213k
    for (auto i = 0u; i < 2; i++) {
1600
166k
        auto candidate = get_motion_vector_from_current_or_previous_frame(block_context, candidate_vector, static_cast<ReferenceIndex>(i), use_prev);
1601
166k
        if (candidate.type == ref_frame) {
1602
59.9k
            add_motion_vector_to_list_deduped(candidate.vector, list);
1603
59.9k
            return;
1604
59.9k
        }
1605
166k
    }
1606
106k
}
1607
1608
// scale_mv( refList, refFrame ) in the spec.
1609
static void apply_sign_bias_to_motion_vector(FrameContext const& frame_context, MotionVectorCandidate& candidate, ReferenceFrameType ref_frame)
1610
75.5k
{
1611
75.5k
    if (frame_context.reference_frame_sign_biases[candidate.type] != frame_context.reference_frame_sign_biases[ref_frame])
1612
58.5k
        candidate.vector *= -1;
1613
75.5k
}
1614
1615
// if_diff_ref_frame_add_mv( candidateR, candidateC, refFrame, usePrev ) in the spec.
1616
void Parser::add_motion_vector_if_reference_frame_type_is_different(BlockContext const& block_context, MotionVector candidate_vector, ReferenceFrameType ref_frame, Vector<MotionVector, 2>& list, bool use_prev)
1617
166k
{
1618
166k
    auto first_candidate = get_motion_vector_from_current_or_previous_frame(block_context, candidate_vector, ReferenceIndex::Primary, use_prev);
1619
166k
    if (first_candidate.type > ReferenceFrameType::None && first_candidate.type != ref_frame) {
1620
54.4k
        apply_sign_bias_to_motion_vector(block_context.frame_context, first_candidate, ref_frame);
1621
54.4k
        add_motion_vector_to_list_deduped(first_candidate.vector, list);
1622
54.4k
    }
1623
1624
166k
    auto second_candidate = get_motion_vector_from_current_or_previous_frame(block_context, candidate_vector, ReferenceIndex::Secondary, use_prev);
1625
166k
    auto mvs_are_same = first_candidate.vector == second_candidate.vector;
1626
166k
    if (second_candidate.type > ReferenceFrameType::None && second_candidate.type != ref_frame && !mvs_are_same) {
1627
21.1k
        apply_sign_bias_to_motion_vector(block_context.frame_context, second_candidate, ref_frame);
1628
21.1k
        add_motion_vector_to_list_deduped(second_candidate.vector, list);
1629
21.1k
    }
1630
166k
}
1631
1632
// This function handles both clamp_mv_row( mvec, border ) and clamp_mv_col( mvec, border ) in the spec.
1633
static MotionVector clamp_motion_vector(BlockContext const& block_context, MotionVector vector, i32 border)
1634
266k
{
1635
266k
    i32 blocks_high = num_8x8_blocks_high_lookup[block_context.size];
1636
    // Casts must be done here to prevent subtraction underflow from wrapping the values.
1637
266k
    i32 mb_to_top_edge = -8 * (static_cast<i32>(block_context.row) * MI_SIZE);
1638
266k
    i32 mb_to_bottom_edge = 8 * ((static_cast<i32>(block_context.frame_context.rows()) - blocks_high - static_cast<i32>(block_context.row)) * MI_SIZE);
1639
1640
266k
    i32 blocks_wide = num_8x8_blocks_wide_lookup[block_context.size];
1641
266k
    i32 mb_to_left_edge = -8 * (static_cast<i32>(block_context.column) * MI_SIZE);
1642
266k
    i32 mb_to_right_edge = 8 * ((static_cast<i32>(block_context.frame_context.columns()) - blocks_wide - static_cast<i32>(block_context.column)) * MI_SIZE);
1643
1644
266k
    return {
1645
266k
        clip_3(mb_to_top_edge - border, mb_to_bottom_edge + border, vector.row()),
1646
266k
        clip_3(mb_to_left_edge - border, mb_to_right_edge + border, vector.column())
1647
266k
    };
1648
266k
}
1649
1650
// 6.5.1 Find MV refs syntax
1651
// find_mv_refs( refFrame, block ) in the spec.
1652
MotionVectorPair Parser::find_reference_motion_vectors(BlockContext& block_context, ReferenceFrameType reference_frame, i32 block)
1653
53.9k
{
1654
    // FIXME: We should be able to change behavior based on the reference motion vector that will be selected.
1655
    //        If block_context.y_prediction_mode() != NearMv, then we only need the first motion vector that is added to our result.
1656
    //        This behavior should combine this function with select_best_reference_motion_vectors(). When that is done, check whether
1657
    //        the motion vector clamping in that function is always a larger area than in this function. If so, we can drop that call.
1658
53.9k
    bool different_ref_found = false;
1659
53.9k
    u8 context_counter = 0;
1660
1661
53.9k
    Vector<MotionVector, 2> list;
1662
1663
53.9k
    MotionVector base_coordinates = MotionVector(block_context.row, block_context.column);
1664
1665
161k
    for (auto i = 0u; i < 2; i++) {
1666
107k
        auto offset_vector = mv_ref_blocks[block_context.size][i];
1667
107k
        auto candidate = base_coordinates + offset_vector;
1668
1669
107k
        if (motion_vector_is_inside_tile(block_context.tile_context, candidate)) {
1670
60.2k
            different_ref_found = true;
1671
60.2k
            auto context = block_context.frame_block_contexts().at(candidate.row(), candidate.column());
1672
60.2k
            context_counter += mode_2_counter[to_underlying(context.y_mode)];
1673
1674
102k
            for (auto i = 0u; i < 2; i++) {
1675
87.8k
                auto reference_index = static_cast<ReferenceIndex>(i);
1676
87.8k
                if (context.ref_frames[reference_index] == reference_frame) {
1677
                    // This section up until add_mv_ref_list() is defined in spec as get_sub_block_mv().
1678
45.8k
                    constexpr u8 idx_n_column_to_subblock[4][2] = {
1679
45.8k
                        { 1, 2 },
1680
45.8k
                        { 1, 3 },
1681
45.8k
                        { 3, 2 },
1682
45.8k
                        { 3, 3 }
1683
45.8k
                    };
1684
45.8k
                    auto index = block >= 0 ? idx_n_column_to_subblock[block][offset_vector.column() == 0] : 3;
1685
1686
45.8k
                    add_motion_vector_to_list_deduped(context.sub_block_motion_vectors[index][reference_index], list);
1687
45.8k
                    break;
1688
45.8k
                }
1689
87.8k
            }
1690
60.2k
        }
1691
107k
    }
1692
53.9k
    block_context.mode_context[reference_frame] = counter_to_context[context_counter];
1693
1694
377k
    for (auto i = 2u; i < MVREF_NEIGHBORS; i++) {
1695
323k
        MotionVector candidate = base_coordinates + mv_ref_blocks[block_context.size][i];
1696
323k
        if (motion_vector_is_inside_tile(block_context.tile_context, candidate)) {
1697
86.8k
            different_ref_found = true;
1698
86.8k
            add_motion_vector_if_reference_frame_type_is_same(block_context, candidate, reference_frame, list, false);
1699
86.8k
        }
1700
323k
    }
1701
53.9k
    if (block_context.frame_context.use_previous_frame_motion_vectors)
1702
19.6k
        add_motion_vector_if_reference_frame_type_is_same(block_context, base_coordinates, reference_frame, list, true);
1703
1704
53.9k
    if (different_ref_found) {
1705
470k
        for (auto i = 0u; i < MVREF_NEIGHBORS; i++) {
1706
418k
            MotionVector candidate = base_coordinates + mv_ref_blocks[block_context.size][i];
1707
418k
            if (motion_vector_is_inside_tile(block_context.tile_context, candidate))
1708
147k
                add_motion_vector_if_reference_frame_type_is_different(block_context, candidate, reference_frame, list, false);
1709
418k
        }
1710
52.3k
    }
1711
53.9k
    if (block_context.frame_context.use_previous_frame_motion_vectors)
1712
19.6k
        add_motion_vector_if_reference_frame_type_is_different(block_context, base_coordinates, reference_frame, list, true);
1713
1714
130k
    for (auto i = 0u; i < list.size(); i++) {
1715
        // clamp_mv_ref( i ) in the spec.
1716
76.7k
        list[i] = clamp_motion_vector(block_context, list[i], MV_BORDER);
1717
76.7k
    }
1718
1719
53.9k
    MotionVectorPair result;
1720
130k
    for (auto i = 0u; i < list.size(); i++)
1721
76.7k
        result[static_cast<ReferenceIndex>(i)] = list[i];
1722
53.9k
    result.primary = clamp_motion_vector(block_context, result.primary, MV_BORDER);
1723
53.9k
    result.secondary = clamp_motion_vector(block_context, result.secondary, MV_BORDER);
1724
53.9k
    return result;
1725
53.9k
}
1726
1727
// find_best_ref_mvs( refList ) in the spec.
1728
static void select_best_reference_motion_vectors(BlockContext& block_context, MotionVectorPair reference_motion_vectors, BlockMotionVectorCandidates& candidates, ReferenceIndex reference_index)
1729
40.6k
{
1730
81.3k
    auto adjust_and_clamp_vector = [&](MotionVector& vector) {
1731
81.3k
        auto delta_row = vector.row();
1732
81.3k
        auto delta_column = vector.column();
1733
81.3k
        if (!block_context.frame_context.high_precision_motion_vectors_allowed || !should_use_high_precision_motion_vector(vector)) {
1734
51.1k
            if ((delta_row & 1) != 0)
1735
295
                delta_row += delta_row > 0 ? -1 : 1;
1736
51.1k
            if ((delta_column & 1) != 0)
1737
335
                delta_column += delta_column > 0 ? -1 : 1;
1738
51.1k
        }
1739
81.3k
        vector = { delta_row, delta_column };
1740
81.3k
        vector = clamp_motion_vector(block_context, vector, (BORDERINPIXELS - INTERP_EXTEND) << 3);
1741
81.3k
    };
1742
40.6k
    adjust_and_clamp_vector(reference_motion_vectors.primary);
1743
40.6k
    adjust_and_clamp_vector(reference_motion_vectors.secondary);
1744
1745
40.6k
    candidates[reference_index].nearest_vector = reference_motion_vectors.primary;
1746
40.6k
    candidates[reference_index].near_vector = reference_motion_vectors.secondary;
1747
40.6k
    candidates[reference_index].best_vector = reference_motion_vectors.primary;
1748
40.6k
}
1749
1750
// append_sub8x8_mvs( block, refList ) in the spec.
1751
void Parser::select_best_sub_block_reference_motion_vectors(BlockContext& block_context, BlockMotionVectorCandidates& candidates, i32 block, ReferenceIndex reference_index)
1752
13.2k
{
1753
13.2k
    Array<MotionVector, 2> sub_8x8_mvs;
1754
13.2k
    MotionVectorPair reference_motion_vectors = find_reference_motion_vectors(block_context, block_context.reference_frame_types[reference_index], block);
1755
13.2k
    auto destination_index = 0;
1756
13.2k
    if (block == 0) {
1757
5.23k
        sub_8x8_mvs[destination_index++] = reference_motion_vectors.primary;
1758
5.23k
        sub_8x8_mvs[destination_index++] = reference_motion_vectors.secondary;
1759
8.05k
    } else if (block <= 2) {
1760
6.55k
        sub_8x8_mvs[destination_index++] = block_context.sub_block_motion_vectors[0][reference_index];
1761
6.55k
    } else {
1762
1.49k
        sub_8x8_mvs[destination_index++] = block_context.sub_block_motion_vectors[2][reference_index];
1763
3.64k
        for (auto index = 1; index >= 0 && destination_index < 2; index--) {
1764
2.15k
            auto block_vector = block_context.sub_block_motion_vectors[index][reference_index];
1765
2.15k
            if (block_vector != sub_8x8_mvs[0])
1766
918
                sub_8x8_mvs[destination_index++] = block_vector;
1767
2.15k
        }
1768
1.49k
    }
1769
1770
25.0k
    for (auto n = 0u; n < 2 && destination_index < 2; n++) {
1771
11.7k
        auto ref_list_vector = reference_motion_vectors[static_cast<ReferenceIndex>(n)];
1772
11.7k
        if (ref_list_vector != sub_8x8_mvs[0])
1773
4.84k
            sub_8x8_mvs[destination_index++] = ref_list_vector;
1774
11.7k
    }
1775
1776
13.2k
    if (destination_index < 2)
1777
2.29k
        sub_8x8_mvs[destination_index++] = {};
1778
13.2k
    candidates[reference_index].nearest_vector = sub_8x8_mvs[0];
1779
13.2k
    candidates[reference_index].near_vector = sub_8x8_mvs[1];
1780
13.2k
}
1781
1782
}