FFmpeg
vp3dsp.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004 The FFmpeg project
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  * Standard C DSP-oriented functions cribbed from the original VP3
24  * source code.
25  */
26 
27 #include "libavutil/attributes.h"
28 #include "libavutil/common.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/avassert.h"
31 
32 #include "avcodec.h"
33 #include "rnd_avg.h"
34 #include "vp3dsp.h"
35 
36 #define IdctAdjustBeforeShift 8
37 #define xC1S7 64277
38 #define xC2S6 60547
39 #define xC3S5 54491
40 #define xC4S4 46341
41 #define xC5S3 36410
42 #define xC6S2 25080
43 #define xC7S1 12785
44 
45 #define M(a, b) ((int)((SUINT)(a) * (b)) >> 16)
46 
47 static av_always_inline void idct(uint8_t *dst, ptrdiff_t stride,
48  int16_t *input, int type)
49 {
50  int16_t *ip = input;
51 
52  int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
53  int Ed, Gd, Add, Bdd, Fd, Hd;
54 
55  int i;
56 
57  /* Inverse DCT on the rows now */
58  for (i = 0; i < 8; i++) {
59  /* Check for non-zero values */
60  if (ip[0 * 8] | ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
61  ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8]) {
62  A = M(xC1S7, ip[1 * 8]) + M(xC7S1, ip[7 * 8]);
63  B = M(xC7S1, ip[1 * 8]) - M(xC1S7, ip[7 * 8]);
64  C = M(xC3S5, ip[3 * 8]) + M(xC5S3, ip[5 * 8]);
65  D = M(xC3S5, ip[5 * 8]) - M(xC5S3, ip[3 * 8]);
66 
67  Ad = M(xC4S4, (A - C));
68  Bd = M(xC4S4, (B - D));
69 
70  Cd = A + C;
71  Dd = B + D;
72 
73  E = M(xC4S4, (ip[0 * 8] + ip[4 * 8]));
74  F = M(xC4S4, (ip[0 * 8] - ip[4 * 8]));
75 
76  G = M(xC2S6, ip[2 * 8]) + M(xC6S2, ip[6 * 8]);
77  H = M(xC6S2, ip[2 * 8]) - M(xC2S6, ip[6 * 8]);
78 
79  Ed = E - G;
80  Gd = E + G;
81 
82  Add = F + Ad;
83  Bdd = Bd - H;
84 
85  Fd = F - Ad;
86  Hd = Bd + H;
87 
88  /* Final sequence of operations over-write original inputs. */
89  ip[0 * 8] = Gd + Cd;
90  ip[7 * 8] = Gd - Cd;
91 
92  ip[1 * 8] = Add + Hd;
93  ip[2 * 8] = Add - Hd;
94 
95  ip[3 * 8] = Ed + Dd;
96  ip[4 * 8] = Ed - Dd;
97 
98  ip[5 * 8] = Fd + Bdd;
99  ip[6 * 8] = Fd - Bdd;
100  }
101 
102  ip += 1; /* next row */
103  }
104 
105  ip = input;
106 
107  for (i = 0; i < 8; i++) {
108  /* Check for non-zero values (bitwise or faster than ||) */
109  if (ip[1] | ip[2] | ip[3] |
110  ip[4] | ip[5] | ip[6] | ip[7]) {
111  A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);
112  B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);
113  C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);
114  D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);
115 
116  Ad = M(xC4S4, (A - C));
117  Bd = M(xC4S4, (B - D));
118 
119  Cd = A + C;
120  Dd = B + D;
121 
122  E = M(xC4S4, (ip[0] + ip[4])) + 8;
123  F = M(xC4S4, (ip[0] - ip[4])) + 8;
124 
125  if (type == 1) { // HACK
126  E += 16 * 128;
127  F += 16 * 128;
128  }
129 
130  G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);
131  H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);
132 
133  Ed = E - G;
134  Gd = E + G;
135 
136  Add = F + Ad;
137  Bdd = Bd - H;
138 
139  Fd = F - Ad;
140  Hd = Bd + H;
141 
142  /* Final sequence of operations over-write original inputs. */
143  if (type == 1) {
144  dst[0 * stride] = av_clip_uint8((Gd + Cd) >> 4);
145  dst[7 * stride] = av_clip_uint8((Gd - Cd) >> 4);
146 
147  dst[1 * stride] = av_clip_uint8((Add + Hd) >> 4);
148  dst[2 * stride] = av_clip_uint8((Add - Hd) >> 4);
149 
150  dst[3 * stride] = av_clip_uint8((Ed + Dd) >> 4);
151  dst[4 * stride] = av_clip_uint8((Ed - Dd) >> 4);
152 
153  dst[5 * stride] = av_clip_uint8((Fd + Bdd) >> 4);
154  dst[6 * stride] = av_clip_uint8((Fd - Bdd) >> 4);
155  } else {
156  dst[0 * stride] = av_clip_uint8(dst[0 * stride] + ((Gd + Cd) >> 4));
157  dst[7 * stride] = av_clip_uint8(dst[7 * stride] + ((Gd - Cd) >> 4));
158 
159  dst[1 * stride] = av_clip_uint8(dst[1 * stride] + ((Add + Hd) >> 4));
160  dst[2 * stride] = av_clip_uint8(dst[2 * stride] + ((Add - Hd) >> 4));
161 
162  dst[3 * stride] = av_clip_uint8(dst[3 * stride] + ((Ed + Dd) >> 4));
163  dst[4 * stride] = av_clip_uint8(dst[4 * stride] + ((Ed - Dd) >> 4));
164 
165  dst[5 * stride] = av_clip_uint8(dst[5 * stride] + ((Fd + Bdd) >> 4));
166  dst[6 * stride] = av_clip_uint8(dst[6 * stride] + ((Fd - Bdd) >> 4));
167  }
168  } else {
169  if (type == 1) {
170  dst[0*stride] =
171  dst[1*stride] =
172  dst[2*stride] =
173  dst[3*stride] =
174  dst[4*stride] =
175  dst[5*stride] =
176  dst[6*stride] =
177  dst[7*stride] = av_clip_uint8(128 + ((xC4S4 * ip[0] + (IdctAdjustBeforeShift << 16)) >> 20));
178  } else {
179  if (ip[0]) {
180  int v = (xC4S4 * ip[0] + (IdctAdjustBeforeShift << 16)) >> 20;
181  dst[0 * stride] = av_clip_uint8(dst[0 * stride] + v);
182  dst[1 * stride] = av_clip_uint8(dst[1 * stride] + v);
183  dst[2 * stride] = av_clip_uint8(dst[2 * stride] + v);
184  dst[3 * stride] = av_clip_uint8(dst[3 * stride] + v);
185  dst[4 * stride] = av_clip_uint8(dst[4 * stride] + v);
186  dst[5 * stride] = av_clip_uint8(dst[5 * stride] + v);
187  dst[6 * stride] = av_clip_uint8(dst[6 * stride] + v);
188  dst[7 * stride] = av_clip_uint8(dst[7 * stride] + v);
189  }
190  }
191  }
192 
193  ip += 8; /* next column */
194  dst++;
195  }
196 }
197 
198 static av_always_inline void idct10(uint8_t *dst, ptrdiff_t stride,
199  int16_t *input, int type)
200 {
201  int16_t *ip = input;
202 
203  int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
204  int Ed, Gd, Add, Bdd, Fd, Hd;
205 
206  int i;
207 
208  /* Inverse DCT on the rows now */
209  for (i = 0; i < 4; i++) {
210  /* Check for non-zero values */
211  if (ip[0 * 8] | ip[1 * 8] | ip[2 * 8] | ip[3 * 8]) {
212  A = M(xC1S7, ip[1 * 8]);
213  B = M(xC7S1, ip[1 * 8]);
214  C = M(xC3S5, ip[3 * 8]);
215  D = -M(xC5S3, ip[3 * 8]);
216 
217  Ad = M(xC4S4, (A - C));
218  Bd = M(xC4S4, (B - D));
219 
220  Cd = A + C;
221  Dd = B + D;
222 
223  E = M(xC4S4, ip[0 * 8]);
224  F = E;
225 
226  G = M(xC2S6, ip[2 * 8]);
227  H = M(xC6S2, ip[2 * 8]);
228 
229  Ed = E - G;
230  Gd = E + G;
231 
232  Add = F + Ad;
233  Bdd = Bd - H;
234 
235  Fd = F - Ad;
236  Hd = Bd + H;
237 
238  /* Final sequence of operations over-write original inputs */
239  ip[0 * 8] = Gd + Cd;
240  ip[7 * 8] = Gd - Cd;
241 
242  ip[1 * 8] = Add + Hd;
243  ip[2 * 8] = Add - Hd;
244 
245  ip[3 * 8] = Ed + Dd;
246  ip[4 * 8] = Ed - Dd;
247 
248  ip[5 * 8] = Fd + Bdd;
249  ip[6 * 8] = Fd - Bdd;
250 
251  }
252 
253  ip += 1;
254  }
255 
256  ip = input;
257 
258  for (i = 0; i < 8; i++) {
259  /* Check for non-zero values (bitwise or faster than ||) */
260  if (ip[0] | ip[1] | ip[2] | ip[3]) {
261  A = M(xC1S7, ip[1]);
262  B = M(xC7S1, ip[1]);
263  C = M(xC3S5, ip[3]);
264  D = -M(xC5S3, ip[3]);
265 
266  Ad = M(xC4S4, (A - C));
267  Bd = M(xC4S4, (B - D));
268 
269  Cd = A + C;
270  Dd = B + D;
271 
272  E = M(xC4S4, ip[0]);
273  if (type == 1)
274  E += 16 * 128;
275  F = E;
276 
277  G = M(xC2S6, ip[2]);
278  H = M(xC6S2, ip[2]);
279 
280  Ed = E - G;
281  Gd = E + G;
282 
283  Add = F + Ad;
284  Bdd = Bd - H;
285 
286  Fd = F - Ad;
287  Hd = Bd + H;
288 
289  Gd += 8;
290  Add += 8;
291  Ed += 8;
292  Fd += 8;
293 
294  /* Final sequence of operations over-write original inputs. */
295  if (type == 1) {
296  dst[0 * stride] = av_clip_uint8((Gd + Cd) >> 4);
297  dst[7 * stride] = av_clip_uint8((Gd - Cd) >> 4);
298 
299  dst[1 * stride] = av_clip_uint8((Add + Hd) >> 4);
300  dst[2 * stride] = av_clip_uint8((Add - Hd) >> 4);
301 
302  dst[3 * stride] = av_clip_uint8((Ed + Dd) >> 4);
303  dst[4 * stride] = av_clip_uint8((Ed - Dd) >> 4);
304 
305  dst[5 * stride] = av_clip_uint8((Fd + Bdd) >> 4);
306  dst[6 * stride] = av_clip_uint8((Fd - Bdd) >> 4);
307  } else {
308  dst[0 * stride] = av_clip_uint8(dst[0 * stride] + ((Gd + Cd) >> 4));
309  dst[7 * stride] = av_clip_uint8(dst[7 * stride] + ((Gd - Cd) >> 4));
310 
311  dst[1 * stride] = av_clip_uint8(dst[1 * stride] + ((Add + Hd) >> 4));
312  dst[2 * stride] = av_clip_uint8(dst[2 * stride] + ((Add - Hd) >> 4));
313 
314  dst[3 * stride] = av_clip_uint8(dst[3 * stride] + ((Ed + Dd) >> 4));
315  dst[4 * stride] = av_clip_uint8(dst[4 * stride] + ((Ed - Dd) >> 4));
316 
317  dst[5 * stride] = av_clip_uint8(dst[5 * stride] + ((Fd + Bdd) >> 4));
318  dst[6 * stride] = av_clip_uint8(dst[6 * stride] + ((Fd - Bdd) >> 4));
319  }
320  } else {
321  if (type == 1) {
322  dst[0*stride] =
323  dst[1*stride] =
324  dst[2*stride] =
325  dst[3*stride] =
326  dst[4*stride] =
327  dst[5*stride] =
328  dst[6*stride] =
329  dst[7*stride] = 128;
330  }
331  }
332 
333  ip += 8;
334  dst++;
335  }
336 }
337 
338 void ff_vp3dsp_idct10_put(uint8_t *dest, ptrdiff_t stride, int16_t *block)
339 {
340  idct10(dest, stride, block, 1);
341  memset(block, 0, sizeof(*block) * 64);
342 }
343 
344 void ff_vp3dsp_idct10_add(uint8_t *dest, ptrdiff_t stride, int16_t *block)
345 {
346  idct10(dest, stride, block, 2);
347  memset(block, 0, sizeof(*block) * 64);
348 }
349 
350 static void vp3_idct_put_c(uint8_t *dest /* align 8 */, ptrdiff_t stride,
351  int16_t *block /* align 16 */)
352 {
353  idct(dest, stride, block, 1);
354  memset(block, 0, sizeof(*block) * 64);
355 }
356 
357 static void vp3_idct_add_c(uint8_t *dest /* align 8 */, ptrdiff_t stride,
358  int16_t *block /* align 16 */)
359 {
360  idct(dest, stride, block, 2);
361  memset(block, 0, sizeof(*block) * 64);
362 }
363 
364 static void vp3_idct_dc_add_c(uint8_t *dest /* align 8 */, ptrdiff_t stride,
365  int16_t *block /* align 16 */)
366 {
367  int i, dc = (block[0] + 15) >> 5;
368 
369  for (i = 0; i < 8; i++) {
370  dest[0] = av_clip_uint8(dest[0] + dc);
371  dest[1] = av_clip_uint8(dest[1] + dc);
372  dest[2] = av_clip_uint8(dest[2] + dc);
373  dest[3] = av_clip_uint8(dest[3] + dc);
374  dest[4] = av_clip_uint8(dest[4] + dc);
375  dest[5] = av_clip_uint8(dest[5] + dc);
376  dest[6] = av_clip_uint8(dest[6] + dc);
377  dest[7] = av_clip_uint8(dest[7] + dc);
378  dest += stride;
379  }
380  block[0] = 0;
381 }
382 
383 static av_always_inline void vp3_v_loop_filter_c(uint8_t *first_pixel, ptrdiff_t stride,
384  int *bounding_values, int count)
385 {
386  unsigned char *end;
387  int filter_value;
388  const ptrdiff_t nstride = -stride;
389 
390  for (end = first_pixel + count; first_pixel < end; first_pixel++) {
391  filter_value = (first_pixel[2 * nstride] - first_pixel[stride]) +
392  (first_pixel[0] - first_pixel[nstride]) * 3;
393  filter_value = bounding_values[(filter_value + 4) >> 3];
394 
395  first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value);
396  first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value);
397  }
398 }
399 
400 static av_always_inline void vp3_h_loop_filter_c(uint8_t *first_pixel, ptrdiff_t stride,
401  int *bounding_values, int count)
402 {
403  unsigned char *end;
404  int filter_value;
405 
406  for (end = first_pixel + count * stride; first_pixel != end; first_pixel += stride) {
407  filter_value = (first_pixel[-2] - first_pixel[1]) +
408  (first_pixel[ 0] - first_pixel[-1]) * 3;
409  filter_value = bounding_values[(filter_value + 4) >> 3];
410 
411  first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value);
412  first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value);
413  }
414 }
415 
416 #define LOOP_FILTER(prefix, suffix, dim, count) \
417 void prefix##_##dim##_loop_filter_##count##suffix(uint8_t *first_pixel, ptrdiff_t stride, \
418  int *bounding_values) \
419 { \
420  vp3_##dim##_loop_filter_c(first_pixel, stride, bounding_values, count); \
421 }
422 
423 static LOOP_FILTER(vp3,_c, v, 8)
424 static LOOP_FILTER(vp3,_c, h, 8)
425 LOOP_FILTER(ff_vp3dsp, , v, 12)
426 LOOP_FILTER(ff_vp3dsp, , h, 12)
427 
428 static void put_no_rnd_pixels_l2(uint8_t *dst, const uint8_t *src1,
429  const uint8_t *src2, ptrdiff_t stride, int h)
430 {
431  int i;
432 
433  for (i = 0; i < h; i++) {
434  uint32_t a, b;
435 
436  a = AV_RN32(&src1[i * stride]);
437  b = AV_RN32(&src2[i * stride]);
438  AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
439  a = AV_RN32(&src1[i * stride + 4]);
440  b = AV_RN32(&src2[i * stride + 4]);
441  AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
442  }
443 }
444 
446 {
447  c->put_no_rnd_pixels_l2 = put_no_rnd_pixels_l2;
448 
452  c->v_loop_filter = vp3_v_loop_filter_8_c;
453  c->h_loop_filter = vp3_h_loop_filter_8_c;
454 
455  if (ARCH_ARM)
456  ff_vp3dsp_init_arm(c, flags);
457  if (ARCH_PPC)
458  ff_vp3dsp_init_ppc(c, flags);
459  if (ARCH_X86)
460  ff_vp3dsp_init_x86(c, flags);
461  if (ARCH_MIPS)
462  ff_vp3dsp_init_mips(c, flags);
463 }
464 
465 /*
466  * This function initializes the loop filter boundary limits if the frame's
467  * quality index is different from the previous frame's.
468  *
469  * where sizeof(bounding_values_array) is 256 * sizeof(int)
470  *
471  * The filter_limit_values may not be larger than 127.
472  */
473 void ff_vp3dsp_set_bounding_values(int * bounding_values_array, int filter_limit)
474 {
475  int *bounding_values = bounding_values_array + 127;
476  int x;
477  int value;
478 
479  av_assert0(filter_limit < 128U);
480 
481  /* set up the bounding values */
482  memset(bounding_values_array, 0, 256 * sizeof(int));
483  for (x = 0; x < filter_limit; x++) {
484  bounding_values[-x] = -x;
485  bounding_values[x] = x;
486  }
487  for (x = value = filter_limit; x < 128 && value; x++, value--) {
488  bounding_values[ x] = value;
489  bounding_values[-x] = -value;
490  }
491  if (value)
492  bounding_values[128] = value;
493  bounding_values[129] = bounding_values[130] = filter_limit * 0x02020202;
494 }
static void vp3_idct_put_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:350
void(* put_no_rnd_pixels_l2)(uint8_t *dst, const uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h)
Copy 8xH pixels from source to destination buffer using a bilinear filter with no rounding (i...
Definition: vp3dsp.h:36
#define xC4S4
Definition: vp3dsp.c:40
void(* v_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values)
Definition: vp3dsp.h:44
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
GLint GLenum type
Definition: opengl_enc.c:104
#define AV_WN32A(p, v)
Definition: intreadwrite.h:538
Macro definitions for various function/variable attributes.
av_cold void ff_vp3dsp_init_mips(VP3DSPContext *c, int flags)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
#define xC1S7
Definition: vp3dsp.c:37
void ff_vp3dsp_idct10_add(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:344
#define M(a, b)
Definition: vp3dsp.c:45
The exact code depends on how similar the blocks are and how related they are to the block
uint8_t
void ff_vp3dsp_idct10_put(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:338
#define av_cold
Definition: attributes.h:82
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:108
static av_always_inline void vp3_h_loop_filter_c(uint8_t *first_pixel, ptrdiff_t stride, int *bounding_values, int count)
Definition: vp3dsp.c:400
static av_always_inline void vp3_v_loop_filter_c(uint8_t *first_pixel, ptrdiff_t stride, int *bounding_values, int count)
Definition: vp3dsp.c:383
#define A(x)
Definition: vp56_arith.h:28
static void vp3_idct_add_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:357
#define xC6S2
Definition: vp3dsp.c:42
#define U(x)
Definition: vp56_arith.h:37
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define B
Definition: huffyuvdsp.h:32
void(* idct_add)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.h:42
#define xC2S6
Definition: vp3dsp.c:38
void(* h_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values)
Definition: vp3dsp.h:45
simple assert() macros that are a bit more flexible than ISO C assert().
GLsizei count
Definition: opengl_enc.c:108
#define xC7S1
Definition: vp3dsp.c:43
#define b
Definition: input.c:41
static uint32_t no_rnd_avg32(uint32_t a, uint32_t b)
Definition: rnd_avg.h:36
#define E
Definition: avdct.c:32
static int filter_value(int in, int rrp[8], int v[9])
#define LOOP_FILTER(prefix, suffix, dim, count)
Definition: vp3dsp.c:416
void(* idct_dc_add)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.h:43
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s your new playground is ready Some little details about what s going which in turn will define variables for the build system and the C
#define src1
Definition: h264pred.c:139
Libavcodec external API header.
av_cold void ff_vp3dsp_init_arm(VP3DSPContext *c, int flags)
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2]...the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so...,+,-,+,-,+,+,-,+,-,+,...hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32-hcoeff[1]-hcoeff[2]-...a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2}an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||.........intra?||||:Block01:yes no||||:Block02:.................||||:Block03::y DC::ref index:||||:Block04::cb DC::motion x:||||.........:cr DC::motion y:||||.................|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------------------------------|||Y subbands||Cb subbands||Cr subbands||||------||------||------|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||------||------||------||||------||------||------|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||------||------||------||||------||------||------|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||------||------||------||||------||------||------|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------------------------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction------------|\Dequantization-------------------\||Reference frames|\IDWT|--------------|Motion\|||Frame 0||Frame 1||Compensation.OBMC v-------|--------------|--------------.\------> Frame n output Frame Frame<----------------------------------/|...|-------------------Range Coder:============Binary Range Coder:-------------------The implemented range coder is an adapted version based upon"Range encoding: an algorithm for removing redundancy from a digitised message."by G.N.N.Martin.The symbols encoded by the Snow range coder are bits(0|1).The associated probabilities are not fix but change depending on the symbol mix seen so far.bit seen|new state---------+-----------------------------------------------0|256-state_transition_table[256-old_state];1|state_transition_table[old_state];state_transition_table={0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:-------------------------FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1.the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff)*mv_scale Intra DC Prediction block[y][x] dc[1]
Definition: snow.txt:400
static void vp3_idct_dc_add_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:364
void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags)
Definition: vp3dsp_init.c:46
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
static av_always_inline void idct10(uint8_t *dst, ptrdiff_t stride, int16_t *input, int type)
Definition: vp3dsp.c:198
#define AV_RN32(p)
Definition: intreadwrite.h:364
#define flags(name, subs,...)
Definition: cbs_av1.c:561
#define xC3S5
Definition: vp3dsp.c:39
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
common internal and external API header
#define G
Definition: huffyuvdsp.h:33
D(D(float, sse)
Definition: rematrix_init.c:28
void ff_vp3dsp_set_bounding_values(int *bounding_values_array, int filter_limit)
Definition: vp3dsp.c:473
av_cold void ff_vp3dsp_init_ppc(VP3DSPContext *c, int flags)
static av_always_inline void idct(uint8_t *dst, ptrdiff_t stride, int16_t *input, int type)
Definition: vp3dsp.c:47
#define F(x)
#define H
Definition: pixlet.c:39
#define av_always_inline
Definition: attributes.h:39
#define IdctAdjustBeforeShift
Definition: vp3dsp.c:36
void(* idct_put)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.h:41
#define stride
av_cold void ff_vp3dsp_init(VP3DSPContext *c, int flags)
Definition: vp3dsp.c:445
#define xC5S3
Definition: vp3dsp.c:41