]> git.sesse.net Git - ffmpeg/blob - libavcodec/vp56.h
Merge commit 'a2a991b2ddf951454ffceb7bcedc9db93e26c610'
[ffmpeg] / libavcodec / vp56.h
1 /*
2  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * VP5 and VP6 compatible video decoder (common features)
24  */
25
26 #ifndef AVCODEC_VP56_H
27 #define AVCODEC_VP56_H
28
29 #include "vp56data.h"
30 #include "dsputil.h"
31 #include "get_bits.h"
32 #include "bytestream.h"
33 #include "videodsp.h"
34 #include "vp3dsp.h"
35 #include "vp56dsp.h"
36
37 typedef struct vp56_context VP56Context;
38
39 typedef struct VP56mv {
40     DECLARE_ALIGNED(4, int16_t, x);
41     int16_t y;
42 } VP56mv;
43
44 #define VP56_SIZE_CHANGE 1
45
46 typedef void (*VP56ParseVectorAdjustment)(VP56Context *s,
47                                           VP56mv *vect);
48 typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src,
49                            int offset1, int offset2, int stride,
50                            VP56mv mv, int mask, int select, int luma);
51 typedef void (*VP56ParseCoeff)(VP56Context *s);
52 typedef void (*VP56DefaultModelsInit)(VP56Context *s);
53 typedef void (*VP56ParseVectorModels)(VP56Context *s);
54 typedef int  (*VP56ParseCoeffModels)(VP56Context *s);
55 typedef int  (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf,
56                                 int buf_size);
57
58 typedef struct VP56RangeCoder {
59     int high;
60     int bits; /* stored negated (i.e. negative "bits" is a positive number of
61                  bits left) in order to eliminate a negate in cache refilling */
62     const uint8_t *buffer;
63     const uint8_t *end;
64     unsigned int code_word;
65 } VP56RangeCoder;
66
67 typedef struct VP56RefDc {
68     uint8_t not_null_dc;
69     VP56Frame ref_frame;
70     DCTELEM dc_coeff;
71 } VP56RefDc;
72
73 typedef struct VP56Macroblock {
74     uint8_t type;
75     VP56mv mv;
76 } VP56Macroblock;
77
78 typedef struct VP56Model {
79     uint8_t coeff_reorder[64];       /* used in vp6 only */
80     uint8_t coeff_index_to_pos[64];  /* used in vp6 only */
81     uint8_t vector_sig[2];           /* delta sign */
82     uint8_t vector_dct[2];           /* delta coding types */
83     uint8_t vector_pdi[2][2];        /* predefined delta init */
84     uint8_t vector_pdv[2][7];        /* predefined delta values */
85     uint8_t vector_fdv[2][8];        /* 8 bit delta value definition */
86     uint8_t coeff_dccv[2][11];       /* DC coeff value */
87     uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */
88     uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */
89     uint8_t coeff_dcct[2][36][5];    /* DC coeff coding type */
90     uint8_t coeff_runv[2][14];       /* run value (vp6 only) */
91     uint8_t mb_type[3][10][10];      /* model for decoding MB type */
92     uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */
93 } VP56Model;
94
95 struct vp56_context {
96     AVCodecContext *avctx;
97     DSPContext dsp;
98     VideoDSPContext vdsp;
99     VP3DSPContext vp3dsp;
100     VP56DSPContext vp56dsp;
101     ScanTable scantable;
102     AVFrame frames[4];
103     AVFrame *framep[6];
104     uint8_t *edge_emu_buffer_alloc;
105     uint8_t *edge_emu_buffer;
106     VP56RangeCoder c;
107     VP56RangeCoder cc;
108     VP56RangeCoder *ccp;
109     int sub_version;
110
111     /* frame info */
112     int golden_frame;
113     int plane_width[4];
114     int plane_height[4];
115     int mb_width;   /* number of horizontal MB */
116     int mb_height;  /* number of vertical MB */
117     int block_offset[6];
118
119     int quantizer;
120     uint16_t dequant_dc;
121     uint16_t dequant_ac;
122     int8_t *qscale_table;
123
124     /* DC predictors management */
125     VP56RefDc *above_blocks;
126     VP56RefDc left_block[4];
127     int above_block_idx[6];
128     DCTELEM prev_dc[3][3];    /* [plan][ref_frame] */
129
130     /* blocks / macroblock */
131     VP56mb mb_type;
132     VP56Macroblock *macroblocks;
133     DECLARE_ALIGNED(16, DCTELEM, block_coeff)[6][64];
134
135     /* motion vectors */
136     VP56mv mv[6];  /* vectors for each block in MB */
137     VP56mv vector_candidate[2];
138     int vector_candidate_pos;
139
140     /* filtering hints */
141     int filter_header;               /* used in vp6 only */
142     int deblock_filtering;
143     int filter_selection;
144     int filter_mode;
145     int max_vector_length;
146     int sample_variance_threshold;
147
148     uint8_t coeff_ctx[4][64];              /* used in vp5 only */
149     uint8_t coeff_ctx_last[4];             /* used in vp5 only */
150
151     int has_alpha;
152
153     /* upside-down flipping hints */
154     int flip;  /* are we flipping ? */
155     int frbi;  /* first row block index in MB */
156     int srbi;  /* second row block index in MB */
157     int stride[4];  /* stride for each plan */
158
159     const uint8_t *vp56_coord_div;
160     VP56ParseVectorAdjustment parse_vector_adjustment;
161     VP56Filter filter;
162     VP56ParseCoeff parse_coeff;
163     VP56DefaultModelsInit default_models_init;
164     VP56ParseVectorModels parse_vector_models;
165     VP56ParseCoeffModels parse_coeff_models;
166     VP56ParseHeader parse_header;
167
168     /* for "slice" parallelism between YUV and A */
169     VP56Context *alpha_context;
170
171     VP56Model *modelp;
172     VP56Model model;
173
174     /* huffman decoding */
175     int use_huffman;
176     GetBitContext gb;
177     VLC dccv_vlc[2];
178     VLC runv_vlc[2];
179     VLC ract_vlc[2][3][6];
180     unsigned int nb_null[2][2];       /* number of consecutive NULL DC/AC */
181 };
182
183
184 void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
185 void ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
186                           int flip, int has_alpha);
187 int ff_vp56_free(AVCodecContext *avctx);
188 int ff_vp56_free_context(VP56Context *s);
189 void ff_vp56_init_dequant(VP56Context *s, int quantizer);
190 int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
191                          AVPacket *avpkt);
192
193
194 /**
195  * vp56 specific range coder implementation
196  */
197
198 extern const uint8_t ff_vp56_norm_shift[256];
199 void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size);
200
201 static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c)
202 {
203     int shift = ff_vp56_norm_shift[c->high];
204     int bits = c->bits;
205     unsigned int code_word = c->code_word;
206
207     c->high   <<= shift;
208     code_word <<= shift;
209     bits       += shift;
210     if(bits >= 0 && c->buffer < c->end) {
211         code_word |= bytestream_get_be16(&c->buffer) << bits;
212         bits -= 16;
213     }
214     c->bits = bits;
215     return code_word;
216 }
217
218 #if   ARCH_ARM
219 #include "arm/vp56_arith.h"
220 #elif ARCH_X86
221 #include "x86/vp56_arith.h"
222 #endif
223
224 #ifndef vp56_rac_get_prob
225 #define vp56_rac_get_prob vp56_rac_get_prob
226 static av_always_inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob)
227 {
228     unsigned int code_word = vp56_rac_renorm(c);
229     unsigned int low = 1 + (((c->high - 1) * prob) >> 8);
230     unsigned int low_shift = low << 16;
231     int bit = code_word >= low_shift;
232
233     c->high = bit ? c->high - low : low;
234     c->code_word = bit ? code_word - low_shift : code_word;
235
236     return bit;
237 }
238 #endif
239
240 #ifndef vp56_rac_get_prob_branchy
241 // branchy variant, to be used where there's a branch based on the bit decoded
242 static av_always_inline int vp56_rac_get_prob_branchy(VP56RangeCoder *c, int prob)
243 {
244     unsigned long code_word = vp56_rac_renorm(c);
245     unsigned low = 1 + (((c->high - 1) * prob) >> 8);
246     unsigned low_shift = low << 16;
247
248     if (code_word >= low_shift) {
249         c->high     -= low;
250         c->code_word = code_word - low_shift;
251         return 1;
252     }
253
254     c->high = low;
255     c->code_word = code_word;
256     return 0;
257 }
258 #endif
259
260 static av_always_inline int vp56_rac_get(VP56RangeCoder *c)
261 {
262     unsigned int code_word = vp56_rac_renorm(c);
263     /* equiprobable */
264     int low = (c->high + 1) >> 1;
265     unsigned int low_shift = low << 16;
266     int bit = code_word >= low_shift;
267     if (bit) {
268         c->high   -= low;
269         code_word -= low_shift;
270     } else {
271         c->high = low;
272     }
273
274     c->code_word = code_word;
275     return bit;
276 }
277
278 // rounding is different than vp56_rac_get, is vp56_rac_get wrong?
279 static av_always_inline int vp8_rac_get(VP56RangeCoder *c)
280 {
281     return vp56_rac_get_prob(c, 128);
282 }
283
284 static av_unused int vp56_rac_gets(VP56RangeCoder *c, int bits)
285 {
286     int value = 0;
287
288     while (bits--) {
289         value = (value << 1) | vp56_rac_get(c);
290     }
291
292     return value;
293 }
294
295 static av_unused int vp8_rac_get_uint(VP56RangeCoder *c, int bits)
296 {
297     int value = 0;
298
299     while (bits--) {
300         value = (value << 1) | vp8_rac_get(c);
301     }
302
303     return value;
304 }
305
306 // fixme: add 1 bit to all the calls to this?
307 static av_unused int vp8_rac_get_sint(VP56RangeCoder *c, int bits)
308 {
309     int v;
310
311     if (!vp8_rac_get(c))
312         return 0;
313
314     v = vp8_rac_get_uint(c, bits);
315
316     if (vp8_rac_get(c))
317         v = -v;
318
319     return v;
320 }
321
322 // P(7)
323 static av_unused int vp56_rac_gets_nn(VP56RangeCoder *c, int bits)
324 {
325     int v = vp56_rac_gets(c, 7) << 1;
326     return v + !v;
327 }
328
329 static av_unused int vp8_rac_get_nn(VP56RangeCoder *c)
330 {
331     int v = vp8_rac_get_uint(c, 7) << 1;
332     return v + !v;
333 }
334
335 static av_always_inline
336 int vp56_rac_get_tree(VP56RangeCoder *c,
337                       const VP56Tree *tree,
338                       const uint8_t *probs)
339 {
340     while (tree->val > 0) {
341         if (vp56_rac_get_prob(c, probs[tree->prob_idx]))
342             tree += tree->val;
343         else
344             tree++;
345     }
346     return -tree->val;
347 }
348
349 // how probabilities are associated with decisions is different I think
350 // well, the new scheme fits in the old but this way has one fewer branches per decision
351 static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2],
352                                    const uint8_t *probs)
353 {
354     int i = 0;
355
356     do {
357         i = tree[i][vp56_rac_get_prob(c, probs[i])];
358     } while (i > 0);
359
360     return -i;
361 }
362
363 // DCTextra
364 static av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob)
365 {
366     int v = 0;
367
368     do {
369         v = (v<<1) + vp56_rac_get_prob(c, *prob++);
370     } while (*prob);
371
372     return v;
373 }
374
375 #endif /* AVCODEC_VP56_H */