FFmpeg
vc1dsp.c
Go to the documentation of this file.
1 /*
2  * VC-1 and WMV3 decoder - DSP functions
3  * Copyright (c) 2006 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * VC-1 and WMV3 decoder
25  */
26 
27 #include "config_components.h"
28 
29 #include "libavutil/avassert.h"
30 #include "libavutil/common.h"
31 #include "libavutil/intreadwrite.h"
32 #include "h264chroma.h"
33 #include "qpeldsp.h"
34 #include "rnd_avg.h"
35 #include "vc1dsp.h"
36 #include "startcode.h"
37 
38 /* Apply overlap transform to horizontal edge */
39 static void vc1_v_overlap_c(uint8_t *src, ptrdiff_t stride)
40 {
41  int i;
42  int a, b, c, d;
43  int d1, d2;
44  int rnd = 1;
45  for (i = 0; i < 8; i++) {
46  a = src[-2 * stride];
47  b = src[-stride];
48  c = src[0];
49  d = src[stride];
50  d1 = (a - d + 3 + rnd) >> 3;
51  d2 = (a - d + b - c + 4 - rnd) >> 3;
52 
53  src[-2 * stride] = a - d1;
54  src[-stride] = av_clip_uint8(b - d2);
55  src[0] = av_clip_uint8(c + d2);
56  src[stride] = d + d1;
57  src++;
58  rnd = !rnd;
59  }
60 }
61 
62 /* Apply overlap transform to vertical edge */
63 static void vc1_h_overlap_c(uint8_t *src, ptrdiff_t stride)
64 {
65  int i;
66  int a, b, c, d;
67  int d1, d2;
68  int rnd = 1;
69  for (i = 0; i < 8; i++) {
70  a = src[-2];
71  b = src[-1];
72  c = src[0];
73  d = src[1];
74  d1 = (a - d + 3 + rnd) >> 3;
75  d2 = (a - d + b - c + 4 - rnd) >> 3;
76 
77  src[-2] = a - d1;
78  src[-1] = av_clip_uint8(b - d2);
79  src[0] = av_clip_uint8(c + d2);
80  src[1] = d + d1;
81  src += stride;
82  rnd = !rnd;
83  }
84 }
85 
86 static void vc1_v_s_overlap_c(int16_t *top, int16_t *bottom)
87 {
88  int i;
89  int a, b, c, d;
90  int d1, d2;
91  int rnd1 = 4, rnd2 = 3;
92  for (i = 0; i < 8; i++) {
93  a = top[48];
94  b = top[56];
95  c = bottom[0];
96  d = bottom[8];
97  d1 = a - d;
98  d2 = a - d + b - c;
99 
100  top[48] = ((a * 8) - d1 + rnd1) >> 3;
101  top[56] = ((b * 8) - d2 + rnd2) >> 3;
102  bottom[0] = ((c * 8) + d2 + rnd1) >> 3;
103  bottom[8] = ((d * 8) + d1 + rnd2) >> 3;
104 
105  bottom++;
106  top++;
107  rnd2 = 7 - rnd2;
108  rnd1 = 7 - rnd1;
109  }
110 }
111 
112 static void vc1_h_s_overlap_c(int16_t *left, int16_t *right, ptrdiff_t left_stride, ptrdiff_t right_stride, int flags)
113 {
114  int i;
115  int a, b, c, d;
116  int d1, d2;
117  int rnd1 = flags & 2 ? 3 : 4;
118  int rnd2 = 7 - rnd1;
119  for (i = 0; i < 8; i++) {
120  a = left[6];
121  b = left[7];
122  c = right[0];
123  d = right[1];
124  d1 = a - d;
125  d2 = a - d + b - c;
126 
127  left[6] = ((a * 8) - d1 + rnd1) >> 3;
128  left[7] = ((b * 8) - d2 + rnd2) >> 3;
129  right[0] = ((c * 8) + d2 + rnd1) >> 3;
130  right[1] = ((d * 8) + d1 + rnd2) >> 3;
131 
132  right += right_stride;
133  left += left_stride;
134  if (flags & 1) {
135  rnd2 = 7 - rnd2;
136  rnd1 = 7 - rnd1;
137  }
138  }
139 }
140 
141 /**
142  * VC-1 in-loop deblocking filter for one line
143  * @param src source block type
144  * @param stride block stride
145  * @param pq block quantizer
146  * @return whether other 3 pairs should be filtered or not
147  * @see 8.6
148  */
149 static av_always_inline int vc1_filter_line(uint8_t *src, ptrdiff_t stride, int pq)
150 {
151  int a0 = (2 * (src[-2 * stride] - src[1 * stride]) -
152  5 * (src[-1 * stride] - src[0 * stride]) + 4) >> 3;
153  int a0_sign = a0 >> 31; /* Store sign */
154 
155  a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */
156  if (a0 < pq) {
157  int a1 = FFABS((2 * (src[-4 * stride] - src[-1 * stride]) -
158  5 * (src[-3 * stride] - src[-2 * stride]) + 4) >> 3);
159  int a2 = FFABS((2 * (src[ 0 * stride] - src[ 3 * stride]) -
160  5 * (src[ 1 * stride] - src[ 2 * stride]) + 4) >> 3);
161  if (a1 < a0 || a2 < a0) {
162  int clip = src[-1 * stride] - src[0 * stride];
163  int clip_sign = clip >> 31;
164 
165  clip = ((clip ^ clip_sign) - clip_sign) >> 1;
166  if (clip) {
167  int a3 = FFMIN(a1, a2);
168  int d = 5 * (a3 - a0);
169  int d_sign = (d >> 31);
170 
171  d = ((d ^ d_sign) - d_sign) >> 3;
172  d_sign ^= a0_sign;
173 
174  if (d_sign ^ clip_sign)
175  d = 0;
176  else {
177  d = FFMIN(d, clip);
178  d = (d ^ d_sign) - d_sign; /* Restore sign */
179  src[-1 * stride] = av_clip_uint8(src[-1 * stride] - d);
180  src[ 0 * stride] = av_clip_uint8(src[ 0 * stride] + d);
181  }
182  return 1;
183  }
184  }
185  }
186  return 0;
187 }
188 
189 /**
190  * VC-1 in-loop deblocking filter
191  * @param src source block type
192  * @param step distance between horizontally adjacent elements
193  * @param stride distance between vertically adjacent elements
194  * @param len edge length to filter (4 or 8 pixels)
195  * @param pq block quantizer
196  * @see 8.6
197  */
198 static inline void vc1_loop_filter(uint8_t *src, int step, ptrdiff_t stride,
199  int len, int pq)
200 {
201  int i;
202  int filt3;
203 
204  for (i = 0; i < len; i += 4) {
205  filt3 = vc1_filter_line(src + 2 * step, stride, pq);
206  if (filt3) {
207  vc1_filter_line(src + 0 * step, stride, pq);
208  vc1_filter_line(src + 1 * step, stride, pq);
209  vc1_filter_line(src + 3 * step, stride, pq);
210  }
211  src += step * 4;
212  }
213 }
214 
215 static void vc1_v_loop_filter4_c(uint8_t *src, ptrdiff_t stride, int pq)
216 {
217  vc1_loop_filter(src, 1, stride, 4, pq);
218 }
219 
220 static void vc1_h_loop_filter4_c(uint8_t *src, ptrdiff_t stride, int pq)
221 {
222  vc1_loop_filter(src, stride, 1, 4, pq);
223 }
224 
225 static void vc1_v_loop_filter8_c(uint8_t *src, ptrdiff_t stride, int pq)
226 {
227  vc1_loop_filter(src, 1, stride, 8, pq);
228 }
229 
230 static void vc1_h_loop_filter8_c(uint8_t *src, ptrdiff_t stride, int pq)
231 {
232  vc1_loop_filter(src, stride, 1, 8, pq);
233 }
234 
235 static void vc1_v_loop_filter16_c(uint8_t *src, ptrdiff_t stride, int pq)
236 {
237  vc1_loop_filter(src, 1, stride, 16, pq);
238 }
239 
240 static void vc1_h_loop_filter16_c(uint8_t *src, ptrdiff_t stride, int pq)
241 {
242  vc1_loop_filter(src, stride, 1, 16, pq);
243 }
244 
245 /* Do inverse transform on 8x8 block */
246 static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
247 {
248  int i;
249  int dc = block[0];
250 
251  dc = (3 * dc + 1) >> 1;
252  dc = (3 * dc + 16) >> 5;
253 
254  for (i = 0; i < 8; i++) {
255  dest[0] = av_clip_uint8(dest[0] + dc);
256  dest[1] = av_clip_uint8(dest[1] + dc);
257  dest[2] = av_clip_uint8(dest[2] + dc);
258  dest[3] = av_clip_uint8(dest[3] + dc);
259  dest[4] = av_clip_uint8(dest[4] + dc);
260  dest[5] = av_clip_uint8(dest[5] + dc);
261  dest[6] = av_clip_uint8(dest[6] + dc);
262  dest[7] = av_clip_uint8(dest[7] + dc);
263  dest += stride;
264  }
265 }
266 
267 static void vc1_inv_trans_8x8_c(int16_t block[64])
268 {
269  int i;
270  register int t1, t2, t3, t4, t5, t6, t7, t8;
271  int16_t *src, *dst, temp[64];
272 
273  src = block;
274  dst = temp;
275  for (i = 0; i < 8; i++) {
276  t1 = 12 * (src[ 0] + src[32]) + 4;
277  t2 = 12 * (src[ 0] - src[32]) + 4;
278  t3 = 16 * src[16] + 6 * src[48];
279  t4 = 6 * src[16] - 16 * src[48];
280 
281  t5 = t1 + t3;
282  t6 = t2 + t4;
283  t7 = t2 - t4;
284  t8 = t1 - t3;
285 
286  t1 = 16 * src[ 8] + 15 * src[24] + 9 * src[40] + 4 * src[56];
287  t2 = 15 * src[ 8] - 4 * src[24] - 16 * src[40] - 9 * src[56];
288  t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56];
289  t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56];
290 
291  dst[0] = (t5 + t1) >> 3;
292  dst[1] = (t6 + t2) >> 3;
293  dst[2] = (t7 + t3) >> 3;
294  dst[3] = (t8 + t4) >> 3;
295  dst[4] = (t8 - t4) >> 3;
296  dst[5] = (t7 - t3) >> 3;
297  dst[6] = (t6 - t2) >> 3;
298  dst[7] = (t5 - t1) >> 3;
299 
300  src += 1;
301  dst += 8;
302  }
303 
304  src = temp;
305  dst = block;
306  for (i = 0; i < 8; i++) {
307  t1 = 12 * (src[ 0] + src[32]) + 64;
308  t2 = 12 * (src[ 0] - src[32]) + 64;
309  t3 = 16 * src[16] + 6 * src[48];
310  t4 = 6 * src[16] - 16 * src[48];
311 
312  t5 = t1 + t3;
313  t6 = t2 + t4;
314  t7 = t2 - t4;
315  t8 = t1 - t3;
316 
317  t1 = 16 * src[ 8] + 15 * src[24] + 9 * src[40] + 4 * src[56];
318  t2 = 15 * src[ 8] - 4 * src[24] - 16 * src[40] - 9 * src[56];
319  t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56];
320  t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56];
321 
322  dst[ 0] = (t5 + t1) >> 7;
323  dst[ 8] = (t6 + t2) >> 7;
324  dst[16] = (t7 + t3) >> 7;
325  dst[24] = (t8 + t4) >> 7;
326  dst[32] = (t8 - t4 + 1) >> 7;
327  dst[40] = (t7 - t3 + 1) >> 7;
328  dst[48] = (t6 - t2 + 1) >> 7;
329  dst[56] = (t5 - t1 + 1) >> 7;
330 
331  src++;
332  dst++;
333  }
334 }
335 
336 /* Do inverse transform on 8x4 part of block */
337 static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
338 {
339  int i;
340  int dc = block[0];
341 
342  dc = (3 * dc + 1) >> 1;
343  dc = (17 * dc + 64) >> 7;
344 
345  for (i = 0; i < 4; i++) {
346  dest[0] = av_clip_uint8(dest[0] + dc);
347  dest[1] = av_clip_uint8(dest[1] + dc);
348  dest[2] = av_clip_uint8(dest[2] + dc);
349  dest[3] = av_clip_uint8(dest[3] + dc);
350  dest[4] = av_clip_uint8(dest[4] + dc);
351  dest[5] = av_clip_uint8(dest[5] + dc);
352  dest[6] = av_clip_uint8(dest[6] + dc);
353  dest[7] = av_clip_uint8(dest[7] + dc);
354  dest += stride;
355  }
356 }
357 
358 static void vc1_inv_trans_8x4_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
359 {
360  int i;
361  register int t1, t2, t3, t4, t5, t6, t7, t8;
362  int16_t *src, *dst;
363 
364  src = block;
365  dst = block;
366 
367  for (i = 0; i < 4; i++) {
368  t1 = 12 * (src[0] + src[4]) + 4;
369  t2 = 12 * (src[0] - src[4]) + 4;
370  t3 = 16 * src[2] + 6 * src[6];
371  t4 = 6 * src[2] - 16 * src[6];
372 
373  t5 = t1 + t3;
374  t6 = t2 + t4;
375  t7 = t2 - t4;
376  t8 = t1 - t3;
377 
378  t1 = 16 * src[1] + 15 * src[3] + 9 * src[5] + 4 * src[7];
379  t2 = 15 * src[1] - 4 * src[3] - 16 * src[5] - 9 * src[7];
380  t3 = 9 * src[1] - 16 * src[3] + 4 * src[5] + 15 * src[7];
381  t4 = 4 * src[1] - 9 * src[3] + 15 * src[5] - 16 * src[7];
382 
383  dst[0] = (t5 + t1) >> 3;
384  dst[1] = (t6 + t2) >> 3;
385  dst[2] = (t7 + t3) >> 3;
386  dst[3] = (t8 + t4) >> 3;
387  dst[4] = (t8 - t4) >> 3;
388  dst[5] = (t7 - t3) >> 3;
389  dst[6] = (t6 - t2) >> 3;
390  dst[7] = (t5 - t1) >> 3;
391 
392  src += 8;
393  dst += 8;
394  }
395 
396  src = block;
397  for (i = 0; i < 8; i++) {
398  t1 = 17 * (src[ 0] + src[16]) + 64;
399  t2 = 17 * (src[ 0] - src[16]) + 64;
400  t3 = 22 * src[ 8] + 10 * src[24];
401  t4 = 22 * src[24] - 10 * src[ 8];
402 
403  dest[0 * stride] = av_clip_uint8(dest[0 * stride] + ((t1 + t3) >> 7));
404  dest[1 * stride] = av_clip_uint8(dest[1 * stride] + ((t2 - t4) >> 7));
405  dest[2 * stride] = av_clip_uint8(dest[2 * stride] + ((t2 + t4) >> 7));
406  dest[3 * stride] = av_clip_uint8(dest[3 * stride] + ((t1 - t3) >> 7));
407 
408  src++;
409  dest++;
410  }
411 }
412 
413 /* Do inverse transform on 4x8 parts of block */
414 static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
415 {
416  int i;
417  int dc = block[0];
418 
419  dc = (17 * dc + 4) >> 3;
420  dc = (12 * dc + 64) >> 7;
421 
422  for (i = 0; i < 8; i++) {
423  dest[0] = av_clip_uint8(dest[0] + dc);
424  dest[1] = av_clip_uint8(dest[1] + dc);
425  dest[2] = av_clip_uint8(dest[2] + dc);
426  dest[3] = av_clip_uint8(dest[3] + dc);
427  dest += stride;
428  }
429 }
430 
431 static void vc1_inv_trans_4x8_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
432 {
433  int i;
434  register int t1, t2, t3, t4, t5, t6, t7, t8;
435  int16_t *src, *dst;
436 
437  src = block;
438  dst = block;
439 
440  for (i = 0; i < 8; i++) {
441  t1 = 17 * (src[0] + src[2]) + 4;
442  t2 = 17 * (src[0] - src[2]) + 4;
443  t3 = 22 * src[1] + 10 * src[3];
444  t4 = 22 * src[3] - 10 * src[1];
445 
446  dst[0] = (t1 + t3) >> 3;
447  dst[1] = (t2 - t4) >> 3;
448  dst[2] = (t2 + t4) >> 3;
449  dst[3] = (t1 - t3) >> 3;
450 
451  src += 8;
452  dst += 8;
453  }
454 
455  src = block;
456  for (i = 0; i < 4; i++) {
457  t1 = 12 * (src[ 0] + src[32]) + 64;
458  t2 = 12 * (src[ 0] - src[32]) + 64;
459  t3 = 16 * src[16] + 6 * src[48];
460  t4 = 6 * src[16] - 16 * src[48];
461 
462  t5 = t1 + t3;
463  t6 = t2 + t4;
464  t7 = t2 - t4;
465  t8 = t1 - t3;
466 
467  t1 = 16 * src[ 8] + 15 * src[24] + 9 * src[40] + 4 * src[56];
468  t2 = 15 * src[ 8] - 4 * src[24] - 16 * src[40] - 9 * src[56];
469  t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56];
470  t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56];
471 
472  dest[0 * stride] = av_clip_uint8(dest[0 * stride] + ((t5 + t1) >> 7));
473  dest[1 * stride] = av_clip_uint8(dest[1 * stride] + ((t6 + t2) >> 7));
474  dest[2 * stride] = av_clip_uint8(dest[2 * stride] + ((t7 + t3) >> 7));
475  dest[3 * stride] = av_clip_uint8(dest[3 * stride] + ((t8 + t4) >> 7));
476  dest[4 * stride] = av_clip_uint8(dest[4 * stride] + ((t8 - t4 + 1) >> 7));
477  dest[5 * stride] = av_clip_uint8(dest[5 * stride] + ((t7 - t3 + 1) >> 7));
478  dest[6 * stride] = av_clip_uint8(dest[6 * stride] + ((t6 - t2 + 1) >> 7));
479  dest[7 * stride] = av_clip_uint8(dest[7 * stride] + ((t5 - t1 + 1) >> 7));
480 
481  src++;
482  dest++;
483  }
484 }
485 
486 /* Do inverse transform on 4x4 part of block */
487 static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
488 {
489  int i;
490  int dc = block[0];
491 
492  dc = (17 * dc + 4) >> 3;
493  dc = (17 * dc + 64) >> 7;
494 
495  for (i = 0; i < 4; i++) {
496  dest[0] = av_clip_uint8(dest[0] + dc);
497  dest[1] = av_clip_uint8(dest[1] + dc);
498  dest[2] = av_clip_uint8(dest[2] + dc);
499  dest[3] = av_clip_uint8(dest[3] + dc);
500  dest += stride;
501  }
502 }
503 
504 static void vc1_inv_trans_4x4_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
505 {
506  int i;
507  register int t1, t2, t3, t4;
508  int16_t *src, *dst;
509 
510  src = block;
511  dst = block;
512  for (i = 0; i < 4; i++) {
513  t1 = 17 * (src[0] + src[2]) + 4;
514  t2 = 17 * (src[0] - src[2]) + 4;
515  t3 = 22 * src[1] + 10 * src[3];
516  t4 = 22 * src[3] - 10 * src[1];
517 
518  dst[0] = (t1 + t3) >> 3;
519  dst[1] = (t2 - t4) >> 3;
520  dst[2] = (t2 + t4) >> 3;
521  dst[3] = (t1 - t3) >> 3;
522 
523  src += 8;
524  dst += 8;
525  }
526 
527  src = block;
528  for (i = 0; i < 4; i++) {
529  t1 = 17 * (src[0] + src[16]) + 64;
530  t2 = 17 * (src[0] - src[16]) + 64;
531  t3 = 22 * src[8] + 10 * src[24];
532  t4 = 22 * src[24] - 10 * src[8];
533 
534  dest[0 * stride] = av_clip_uint8(dest[0 * stride] + ((t1 + t3) >> 7));
535  dest[1 * stride] = av_clip_uint8(dest[1 * stride] + ((t2 - t4) >> 7));
536  dest[2 * stride] = av_clip_uint8(dest[2 * stride] + ((t2 + t4) >> 7));
537  dest[3 * stride] = av_clip_uint8(dest[3 * stride] + ((t1 - t3) >> 7));
538 
539  src++;
540  dest++;
541  }
542 }
543 
544 /* motion compensation functions */
545 
546 /* Filter in case of 2 filters */
547 #define VC1_MSPEL_FILTER_16B(DIR, TYPE) \
548 static av_always_inline int vc1_mspel_ ## DIR ## _filter_16bits(const TYPE *src, \
549  int stride, \
550  int mode) \
551 { \
552  switch(mode) { \
553  case 0: /* no shift - should not occur */ \
554  return 0; \
555  case 1: /* 1/4 shift */ \
556  return -4 * src[-stride] + 53 * src[0] + \
557  18 * src[stride] - 3 * src[stride * 2]; \
558  case 2: /* 1/2 shift */ \
559  return -1 * src[-stride] + 9 * src[0] + \
560  9 * src[stride] - 1 * src[stride * 2]; \
561  case 3: /* 3/4 shift */ \
562  return -3 * src[-stride] + 18 * src[0] + \
563  53 * src[stride] - 4 * src[stride * 2]; \
564  } \
565  return 0; /* should not occur */ \
566 }
567 
568 VC1_MSPEL_FILTER_16B(ver, uint8_t)
569 VC1_MSPEL_FILTER_16B(hor, int16_t)
570 
571 /* Filter used to interpolate fractional pel values */
572 static av_always_inline int vc1_mspel_filter(const uint8_t *src, int stride,
573  int mode, int r)
574 {
575  switch (mode) {
576  case 0: // no shift
577  return src[0];
578  case 1: // 1/4 shift
579  return (-4 * src[-stride] + 53 * src[0] +
580  18 * src[stride] - 3 * src[stride * 2] + 32 - r) >> 6;
581  case 2: // 1/2 shift
582  return (-1 * src[-stride] + 9 * src[0] +
583  9 * src[stride] - 1 * src[stride * 2] + 8 - r) >> 4;
584  case 3: // 3/4 shift
585  return (-3 * src[-stride] + 18 * src[0] +
586  53 * src[stride] - 4 * src[stride * 2] + 32 - r) >> 6;
587  }
588  return 0; // should not occur
589 }
590 
591 /* Function used to do motion compensation with bicubic interpolation */
592 #define VC1_MSPEL_MC(OP, OP4, OPNAME) \
593 static av_always_inline void OPNAME ## vc1_mspel_mc(uint8_t *dst, \
594  const uint8_t *src, \
595  ptrdiff_t stride, \
596  int hmode, \
597  int vmode, \
598  int rnd) \
599 { \
600  int i, j; \
601  \
602  if (vmode) { /* Horizontal filter to apply */ \
603  int r; \
604  \
605  if (hmode) { /* Vertical filter to apply, output to tmp */ \
606  static const int shift_value[] = { 0, 5, 1, 5 }; \
607  int shift = (shift_value[hmode] + shift_value[vmode]) >> 1; \
608  int16_t tmp[11 * 8], *tptr = tmp; \
609  \
610  r = (1 << (shift - 1)) + rnd - 1; \
611  \
612  src -= 1; \
613  for (j = 0; j < 8; j++) { \
614  for (i = 0; i < 11; i++) \
615  tptr[i] = (vc1_mspel_ver_filter_16bits(src + i, stride, vmode) + r) >> shift; \
616  src += stride; \
617  tptr += 11; \
618  } \
619  \
620  r = 64 - rnd; \
621  tptr = tmp + 1; \
622  for (j = 0; j < 8; j++) { \
623  for (i = 0; i < 8; i++) \
624  OP(dst[i], (vc1_mspel_hor_filter_16bits(tptr + i, 1, hmode) + r) >> 7); \
625  dst += stride; \
626  tptr += 11; \
627  } \
628  \
629  return; \
630  } else { /* No horizontal filter, output 8 lines to dst */ \
631  r = 1 - rnd; \
632  \
633  for (j = 0; j < 8; j++) { \
634  for (i = 0; i < 8; i++) \
635  OP(dst[i], vc1_mspel_filter(src + i, stride, vmode, r)); \
636  src += stride; \
637  dst += stride; \
638  } \
639  return; \
640  } \
641  } \
642  \
643  /* Horizontal mode with no vertical mode */ \
644  for (j = 0; j < 8; j++) { \
645  for (i = 0; i < 8; i++) \
646  OP(dst[i], vc1_mspel_filter(src + i, 1, hmode, rnd)); \
647  dst += stride; \
648  src += stride; \
649  } \
650 }\
651 static av_always_inline void OPNAME ## vc1_mspel_mc_16(uint8_t *dst, \
652  const uint8_t *src, \
653  ptrdiff_t stride, \
654  int hmode, \
655  int vmode, \
656  int rnd) \
657 { \
658  int i, j; \
659  \
660  if (vmode) { /* Horizontal filter to apply */ \
661  int r; \
662  \
663  if (hmode) { /* Vertical filter to apply, output to tmp */ \
664  static const int shift_value[] = { 0, 5, 1, 5 }; \
665  int shift = (shift_value[hmode] + shift_value[vmode]) >> 1; \
666  int16_t tmp[19 * 16], *tptr = tmp; \
667  \
668  r = (1 << (shift - 1)) + rnd - 1; \
669  \
670  src -= 1; \
671  for (j = 0; j < 16; j++) { \
672  for (i = 0; i < 19; i++) \
673  tptr[i] = (vc1_mspel_ver_filter_16bits(src + i, stride, vmode) + r) >> shift; \
674  src += stride; \
675  tptr += 19; \
676  } \
677  \
678  r = 64 - rnd; \
679  tptr = tmp + 1; \
680  for (j = 0; j < 16; j++) { \
681  for (i = 0; i < 16; i++) \
682  OP(dst[i], (vc1_mspel_hor_filter_16bits(tptr + i, 1, hmode) + r) >> 7); \
683  dst += stride; \
684  tptr += 19; \
685  } \
686  \
687  return; \
688  } else { /* No horizontal filter, output 8 lines to dst */ \
689  r = 1 - rnd; \
690  \
691  for (j = 0; j < 16; j++) { \
692  for (i = 0; i < 16; i++) \
693  OP(dst[i], vc1_mspel_filter(src + i, stride, vmode, r)); \
694  src += stride; \
695  dst += stride; \
696  } \
697  return; \
698  } \
699  } \
700  \
701  /* Horizontal mode with no vertical mode */ \
702  for (j = 0; j < 16; j++) { \
703  for (i = 0; i < 16; i++) \
704  OP(dst[i], vc1_mspel_filter(src + i, 1, hmode, rnd)); \
705  dst += stride; \
706  src += stride; \
707  } \
708 }\
709 static void OPNAME ## pixels8x8_c(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int rnd){\
710  int i;\
711  for(i=0; i<8; i++){\
712  OP4(*(uint32_t*)(block ), AV_RN32(pixels ));\
713  OP4(*(uint32_t*)(block+4), AV_RN32(pixels+4));\
714  pixels+=line_size;\
715  block +=line_size;\
716  }\
717 }\
718 static void OPNAME ## pixels16x16_c(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int rnd){\
719  int i;\
720  for(i=0; i<16; i++){\
721  OP4(*(uint32_t*)(block ), AV_RN32(pixels ));\
722  OP4(*(uint32_t*)(block+ 4), AV_RN32(pixels+ 4));\
723  OP4(*(uint32_t*)(block+ 8), AV_RN32(pixels+ 8));\
724  OP4(*(uint32_t*)(block+12), AV_RN32(pixels+12));\
725  pixels+=line_size;\
726  block +=line_size;\
727  }\
728 }
729 
730 #define op_put(a, b) (a) = av_clip_uint8(b)
731 #define op_avg(a, b) (a) = ((a) + av_clip_uint8(b) + 1) >> 1
732 #define op4_avg(a, b) (a) = rnd_avg32(a, b)
733 #define op4_put(a, b) (a) = (b)
734 
737 
738 /* pixel functions - really are entry points to vc1_mspel_mc */
739 
740 #define PUT_VC1_MSPEL(a, b) \
741 static void put_vc1_mspel_mc ## a ## b ## _c(uint8_t *dst, \
742  const uint8_t *src, \
743  ptrdiff_t stride, int rnd) \
744 { \
745  put_vc1_mspel_mc(dst, src, stride, a, b, rnd); \
746 } \
747 static void avg_vc1_mspel_mc ## a ## b ## _c(uint8_t *dst, \
748  const uint8_t *src, \
749  ptrdiff_t stride, int rnd) \
750 { \
751  avg_vc1_mspel_mc(dst, src, stride, a, b, rnd); \
752 } \
753 static void put_vc1_mspel_mc ## a ## b ## _16_c(uint8_t *dst, \
754  const uint8_t *src, \
755  ptrdiff_t stride, int rnd) \
756 { \
757  put_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \
758 } \
759 static void avg_vc1_mspel_mc ## a ## b ## _16_c(uint8_t *dst, \
760  const uint8_t *src, \
761  ptrdiff_t stride, int rnd) \
762 { \
763  avg_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \
764 }
765 
766 PUT_VC1_MSPEL(1, 0)
767 PUT_VC1_MSPEL(2, 0)
768 PUT_VC1_MSPEL(3, 0)
769 
770 PUT_VC1_MSPEL(0, 1)
771 PUT_VC1_MSPEL(1, 1)
772 PUT_VC1_MSPEL(2, 1)
773 PUT_VC1_MSPEL(3, 1)
774 
775 PUT_VC1_MSPEL(0, 2)
776 PUT_VC1_MSPEL(1, 2)
777 PUT_VC1_MSPEL(2, 2)
778 PUT_VC1_MSPEL(3, 2)
779 
780 PUT_VC1_MSPEL(0, 3)
781 PUT_VC1_MSPEL(1, 3)
782 PUT_VC1_MSPEL(2, 3)
783 PUT_VC1_MSPEL(3, 3)
784 
785 #define chroma_mc(a) \
786  ((A * src[a] + B * src[a + 1] + \
787  C * src[stride + a] + D * src[stride + a + 1] + 32 - 4) >> 6)
788 static void put_no_rnd_vc1_chroma_mc8_c(uint8_t *dst /* align 8 */,
789  uint8_t *src /* align 1 */,
790  ptrdiff_t stride, int h, int x, int y)
791 {
792  const int A = (8 - x) * (8 - y);
793  const int B = (x) * (8 - y);
794  const int C = (8 - x) * (y);
795  const int D = (x) * (y);
796  int i;
797 
798  av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
799 
800  for (i = 0; i < h; i++) {
801  dst[0] = chroma_mc(0);
802  dst[1] = chroma_mc(1);
803  dst[2] = chroma_mc(2);
804  dst[3] = chroma_mc(3);
805  dst[4] = chroma_mc(4);
806  dst[5] = chroma_mc(5);
807  dst[6] = chroma_mc(6);
808  dst[7] = chroma_mc(7);
809  dst += stride;
810  src += stride;
811  }
812 }
813 
814 static void put_no_rnd_vc1_chroma_mc4_c(uint8_t *dst, uint8_t *src,
815  ptrdiff_t stride, int h, int x, int y)
816 {
817  const int A = (8 - x) * (8 - y);
818  const int B = (x) * (8 - y);
819  const int C = (8 - x) * (y);
820  const int D = (x) * (y);
821  int i;
822 
823  av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
824 
825  for (i = 0; i < h; i++) {
826  dst[0] = chroma_mc(0);
827  dst[1] = chroma_mc(1);
828  dst[2] = chroma_mc(2);
829  dst[3] = chroma_mc(3);
830  dst += stride;
831  src += stride;
832  }
833 }
834 
835 #define avg2(a, b) (((a) + (b) + 1) >> 1)
836 static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst /* align 8 */,
837  uint8_t *src /* align 1 */,
838  ptrdiff_t stride, int h, int x, int y)
839 {
840  const int A = (8 - x) * (8 - y);
841  const int B = (x) * (8 - y);
842  const int C = (8 - x) * (y);
843  const int D = (x) * (y);
844  int i;
845 
846  av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
847 
848  for (i = 0; i < h; i++) {
849  dst[0] = avg2(dst[0], chroma_mc(0));
850  dst[1] = avg2(dst[1], chroma_mc(1));
851  dst[2] = avg2(dst[2], chroma_mc(2));
852  dst[3] = avg2(dst[3], chroma_mc(3));
853  dst[4] = avg2(dst[4], chroma_mc(4));
854  dst[5] = avg2(dst[5], chroma_mc(5));
855  dst[6] = avg2(dst[6], chroma_mc(6));
856  dst[7] = avg2(dst[7], chroma_mc(7));
857  dst += stride;
858  src += stride;
859  }
860 }
861 
862 static void avg_no_rnd_vc1_chroma_mc4_c(uint8_t *dst /* align 8 */,
863  uint8_t *src /* align 1 */,
864  ptrdiff_t stride, int h, int x, int y)
865 {
866  const int A = (8 - x) * (8 - y);
867  const int B = ( x) * (8 - y);
868  const int C = (8 - x) * ( y);
869  const int D = ( x) * ( y);
870  int i;
871 
872  av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
873 
874  for (i = 0; i < h; i++) {
875  dst[0] = avg2(dst[0], chroma_mc(0));
876  dst[1] = avg2(dst[1], chroma_mc(1));
877  dst[2] = avg2(dst[2], chroma_mc(2));
878  dst[3] = avg2(dst[3], chroma_mc(3));
879  dst += stride;
880  src += stride;
881  }
882 }
883 
884 #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
885 
886 static void sprite_h_c(uint8_t *dst, const uint8_t *src, int offset,
887  int advance, int count)
888 {
889  while (count--) {
890  int a = src[(offset >> 16)];
891  int b = src[(offset >> 16) + 1];
892  *dst++ = a + ((b - a) * (offset & 0xFFFF) >> 16);
893  offset += advance;
894  }
895 }
896 
897 static av_always_inline void sprite_v_template(uint8_t *dst,
898  const uint8_t *src1a,
899  const uint8_t *src1b,
900  int offset1,
901  int two_sprites,
902  const uint8_t *src2a,
903  const uint8_t *src2b,
904  int offset2,
905  int alpha, int scaled,
906  int width)
907 {
908  int a1, b1, a2, b2;
909  while (width--) {
910  a1 = *src1a++;
911  if (scaled) {
912  b1 = *src1b++;
913  a1 = a1 + ((b1 - a1) * offset1 >> 16);
914  }
915  if (two_sprites) {
916  a2 = *src2a++;
917  if (scaled > 1) {
918  b2 = *src2b++;
919  a2 = a2 + ((b2 - a2) * offset2 >> 16);
920  }
921  a1 = a1 + ((a2 - a1) * alpha >> 16);
922  }
923  *dst++ = a1;
924  }
925 }
926 
927 static void sprite_v_single_c(uint8_t *dst, const uint8_t *src1a,
928  const uint8_t *src1b,
929  int offset, int width)
930 {
931  sprite_v_template(dst, src1a, src1b, offset, 0, NULL, NULL, 0, 0, 1, width);
932 }
933 
934 static void sprite_v_double_noscale_c(uint8_t *dst, const uint8_t *src1a,
935  const uint8_t *src2a,
936  int alpha, int width)
937 {
938  sprite_v_template(dst, src1a, NULL, 0, 1, src2a, NULL, 0, alpha, 0, width);
939 }
940 
941 static void sprite_v_double_onescale_c(uint8_t *dst,
942  const uint8_t *src1a,
943  const uint8_t *src1b,
944  int offset1,
945  const uint8_t *src2a,
946  int alpha, int width)
947 {
948  sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, NULL, 0, alpha, 1,
949  width);
950 }
951 
952 static void sprite_v_double_twoscale_c(uint8_t *dst,
953  const uint8_t *src1a,
954  const uint8_t *src1b,
955  int offset1,
956  const uint8_t *src2a,
957  const uint8_t *src2b,
958  int offset2,
959  int alpha,
960  int width)
961 {
962  sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, src2b, offset2,
963  alpha, 2, width);
964 }
965 
966 #endif /* CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER */
967 #define FN_ASSIGN(X, Y) \
968  dsp->put_vc1_mspel_pixels_tab[1][X+4*Y] = put_vc1_mspel_mc##X##Y##_c; \
969  dsp->put_vc1_mspel_pixels_tab[0][X+4*Y] = put_vc1_mspel_mc##X##Y##_16_c; \
970  dsp->avg_vc1_mspel_pixels_tab[1][X+4*Y] = avg_vc1_mspel_mc##X##Y##_c; \
971  dsp->avg_vc1_mspel_pixels_tab[0][X+4*Y] = avg_vc1_mspel_mc##X##Y##_16_c
972 
974 {
983 
988 
995 
996  dsp->put_vc1_mspel_pixels_tab[0][0] = put_pixels16x16_c;
997  dsp->avg_vc1_mspel_pixels_tab[0][0] = avg_pixels16x16_c;
998  dsp->put_vc1_mspel_pixels_tab[1][0] = put_pixels8x8_c;
999  dsp->avg_vc1_mspel_pixels_tab[1][0] = avg_pixels8x8_c;
1000  FN_ASSIGN(0, 1);
1001  FN_ASSIGN(0, 2);
1002  FN_ASSIGN(0, 3);
1003 
1004  FN_ASSIGN(1, 0);
1005  FN_ASSIGN(1, 1);
1006  FN_ASSIGN(1, 2);
1007  FN_ASSIGN(1, 3);
1008 
1009  FN_ASSIGN(2, 0);
1010  FN_ASSIGN(2, 1);
1011  FN_ASSIGN(2, 2);
1012  FN_ASSIGN(2, 3);
1013 
1014  FN_ASSIGN(3, 0);
1015  FN_ASSIGN(3, 1);
1016  FN_ASSIGN(3, 2);
1017  FN_ASSIGN(3, 3);
1018 
1023 
1024 #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
1025  dsp->sprite_h = sprite_h_c;
1026  dsp->sprite_v_single = sprite_v_single_c;
1027  dsp->sprite_v_double_noscale = sprite_v_double_noscale_c;
1028  dsp->sprite_v_double_onescale = sprite_v_double_onescale_c;
1029  dsp->sprite_v_double_twoscale = sprite_v_double_twoscale_c;
1030 #endif /* CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER */
1031 
1033 
1034  if (ARCH_AARCH64)
1036  if (ARCH_ARM)
1037  ff_vc1dsp_init_arm(dsp);
1038  if (ARCH_PPC)
1039  ff_vc1dsp_init_ppc(dsp);
1040  if (ARCH_X86)
1041  ff_vc1dsp_init_x86(dsp);
1042  if (ARCH_MIPS)
1043  ff_vc1dsp_init_mips(dsp);
1044  if (ARCH_LOONGARCH)
1046 }
VC1DSPContext::sprite_v_double_noscale
void(* sprite_v_double_noscale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src2a, int alpha, int width)
Definition: vc1dsp.h:69
VC1_MSPEL_MC
#define VC1_MSPEL_MC(OP, OP4, OPNAME)
Definition: vc1dsp.c:592
vc1_mspel_filter
static av_always_inline int vc1_mspel_filter(const uint8_t *src, int stride, int mode, int r)
Definition: vc1dsp.c:572
VC1DSPContext::vc1_v_loop_filter16
void(* vc1_v_loop_filter16)(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.h:53
r
const char * r
Definition: vf_curves.c:116
vc1_inv_trans_8x8_c
static void vc1_inv_trans_8x8_c(int16_t block[64])
Definition: vc1dsp.c:267
vc1_inv_trans_4x8_dc_c
static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.c:414
vc1dsp.h
ff_vc1dsp_init_aarch64
av_cold void ff_vc1dsp_init_aarch64(VC1DSPContext *dsp)
Definition: vc1dsp_init_aarch64.c:37
vc1_inv_trans_8x4_dc_c
static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.c:337
VC1DSPContext::vc1_inv_trans_4x4
void(* vc1_inv_trans_4x4)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.h:40
VC1DSPContext::avg_vc1_mspel_pixels_tab
vc1op_pixels_func avg_vc1_mspel_pixels_tab[2][16]
Definition: vc1dsp.h:60
VC1DSPContext::avg_no_rnd_vc1_chroma_pixels_tab
h264_chroma_mc_func avg_no_rnd_vc1_chroma_pixels_tab[3]
Definition: vc1dsp.h:64
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
b
#define b
Definition: input.c:34
ff_startcode_find_candidate_c
int ff_startcode_find_candidate_c(const uint8_t *buf, int size)
Definition: startcode.c:31
t1
#define t1
Definition: regdef.h:29
VC1DSPContext::vc1_inv_trans_8x8_dc
void(* vc1_inv_trans_8x8_dc)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.h:41
ff_vc1dsp_init_mips
av_cold void ff_vc1dsp_init_mips(VC1DSPContext *dsp)
Definition: vc1dsp_init_mips.c:31
VC1DSPContext::put_no_rnd_vc1_chroma_pixels_tab
h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3]
Definition: vc1dsp.h:63
VC1DSPContext::vc1_inv_trans_4x4_dc
void(* vc1_inv_trans_4x4_dc)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.h:44
D
D(D(float, sse)
Definition: rematrix_init.c:29
VC1DSPContext::vc1_h_overlap
void(* vc1_h_overlap)(uint8_t *src, ptrdiff_t stride)
Definition: vc1dsp.h:46
VC1DSPContext::vc1_v_loop_filter4
void(* vc1_v_loop_filter4)(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.h:49
ff_vc1dsp_init_arm
av_cold void ff_vc1dsp_init_arm(VC1DSPContext *dsp)
Definition: vc1dsp_init_arm.c:27
A
#define A(x)
Definition: vp56_arith.h:28
b1
static double b1(void *priv, double x, double y)
Definition: vf_xfade.c:1703
FN_ASSIGN
#define FN_ASSIGN(X, Y)
Definition: vc1dsp.c:967
vc1_v_overlap_c
static void vc1_v_overlap_c(uint8_t *src, ptrdiff_t stride)
Definition: vc1dsp.c:39
VC1DSPContext::vc1_h_loop_filter4
void(* vc1_h_loop_filter4)(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.h:50
vc1_v_loop_filter16_c
static void vc1_v_loop_filter16_c(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.c:235
op_avg
#define op_avg(a, b)
Definition: vc1dsp.c:731
a1
#define a1
Definition: regdef.h:47
vc1_inv_trans_8x4_c
static void vc1_inv_trans_8x4_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.c:358
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
rnd
#define rnd()
Definition: checkasm.h:112
VC1DSPContext::vc1_inv_trans_8x4_dc
void(* vc1_inv_trans_8x4_dc)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.h:42
av_cold
#define av_cold
Definition: attributes.h:90
avg2
#define avg2(a, b)
Definition: vc1dsp.c:835
VC1DSPContext::sprite_v_double_twoscale
void(* sprite_v_double_twoscale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1, const uint8_t *src2a, const uint8_t *src2b, int offset2, int alpha, int width)
Definition: vc1dsp.h:72
clip
clip
Definition: af_crystalizer.c:122
VC1DSPContext::vc1_h_loop_filter16
void(* vc1_h_loop_filter16)(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.h:54
width
#define width
intreadwrite.h
VC1DSPContext::sprite_h
void(* sprite_h)(uint8_t *dst, const uint8_t *src, int offset, int advance, int count)
Definition: vc1dsp.h:67
t7
#define t7
Definition: regdef.h:35
put_no_rnd_vc1_chroma_mc8_c
static void put_no_rnd_vc1_chroma_mc8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y)
Definition: vc1dsp.c:788
VC1DSPContext::vc1_v_overlap
void(* vc1_v_overlap)(uint8_t *src, ptrdiff_t stride)
Definition: vc1dsp.h:45
avg_no_rnd_vc1_chroma_mc4_c
static void avg_no_rnd_vc1_chroma_mc4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y)
Definition: vc1dsp.c:862
avg_no_rnd_vc1_chroma_mc8_c
static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y)
Definition: vc1dsp.c:836
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:64
op4_avg
#define op4_avg(a, b)
Definition: vc1dsp.c:732
NULL
#define NULL
Definition: coverity.c:32
vc1_inv_trans_8x8_dc_c
static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.c:246
chroma_mc
#define chroma_mc(a)
Definition: vc1dsp.c:785
VC1DSPContext::vc1_inv_trans_8x4
void(* vc1_inv_trans_8x4)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.h:38
t5
#define t5
Definition: regdef.h:33
vc1_h_loop_filter16_c
static void vc1_h_loop_filter16_c(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.c:240
vc1_h_loop_filter4_c
static void vc1_h_loop_filter4_c(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.c:220
t6
#define t6
Definition: regdef.h:34
qpeldsp.h
VC1DSPContext::vc1_inv_trans_4x8_dc
void(* vc1_inv_trans_4x8_dc)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.h:43
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
ff_vc1dsp_init_x86
void ff_vc1dsp_init_x86(VC1DSPContext *dsp)
Definition: vc1dsp_init.c:105
startcode.h
VC1_MSPEL_FILTER_16B
#define VC1_MSPEL_FILTER_16B(DIR, TYPE)
Definition: vc1dsp.c:547
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
PUT_VC1_MSPEL
#define PUT_VC1_MSPEL(a, b)
Definition: vc1dsp.c:740
vc1_inv_trans_4x8_c
static void vc1_inv_trans_4x8_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.c:431
vc1_filter_line
static av_always_inline int vc1_filter_line(uint8_t *src, ptrdiff_t stride, int pq)
VC-1 in-loop deblocking filter for one line.
Definition: vc1dsp.c:149
vc1_h_overlap_c
static void vc1_h_overlap_c(uint8_t *src, ptrdiff_t stride)
Definition: vc1dsp.c:63
h264chroma.h
t8
#define t8
Definition: regdef.h:53
vc1_inv_trans_4x4_dc_c
static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.c:487
b2
static double b2(void *priv, double x, double y)
Definition: vf_xfade.c:1704
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
offset
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 offset
Definition: writing_filters.txt:86
VC1DSPContext::sprite_v_single
void(* sprite_v_single)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset, int width)
Definition: vc1dsp.h:68
a0
#define a0
Definition: regdef.h:46
VC1DSPContext::vc1_inv_trans_8x8
void(* vc1_inv_trans_8x8)(int16_t *b)
Definition: vc1dsp.h:37
VC1DSPContext::startcode_find_candidate
int(* startcode_find_candidate)(const uint8_t *buf, int size)
Search buf from the start for up to size bytes.
Definition: vc1dsp.h:82
vc1_v_loop_filter4_c
static void vc1_v_loop_filter4_c(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.c:215
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
VC1DSPContext::sprite_v_double_onescale
void(* sprite_v_double_onescale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1, const uint8_t *src2a, int alpha, int width)
Definition: vc1dsp.h:70
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
t4
#define t4
Definition: regdef.h:32
t3
#define t3
Definition: regdef.h:31
op_put
#define op_put(a, b)
Definition: vc1dsp.c:730
a2
#define a2
Definition: regdef.h:48
common.h
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
len
int len
Definition: vorbis_enc_data.h:426
stride
#define stride
Definition: h264pred_template.c:537
rnd_avg.h
vc1_loop_filter
static void vc1_loop_filter(uint8_t *src, int step, ptrdiff_t stride, int len, int pq)
VC-1 in-loop deblocking filter.
Definition: vc1dsp.c:198
VC1DSPContext
Definition: vc1dsp.h:35
VC1DSPContext::vc1_h_loop_filter8
void(* vc1_h_loop_filter8)(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.h:52
VC1DSPContext::put_vc1_mspel_pixels_tab
vc1op_pixels_func put_vc1_mspel_pixels_tab[2][16]
Definition: vc1dsp.h:59
vc1_v_s_overlap_c
static void vc1_v_s_overlap_c(int16_t *top, int16_t *bottom)
Definition: vc1dsp.c:86
left
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 left
Definition: snow.txt:386
B
#define B
Definition: huffyuvdsp.h:32
t2
#define t2
Definition: regdef.h:30
op4_put
#define op4_put(a, b)
Definition: vc1dsp.c:733
mode
mode
Definition: ebur128.h:83
VC1DSPContext::vc1_v_loop_filter8
void(* vc1_v_loop_filter8)(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.h:51
vc1_inv_trans_4x4_c
static void vc1_inv_trans_4x4_c(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.c:504
temp
else temp
Definition: vf_mcdeint.c:248
av_clip_uint8
#define av_clip_uint8
Definition: common.h:101
vc1_h_s_overlap_c
static void vc1_h_s_overlap_c(int16_t *left, int16_t *right, ptrdiff_t left_stride, ptrdiff_t right_stride, int flags)
Definition: vc1dsp.c:112
put_no_rnd_vc1_chroma_mc4_c
static void put_no_rnd_vc1_chroma_mc4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y)
Definition: vc1dsp.c:814
ff_vc1dsp_init_ppc
av_cold void ff_vc1dsp_init_ppc(VC1DSPContext *dsp)
Definition: vc1dsp_altivec.c:354
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
ff_vc1dsp_init
av_cold void ff_vc1dsp_init(VC1DSPContext *dsp)
Definition: vc1dsp.c:973
d
d
Definition: ffmpeg_filter.c:153
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
VC1DSPContext::vc1_inv_trans_4x8
void(* vc1_inv_trans_4x8)(uint8_t *dest, ptrdiff_t stride, int16_t *block)
Definition: vc1dsp.h:39
ff_vc1dsp_init_loongarch
av_cold void ff_vc1dsp_init_loongarch(VC1DSPContext *dsp)
Definition: vc1dsp_init_loongarch.c:37
vc1_v_loop_filter8_c
static void vc1_v_loop_filter8_c(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.c:225
a3
#define a3
Definition: regdef.h:49
VC1DSPContext::vc1_v_s_overlap
void(* vc1_v_s_overlap)(int16_t *top, int16_t *bottom)
Definition: vc1dsp.h:47
vc1_h_loop_filter8_c
static void vc1_h_loop_filter8_c(uint8_t *src, ptrdiff_t stride, int pq)
Definition: vc1dsp.c:230
VC1DSPContext::vc1_h_s_overlap
void(* vc1_h_s_overlap)(int16_t *left, int16_t *right, ptrdiff_t left_stride, ptrdiff_t right_stride, int flags)
Definition: vc1dsp.h:48