FFmpeg
postprocess.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at)
3  *
4  * AltiVec optimizations (C) 2004 Romain Dolbeau <romain@dolbeau.org>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file
25  * postprocessing.
26  */
27 
28 /*
29  C MMX MMX2 AltiVec
30 isVertDC Ec Ec Ec
31 isVertMinMaxOk Ec Ec Ec
32 doVertLowPass E e Ec
33 doVertDefFilter Ec Ec e Ec
34 isHorizDC Ec Ec Ec
35 isHorizMinMaxOk a E Ec
36 doHorizLowPass E e Ec
37 doHorizDefFilter Ec Ec e Ec
38 do_a_deblock Ec E Ec
39 deRing E e Ecp
40 Vertical RKAlgo1 E a
41 Horizontal RKAlgo1 a
42 Vertical X1# a E
43 Horizontal X1# a E
44 LinIpolDeinterlace e E
45 CubicIpolDeinterlace a e
46 LinBlendDeinterlace e E
47 MedianDeinterlace# E Ec Ec
48 TempDeNoiser# E e Ec
49 
50 # more or less selfinvented filters so the exactness is not too meaningful
51 E = Exact implementation
52 e = almost exact implementation (slightly different rounding,...)
53 a = alternative / approximate impl
54 c = checked against the other implementations (-vo md5)
55 p = partially optimized, still some work to do
56 */
57 
58 /*
59 TODO:
60 reduce the time wasted on the mem transfer
61 unroll stuff if instructions depend too much on the prior one
62 move YScale thing to the end instead of fixing QP
63 write a faster and higher quality deblocking filter :)
64 make the mainloop more flexible (variable number of blocks at once
65  (the if/else stuff per block is slowing things down)
66 compare the quality & speed of all filters
67 split this huge file
68 optimize c versions
69 try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks
70 ...
71 */
72 
73 //Changelog: use git log
74 
75 #include <stddef.h>
76 #include <stdlib.h>
77 #include <string.h>
78 
79 #include "config.h"
80 #include "libavutil/common.h"
81 #include "libavutil/cpu.h"
82 #include "libavutil/intreadwrite.h"
83 #include "libavutil/mem.h"
84 //#undef HAVE_MMXEXT_INLINE
85 //#undef HAVE_MMX_INLINE
86 //#undef ARCH_X86
87 //#define DEBUG_BRIGHTNESS
88 #include "postprocess.h"
89 #include "postprocess_internal.h"
90 #include "libavutil/avstring.h"
91 
92 #define GET_MODE_BUFFER_SIZE 500
93 #define OPTIONS_ARRAY_SIZE 10
94 #define BLOCK_SIZE 8
95 #define TEMP_STRIDE 8
96 //#define NUM_BLOCKS_AT_ONCE 16 //not used yet
97 
98 #if ARCH_X86 && HAVE_INLINE_ASM
99 DECLARE_ASM_CONST(8, uint64_t, w05)= 0x0005000500050005LL;
100 DECLARE_ASM_CONST(8, uint64_t, w04)= 0x0004000400040004LL;
101 DECLARE_ASM_CONST(8, uint64_t, w20)= 0x0020002000200020LL;
102 DECLARE_ASM_CONST(8, uint64_t, b00)= 0x0000000000000000LL;
103 DECLARE_ASM_CONST(8, uint64_t, b01)= 0x0101010101010101LL;
104 DECLARE_ASM_CONST(8, uint64_t, b02)= 0x0202020202020202LL;
105 DECLARE_ASM_CONST(8, uint64_t, b08)= 0x0808080808080808LL;
106 DECLARE_ASM_CONST(8, uint64_t, b80)= 0x8080808080808080LL;
107 #endif
108 
109 DECLARE_ASM_CONST(8, int, deringThreshold)= 20;
110 
111 
112 static const struct PPFilter filters[]=
113 {
114  {"hb", "hdeblock", 1, 1, 3, H_DEBLOCK},
115  {"vb", "vdeblock", 1, 2, 4, V_DEBLOCK},
116 /* {"hr", "rkhdeblock", 1, 1, 3, H_RK1_FILTER},
117  {"vr", "rkvdeblock", 1, 2, 4, V_RK1_FILTER},*/
118  {"h1", "x1hdeblock", 1, 1, 3, H_X1_FILTER},
119  {"v1", "x1vdeblock", 1, 2, 4, V_X1_FILTER},
120  {"ha", "ahdeblock", 1, 1, 3, H_A_DEBLOCK},
121  {"va", "avdeblock", 1, 2, 4, V_A_DEBLOCK},
122  {"dr", "dering", 1, 5, 6, DERING},
123  {"al", "autolevels", 0, 1, 2, LEVEL_FIX},
124  {"lb", "linblenddeint", 1, 1, 4, LINEAR_BLEND_DEINT_FILTER},
125  {"li", "linipoldeint", 1, 1, 4, LINEAR_IPOL_DEINT_FILTER},
126  {"ci", "cubicipoldeint", 1, 1, 4, CUBIC_IPOL_DEINT_FILTER},
127  {"md", "mediandeint", 1, 1, 4, MEDIAN_DEINT_FILTER},
128  {"fd", "ffmpegdeint", 1, 1, 4, FFMPEG_DEINT_FILTER},
129  {"l5", "lowpass5", 1, 1, 4, LOWPASS5_DEINT_FILTER},
130  {"tn", "tmpnoise", 1, 7, 8, TEMP_NOISE_FILTER},
131  {"fq", "forcequant", 1, 0, 0, FORCE_QUANT},
132  {"be", "bitexact", 1, 0, 0, BITEXACT},
133  {"vi", "visualize", 1, 0, 0, VISUALIZE},
134  {NULL, NULL,0,0,0,0} //End Marker
135 };
136 
137 static const char * const replaceTable[]=
138 {
139  "default", "hb:a,vb:a,dr:a",
140  "de", "hb:a,vb:a,dr:a",
141  "fast", "h1:a,v1:a,dr:a",
142  "fa", "h1:a,v1:a,dr:a",
143  "ac", "ha:a:128:7,va:a,dr:a",
144  NULL //End Marker
145 };
146 
147 /* The horizontal functions exist only in C because the MMX
148  * code is faster with vertical filters and transposing. */
149 
150 /**
151  * Check if the given 8x8 Block is mostly "flat"
152  */
153 static inline int isHorizDC_C(const uint8_t src[], int stride, const PPContext *c)
154 {
155  int numEq= 0;
156  int y;
157  const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
158  const int dcThreshold= dcOffset*2 + 1;
159 
160  for(y=0; y<BLOCK_SIZE; y++){
161  numEq += ((unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold;
162  numEq += ((unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold;
163  numEq += ((unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold;
164  numEq += ((unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold;
165  numEq += ((unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold;
166  numEq += ((unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold;
167  numEq += ((unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold;
168  src+= stride;
169  }
170  return numEq > c->ppMode.flatnessThreshold;
171 }
172 
173 /**
174  * Check if the middle 8x8 Block in the given 8x16 block is flat
175  */
176 static inline int isVertDC_C(const uint8_t src[], int stride, const PPContext *c)
177 {
178  int numEq= 0;
179  int y;
180  const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
181  const int dcThreshold= dcOffset*2 + 1;
182 
183  src+= stride*4; // src points to begin of the 8x8 Block
184  for(y=0; y<BLOCK_SIZE-1; y++){
185  numEq += ((unsigned)(src[0] - src[0+stride] + dcOffset)) < dcThreshold;
186  numEq += ((unsigned)(src[1] - src[1+stride] + dcOffset)) < dcThreshold;
187  numEq += ((unsigned)(src[2] - src[2+stride] + dcOffset)) < dcThreshold;
188  numEq += ((unsigned)(src[3] - src[3+stride] + dcOffset)) < dcThreshold;
189  numEq += ((unsigned)(src[4] - src[4+stride] + dcOffset)) < dcThreshold;
190  numEq += ((unsigned)(src[5] - src[5+stride] + dcOffset)) < dcThreshold;
191  numEq += ((unsigned)(src[6] - src[6+stride] + dcOffset)) < dcThreshold;
192  numEq += ((unsigned)(src[7] - src[7+stride] + dcOffset)) < dcThreshold;
193  src+= stride;
194  }
195  return numEq > c->ppMode.flatnessThreshold;
196 }
197 
198 static inline int isHorizMinMaxOk_C(const uint8_t src[], int stride, int QP)
199 {
200  int i;
201  for(i=0; i<2; i++){
202  if((unsigned)(src[0] - src[5] + 2*QP) > 4*QP) return 0;
203  src += stride;
204  if((unsigned)(src[2] - src[7] + 2*QP) > 4*QP) return 0;
205  src += stride;
206  if((unsigned)(src[4] - src[1] + 2*QP) > 4*QP) return 0;
207  src += stride;
208  if((unsigned)(src[6] - src[3] + 2*QP) > 4*QP) return 0;
209  src += stride;
210  }
211  return 1;
212 }
213 
214 static inline int isVertMinMaxOk_C(const uint8_t src[], int stride, int QP)
215 {
216  int x;
217  src+= stride*4;
218  for(x=0; x<BLOCK_SIZE; x+=4){
219  if((unsigned)(src[ x + 0*stride] - src[ x + 5*stride] + 2*QP) > 4*QP) return 0;
220  if((unsigned)(src[1+x + 2*stride] - src[1+x + 7*stride] + 2*QP) > 4*QP) return 0;
221  if((unsigned)(src[2+x + 4*stride] - src[2+x + 1*stride] + 2*QP) > 4*QP) return 0;
222  if((unsigned)(src[3+x + 6*stride] - src[3+x + 3*stride] + 2*QP) > 4*QP) return 0;
223  }
224  return 1;
225 }
226 
227 static inline int horizClassify_C(const uint8_t src[], int stride, const PPContext *c)
228 {
229  if( isHorizDC_C(src, stride, c) ){
230  return isHorizMinMaxOk_C(src, stride, c->QP);
231  }else{
232  return 2;
233  }
234 }
235 
236 static inline int vertClassify_C(const uint8_t src[], int stride, const PPContext *c)
237 {
238  if( isVertDC_C(src, stride, c) ){
239  return isVertMinMaxOk_C(src, stride, c->QP);
240  }else{
241  return 2;
242  }
243 }
244 
245 static inline void doHorizDefFilter_C(uint8_t dst[], int stride, const PPContext *c)
246 {
247  int y;
248  for(y=0; y<BLOCK_SIZE; y++){
249  const int middleEnergy= 5*(dst[4] - dst[3]) + 2*(dst[2] - dst[5]);
250 
251  if(FFABS(middleEnergy) < 8*c->QP){
252  const int q=(dst[3] - dst[4])/2;
253  const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
254  const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]);
255 
256  int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) );
257  d= FFMAX(d, 0);
258 
259  d= (5*d + 32) >> 6;
260  d*= FFSIGN(-middleEnergy);
261 
262  if(q>0)
263  {
264  d = FFMAX(d, 0);
265  d = FFMIN(d, q);
266  }
267  else
268  {
269  d = FFMIN(d, 0);
270  d = FFMAX(d, q);
271  }
272 
273  dst[3]-= d;
274  dst[4]+= d;
275  }
276  dst+= stride;
277  }
278 }
279 
280 /**
281  * Do a horizontal low pass filter on the 10x8 block (dst points to middle 8x8 Block)
282  * using the 9-Tap Filter (1,1,2,2,4,2,2,1,1)/16 (C version)
283  */
284 static inline void doHorizLowPass_C(uint8_t dst[], int stride, const PPContext *c)
285 {
286  int y;
287  for(y=0; y<BLOCK_SIZE; y++){
288  const int first= FFABS(dst[-1] - dst[0]) < c->QP ? dst[-1] : dst[0];
289  const int last= FFABS(dst[8] - dst[7]) < c->QP ? dst[8] : dst[7];
290 
291  int sums[10];
292  sums[0] = 4*first + dst[0] + dst[1] + dst[2] + 4;
293  sums[1] = sums[0] - first + dst[3];
294  sums[2] = sums[1] - first + dst[4];
295  sums[3] = sums[2] - first + dst[5];
296  sums[4] = sums[3] - first + dst[6];
297  sums[5] = sums[4] - dst[0] + dst[7];
298  sums[6] = sums[5] - dst[1] + last;
299  sums[7] = sums[6] - dst[2] + last;
300  sums[8] = sums[7] - dst[3] + last;
301  sums[9] = sums[8] - dst[4] + last;
302 
303  dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4;
304  dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4;
305  dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4;
306  dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4;
307  dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4;
308  dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4;
309  dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4;
310  dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4;
311 
312  dst+= stride;
313  }
314 }
315 
316 /**
317  * Experimental Filter 1 (Horizontal)
318  * will not damage linear gradients
319  * Flat blocks should look like they were passed through the (1,1,2,2,4,2,2,1,1) 9-Tap filter
320  * can only smooth blocks at the expected locations (it cannot smooth them if they did move)
321  * MMX2 version does correct clipping C version does not
322  * not identical with the vertical one
323  */
324 static inline void horizX1Filter(uint8_t *src, int stride, int QP)
325 {
326  int y;
327  static uint64_t lut[256];
328  if(!lut[255])
329  {
330  int i;
331  for(i=0; i<256; i++)
332  {
333  int v= i < 128 ? 2*i : 2*(i-256);
334 /*
335 //Simulate 112242211 9-Tap filter
336  uint64_t a= (v/16) & 0xFF;
337  uint64_t b= (v/8) & 0xFF;
338  uint64_t c= (v/4) & 0xFF;
339  uint64_t d= (3*v/8) & 0xFF;
340 */
341 //Simulate piecewise linear interpolation
342  uint64_t a= (v/16) & 0xFF;
343  uint64_t b= (v*3/16) & 0xFF;
344  uint64_t c= (v*5/16) & 0xFF;
345  uint64_t d= (7*v/16) & 0xFF;
346  uint64_t A= (0x100 - a)&0xFF;
347  uint64_t B= (0x100 - b)&0xFF;
348  uint64_t C= (0x100 - c)&0xFF;
349  uint64_t D= (0x100 - c)&0xFF;
350 
351  lut[i] = (a<<56) | (b<<48) | (c<<40) | (d<<32) |
352  (D<<24) | (C<<16) | (B<<8) | (A);
353  //lut[i] = (v<<32) | (v<<24);
354  }
355  }
356 
357  for(y=0; y<BLOCK_SIZE; y++){
358  int a= src[1] - src[2];
359  int b= src[3] - src[4];
360  int c= src[5] - src[6];
361 
362  int d= FFMAX(FFABS(b) - (FFABS(a) + FFABS(c))/2, 0);
363 
364  if(d < QP){
365  int v = d * FFSIGN(-b);
366 
367  src[1] +=v/8;
368  src[2] +=v/4;
369  src[3] +=3*v/8;
370  src[4] -=3*v/8;
371  src[5] -=v/4;
372  src[6] -=v/8;
373  }
374  src+=stride;
375  }
376 }
377 
378 /**
379  * accurate deblock filter
380  */
381 static av_always_inline void do_a_deblock_C(uint8_t *src, int step,
382  int stride, const PPContext *c, int mode)
383 {
384  int y;
385  const int QP= c->QP;
386  const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
387  const int dcThreshold= dcOffset*2 + 1;
388 
389  src+= step*4; // src points to begin of the 8x8 Block
390  for(y=0; y<8; y++){
391  int numEq= 0;
392 
393  numEq += ((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold;
394  numEq += ((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold;
395  numEq += ((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold;
396  numEq += ((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold;
397  numEq += ((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold;
398  numEq += ((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold;
399  numEq += ((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold;
400  numEq += ((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold;
401  numEq += ((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold;
402  if(numEq > c->ppMode.flatnessThreshold){
403  int min, max, x;
404 
405  if(src[0] > src[step]){
406  max= src[0];
407  min= src[step];
408  }else{
409  max= src[step];
410  min= src[0];
411  }
412  for(x=2; x<8; x+=2){
413  if(src[x*step] > src[(x+1)*step]){
414  if(src[x *step] > max) max= src[ x *step];
415  if(src[(x+1)*step] < min) min= src[(x+1)*step];
416  }else{
417  if(src[(x+1)*step] > max) max= src[(x+1)*step];
418  if(src[ x *step] < min) min= src[ x *step];
419  }
420  }
421  if(max-min < 2*QP){
422  const int first= FFABS(src[-1*step] - src[0]) < QP ? src[-1*step] : src[0];
423  const int last= FFABS(src[8*step] - src[7*step]) < QP ? src[8*step] : src[7*step];
424 
425  int sums[10];
426  sums[0] = 4*first + src[0*step] + src[1*step] + src[2*step] + 4;
427  sums[1] = sums[0] - first + src[3*step];
428  sums[2] = sums[1] - first + src[4*step];
429  sums[3] = sums[2] - first + src[5*step];
430  sums[4] = sums[3] - first + src[6*step];
431  sums[5] = sums[4] - src[0*step] + src[7*step];
432  sums[6] = sums[5] - src[1*step] + last;
433  sums[7] = sums[6] - src[2*step] + last;
434  sums[8] = sums[7] - src[3*step] + last;
435  sums[9] = sums[8] - src[4*step] + last;
436 
437  if (mode & VISUALIZE) {
438  src[0*step] =
439  src[1*step] =
440  src[2*step] =
441  src[3*step] =
442  src[4*step] =
443  src[5*step] =
444  src[6*step] =
445  src[7*step] = 128;
446  }
447  src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4;
448  src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4;
449  src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4;
450  src[3*step]= (sums[3] + sums[5] + 2*src[3*step])>>4;
451  src[4*step]= (sums[4] + sums[6] + 2*src[4*step])>>4;
452  src[5*step]= (sums[5] + sums[7] + 2*src[5*step])>>4;
453  src[6*step]= (sums[6] + sums[8] + 2*src[6*step])>>4;
454  src[7*step]= (sums[7] + sums[9] + 2*src[7*step])>>4;
455  }
456  }else{
457  const int middleEnergy= 5*(src[4*step] - src[3*step]) + 2*(src[2*step] - src[5*step]);
458 
459  if(FFABS(middleEnergy) < 8*QP){
460  const int q=(src[3*step] - src[4*step])/2;
461  const int leftEnergy= 5*(src[2*step] - src[1*step]) + 2*(src[0*step] - src[3*step]);
462  const int rightEnergy= 5*(src[6*step] - src[5*step]) + 2*(src[4*step] - src[7*step]);
463 
464  int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) );
465  d= FFMAX(d, 0);
466 
467  d= (5*d + 32) >> 6;
468  d*= FFSIGN(-middleEnergy);
469 
470  if(q>0){
471  d = FFMAX(d, 0);
472  d = FFMIN(d, q);
473  }else{
474  d = FFMIN(d, 0);
475  d = FFMAX(d, q);
476  }
477 
478  if ((mode & VISUALIZE) && d) {
479  d= (d < 0) ? 32 : -32;
480  src[3*step]= av_clip_uint8(src[3*step] - d);
481  src[4*step]= av_clip_uint8(src[4*step] + d);
482  d = 0;
483  }
484 
485  src[3*step]-= d;
486  src[4*step]+= d;
487  }
488  }
489 
490  src += stride;
491  }
492 }
493 
494 //Note: we have C and SSE2 version (which uses MMX(EXT) when advantageous)
495 //Plain C versions
496 //we always compile C for testing which needs bitexactness
497 #define TEMPLATE_PP_C 1
498 #include "postprocess_template.c"
499 
500 #if HAVE_ALTIVEC
502 
503 # define TEMPLATE_PP_ALTIVEC 1
505 # include "postprocess_template.c"
506 #endif
507 
508 #if ARCH_X86 && HAVE_INLINE_ASM
509 # if CONFIG_RUNTIME_CPUDETECT
510 # define TEMPLATE_PP_SSE2 1
511 # include "postprocess_template.c"
512 # else
513 # if HAVE_SSE2_INLINE
514 # define TEMPLATE_PP_SSE2 1
515 # include "postprocess_template.c"
516 # endif
517 # endif
518 #endif
519 
520 typedef void (*pp_fn)(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height,
521  const int8_t QPs[], int QPStride, int isColor, PPContext *c2);
522 
523 static inline void postProcess(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height,
524  const int8_t QPs[], int QPStride, int isColor, pp_mode *vm, pp_context *vc)
525 {
526  pp_fn pp = postProcess_C;
527  PPContext *c= (PPContext *)vc;
528  PPMode *ppMode= (PPMode *)vm;
529  c->ppMode= *ppMode; //FIXME
530 
531  if (!(ppMode->lumMode & BITEXACT)) {
532 #if CONFIG_RUNTIME_CPUDETECT
533 #if ARCH_X86 && HAVE_INLINE_ASM
534  // ordered per speed fastest first
535  if (c->cpuCaps & AV_CPU_FLAG_SSE2) pp = postProcess_SSE2;
536 #elif HAVE_ALTIVEC
537  if (c->cpuCaps & AV_CPU_FLAG_ALTIVEC) pp = postProcess_altivec;
538 #endif
539 #else /* CONFIG_RUNTIME_CPUDETECT */
540 #if HAVE_SSE2_INLINE
541  pp = postProcess_SSE2;
542 #elif HAVE_ALTIVEC
543  pp = postProcess_altivec;
544 #endif
545 #endif /* !CONFIG_RUNTIME_CPUDETECT */
546  }
547 
548  pp(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
549 }
550 
551 /* -pp Command line Help
552 */
553 const char pp_help[] =
554 "Available postprocessing filters:\n"
555 "Filters Options\n"
556 "short long name short long option Description\n"
557 "* * a autoq CPU power dependent enabler\n"
558 " c chrom chrominance filtering enabled\n"
559 " y nochrom chrominance filtering disabled\n"
560 " n noluma luma filtering disabled\n"
561 "hb hdeblock (2 threshold) horizontal deblocking filter\n"
562 " 1. difference factor: default=32, higher -> more deblocking\n"
563 " 2. flatness threshold: default=39, lower -> more deblocking\n"
564 " the h & v deblocking filters share these\n"
565 " so you can't set different thresholds for h / v\n"
566 "vb vdeblock (2 threshold) vertical deblocking filter\n"
567 "ha hadeblock (2 threshold) horizontal deblocking filter\n"
568 "va vadeblock (2 threshold) vertical deblocking filter\n"
569 "h1 x1hdeblock experimental h deblock filter 1\n"
570 "v1 x1vdeblock experimental v deblock filter 1\n"
571 "dr dering deringing filter\n"
572 "al autolevels automatic brightness / contrast\n"
573 " f fullyrange stretch luminance to (0..255)\n"
574 "lb linblenddeint linear blend deinterlacer\n"
575 "li linipoldeint linear interpolating deinterlace\n"
576 "ci cubicipoldeint cubic interpolating deinterlacer\n"
577 "md mediandeint median deinterlacer\n"
578 "fd ffmpegdeint ffmpeg deinterlacer\n"
579 "l5 lowpass5 FIR lowpass deinterlacer\n"
580 "de default hb:a,vb:a,dr:a\n"
581 "fa fast h1:a,v1:a,dr:a\n"
582 "ac ha:a:128:7,va:a,dr:a\n"
583 "tn tmpnoise (3 threshold) temporal noise reducer\n"
584 " 1. <= 2. <= 3. larger -> stronger filtering\n"
585 "fq forceQuant <quantizer> force quantizer\n"
586 "Usage:\n"
587 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n"
588 "long form example:\n"
589 "vdeblock:autoq/hdeblock:autoq/linblenddeint default,-vdeblock\n"
590 "short form example:\n"
591 "vb:a/hb:a/lb de,-vb\n"
592 "more examples:\n"
593 "tn:64:128:256\n"
594 "\n"
595 ;
596 
598 {
600  char *p= temp;
601  static const char filterDelimiters[] = ",/";
602  static const char optionDelimiters[] = ":|";
603  struct PPMode *ppMode;
604  char *filterToken;
605 
606  if (!name) {
607  av_log(NULL, AV_LOG_ERROR, "pp: Missing argument\n");
608  return NULL;
609  }
610 
611  if (!strcmp(name, "help")) {
612  const char *p;
613  for (p = pp_help; strchr(p, '\n'); p = strchr(p, '\n') + 1) {
614  av_strlcpy(temp, p, FFMIN(sizeof(temp), strchr(p, '\n') - p + 2));
615  av_log(NULL, AV_LOG_INFO, "%s", temp);
616  }
617  return NULL;
618  }
619 
620  ppMode= av_malloc(sizeof(PPMode));
621  if (!ppMode)
622  return NULL;
623 
624  ppMode->lumMode= 0;
625  ppMode->chromMode= 0;
626  ppMode->maxTmpNoise[0]= 700;
627  ppMode->maxTmpNoise[1]= 1500;
628  ppMode->maxTmpNoise[2]= 3000;
629  ppMode->maxAllowedY= 234;
630  ppMode->minAllowedY= 16;
631  ppMode->baseDcDiff= 256/8;
632  ppMode->flatnessThreshold= 56-16-1;
633  ppMode->maxClippedThreshold= (AVRational){1,100};
634  ppMode->error=0;
635 
636  memset(temp, 0, GET_MODE_BUFFER_SIZE);
638 
639  av_log(NULL, AV_LOG_DEBUG, "pp: %s\n", name);
640 
641  for(;;){
642  const char *filterName;
643  int q= 1000000; //PP_QUALITY_MAX;
644  int chrom=-1;
645  int luma=-1;
646  const char *option;
647  const char *options[OPTIONS_ARRAY_SIZE];
648  int i;
649  int filterNameOk=0;
650  int numOfUnknownOptions=0;
651  int enable=1; //does the user want us to enabled or disabled the filter
652  char *tokstate;
653 
654  filterToken= av_strtok(p, filterDelimiters, &tokstate);
655  if(!filterToken) break;
656  p+= strlen(filterToken) + 1; // p points to next filterToken
657  filterName= av_strtok(filterToken, optionDelimiters, &tokstate);
658  if (!filterName) {
659  ppMode->error++;
660  break;
661  }
662  av_log(NULL, AV_LOG_DEBUG, "pp: %s::%s\n", filterToken, filterName);
663 
664  if(*filterName == '-'){
665  enable=0;
666  filterName++;
667  }
668 
669  for(;;){ //for all options
670  option= av_strtok(NULL, optionDelimiters, &tokstate);
671  if(!option) break;
672 
673  av_log(NULL, AV_LOG_DEBUG, "pp: option: %s\n", option);
674  if(!strcmp("autoq", option) || !strcmp("a", option)) q= quality;
675  else if(!strcmp("nochrom", option) || !strcmp("y", option)) chrom=0;
676  else if(!strcmp("chrom", option) || !strcmp("c", option)) chrom=1;
677  else if(!strcmp("noluma", option) || !strcmp("n", option)) luma=0;
678  else{
679  options[numOfUnknownOptions] = option;
680  numOfUnknownOptions++;
681  }
682  if(numOfUnknownOptions >= OPTIONS_ARRAY_SIZE-1) break;
683  }
684  options[numOfUnknownOptions] = NULL;
685 
686  /* replace stuff from the replace Table */
687  for(i=0; replaceTable[2*i]; i++){
688  if(!strcmp(replaceTable[2*i], filterName)){
689  size_t newlen = strlen(replaceTable[2*i + 1]);
690  int plen;
691  int spaceLeft;
692 
693  p--, *p=',';
694 
695  plen= strlen(p);
696  spaceLeft= p - temp + plen;
697  if(spaceLeft + newlen >= GET_MODE_BUFFER_SIZE - 1){
698  ppMode->error++;
699  break;
700  }
701  memmove(p + newlen, p, plen+1);
702  memcpy(p, replaceTable[2*i + 1], newlen);
703  filterNameOk=1;
704  }
705  }
706 
707  for(i=0; filters[i].shortName; i++){
708  if( !strcmp(filters[i].longName, filterName)
709  || !strcmp(filters[i].shortName, filterName)){
710  ppMode->lumMode &= ~filters[i].mask;
711  ppMode->chromMode &= ~filters[i].mask;
712 
713  filterNameOk=1;
714  if(!enable) break; // user wants to disable it
715 
716  if(q >= filters[i].minLumQuality && luma)
717  ppMode->lumMode|= filters[i].mask;
718  if(chrom==1 || (chrom==-1 && filters[i].chromDefault))
719  if(q >= filters[i].minChromQuality)
720  ppMode->chromMode|= filters[i].mask;
721 
722  if(filters[i].mask == LEVEL_FIX){
723  int o;
724  ppMode->minAllowedY= 16;
725  ppMode->maxAllowedY= 234;
726  for(o=0; options[o]; o++){
727  if( !strcmp(options[o],"fullyrange")
728  ||!strcmp(options[o],"f")){
729  ppMode->minAllowedY= 0;
730  ppMode->maxAllowedY= 255;
731  numOfUnknownOptions--;
732  }
733  }
734  }
735  else if(filters[i].mask == TEMP_NOISE_FILTER)
736  {
737  int o;
738  int numOfNoises=0;
739 
740  for(o=0; options[o]; o++){
741  char *tail;
742  ppMode->maxTmpNoise[numOfNoises]=
743  strtol(options[o], &tail, 0);
744  if(tail!=options[o]){
745  numOfNoises++;
746  numOfUnknownOptions--;
747  if(numOfNoises >= 3) break;
748  }
749  }
750  }
751  else if(filters[i].mask == V_DEBLOCK || filters[i].mask == H_DEBLOCK
753  int o;
754 
755  for(o=0; options[o] && o<2; o++){
756  char *tail;
757  int val= strtol(options[o], &tail, 0);
758  if(tail==options[o]) break;
759 
760  numOfUnknownOptions--;
761  if(o==0) ppMode->baseDcDiff= val;
762  else ppMode->flatnessThreshold= val;
763  }
764  }
765  else if(filters[i].mask == FORCE_QUANT){
766  int o;
767  ppMode->forcedQuant= 15;
768 
769  for(o=0; options[o] && o<1; o++){
770  char *tail;
771  int val= strtol(options[o], &tail, 0);
772  if(tail==options[o]) break;
773 
774  numOfUnknownOptions--;
775  ppMode->forcedQuant= val;
776  }
777  }
778  }
779  }
780  if(!filterNameOk) ppMode->error++;
781  ppMode->error += numOfUnknownOptions;
782  }
783 
784  av_log(NULL, AV_LOG_DEBUG, "pp: lumMode=%X, chromMode=%X\n", ppMode->lumMode, ppMode->chromMode);
785  if(ppMode->error){
786  av_log(NULL, AV_LOG_ERROR, "%d errors in postprocess string \"%s\"\n", ppMode->error, name);
787  av_free(ppMode);
788  return NULL;
789  }
790  return ppMode;
791 }
792 
794  av_free(mode);
795 }
796 
797 static void reallocAlign(void **p, int size){
798  av_free(*p);
799  *p= av_mallocz(size);
800 }
801 
802 static void reallocBuffers(PPContext *c, int width, int height, int stride, int qpStride){
803  int mbWidth = (width+15)>>4;
804  int mbHeight= (height+15)>>4;
805  int i;
806 
807  c->stride= stride;
808  c->qpStride= qpStride;
809 
810  reallocAlign((void **)&c->tempDst, stride*24+32);
811  reallocAlign((void **)&c->tempSrc, stride*24);
812  reallocAlign((void **)&c->tempBlocks, 2*16*8);
813  reallocAlign((void **)&c->yHistogram, 256*sizeof(uint64_t));
814  for(i=0; i<256; i++)
815  c->yHistogram[i]= width*height/64*15/256;
816 
817  for(i=0; i<3; i++){
818  //Note: The +17*1024 is just there so I do not have to worry about r/w over the end.
819  reallocAlign((void **)&c->tempBlurred[i], stride*mbHeight*16 + 17*1024);
820  reallocAlign((void **)&c->tempBlurredPast[i], 256*((height+7)&(~7))/2 + 17*1024);//FIXME size
821  }
822 
823  reallocAlign((void **)&c->deintTemp, 2*width+32);
824  reallocAlign((void **)&c->nonBQPTable, qpStride*mbHeight*sizeof(int8_t));
825  reallocAlign((void **)&c->stdQPTable, qpStride*mbHeight*sizeof(int8_t));
826  reallocAlign((void **)&c->forcedQPTable, mbWidth*sizeof(int8_t));
827 }
828 
829 static const char * context_to_name(void * ptr) {
830  return "postproc";
831 }
832 
833 static const AVClass av_codec_context_class = { "Postproc", context_to_name, NULL };
834 
835 av_cold pp_context *pp_get_context(int width, int height, int cpuCaps){
836  PPContext *c= av_mallocz(sizeof(PPContext));
837  int stride= FFALIGN(width, 16); //assumed / will realloc if needed
838  int qpStride= (width+15)/16 + 2; //assumed / will realloc if needed
839 
840  if (!c)
841  return NULL;
842 
843  c->av_class = &av_codec_context_class;
844  if(cpuCaps&PP_FORMAT){
845  c->hChromaSubSample= cpuCaps&0x3;
846  c->vChromaSubSample= (cpuCaps>>4)&0x3;
847  }else{
848  c->hChromaSubSample= 1;
849  c->vChromaSubSample= 1;
850  }
851  if (cpuCaps & PP_CPU_CAPS_AUTO) {
852  c->cpuCaps = av_get_cpu_flags();
853  } else {
854  c->cpuCaps = 0;
855  if (cpuCaps & PP_CPU_CAPS_ALTIVEC) c->cpuCaps |= AV_CPU_FLAG_ALTIVEC;
856  }
857 
858  reallocBuffers(c, width, height, stride, qpStride);
859 
860  c->frameNum=-1;
861 
862  return c;
863 }
864 
865 av_cold void pp_free_context(void *vc){
866  PPContext *c = (PPContext*)vc;
867  int i;
868 
869  for(i=0; i<FF_ARRAY_ELEMS(c->tempBlurred); i++)
870  av_free(c->tempBlurred[i]);
871  for(i=0; i<FF_ARRAY_ELEMS(c->tempBlurredPast); i++)
872  av_free(c->tempBlurredPast[i]);
873 
874  av_free(c->tempBlocks);
875  av_free(c->yHistogram);
876  av_free(c->tempDst);
877  av_free(c->tempSrc);
878  av_free(c->deintTemp);
879  av_free(c->stdQPTable);
880  av_free(c->nonBQPTable);
881  av_free(c->forcedQPTable);
882 
883  memset(c, 0, sizeof(PPContext));
884 
885  av_free(c);
886 }
887 
888 void pp_postprocess(const uint8_t * src[3], const int srcStride[3],
889  uint8_t * dst[3], const int dstStride[3],
890  int width, int height,
891  const int8_t *QP_store, int QPStride,
892  pp_mode *vm, void *vc, int pict_type)
893 {
894  int mbWidth = (width+15)>>4;
895  int mbHeight= (height+15)>>4;
896  PPMode *mode = vm;
897  PPContext *c = vc;
898  int minStride= FFMAX(FFABS(srcStride[0]), FFABS(dstStride[0]));
899  int absQPStride = FFABS(QPStride);
900 
901  // c->stride and c->QPStride are always positive
902  if(c->stride < minStride || c->qpStride < absQPStride)
904  FFMAX(minStride, c->stride),
905  FFMAX(c->qpStride, absQPStride));
906 
907  if(!QP_store || (mode->lumMode & FORCE_QUANT)){
908  int i;
909  QP_store= c->forcedQPTable;
910  absQPStride = QPStride = 0;
911  if(mode->lumMode & FORCE_QUANT)
912  for(i=0; i<mbWidth; i++) c->forcedQPTable[i]= mode->forcedQuant;
913  else
914  for(i=0; i<mbWidth; i++) c->forcedQPTable[i]= 1;
915  }
916 
917  if(pict_type & PP_PICT_TYPE_QP2){
918  int i;
919  const int count= FFMAX(mbHeight * absQPStride, mbWidth);
920  for(i=0; i<(count>>2); i++){
921  AV_WN32(c->stdQPTable + (i<<2), AV_RN32(QP_store + (i<<2)) >> 1 & 0x7F7F7F7F);
922  }
923  for(i<<=2; i<count; i++){
924  c->stdQPTable[i] = QP_store[i]>>1;
925  }
926  QP_store= c->stdQPTable;
927  QPStride= absQPStride;
928  }
929 
930  if(0){
931  int x,y;
932  for(y=0; y<mbHeight; y++){
933  for(x=0; x<mbWidth; x++){
934  av_log(c, AV_LOG_INFO, "%2d ", QP_store[x + y*QPStride]);
935  }
936  av_log(c, AV_LOG_INFO, "\n");
937  }
938  av_log(c, AV_LOG_INFO, "\n");
939  }
940 
941  if((pict_type&7)!=3){
942  if (QPStride >= 0){
943  int i;
944  const int count= FFMAX(mbHeight * QPStride, mbWidth);
945  for(i=0; i<(count>>2); i++){
946  AV_WN32(c->nonBQPTable + (i<<2), AV_RN32(QP_store + (i<<2)) & 0x3F3F3F3F);
947  }
948  for(i<<=2; i<count; i++){
949  c->nonBQPTable[i] = QP_store[i] & 0x3F;
950  }
951  } else {
952  int i,j;
953  for(i=0; i<mbHeight; i++) {
954  for(j=0; j<absQPStride; j++) {
955  c->nonBQPTable[i*absQPStride+j] = QP_store[i*QPStride+j] & 0x3F;
956  }
957  }
958  }
959  }
960 
961  av_log(c, AV_LOG_DEBUG, "using npp filters 0x%X/0x%X\n",
962  mode->lumMode, mode->chromMode);
963 
964  postProcess(src[0], srcStride[0], dst[0], dstStride[0],
965  width, height, QP_store, QPStride, 0, mode, c);
966 
967  if (!(src[1] && src[2] && dst[1] && dst[2]))
968  return;
969 
970  width = (width )>>c->hChromaSubSample;
971  height = (height)>>c->vChromaSubSample;
972 
973  if(mode->chromMode){
974  postProcess(src[1], srcStride[1], dst[1], dstStride[1],
975  width, height, QP_store, QPStride, 1, mode, c);
976  postProcess(src[2], srcStride[2], dst[2], dstStride[2],
977  width, height, QP_store, QPStride, 2, mode, c);
978  }
979  else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]){
980  linecpy(dst[1], src[1], height, srcStride[1]);
981  linecpy(dst[2], src[2], height, srcStride[2]);
982  }else{
983  int y;
984  for(y=0; y<height; y++){
985  memcpy(&(dst[1][y*dstStride[1]]), &(src[1][y*srcStride[1]]), width);
986  memcpy(&(dst[2][y*dstStride[2]]), &(src[2][y*srcStride[2]]), width);
987  }
988  }
989 }
A
#define A(x)
Definition: vpx_arith.h:28
pp_get_mode_by_name_and_quality
pp_mode * pp_get_mode_by_name_and_quality(const char *name, int quality)
Return a pp_mode or NULL if an error occurred.
Definition: postprocess.c:597
FFMPEG_DEINT_FILTER
#define FFMPEG_DEINT_FILTER
Definition: postprocess_internal.h:67
name
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 minimum maximum flags name is the option name
Definition: writing_filters.txt:88
FORCE_QUANT
#define FORCE_QUANT
Definition: postprocess_internal.h:71
reallocAlign
static void reallocAlign(void **p, int size)
Definition: postprocess.c:797
av_codec_context_class
static const AVClass av_codec_context_class
Definition: postprocess.c:833
PPContext
postprocess context.
Definition: postprocess_internal.h:116
filters
static const struct PPFilter filters[]
Definition: postprocess.c:112
postprocess_altivec_template.c
PPMode::flatnessThreshold
int flatnessThreshold
Definition: postprocess_internal.h:108
PP_FORMAT
#define PP_FORMAT
Definition: postprocess.h:94
mask
int mask
Definition: mediacodecdec_common.c:154
replaceTable
static const char *const replaceTable[]
Definition: postprocess.c:137
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
LOWPASS5_DEINT_FILTER
#define LOWPASS5_DEINT_FILTER
Definition: postprocess_internal.h:68
b
#define b
Definition: input.c:41
horizX1Filter
static void horizX1Filter(uint8_t *src, int stride, int QP)
Experimental Filter 1 (Horizontal) will not damage linear gradients Flat blocks should look like they...
Definition: postprocess.c:324
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:107
H_A_DEBLOCK
#define H_A_DEBLOCK
Definition: postprocess_internal.h:56
PPFilter::mask
int mask
Bitmask to turn this filter on.
Definition: postprocess_internal.h:90
postprocess_template.c
quality
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
Definition: rate_distortion.txt:12
PP_PICT_TYPE_QP2
#define PP_PICT_TYPE_QP2
MPEG2 style QScale.
Definition: postprocess.h:101
D
D(D(float, sse)
Definition: rematrix_init.c:30
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
PPMode::chromMode
int chromMode
activates filters for chrominance
Definition: postprocess_internal.h:98
PPMode::baseDcDiff
int baseDcDiff
Definition: postprocess_internal.h:107
isHorizMinMaxOk_C
static int isHorizMinMaxOk_C(const uint8_t src[], int stride, int QP)
Definition: postprocess.c:198
FFSIGN
#define FFSIGN(a)
Definition: common.h:75
QP
#define QP(qP, depth)
Definition: h264data.c:190
val
static double val(void *priv, double ch)
Definition: aeval.c:77
pp_free_context
av_cold void pp_free_context(void *vc)
Definition: postprocess.c:865
PPMode
Postprocessing mode.
Definition: postprocess_internal.h:96
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
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
pp_free_mode
void pp_free_mode(pp_mode *mode)
Definition: postprocess.c:793
postprocess.h
postProcess
static void postProcess(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, const int8_t QPs[], int QPStride, int isColor, pp_mode *vm, pp_context *vc)
Definition: postprocess.c:523
pp_postprocess
void pp_postprocess(const uint8_t *src[3], const int srcStride[3], uint8_t *dst[3], const int dstStride[3], int width, int height, const int8_t *QP_store, int QPStride, pp_mode *vm, void *vc, int pict_type)
Definition: postprocess.c:888
intreadwrite.h
V_A_DEBLOCK
#define V_A_DEBLOCK
Definition: postprocess_internal.h:52
av_strtok
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition: avstring.c:178
pp_help
const char pp_help[]
a simple help text
Definition: postprocess.c:553
B
#define B
Definition: huffyuv.h:42
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
V_DEBLOCK
#define V_DEBLOCK
Definition: postprocess_internal.h:36
TEMP_NOISE_FILTER
#define TEMP_NOISE_FILTER
Definition: postprocess_internal.h:70
PP_CPU_CAPS_AUTO
#define PP_CPU_CAPS_AUTO
Definition: postprocess.h:92
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
pp_get_context
av_cold pp_context * pp_get_context(int width, int height, int cpuCaps)
Definition: postprocess.c:835
option
option
Definition: libkvazaar.c:320
horizClassify_C
static int horizClassify_C(const uint8_t src[], int stride, const PPContext *c)
Definition: postprocess.c:227
context_to_name
static const char * context_to_name(void *ptr)
Definition: postprocess.c:829
doHorizDefFilter_C
static void doHorizDefFilter_C(uint8_t dst[], int stride, const PPContext *c)
Definition: postprocess.c:245
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
MEDIAN_DEINT_FILTER
#define MEDIAN_DEINT_FILTER
Definition: postprocess_internal.h:66
AV_RN32
#define AV_RN32(p)
Definition: intreadwrite.h:360
linecpy
static void linecpy(void *dest, const void *src, int lines, int stride)
Definition: postprocess_internal.h:177
reallocBuffers
static void reallocBuffers(PPContext *c, int width, int height, int stride, int qpStride)
Definition: postprocess.c:802
GET_MODE_BUFFER_SIZE
#define GET_MODE_BUFFER_SIZE
Definition: postprocess.c:92
V_X1_FILTER
#define V_X1_FILTER
Definition: postprocess_internal.h:51
AV_CPU_FLAG_ALTIVEC
#define AV_CPU_FLAG_ALTIVEC
standard
Definition: cpu.h:61
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
AV_CPU_FLAG_SSE2
#define AV_CPU_FLAG_SSE2
PIV SSE2 functions.
Definition: cpu.h:35
options
const OptionDef options[]
BITEXACT
#define BITEXACT
Definition: postprocess_internal.h:72
height
#define height
Definition: dsp.h:85
AV_WN32
#define AV_WN32(p, v)
Definition: intreadwrite.h:372
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
cpu.h
postprocess_internal.h
size
int size
Definition: twinvq_data.h:10344
isVertMinMaxOk_C
static int isVertMinMaxOk_C(const uint8_t src[], int stride, int QP)
Definition: postprocess.c:214
pp_mode
void pp_mode
Definition: postprocess.h:65
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_DEBLOCK
#define H_DEBLOCK
Definition: postprocess_internal.h:37
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
DERING
#define DERING
Definition: postprocess_internal.h:38
do_a_deblock_C
static av_always_inline void do_a_deblock_C(uint8_t *src, int step, int stride, const PPContext *c, int mode)
accurate deblock filter
Definition: postprocess.c:381
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
VISUALIZE
#define VISUALIZE
Definition: postprocess_internal.h:73
common.h
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
PPMode::minAllowedY
int minAllowedY
for brightness correction
Definition: postprocess_internal.h:101
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
stride
#define stride
Definition: h264pred_template.c:537
CUBIC_IPOL_DEINT_FILTER
#define CUBIC_IPOL_DEINT_FILTER
Definition: postprocess_internal.h:65
PP_CPU_CAPS_ALTIVEC
#define PP_CPU_CAPS_ALTIVEC
Definition: postprocess.h:91
pp_fn
void(* pp_fn)(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, const int8_t QPs[], int QPStride, int isColor, PPContext *c2)
Definition: postprocess.c:520
isHorizDC_C
static int isHorizDC_C(const uint8_t src[], int stride, const PPContext *c)
Check if the given 8x8 Block is mostly "flat".
Definition: postprocess.c:153
DECLARE_ASM_CONST
DECLARE_ASM_CONST(8, int, deringThreshold)
c2
static const uint64_t c2
Definition: murmur3.c:53
mode
mode
Definition: ebur128.h:83
doHorizLowPass_C
static void doHorizLowPass_C(uint8_t dst[], int stride, const PPContext *c)
Do a horizontal low pass filter on the 10x8 block (dst points to middle 8x8 Block) using the 9-Tap Fi...
Definition: postprocess.c:284
PPFilter::shortName
const char * shortName
Definition: postprocess_internal.h:85
LINEAR_BLEND_DEINT_FILTER
#define LINEAR_BLEND_DEINT_FILTER
Definition: postprocess_internal.h:63
temp
else temp
Definition: vf_mcdeint.c:263
PPMode::error
int error
non zero on error
Definition: postprocess_internal.h:99
vertClassify_C
static int vertClassify_C(const uint8_t src[], int stride, const PPContext *c)
Definition: postprocess.c:236
PPMode::maxClippedThreshold
AVRational maxClippedThreshold
amount of "black" you are willing to lose to get a brightness-corrected picture
Definition: postprocess_internal.h:103
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
LINEAR_IPOL_DEINT_FILTER
#define LINEAR_IPOL_DEINT_FILTER
Definition: postprocess_internal.h:62
mem.h
isVertDC_C
static int isVertDC_C(const uint8_t src[], int stride, const PPContext *c)
Check if the middle 8x8 Block in the given 8x16 block is flat.
Definition: postprocess.c:176
util_altivec.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
H_X1_FILTER
#define H_X1_FILTER
Definition: postprocess_internal.h:55
PPMode::maxTmpNoise
int maxTmpNoise[3]
for Temporal Noise Reducing filter (Maximal sum of abs differences)
Definition: postprocess_internal.h:105
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
OPTIONS_ARRAY_SIZE
#define OPTIONS_ARRAY_SIZE
Definition: postprocess.c:93
BLOCK_SIZE
#define BLOCK_SIZE
Definition: postprocess.c:94
avstring.h
width
#define width
Definition: dsp.h:85
pp_context
void pp_context
Definition: postprocess.h:64
LEVEL_FIX
#define LEVEL_FIX
Brightness & Contrast.
Definition: postprocess_internal.h:39
PPFilter
Postprocessing filter.
Definition: postprocess_internal.h:84
PPMode::forcedQuant
int forcedQuant
quantizer if FORCE_QUANT is used
Definition: postprocess_internal.h:110
src
#define src
Definition: vp8dsp.c:248
PPMode::lumMode
int lumMode
activates filters for luminance
Definition: postprocess_internal.h:97
PPMode::maxAllowedY
int maxAllowedY
for brightness correction
Definition: postprocess_internal.h:102
min
float min
Definition: vorbis_enc_data.h:429