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