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