summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibVideo/VP9/Decoder.h
blob: fa9b5f4c928047d129c4f5cb279d5b060182e852 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*
 * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include "BitStream.h"
#include "LookupTables.h"
#include "ProbabilityTables.h"
#include "SyntaxElementCounter.h"
#include "TreeParser.h"
#include <AK/ByteBuffer.h>
#include <AK/OwnPtr.h>

namespace Video::VP9 {

class Decoder {
    friend class TreeParser;

public:
    Decoder();
    ~Decoder();
    bool parse_frame(ByteBuffer const&);
    void dump_info();

private:
    FrameType read_frame_type()
    {
        if (m_bit_stream->read_bit())
            return NonKeyFrame;
        return KeyFrame;
    }

    ColorRange read_color_range()
    {
        if (m_bit_stream->read_bit())
            return FullSwing;
        return StudioSwing;
    }

    bool uncompressed_header();
    bool frame_sync_code();
    bool color_config();
    bool frame_size();
    bool render_size();
    bool frame_size_with_refs();
    bool compute_image_size();
    bool read_interpolation_filter();
    bool loop_filter_params();
    bool quantization_params();
    i8 read_delta_q();
    bool segmentation_params();
    u8 read_prob();
    bool tile_info();
    u16 calc_min_log2_tile_cols();
    u16 calc_max_log2_tile_cols();
    bool setup_past_independence();
    bool trailing_bits();

    bool compressed_header();
    bool read_tx_mode();
    bool tx_mode_probs();
    u8 diff_update_prob(u8 prob);
    u8 decode_term_subexp();
    u8 inv_remap_prob(u8 delta_prob, u8 prob);
    u8 inv_recenter_nonneg(u8 v, u8 m);
    bool read_coef_probs();
    bool read_skip_prob();
    bool read_inter_mode_probs();
    bool read_interp_filter_probs();
    bool read_is_inter_probs();
    bool frame_reference_mode();
    bool frame_reference_mode_probs();
    bool read_y_mode_probs();
    bool read_partition_probs();
    bool mv_probs();
    u8 update_mv_prob(u8 prob);
    bool setup_compound_reference_mode();

    bool decode_tiles();
    bool clear_above_context();
    u32 get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2);
    bool decode_tile();
    bool clear_left_context();
    bool decode_partition(u32 row, u32 col, u8 block_subsize);
    bool decode_block(u32 row, u32 col, u8 subsize);
    bool mode_info();
    bool intra_frame_mode_info();
    bool intra_segment_id();
    bool read_skip();
    bool seg_feature_active(u8 feature);
    bool read_tx_size(bool allow_select);
    bool inter_frame_mode_info();
    bool inter_segment_id();
    u8 get_segment_id();
    bool read_is_inter();
    bool intra_block_mode_info();
    bool inter_block_mode_info();
    bool read_ref_frames();
    bool assign_mv(bool is_compound);
    bool read_mv(u8 ref);

    /* (6.5) Motion Vector Prediction */
    bool find_mv_refs(ReferenceFrame, int block);
    bool find_best_ref_mvs(int ref_list);
    bool append_sub8x8_mvs(u8 block, u8 ref_list);

    u8 m_profile { 0 };
    u8 m_frame_to_show_map_index { 0 };
    u16 m_header_size_in_bytes { 0 };
    u8 m_refresh_frame_flags { 0 };
    u8 m_loop_filter_level { 0 };
    u8 m_loop_filter_sharpness { 0 };
    bool m_loop_filter_delta_enabled { false };
    FrameType m_frame_type;
    FrameType m_last_frame_type;
    bool m_show_frame { false };
    bool m_error_resilient_mode { false };
    bool m_frame_is_intra { false };
    u8 m_reset_frame_context { 0 };
    bool m_allow_high_precision_mv { false };
    u8 m_ref_frame_idx[3];
    u8 m_ref_frame_sign_bias[LastFrame + 3];
    bool m_refresh_frame_context { false };
    bool m_frame_parallel_decoding_mode { false };
    u8 m_frame_context_idx { 0 };
    u8 m_bit_depth { 0 };
    ColorSpace m_color_space;
    ColorRange m_color_range;
    bool m_subsampling_x { false };
    bool m_subsampling_y { false };
    u32 m_frame_width { 0 };
    u32 m_frame_height { 0 };
    u16 m_render_width { 0 };
    u16 m_render_height { 0 };
    bool m_render_and_frame_size_different { false };
    u32 m_mi_cols { 0 };
    u32 m_mi_rows { 0 };
    u32 m_sb64_cols { 0 };
    u32 m_sb64_rows { 0 };
    InterpolationFilter m_interpolation_filter;
    bool m_lossless { false };
    u8 m_segmentation_tree_probs[7];
    u8 m_segmentation_pred_prob[3];
    bool m_feature_enabled[8][4];
    u8 m_feature_data[8][4];
    bool m_segmentation_enabled { false };
    bool m_segmentation_update_map { false };
    bool m_segmentation_temporal_update { false };
    bool m_segmentation_abs_or_delta_update { false };
    u16 m_tile_cols_log2 { 0 };
    u16 m_tile_rows_log2 { 0 };
    i8 m_loop_filter_ref_deltas[MAX_REF_FRAMES];
    i8 m_loop_filter_mode_deltas[2];

    u8** m_above_nonzero_context { nullptr };
    u8** m_left_nonzero_context { nullptr };
    u8* m_above_seg_pred_context { nullptr };
    u8* m_left_seg_pred_context { nullptr };
    u8* m_above_partition_context { nullptr };
    u8* m_left_partition_context { nullptr };
    u32 m_mi_row_start { 0 };
    u32 m_mi_row_end { 0 };
    u32 m_mi_col_start { 0 };
    u32 m_mi_col_end { 0 };
    u32 m_mi_row { 0 };
    u32 m_mi_col { 0 };
    u32 m_mi_size { 0 };
    bool m_available_u { false };
    bool m_available_l { false };
    u8 m_segment_id { 0 };
    bool m_skip { false };
    u8 m_num_8x8 { 0 };
    bool m_has_rows { false };
    bool m_has_cols { false };
    TXSize m_max_tx_size { TX_4x4 };
    u8 m_block_subsize { 0 };
    u32 m_row { 0 };
    u32 m_col { 0 };
    TXSize m_tx_size { TX_4x4 };
    ReferenceFrame m_ref_frame[2];
    bool m_is_inter { false };
    IntraMode m_default_intra_mode { DcPred };
    u8 m_y_mode { 0 };
    u8 m_block_sub_modes[4];
    u8 m_num_4x4_w { 0 };
    u8 m_num_4x4_h { 0 };
    u8 m_uv_mode { 0 }; // FIXME: Is u8 the right size?
    ReferenceFrame m_left_ref_frame[2];
    ReferenceFrame m_above_ref_frame[2];
    Vector<Vector<Vector<ReferenceFrame>>> m_ref_frames; // TODO: Can we make these fixed sized allocations?
    bool m_left_intra { false };
    bool m_above_intra { false };
    bool m_left_single { false };
    bool m_above_single { false };
    Vector<Vector<u8>> m_prev_segment_ids;
    InterpolationFilter m_interp_filter { EightTap };
    InterMode m_mv[2];
    InterMode m_near_mv[2];
    InterMode m_nearest_mv[2];
    Vector<Vector<Vector<IntraMode>>> m_sub_modes; // FIXME: Can we make these fixed sized allocations?

    bool m_use_hp { false };

    TXMode m_tx_mode;
    ReferenceMode m_reference_mode;
    ReferenceFrame m_comp_fixed_ref;
    ReferenceFrame m_comp_var_ref[2];

    OwnPtr<BitStream> m_bit_stream;
    OwnPtr<ProbabilityTables> m_probability_tables;
    OwnPtr<SyntaxElementCounter> m_syntax_element_counter;
    NonnullOwnPtr<TreeParser> m_tree_parser;
};

}