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 <string.h>
28 
29 #include "config.h"
30 #include "libavutil/attributes.h"
31 #include "libavutil/common.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/avassert.h"
35 
36 #include "rnd_avg.h"
37 #include "vp3dsp.h"
38 
39 #define IdctAdjustBeforeShift 8
40 #define xC1S7 64277
41 #define xC2S6 60547
42 #define xC3S5 54491
43 #define xC4S4 46341
44 #define xC5S3 36410
45 #define xC6S2 25080
46 #define xC7S1 12785
47 
48 #define M(a, b) ((int)((SUINT)(a) * (b)) >> 16)
49 
50 static av_always_inline void idct(uint8_t *dst, ptrdiff_t stride,
51  int16_t *input, int type)
52 {
53  int16_t *ip = input;
54 
55  int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
56  int Ed, Gd, Add, Bdd, Fd, Hd;
57 
58  int i;
59 
60  /* Inverse DCT on the rows now */
61  for (i = 0; i < 8; i++) {
62  /* Check for non-zero values */
63  if (ip[0 * 8] | ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
64  ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8]) {
65  A = M(xC1S7, ip[1 * 8]) + M(xC7S1, ip[7 * 8]);
66  B = M(xC7S1, ip[1 * 8]) - M(xC1S7, ip[7 * 8]);
67  C = M(xC3S5, ip[3 * 8]) + M(xC5S3, ip[5 * 8]);
68  D = M(xC3S5, ip[5 * 8]) - M(xC5S3, ip[3 * 8]);
69 
70  Ad = M(xC4S4, (A - C));
71  Bd = M(xC4S4, (B - D));
72 
73  Cd = A + C;
74  Dd = B + D;
75 
76  E = M(xC4S4, (ip[0 * 8] + ip[4 * 8]));
77  F = M(xC4S4, (ip[0 * 8] - ip[4 * 8]));
78 
79  G = M(xC2S6, ip[2 * 8]) + M(xC6S2, ip[6 * 8]);
80  H = M(xC6S2, ip[2 * 8]) - M(xC2S6, ip[6 * 8]);
81 
82  Ed = E - G;
83  Gd = E + G;
84 
85  Add = F + Ad;
86  Bdd = Bd - H;
87 
88  Fd = F - Ad;
89  Hd = Bd + H;
90 
91  /* Final sequence of operations over-write original inputs. */
92  ip[0 * 8] = Gd + Cd;
93  ip[7 * 8] = Gd - Cd;
94 
95  ip[1 * 8] = Add + Hd;
96  ip[2 * 8] = Add - Hd;
97 
98  ip[3 * 8] = Ed + Dd;
99  ip[4 * 8] = Ed - Dd;
100 
101  ip[5 * 8] = Fd + Bdd;
102  ip[6 * 8] = Fd - Bdd;
103  }
104 
105  ip += 1; /* next row */
106  }
107 
108  ip = input;
109 
110  for (i = 0; i < 8; i++) {
111  /* Check for non-zero values (bitwise or faster than ||) */
112  if (ip[1] | ip[2] | ip[3] |
113  ip[4] | ip[5] | ip[6] | ip[7]) {
114  A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);
115  B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);
116  C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);
117  D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);
118 
119  Ad = M(xC4S4, (A - C));
120  Bd = M(xC4S4, (B - D));
121 
122  Cd = A + C;
123  Dd = B + D;
124 
125  E = M(xC4S4, (ip[0] + ip[4])) + 8;
126  F = M(xC4S4, (ip[0] - ip[4])) + 8;
127 
128  if (type == 1) { // HACK
129  E += 16 * 128;
130  F += 16 * 128;
131  }
132 
133  G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);
134  H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);
135 
136  Ed = E - G;
137  Gd = E + G;
138 
139  Add = F + Ad;
140  Bdd = Bd - H;
141 
142  Fd = F - Ad;
143  Hd = Bd + H;
144 
145  /* Final sequence of operations over-write original inputs. */
146  if (type == 1) {
147  dst[0 * stride] = av_clip_uint8((Gd + Cd) >> 4);
148  dst[7 * stride] = av_clip_uint8((Gd - Cd) >> 4);
149 
150  dst[1 * stride] = av_clip_uint8((Add + Hd) >> 4);
151  dst[2 * stride] = av_clip_uint8((Add - Hd) >> 4);
152 
153  dst[3 * stride] = av_clip_uint8((Ed + Dd) >> 4);
154  dst[4 * stride] = av_clip_uint8((Ed - Dd) >> 4);
155 
156  dst[5 * stride] = av_clip_uint8((Fd + Bdd) >> 4);
157  dst[6 * stride] = av_clip_uint8((Fd - Bdd) >> 4);
158  } else {
159  dst[0 * stride] = av_clip_uint8(dst[0 * stride] + ((Gd + Cd) >> 4));
160  dst[7 * stride] = av_clip_uint8(dst[7 * stride] + ((Gd - Cd) >> 4));
161 
162  dst[1 * stride] = av_clip_uint8(dst[1 * stride] + ((Add + Hd) >> 4));
163  dst[2 * stride] = av_clip_uint8(dst[2 * stride] + ((Add - Hd) >> 4));
164 
165  dst[3 * stride] = av_clip_uint8(dst[3 * stride] + ((Ed + Dd) >> 4));
166  dst[4 * stride] = av_clip_uint8(dst[4 * stride] + ((Ed - Dd) >> 4));
167 
168  dst[5 * stride] = av_clip_uint8(dst[5 * stride] + ((Fd + Bdd) >> 4));
169  dst[6 * stride] = av_clip_uint8(dst[6 * stride] + ((Fd - Bdd) >> 4));
170  }
171  } else {
172  if (type == 1) {
173  dst[0*stride] =
174  dst[1*stride] =
175  dst[2*stride] =
176  dst[3*stride] =
177  dst[4*stride] =
178  dst[5*stride] =
179  dst[6*stride] =
180  dst[7*stride] = av_clip_uint8(128 + ((xC4S4 * ip[0] + (IdctAdjustBeforeShift << 16)) >> 20));
181  } else {
182  if (ip[0]) {
183  int v = (xC4S4 * ip[0] + (IdctAdjustBeforeShift << 16)) >> 20;
184  dst[0 * stride] = av_clip_uint8(dst[0 * stride] + v);
185  dst[1 * stride] = av_clip_uint8(dst[1 * stride] + v);
186  dst[2 * stride] = av_clip_uint8(dst[2 * stride] + v);
187  dst[3 * stride] = av_clip_uint8(dst[3 * stride] + v);
188  dst[4 * stride] = av_clip_uint8(dst[4 * stride] + v);
189  dst[5 * stride] = av_clip_uint8(dst[5 * stride] + v);
190  dst[6 * stride] = av_clip_uint8(dst[6 * stride] + v);
191  dst[7 * stride] = av_clip_uint8(dst[7 * stride] + v);
192  }
193  }
194  }
195 
196  ip += 8; /* next column */
197  dst++;
198  }
199 }
200 
201 static av_always_inline void idct10(uint8_t *dst, ptrdiff_t stride,
202  int16_t *input, int type)
203 {
204  int16_t *ip = input;
205 
206  int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
207  int Ed, Gd, Add, Bdd, Fd, Hd;
208 
209  int i;
210 
211  /* Inverse DCT on the rows now */
212  for (i = 0; i < 4; i++) {
213  /* Check for non-zero values */
214  if (ip[0 * 8] | ip[1 * 8] | ip[2 * 8] | ip[3 * 8]) {
215  A = M(xC1S7, ip[1 * 8]);
216  B = M(xC7S1, ip[1 * 8]);
217  C = M(xC3S5, ip[3 * 8]);
218  D = -M(xC5S3, ip[3 * 8]);
219 
220  Ad = M(xC4S4, (A - C));
221  Bd = M(xC4S4, (B - D));
222 
223  Cd = A + C;
224  Dd = B + D;
225 
226  E = M(xC4S4, ip[0 * 8]);
227  F = E;
228 
229  G = M(xC2S6, ip[2 * 8]);
230  H = M(xC6S2, ip[2 * 8]);
231 
232  Ed = E - G;
233  Gd = E + G;
234 
235  Add = F + Ad;
236  Bdd = Bd - H;
237 
238  Fd = F - Ad;
239  Hd = Bd + H;
240 
241  /* Final sequence of operations over-write original inputs */
242  ip[0 * 8] = Gd + Cd;
243  ip[7 * 8] = Gd - Cd;
244 
245  ip[1 * 8] = Add + Hd;
246  ip[2 * 8] = Add - Hd;
247 
248  ip[3 * 8] = Ed + Dd;
249  ip[4 * 8] = Ed - Dd;
250 
251  ip[5 * 8] = Fd + Bdd;
252  ip[6 * 8] = Fd - Bdd;
253 
254  }
255 
256  ip += 1;
257  }
258 
259  ip = input;
260 
261  for (i = 0; i < 8; i++) {
262  /* Check for non-zero values (bitwise or faster than ||) */
263  if (ip[0] | ip[1] | ip[2] | ip[3]) {
264  A = M(xC1S7, ip[1]);
265  B = M(xC7S1, ip[1]);
266  C = M(xC3S5, ip[3]);
267  D = -M(xC5S3, ip[3]);
268 
269  Ad = M(xC4S4, (A - C));
270  Bd = M(xC4S4, (B - D));
271 
272  Cd = A + C;
273  Dd = B + D;
274 
275  E = M(xC4S4, ip[0]);
276  if (type == 1)
277  E += 16 * 128;
278  F = E;
279 
280  G = M(xC2S6, ip[2]);
281  H = M(xC6S2, ip[2]);
282 
283  Ed = E - G;
284  Gd = E + G;
285 
286  Add = F + Ad;
287  Bdd = Bd - H;
288 
289  Fd = F - Ad;
290  Hd = Bd + H;
291 
292  Gd += 8;
293  Add += 8;
294  Ed += 8;
295  Fd += 8;
296 
297  /* Final sequence of operations over-write original inputs. */
298  if (type == 1) {
299  dst[0 * stride] = av_clip_uint8((Gd + Cd) >> 4);
300  dst[7 * stride] = av_clip_uint8((Gd - Cd) >> 4);
301 
302  dst[1 * stride] = av_clip_uint8((Add + Hd) >> 4);
303  dst[2 * stride] = av_clip_uint8((Add - Hd) >> 4);
304 
305  dst[3 * stride] = av_clip_uint8((Ed + Dd) >> 4);
306  dst[4 * stride] = av_clip_uint8((Ed - Dd) >> 4);
307 
308  dst[5 * stride] = av_clip_uint8((Fd + Bdd) >> 4);
309  dst[6 * stride] = av_clip_uint8((Fd - Bdd) >> 4);
310  } else {
311  dst[0 * stride] = av_clip_uint8(dst[0 * stride] + ((Gd + Cd) >> 4));
312  dst[7 * stride] = av_clip_uint8(dst[7 * stride] + ((Gd - Cd) >> 4));
313 
314  dst[1 * stride] = av_clip_uint8(dst[1 * stride] + ((Add + Hd) >> 4));
315  dst[2 * stride] = av_clip_uint8(dst[2 * stride] + ((Add - Hd) >> 4));
316 
317  dst[3 * stride] = av_clip_uint8(dst[3 * stride] + ((Ed + Dd) >> 4));
318  dst[4 * stride] = av_clip_uint8(dst[4 * stride] + ((Ed - Dd) >> 4));
319 
320  dst[5 * stride] = av_clip_uint8(dst[5 * stride] + ((Fd + Bdd) >> 4));
321  dst[6 * stride] = av_clip_uint8(dst[6 * stride] + ((Fd - Bdd) >> 4));
322  }
323  } else {
324  if (type == 1) {
325  dst[0*stride] =
326  dst[1*stride] =
327  dst[2*stride] =
328  dst[3*stride] =
329  dst[4*stride] =
330  dst[5*stride] =
331  dst[6*stride] =
332  dst[7*stride] = 128;
333  }
334  }
335 
336  ip += 8;
337  dst++;
338  }
339 }
340 
341 void ff_vp3dsp_idct10_put(uint8_t *dest, ptrdiff_t stride, int16_t *block)
342 {
343  idct10(dest, stride, block, 1);
344  memset(block, 0, sizeof(*block) * 64);
345 }
346 
347 void ff_vp3dsp_idct10_add(uint8_t *dest, ptrdiff_t stride, int16_t *block)
348 {
349  idct10(dest, stride, block, 2);
350  memset(block, 0, sizeof(*block) * 64);
351 }
352 
353 static void vp3_idct_put_c(uint8_t *dest /* align 8 */, ptrdiff_t stride,
354  int16_t *block /* align 16 */)
355 {
356  idct(dest, stride, block, 1);
357  memset(block, 0, sizeof(*block) * 64);
358 }
359 
360 static void vp3_idct_add_c(uint8_t *dest /* align 8 */, ptrdiff_t stride,
361  int16_t *block /* align 16 */)
362 {
363  idct(dest, stride, block, 2);
364  memset(block, 0, sizeof(*block) * 64);
365 }
366 
367 static void vp3_idct_dc_add_c(uint8_t *dest /* align 8 */, ptrdiff_t stride,
368  int16_t *block /* align 16 */)
369 {
370  int i, dc = (block[0] + 15) >> 5;
371 
372  for (i = 0; i < 8; i++) {
373  dest[0] = av_clip_uint8(dest[0] + dc);
374  dest[1] = av_clip_uint8(dest[1] + dc);
375  dest[2] = av_clip_uint8(dest[2] + dc);
376  dest[3] = av_clip_uint8(dest[3] + dc);
377  dest[4] = av_clip_uint8(dest[4] + dc);
378  dest[5] = av_clip_uint8(dest[5] + dc);
379  dest[6] = av_clip_uint8(dest[6] + dc);
380  dest[7] = av_clip_uint8(dest[7] + dc);
381  dest += stride;
382  }
383  block[0] = 0;
384 }
385 
386 static av_always_inline void vp3_v_loop_filter_c(uint8_t *first_pixel, ptrdiff_t stride,
387  int *bounding_values, int count)
388 {
389  unsigned char *end;
390  int filter_value;
391  const ptrdiff_t nstride = -stride;
392 
393  for (end = first_pixel + count; first_pixel < end; first_pixel++) {
394  filter_value = (first_pixel[2 * nstride] - first_pixel[stride]) +
395  (first_pixel[0] - first_pixel[nstride]) * 3;
396  filter_value = bounding_values[(filter_value + 4) >> 3];
397 
398  first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value);
399  first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value);
400  }
401 }
402 
403 static av_always_inline void vp3_h_loop_filter_c(uint8_t *first_pixel, ptrdiff_t stride,
404  int *bounding_values, int count)
405 {
406  unsigned char *end;
407  int filter_value;
408 
409  for (end = first_pixel + count * stride; first_pixel != end; first_pixel += stride) {
410  filter_value = (first_pixel[-2] - first_pixel[1]) +
411  (first_pixel[ 0] - first_pixel[-1]) * 3;
412  filter_value = bounding_values[(filter_value + 4) >> 3];
413 
414  first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value);
415  first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value);
416  }
417 }
418 
419 #define LOOP_FILTER(prefix, suffix, dim, count) \
420 void prefix##_##dim##_loop_filter_##count##suffix(uint8_t *first_pixel, ptrdiff_t stride, \
421  int *bounding_values) \
422 { \
423  vp3_##dim##_loop_filter_c(first_pixel, stride, bounding_values, count); \
424 }
425 
426 static LOOP_FILTER(vp3,_c, v, 8)
427 static LOOP_FILTER(vp3,_c, h, 8)
428 LOOP_FILTER(ff_vp3dsp, , v, 12)
429 LOOP_FILTER(ff_vp3dsp, , h, 12)
430 
431 static void put_no_rnd_pixels_l2(uint8_t *dst, const uint8_t *src1,
432  const uint8_t *src2, ptrdiff_t stride, int h)
433 {
434  int i;
435 
436  for (i = 0; i < h; i++) {
437  uint32_t a, b;
438 
439  a = AV_RN32(&src1[i * stride]);
440  b = AV_RN32(&src2[i * stride]);
441  AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
442  a = AV_RN32(&src1[i * stride + 4]);
443  b = AV_RN32(&src2[i * stride + 4]);
444  AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
445  }
446 }
447 
449 {
450  c->put_no_rnd_pixels_l2 = put_no_rnd_pixels_l2;
451 
452  c->idct_put = vp3_idct_put_c;
453  c->idct_add = vp3_idct_add_c;
454  c->idct_dc_add = vp3_idct_dc_add_c;
455  c->v_loop_filter = c->v_loop_filter_unaligned = vp3_v_loop_filter_8_c;
456  c->h_loop_filter = c->h_loop_filter_unaligned = vp3_h_loop_filter_8_c;
457 
458  if (ARCH_ARM)
460  if (ARCH_PPC)
462  if (ARCH_X86)
464  if (ARCH_MIPS)
466 }
467 
468 /*
469  * This function initializes the loop filter boundary limits if the frame's
470  * quality index is different from the previous frame's.
471  *
472  * where sizeof(bounding_values_array) is 256 * sizeof(int)
473  *
474  * The filter_limit_values may not be larger than 127.
475  */
476 void ff_vp3dsp_set_bounding_values(int * bounding_values_array, int filter_limit)
477 {
478  int *bounding_values = bounding_values_array + 127;
479  int x;
480  int value;
481 
482  av_assert0(filter_limit < 128U);
483 
484  /* set up the bounding values */
485  memset(bounding_values_array, 0, 256 * sizeof(int));
486  for (x = 0; x < filter_limit; x++) {
487  bounding_values[-x] = -x;
488  bounding_values[x] = x;
489  }
490  for (x = value = filter_limit; x < 128 && value; x++, value--) {
491  bounding_values[ x] = value;
492  bounding_values[-x] = -value;
493  }
494  if (value)
495  bounding_values[128] = value;
496  bounding_values[129] = bounding_values[130] = filter_limit * 0x02020202U;
497 }
M
#define M(a, b)
Definition: vp3dsp.c:48
stride
int stride
Definition: mace.c:144
VP3DSPContext
Definition: vp3dsp.h:25
no_rnd_avg32
static uint32_t no_rnd_avg32(uint32_t a, uint32_t b)
Definition: rnd_avg.h:36
ff_vp3dsp_idct10_put
void ff_vp3dsp_idct10_put(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:341
ff_vp3dsp_idct10_add
void ff_vp3dsp_idct10_add(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:347
vp3dsp.h
ff_vp3dsp_set_bounding_values
void ff_vp3dsp_set_bounding_values(int *bounding_values_array, int filter_limit)
Definition: vp3dsp.c:476
b
#define b
Definition: input.c:40
xC1S7
#define xC1S7
Definition: vp3dsp.c:40
F
#define F(x)
AV_WN32A
#define AV_WN32A(p, v)
Definition: intreadwrite.h:538
D
D(D(float, sse)
Definition: rematrix_init.c:29
A
#define A(x)
Definition: vp56_arith.h:28
vp3_h_loop_filter_c
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:403
U
#define U(x)
Definition: vp56_arith.h:37
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
C
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
Definition: writing_filters.txt:58
avassert.h
av_cold
#define av_cold
Definition: attributes.h:90
intreadwrite.h
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
E
#define E
Definition: avdct.c:32
vp3_idct_dc_add_c
static void vp3_idct_dc_add_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:367
xC7S1
#define xC7S1
Definition: vp3dsp.c:46
AV_RN32
#define AV_RN32(p)
Definition: intreadwrite.h:364
xC6S2
#define xC6S2
Definition: vp3dsp.c:45
xC2S6
#define xC2S6
Definition: vp3dsp.c:41
c
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
vp3_v_loop_filter_c
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:386
dc
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
filter_value
static int filter_value(int in, int rrp[8], int v[9])
Definition: gsmdec_template.c:72
ff_vp3dsp_init_ppc
av_cold void ff_vp3dsp_init_ppc(VP3DSPContext *c, int flags)
Definition: vp3dsp_altivec.c:195
a
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:41
H
#define H
Definition: pixlet.c:39
attributes.h
input
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
Definition: filter_design.txt:172
LOOP_FILTER
#define LOOP_FILTER(prefix, suffix, dim, count)
Definition: vp3dsp.c:419
xC3S5
#define xC3S5
Definition: vp3dsp.c:42
src1
#define src1
Definition: h264pred.c:140
vp3_idct_put_c
static void vp3_idct_put_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:353
ff_vp3dsp_init
av_cold void ff_vp3dsp_init(VP3DSPContext *c, int flags)
Definition: vp3dsp.c:448
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
internal.h
idct
static av_always_inline void idct(uint8_t *dst, ptrdiff_t stride, int16_t *input, int type)
Definition: vp3dsp.c:50
common.h
vp3_idct_add_c
static void vp3_idct_add_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vp3dsp.c:360
av_always_inline
#define av_always_inline
Definition: attributes.h:49
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
ff_vp3dsp_init_x86
void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags)
Definition: vp3dsp_init.c:46
rnd_avg.h
G
#define G
Definition: huffyuvdsp.h:33
B
#define B
Definition: huffyuvdsp.h:32
xC5S3
#define xC5S3
Definition: vp3dsp.c:44
av_clip_uint8
#define av_clip_uint8
Definition: common.h:102
ff_vp3dsp_init_mips
av_cold void ff_vp3dsp_init_mips(VP3DSPContext *c, int flags)
Definition: vp3dsp_init_mips.c:29
IdctAdjustBeforeShift
#define IdctAdjustBeforeShift
Definition: vp3dsp.c:39
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
h
h
Definition: vp9dsp_template.c:2038
ff_vp3dsp_init_arm
av_cold void ff_vp3dsp_init_arm(VP3DSPContext *c, int flags)
Definition: vp3dsp_init_arm.c:33
idct10
static av_always_inline void idct10(uint8_t *dst, ptrdiff_t stride, int16_t *input, int type)
Definition: vp3dsp.c:201
xC4S4
#define xC4S4
Definition: vp3dsp.c:43