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