Coverage Report

Created: 2025-03-04 07:22

/src/serenity/Userland/Libraries/LibMedia/Video/VP9/Decoder.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
3
 * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
4
 *
5
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#pragma once
9
10
#include <AK/ByteBuffer.h>
11
#include <AK/Error.h>
12
#include <AK/NonnullOwnPtr.h>
13
#include <AK/Queue.h>
14
#include <AK/Span.h>
15
#include <LibMedia/Color/CodingIndependentCodePoints.h>
16
#include <LibMedia/DecoderError.h>
17
#include <LibMedia/VideoDecoder.h>
18
#include <LibMedia/VideoFrame.h>
19
20
#include "Parser.h"
21
22
namespace Media::Video::VP9 {
23
24
class Decoder final : public VideoDecoder {
25
    friend class Parser;
26
27
public:
28
    Decoder();
29
783
    ~Decoder() override { }
30
    /* (8.1) General */
31
    DecoderErrorOr<void> receive_sample(Duration timestamp, ReadonlyBytes) override;
32
33
    DecoderErrorOr<NonnullOwnPtr<VideoFrame>> get_decoded_frame() override;
34
35
    void flush() override;
36
37
private:
38
    typedef i32 Intermediate;
39
40
    // Based on the maximum size resulting from num_4x4_blocks_wide_lookup.
41
    static constexpr size_t maximum_block_dimensions = 64ULL;
42
    static constexpr size_t maximum_block_size = maximum_block_dimensions * maximum_block_dimensions;
43
    // Based on the maximum for TXSize.
44
    static constexpr size_t maximum_transform_size = 32ULL * 32ULL;
45
46
    DecoderErrorOr<void> decode_frame(Duration timestamp, ReadonlyBytes);
47
    template<typename T>
48
    DecoderErrorOr<void> create_video_frame(Duration timestamp, FrameContext const&);
49
50
    DecoderErrorOr<void> allocate_buffers(FrameContext const&);
51
    Vector<u16>& get_output_buffer(u8 plane);
52
53
    /* (8.4) Probability Adaptation Process */
54
    u8 merge_prob(u8 pre_prob, u32 count_0, u32 count_1, u8 count_sat, u8 max_update_factor);
55
    u32 merge_probs(int const* tree, int index, u8* probs, u32* counts, u8 count_sat, u8 max_update_factor);
56
    DecoderErrorOr<void> adapt_coef_probs(FrameContext const&);
57
    DecoderErrorOr<void> adapt_non_coef_probs(FrameContext const&);
58
    void adapt_probs(int const* tree, u8* probs, u32* counts);
59
    u8 adapt_prob(u8 prob, u32 counts[2]);
60
61
    /* (8.5) Prediction Processes */
62
    // (8.5.1) Intra prediction process
63
    DecoderErrorOr<void> predict_intra(u8 plane, BlockContext const& block_context, u32 x, u32 y, bool have_left, bool have_above, bool not_on_right, TransformSize transform_size, u32 block_index);
64
65
    DecoderErrorOr<void> prepare_referenced_frame(Gfx::Size<u32> frame_size, u8 reference_frame_index);
66
67
    // (8.5.1) Inter prediction process
68
    DecoderErrorOr<void> predict_inter(u8 plane, BlockContext const& block_context, u32 x, u32 y, u32 width, u32 height, u32 block_index);
69
    // (8.5.2.1) Motion vector selection process
70
    MotionVector select_motion_vector(u8 plane, BlockContext const&, ReferenceIndex, u32 block_index);
71
    // (8.5.2.2) Motion vector clamping process
72
    MotionVector clamp_motion_vector(u8 plane, BlockContext const&, u32 block_row, u32 block_column, MotionVector vector);
73
    // From (8.5.1) Inter prediction process, steps 2-5
74
    DecoderErrorOr<void> predict_inter_block(u8 plane, BlockContext const&, ReferenceIndex, u32 block_row, u32 block_column, u32 x, u32 y, u32 width, u32 height, u32 block_index, Span<u16> block_buffer);
75
76
    /* (8.6) Reconstruction and Dequantization */
77
78
    // Returns the quantizer index for the current block
79
    static u8 get_base_quantizer_index(SegmentFeatureStatus alternative_quantizer_feature, bool should_use_absolute_segment_base_quantizer, u8 base_quantizer_index);
80
    // Returns the quantizer value for the dc coefficient for a particular plane
81
    static u16 get_dc_quantizer(u8 bit_depth, u8 base, i8 delta);
82
    // Returns the quantizer value for the ac coefficient for a particular plane
83
    static u16 get_ac_quantizer(u8 bit_depth, u8 base, i8 delta);
84
85
    // (8.6.2) Reconstruct process
86
    DecoderErrorOr<void> reconstruct(u8 plane, BlockContext const&, u32 transform_block_x, u32 transform_block_y, TransformSize transform_block_size, TransformSet);
87
    template<u8 log2_of_block_size>
88
    DecoderErrorOr<void> reconstruct_templated(u8 plane, BlockContext const&, u32 transform_block_x, u32 transform_block_y, TransformSet);
89
90
    // (8.7) Inverse transform process
91
    template<u8 log2_of_block_size>
92
    DecoderErrorOr<void> inverse_transform_2d(BlockContext const&, Span<Intermediate> dequantized, TransformSet);
93
94
    // (8.7.1) 1D Transforms
95
    // (8.7.1.1) Butterfly functions
96
97
    inline i32 cos64(u8 angle);
98
    inline i32 sin64(u8 angle);
99
    // The function B( a, b, angle, 0 ) performs a butterfly rotation.
100
    inline void butterfly_rotation_in_place(Span<Intermediate> data, size_t index_a, size_t index_b, u8 angle, bool flip);
101
    // The function H( a, b, 0 ) performs a Hadamard rotation.
102
    inline void hadamard_rotation_in_place(Span<Intermediate> data, size_t index_a, size_t index_b, bool flip);
103
    // The function SB( a, b, angle, 0 ) performs a butterfly rotation.
104
    // Spec defines the source as array T, and the destination array as S.
105
    template<typename S, typename D>
106
    inline void butterfly_rotation(Span<S> source, Span<D> destination, size_t index_a, size_t index_b, u8 angle, bool flip);
107
    // The function SH( a, b ) performs a Hadamard rotation and rounding.
108
    // Spec defines the source array as S, and the destination array as T.
109
    template<typename S, typename D>
110
    inline void hadamard_rotation(Span<S> source, Span<D> destination, size_t index_a, size_t index_b);
111
112
    // (8.7.1.10) This process does an in-place Walsh-Hadamard transform of the array T (of length 4).
113
    inline DecoderErrorOr<void> inverse_walsh_hadamard_transform(Span<Intermediate> data, u8 log2_of_block_size, u8 shift);
114
115
    // (8.7.1.2) Inverse DCT array permutation process
116
    template<u8 log2_of_block_size>
117
    inline DecoderErrorOr<void> inverse_discrete_cosine_transform_array_permutation(Span<Intermediate> data);
118
    // (8.7.1.3) Inverse DCT process
119
    template<u8 log2_of_block_size>
120
    inline DecoderErrorOr<void> inverse_discrete_cosine_transform(Span<Intermediate> data);
121
122
    // (8.7.1.4) This process performs the in-place permutation of the array T of length 2 n which is required as the first step of
123
    // the inverse ADST.
124
    template<u8 log2_of_block_size>
125
    inline void inverse_asymmetric_discrete_sine_transform_input_array_permutation(Span<Intermediate> data);
126
    // (8.7.1.5) This process performs the in-place permutation of the array T of length 2 n which is required before the final
127
    // step of the inverse ADST.
128
    template<u8 log2_of_block_size>
129
    inline void inverse_asymmetric_discrete_sine_transform_output_array_permutation(Span<Intermediate> data);
130
131
    // (8.7.1.6) This process does an in-place transform of the array T to perform an inverse ADST.
132
    inline void inverse_asymmetric_discrete_sine_transform_4(Span<Intermediate> data);
133
    // (8.7.1.7) This process does an in-place transform of the array T using a higher precision array S for intermediate
134
    // results.
135
    inline DecoderErrorOr<void> inverse_asymmetric_discrete_sine_transform_8(Span<Intermediate> data);
136
    // (8.7.1.8) This process does an in-place transform of the array T using a higher precision array S for intermediate
137
    // results.
138
    inline DecoderErrorOr<void> inverse_asymmetric_discrete_sine_transform_16(Span<Intermediate> data);
139
    // (8.7.1.9) This process performs an in-place inverse ADST process on the array T of size 2 n for 2 ≤ n ≤ 4.
140
    template<u8 log2_of_block_size>
141
    inline DecoderErrorOr<void> inverse_asymmetric_discrete_sine_transform(Span<Intermediate> data);
142
143
    /* (8.10) Reference Frame Update Process */
144
    DecoderErrorOr<void> update_reference_frames(FrameContext const&);
145
146
    NonnullOwnPtr<Parser> m_parser;
147
148
    Vector<u16> m_output_buffers[3];
149
150
    Queue<NonnullOwnPtr<VideoFrame>, 1> m_video_frame_queue;
151
};
152
153
}