summaryrefslogtreecommitdiffstats
path: root/libavcodec/vp8.h
blob: 8263997e3fcd48f2f07c61644bedb558a8712223 (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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
/*
 * VP8 compatible video decoder
 *
 * Copyright (C) 2010 David Conrad
 * Copyright (C) 2010 Ronald S. Bultje
 * Copyright (C) 2010 Fiona Glaser
 * Copyright (C) 2012 Daniel Kang
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef AVCODEC_VP8_H
#define AVCODEC_VP8_H

#include <stdatomic.h>

#include "libavutil/buffer.h"
#include "libavutil/thread.h"

#include "h264pred.h"
#include "thread.h"
#include "vp56.h"
#include "vp8dsp.h"

#define VP8_MAX_QUANT 127

enum dct_token {
    DCT_0,
    DCT_1,
    DCT_2,
    DCT_3,
    DCT_4,
    DCT_CAT1,
    DCT_CAT2,
    DCT_CAT3,
    DCT_CAT4,
    DCT_CAT5,
    DCT_CAT6,
    DCT_EOB,

    NUM_DCT_TOKENS
};

// used to signal 4x4 intra pred in luma MBs
#define MODE_I4x4 4

enum inter_mvmode {
    VP8_MVMODE_ZERO = MODE_I4x4 + 1,
    VP8_MVMODE_MV,
    VP8_MVMODE_SPLIT
};

enum inter_splitmvmode {
    VP8_SPLITMVMODE_16x8 = 0,    ///< 2 16x8 blocks (vertical)
    VP8_SPLITMVMODE_8x16,        ///< 2 8x16 blocks (horizontal)
    VP8_SPLITMVMODE_8x8,         ///< 2x2 blocks of 8x8px each
    VP8_SPLITMVMODE_4x4,         ///< 4x4 blocks of 4x4px each
    VP8_SPLITMVMODE_NONE,        ///< (only used in prediction) no split MVs
};

typedef struct VP8FilterStrength {
    uint8_t filter_level;
    uint8_t inner_limit;
    uint8_t inner_filter;
} VP8FilterStrength;

typedef struct VP8Macroblock {
    uint8_t skip;
    // TODO: make it possible to check for at least (i4x4 or split_mv)
    // in one op. are others needed?
    uint8_t mode;
    uint8_t ref_frame;
    uint8_t partitioning;
    uint8_t chroma_pred_mode;
    uint8_t segment;
    uint8_t intra4x4_pred_mode_mb[16];
    DECLARE_ALIGNED(4, uint8_t, intra4x4_pred_mode_top)[4];
    VP56mv mv;
    VP56mv bmv[16];
} VP8Macroblock;

typedef struct VP8intmv {
    int x;
    int y;
} VP8intmv;

typedef struct VP8mvbounds {
    VP8intmv mv_min;
    VP8intmv mv_max;
} VP8mvbounds;

typedef struct VP8ThreadData {
    DECLARE_ALIGNED(16, int16_t, block)[6][4][16];
    DECLARE_ALIGNED(16, int16_t, block_dc)[16];
    /**
     * This is the index plus one of the last non-zero coeff
     * for each of the blocks in the current macroblock.
     * So, 0 -> no coeffs
     *     1 -> dc-only (special transform)
     *     2+-> full transform
     */
    DECLARE_ALIGNED(16, uint8_t, non_zero_count_cache)[6][4];
    /**
     * For coeff decode, we need to know whether the above block had non-zero
     * coefficients. This means for each macroblock, we need data for 4 luma
     * blocks, 2 u blocks, 2 v blocks, and the luma dc block, for a total of 9
     * per macroblock. We keep the last row in top_nnz.
     */
    DECLARE_ALIGNED(8, uint8_t, left_nnz)[9];
    int thread_nr;
#if HAVE_THREADS
    pthread_mutex_t lock;
    pthread_cond_t cond;
#endif
    atomic_int thread_mb_pos; // (mb_y << 16) | (mb_x & 0xFFFF)
    atomic_int wait_mb_pos; // What the current thread is waiting on.

#define EDGE_EMU_LINESIZE 32
    DECLARE_ALIGNED(16, uint8_t, edge_emu_buffer)[21 * EDGE_EMU_LINESIZE];
    VP8FilterStrength *filter_strength;
    VP8mvbounds mv_bounds;
} VP8ThreadData;

typedef struct VP8Frame {
    ThreadFrame tf;
    AVBufferRef *seg_map;
} VP8Frame;

#define MAX_THREADS 8
typedef struct VP8Context {
    VP8ThreadData *thread_data;
    AVCodecContext *avctx;
    VP8Frame *framep[4];
    VP8Frame *next_framep[4];
    VP8Frame *curframe;
    VP8Frame *prev_frame;

    uint16_t mb_width;   /* number of horizontal MB */
    uint16_t mb_height;  /* number of vertical MB */
    ptrdiff_t linesize;
    ptrdiff_t uvlinesize;

    uint8_t keyframe;
    uint8_t deblock_filter;
    uint8_t mbskip_enabled;
    uint8_t profile;
    VP8mvbounds mv_bounds;

    int8_t sign_bias[4]; ///< one state [0, 1] per ref frame type
    int ref_count[3];

    /**
     * Base parameters for segmentation, i.e. per-macroblock parameters.
     * These must be kept unchanged even if segmentation is not used for
     * a frame, since the values persist between interframes.
     */
    struct {
        uint8_t enabled;
        uint8_t absolute_vals;
        uint8_t update_map;
        int8_t base_quant[4];
        int8_t filter_level[4];     ///< base loop filter level
    } segmentation;

    struct {
        uint8_t simple;
        uint8_t level;
        uint8_t sharpness;
    } filter;

    VP8Macroblock *macroblocks;

    uint8_t *intra4x4_pred_mode_top;
    uint8_t intra4x4_pred_mode_left[4];

    /**
     * Macroblocks can have one of 4 different quants in a frame when
     * segmentation is enabled.
     * If segmentation is disabled, only the first segment's values are used.
     */
    struct {
        // [0] - DC qmul  [1] - AC qmul
        int16_t luma_qmul[2];
        int16_t luma_dc_qmul[2];    ///< luma dc-only block quant
        int16_t chroma_qmul[2];
    } qmat[4];

    struct {
        uint8_t enabled;    ///< whether each mb can have a different strength based on mode/ref

        /**
         * filter strength adjustment for the following macroblock modes:
         * [0-3] - i16x16 (always zero)
         * [4]   - i4x4
         * [5]   - zero mv
         * [6]   - inter modes except for zero or split mv
         * [7]   - split mv
         *  i16x16 modes never have any adjustment
         */
        int8_t mode[VP8_MVMODE_SPLIT + 1];

        /**
         * filter strength adjustment for macroblocks that reference:
         * [0] - intra / VP56_FRAME_CURRENT
         * [1] - VP56_FRAME_PREVIOUS
         * [2] - VP56_FRAME_GOLDEN
         * [3] - altref / VP56_FRAME_GOLDEN2
         */
        int8_t ref[4];
    } lf_delta;

    uint8_t (*top_border)[16 + 8 + 8];
    uint8_t (*top_nnz)[9];

    VP56RangeCoder c;   ///< header context, includes mb modes and motion vectors

    /**
     * These are all of the updatable probabilities for binary decisions.
     * They are only implicitly reset on keyframes, making it quite likely
     * for an interframe to desync if a prior frame's header was corrupt
     * or missing outright!
     */
    struct {
        uint8_t segmentid[3];
        uint8_t mbskip;
        uint8_t intra;
        uint8_t last;
        uint8_t golden;
        uint8_t pred16x16[4];
        uint8_t pred8x8c[3];
        uint8_t token[4][16][3][NUM_DCT_TOKENS - 1];
        uint8_t mvc[2][19];
        uint8_t scan[16];
    } prob[2];

    VP8Macroblock *macroblocks_base;
    int invisible;
    int update_last;    ///< update VP56_FRAME_PREVIOUS with the current one
    int update_golden;  ///< VP56_FRAME_NONE if not updated, or which frame to copy if so
    int update_altref;

    /**
     * If this flag is not set, all the probability updates
     * are discarded after this frame is decoded.
     */
    int update_probabilities;

    /**
     * All coefficients are contained in separate arith coding contexts.
     * There can be 1, 2, 4, or 8 of these after the header context.
     */
    int num_coeff_partitions;
    VP56RangeCoder coeff_partition[8];
    VideoDSPContext vdsp;
    VP8DSPContext vp8dsp;
    H264PredContext hpc;
    vp8_mc_func put_pixels_tab[3][3][3];
    VP8Frame frames[5];

    uint8_t colorspace; ///< 0 is the only value allowed (meaning bt601)
    uint8_t fullrange;  ///< whether we can skip clamping in dsp functions

    int num_jobs;
    /**
     * This describes the macroblock memory layout.
     * 0 -> Only width+height*2+1 macroblocks allocated (frame/single thread).
     * 1 -> Macroblocks for entire frame allocated (sliced thread).
     */
    int mb_layout;

    int (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
    void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);

    int vp7;

    /**
     * Fade bit present in bitstream (VP7)
     */
    int fade_present;

    /**
     * Interframe DC prediction (VP7)
     * [0] VP56_FRAME_PREVIOUS
     * [1] VP56_FRAME_GOLDEN
     */
    uint16_t inter_dc_pred[2][2];

    /**
     * Macroblock features (VP7)
     */
    uint8_t feature_enabled[4];
    uint8_t feature_present_prob[4];
    uint8_t feature_index_prob[4][3];
    uint8_t feature_value[4][4];
} VP8Context;

int ff_vp8_decode_init(AVCodecContext *avctx);

int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                        AVPacket *avpkt);

int ff_vp8_decode_free(AVCodecContext *avctx);

#endif /* AVCODEC_VP8_H */
OpenPOWER on IntegriCloud