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