yading@11: /* yading@11: * Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at) yading@11: * yading@11: * AltiVec optimizations (C) 2004 Romain Dolbeau yading@11: * yading@11: * This file is part of FFmpeg. yading@11: * yading@11: * FFmpeg is free software; you can redistribute it and/or modify yading@11: * it under the terms of the GNU General Public License as published by yading@11: * the Free Software Foundation; either version 2 of the License, or yading@11: * (at your option) any later version. yading@11: * yading@11: * FFmpeg is distributed in the hope that it will be useful, yading@11: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the yading@11: * GNU General Public License for more details. yading@11: * yading@11: * You should have received a copy of the GNU General Public License yading@11: * along with FFmpeg; if not, write to the Free Software yading@11: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@11: */ yading@11: yading@11: /** yading@11: * @file yading@11: * postprocessing. yading@11: */ yading@11: yading@11: /* yading@11: C MMX MMX2 3DNow AltiVec yading@11: isVertDC Ec Ec Ec yading@11: isVertMinMaxOk Ec Ec Ec yading@11: doVertLowPass E e e Ec yading@11: doVertDefFilter Ec Ec e e Ec yading@11: isHorizDC Ec Ec Ec yading@11: isHorizMinMaxOk a E Ec yading@11: doHorizLowPass E e e Ec yading@11: doHorizDefFilter Ec Ec e e Ec yading@11: do_a_deblock Ec E Ec E yading@11: deRing E e e* Ecp yading@11: Vertical RKAlgo1 E a a yading@11: Horizontal RKAlgo1 a a yading@11: Vertical X1# a E E yading@11: Horizontal X1# a E E yading@11: LinIpolDeinterlace e E E* yading@11: CubicIpolDeinterlace a e e* yading@11: LinBlendDeinterlace e E E* yading@11: MedianDeinterlace# E Ec Ec yading@11: TempDeNoiser# E e e Ec yading@11: yading@11: * I do not have a 3DNow! CPU -> it is untested, but no one said it does not work so it seems to work yading@11: # more or less selfinvented filters so the exactness is not too meaningful yading@11: E = Exact implementation yading@11: e = almost exact implementation (slightly different rounding,...) yading@11: a = alternative / approximate impl yading@11: c = checked against the other implementations (-vo md5) yading@11: p = partially optimized, still some work to do yading@11: */ yading@11: yading@11: /* yading@11: TODO: yading@11: reduce the time wasted on the mem transfer yading@11: unroll stuff if instructions depend too much on the prior one yading@11: move YScale thing to the end instead of fixing QP yading@11: write a faster and higher quality deblocking filter :) yading@11: make the mainloop more flexible (variable number of blocks at once yading@11: (the if/else stuff per block is slowing things down) yading@11: compare the quality & speed of all filters yading@11: split this huge file yading@11: optimize c versions yading@11: try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks yading@11: ... yading@11: */ yading@11: yading@11: //Changelog: use git log yading@11: yading@11: #include "config.h" yading@11: #include "libavutil/avutil.h" yading@11: #include "libavutil/avassert.h" yading@11: #include yading@11: #include yading@11: #include yading@11: #include yading@11: //#undef HAVE_MMXEXT_INLINE yading@11: //#define HAVE_AMD3DNOW_INLINE yading@11: //#undef HAVE_MMX_INLINE yading@11: //#undef ARCH_X86 yading@11: //#define DEBUG_BRIGHTNESS yading@11: #include "postprocess.h" yading@11: #include "postprocess_internal.h" yading@11: #include "libavutil/avstring.h" yading@11: yading@11: unsigned postproc_version(void) yading@11: { yading@11: av_assert0(LIBPOSTPROC_VERSION_MICRO >= 100); yading@11: return LIBPOSTPROC_VERSION_INT; yading@11: } yading@11: yading@11: const char *postproc_configuration(void) yading@11: { yading@11: return FFMPEG_CONFIGURATION; yading@11: } yading@11: yading@11: const char *postproc_license(void) yading@11: { yading@11: #define LICENSE_PREFIX "libpostproc license: " yading@11: return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; yading@11: } yading@11: yading@11: #if HAVE_ALTIVEC_H yading@11: #include yading@11: #endif yading@11: yading@11: #define GET_MODE_BUFFER_SIZE 500 yading@11: #define OPTIONS_ARRAY_SIZE 10 yading@11: #define BLOCK_SIZE 8 yading@11: #define TEMP_STRIDE 8 yading@11: //#define NUM_BLOCKS_AT_ONCE 16 //not used yet yading@11: yading@11: #if ARCH_X86 && HAVE_INLINE_ASM yading@11: DECLARE_ASM_CONST(8, uint64_t, w05)= 0x0005000500050005LL; yading@11: DECLARE_ASM_CONST(8, uint64_t, w04)= 0x0004000400040004LL; yading@11: DECLARE_ASM_CONST(8, uint64_t, w20)= 0x0020002000200020LL; yading@11: DECLARE_ASM_CONST(8, uint64_t, b00)= 0x0000000000000000LL; yading@11: DECLARE_ASM_CONST(8, uint64_t, b01)= 0x0101010101010101LL; yading@11: DECLARE_ASM_CONST(8, uint64_t, b02)= 0x0202020202020202LL; yading@11: DECLARE_ASM_CONST(8, uint64_t, b08)= 0x0808080808080808LL; yading@11: DECLARE_ASM_CONST(8, uint64_t, b80)= 0x8080808080808080LL; yading@11: #endif yading@11: yading@11: DECLARE_ASM_CONST(8, int, deringThreshold)= 20; yading@11: yading@11: yading@11: static const struct PPFilter filters[]= yading@11: { yading@11: {"hb", "hdeblock", 1, 1, 3, H_DEBLOCK}, yading@11: {"vb", "vdeblock", 1, 2, 4, V_DEBLOCK}, yading@11: /* {"hr", "rkhdeblock", 1, 1, 3, H_RK1_FILTER}, yading@11: {"vr", "rkvdeblock", 1, 2, 4, V_RK1_FILTER},*/ yading@11: {"h1", "x1hdeblock", 1, 1, 3, H_X1_FILTER}, yading@11: {"v1", "x1vdeblock", 1, 2, 4, V_X1_FILTER}, yading@11: {"ha", "ahdeblock", 1, 1, 3, H_A_DEBLOCK}, yading@11: {"va", "avdeblock", 1, 2, 4, V_A_DEBLOCK}, yading@11: {"dr", "dering", 1, 5, 6, DERING}, yading@11: {"al", "autolevels", 0, 1, 2, LEVEL_FIX}, yading@11: {"lb", "linblenddeint", 1, 1, 4, LINEAR_BLEND_DEINT_FILTER}, yading@11: {"li", "linipoldeint", 1, 1, 4, LINEAR_IPOL_DEINT_FILTER}, yading@11: {"ci", "cubicipoldeint", 1, 1, 4, CUBIC_IPOL_DEINT_FILTER}, yading@11: {"md", "mediandeint", 1, 1, 4, MEDIAN_DEINT_FILTER}, yading@11: {"fd", "ffmpegdeint", 1, 1, 4, FFMPEG_DEINT_FILTER}, yading@11: {"l5", "lowpass5", 1, 1, 4, LOWPASS5_DEINT_FILTER}, yading@11: {"tn", "tmpnoise", 1, 7, 8, TEMP_NOISE_FILTER}, yading@11: {"fq", "forcequant", 1, 0, 0, FORCE_QUANT}, yading@11: {"be", "bitexact", 1, 0, 0, BITEXACT}, yading@11: {NULL, NULL,0,0,0,0} //End Marker yading@11: }; yading@11: yading@11: static const char *replaceTable[]= yading@11: { yading@11: "default", "hb:a,vb:a,dr:a", yading@11: "de", "hb:a,vb:a,dr:a", yading@11: "fast", "h1:a,v1:a,dr:a", yading@11: "fa", "h1:a,v1:a,dr:a", yading@11: "ac", "ha:a:128:7,va:a,dr:a", yading@11: NULL //End Marker yading@11: }; yading@11: yading@11: yading@11: #if ARCH_X86 && HAVE_INLINE_ASM yading@11: static inline void prefetchnta(void *p) yading@11: { yading@11: __asm__ volatile( "prefetchnta (%0)\n\t" yading@11: : : "r" (p) yading@11: ); yading@11: } yading@11: yading@11: static inline void prefetcht0(void *p) yading@11: { yading@11: __asm__ volatile( "prefetcht0 (%0)\n\t" yading@11: : : "r" (p) yading@11: ); yading@11: } yading@11: yading@11: static inline void prefetcht1(void *p) yading@11: { yading@11: __asm__ volatile( "prefetcht1 (%0)\n\t" yading@11: : : "r" (p) yading@11: ); yading@11: } yading@11: yading@11: static inline void prefetcht2(void *p) yading@11: { yading@11: __asm__ volatile( "prefetcht2 (%0)\n\t" yading@11: : : "r" (p) yading@11: ); yading@11: } yading@11: #endif yading@11: yading@11: /* The horizontal functions exist only in C because the MMX yading@11: * code is faster with vertical filters and transposing. */ yading@11: yading@11: /** yading@11: * Check if the given 8x8 Block is mostly "flat" yading@11: */ yading@11: static inline int isHorizDC_C(const uint8_t src[], int stride, const PPContext *c) yading@11: { yading@11: int numEq= 0; yading@11: int y; yading@11: const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; yading@11: const int dcThreshold= dcOffset*2 + 1; yading@11: yading@11: for(y=0; y c->ppMode.flatnessThreshold; yading@11: } yading@11: yading@11: /** yading@11: * Check if the middle 8x8 Block in the given 8x16 block is flat yading@11: */ yading@11: static inline int isVertDC_C(const uint8_t src[], int stride, const PPContext *c) yading@11: { yading@11: int numEq= 0; yading@11: int y; yading@11: const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; yading@11: const int dcThreshold= dcOffset*2 + 1; yading@11: yading@11: src+= stride*4; // src points to begin of the 8x8 Block yading@11: for(y=0; y c->ppMode.flatnessThreshold; yading@11: } yading@11: yading@11: static inline int isHorizMinMaxOk_C(const uint8_t src[], int stride, int QP) yading@11: { yading@11: int i; yading@11: for(i=0; i<2; i++){ yading@11: if((unsigned)(src[0] - src[5] + 2*QP) > 4*QP) return 0; yading@11: src += stride; yading@11: if((unsigned)(src[2] - src[7] + 2*QP) > 4*QP) return 0; yading@11: src += stride; yading@11: if((unsigned)(src[4] - src[1] + 2*QP) > 4*QP) return 0; yading@11: src += stride; yading@11: if((unsigned)(src[6] - src[3] + 2*QP) > 4*QP) return 0; yading@11: src += stride; yading@11: } yading@11: return 1; yading@11: } yading@11: yading@11: static inline int isVertMinMaxOk_C(const uint8_t src[], int stride, int QP) yading@11: { yading@11: int x; yading@11: src+= stride*4; yading@11: for(x=0; x 4*QP) return 0; yading@11: if((unsigned)(src[1+x + 2*stride] - src[1+x + 7*stride] + 2*QP) > 4*QP) return 0; yading@11: if((unsigned)(src[2+x + 4*stride] - src[2+x + 1*stride] + 2*QP) > 4*QP) return 0; yading@11: if((unsigned)(src[3+x + 6*stride] - src[3+x + 3*stride] + 2*QP) > 4*QP) return 0; yading@11: } yading@11: return 1; yading@11: } yading@11: yading@11: static inline int horizClassify_C(const uint8_t src[], int stride, const PPContext *c) yading@11: { yading@11: if( isHorizDC_C(src, stride, c) ){ yading@11: if( isHorizMinMaxOk_C(src, stride, c->QP) ) yading@11: return 1; yading@11: else yading@11: return 0; yading@11: }else{ yading@11: return 2; yading@11: } yading@11: } yading@11: yading@11: static inline int vertClassify_C(const uint8_t src[], int stride, const PPContext *c) yading@11: { yading@11: if( isVertDC_C(src, stride, c) ){ yading@11: if( isVertMinMaxOk_C(src, stride, c->QP) ) yading@11: return 1; yading@11: else yading@11: return 0; yading@11: }else{ yading@11: return 2; yading@11: } yading@11: } yading@11: yading@11: static inline void doHorizDefFilter_C(uint8_t dst[], int stride, const PPContext *c) yading@11: { yading@11: int y; yading@11: for(y=0; yQP){ yading@11: const int q=(dst[3] - dst[4])/2; yading@11: const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]); yading@11: const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]); yading@11: yading@11: int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) ); yading@11: d= FFMAX(d, 0); yading@11: yading@11: d= (5*d + 32) >> 6; yading@11: d*= FFSIGN(-middleEnergy); yading@11: yading@11: if(q>0) yading@11: { yading@11: d= d<0 ? 0 : d; yading@11: d= d>q ? q : d; yading@11: } yading@11: else yading@11: { yading@11: d= d>0 ? 0 : d; yading@11: d= dQP ? dst[-1] : dst[0]; yading@11: const int last= FFABS(dst[8] - dst[7]) < c->QP ? dst[8] : dst[7]; yading@11: yading@11: int sums[10]; yading@11: sums[0] = 4*first + dst[0] + dst[1] + dst[2] + 4; yading@11: sums[1] = sums[0] - first + dst[3]; yading@11: sums[2] = sums[1] - first + dst[4]; yading@11: sums[3] = sums[2] - first + dst[5]; yading@11: sums[4] = sums[3] - first + dst[6]; yading@11: sums[5] = sums[4] - dst[0] + dst[7]; yading@11: sums[6] = sums[5] - dst[1] + last; yading@11: sums[7] = sums[6] - dst[2] + last; yading@11: sums[8] = sums[7] - dst[3] + last; yading@11: sums[9] = sums[8] - dst[4] + last; yading@11: yading@11: dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4; yading@11: dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4; yading@11: dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4; yading@11: dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4; yading@11: dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4; yading@11: dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4; yading@11: dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4; yading@11: dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4; yading@11: yading@11: dst+= stride; yading@11: } yading@11: } yading@11: yading@11: /** yading@11: * Experimental Filter 1 (Horizontal) yading@11: * will not damage linear gradients yading@11: * Flat blocks should look like they were passed through the (1,1,2,2,4,2,2,1,1) 9-Tap filter yading@11: * can only smooth blocks at the expected locations (it cannot smooth them if they did move) yading@11: * MMX2 version does correct clipping C version does not yading@11: * not identical with the vertical one yading@11: */ yading@11: static inline void horizX1Filter(uint8_t *src, int stride, int QP) yading@11: { yading@11: int y; yading@11: static uint64_t lut[256]; yading@11: if(!lut[255]) yading@11: { yading@11: int i; yading@11: for(i=0; i<256; i++) yading@11: { yading@11: int v= i < 128 ? 2*i : 2*(i-256); yading@11: /* yading@11: //Simulate 112242211 9-Tap filter yading@11: uint64_t a= (v/16) & 0xFF; yading@11: uint64_t b= (v/8) & 0xFF; yading@11: uint64_t c= (v/4) & 0xFF; yading@11: uint64_t d= (3*v/8) & 0xFF; yading@11: */ yading@11: //Simulate piecewise linear interpolation yading@11: uint64_t a= (v/16) & 0xFF; yading@11: uint64_t b= (v*3/16) & 0xFF; yading@11: uint64_t c= (v*5/16) & 0xFF; yading@11: uint64_t d= (7*v/16) & 0xFF; yading@11: uint64_t A= (0x100 - a)&0xFF; yading@11: uint64_t B= (0x100 - b)&0xFF; yading@11: uint64_t C= (0x100 - c)&0xFF; yading@11: uint64_t D= (0x100 - c)&0xFF; yading@11: yading@11: lut[i] = (a<<56) | (b<<48) | (c<<40) | (d<<32) | yading@11: (D<<24) | (C<<16) | (B<<8) | (A); yading@11: //lut[i] = (v<<32) | (v<<24); yading@11: } yading@11: } yading@11: yading@11: for(y=0; yQP; yading@11: const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; yading@11: const int dcThreshold= dcOffset*2 + 1; yading@11: //START_TIMER yading@11: src+= step*4; // src points to begin of the 8x8 Block yading@11: for(y=0; y<8; y++){ yading@11: int numEq= 0; yading@11: yading@11: if(((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold) numEq++; yading@11: if(((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold) numEq++; yading@11: if(((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold) numEq++; yading@11: if(((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold) numEq++; yading@11: if(((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold) numEq++; yading@11: if(((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold) numEq++; yading@11: if(((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold) numEq++; yading@11: if(((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold) numEq++; yading@11: if(((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold) numEq++; yading@11: if(numEq > c->ppMode.flatnessThreshold){ yading@11: int min, max, x; yading@11: yading@11: if(src[0] > src[step]){ yading@11: max= src[0]; yading@11: min= src[step]; yading@11: }else{ yading@11: max= src[step]; yading@11: min= src[0]; yading@11: } yading@11: for(x=2; x<8; x+=2){ yading@11: if(src[x*step] > src[(x+1)*step]){ yading@11: if(src[x *step] > max) max= src[ x *step]; yading@11: if(src[(x+1)*step] < min) min= src[(x+1)*step]; yading@11: }else{ yading@11: if(src[(x+1)*step] > max) max= src[(x+1)*step]; yading@11: if(src[ x *step] < min) min= src[ x *step]; yading@11: } yading@11: } yading@11: if(max-min < 2*QP){ yading@11: const int first= FFABS(src[-1*step] - src[0]) < QP ? src[-1*step] : src[0]; yading@11: const int last= FFABS(src[8*step] - src[7*step]) < QP ? src[8*step] : src[7*step]; yading@11: yading@11: int sums[10]; yading@11: sums[0] = 4*first + src[0*step] + src[1*step] + src[2*step] + 4; yading@11: sums[1] = sums[0] - first + src[3*step]; yading@11: sums[2] = sums[1] - first + src[4*step]; yading@11: sums[3] = sums[2] - first + src[5*step]; yading@11: sums[4] = sums[3] - first + src[6*step]; yading@11: sums[5] = sums[4] - src[0*step] + src[7*step]; yading@11: sums[6] = sums[5] - src[1*step] + last; yading@11: sums[7] = sums[6] - src[2*step] + last; yading@11: sums[8] = sums[7] - src[3*step] + last; yading@11: sums[9] = sums[8] - src[4*step] + last; yading@11: yading@11: src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4; yading@11: src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4; yading@11: src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4; yading@11: src[3*step]= (sums[3] + sums[5] + 2*src[3*step])>>4; yading@11: src[4*step]= (sums[4] + sums[6] + 2*src[4*step])>>4; yading@11: src[5*step]= (sums[5] + sums[7] + 2*src[5*step])>>4; yading@11: src[6*step]= (sums[6] + sums[8] + 2*src[6*step])>>4; yading@11: src[7*step]= (sums[7] + sums[9] + 2*src[7*step])>>4; yading@11: } yading@11: }else{ yading@11: const int middleEnergy= 5*(src[4*step] - src[3*step]) + 2*(src[2*step] - src[5*step]); yading@11: yading@11: if(FFABS(middleEnergy) < 8*QP){ yading@11: const int q=(src[3*step] - src[4*step])/2; yading@11: const int leftEnergy= 5*(src[2*step] - src[1*step]) + 2*(src[0*step] - src[3*step]); yading@11: const int rightEnergy= 5*(src[6*step] - src[5*step]) + 2*(src[4*step] - src[7*step]); yading@11: yading@11: int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) ); yading@11: d= FFMAX(d, 0); yading@11: yading@11: d= (5*d + 32) >> 6; yading@11: d*= FFSIGN(-middleEnergy); yading@11: yading@11: if(q>0){ yading@11: d= d<0 ? 0 : d; yading@11: d= d>q ? q : d; yading@11: }else{ yading@11: d= d>0 ? 0 : d; yading@11: d= dppMode= *ppMode; //FIXME yading@11: yading@11: if (!(ppMode->lumMode & BITEXACT)) { yading@11: #if CONFIG_RUNTIME_CPUDETECT yading@11: #if ARCH_X86 && HAVE_INLINE_ASM yading@11: // ordered per speed fastest first yading@11: if (c->cpuCaps & AV_CPU_FLAG_SSE2) pp = postProcess_SSE2; yading@11: else if (c->cpuCaps & AV_CPU_FLAG_MMXEXT) pp = postProcess_MMX2; yading@11: else if (c->cpuCaps & AV_CPU_FLAG_3DNOW) pp = postProcess_3DNow; yading@11: else if (c->cpuCaps & AV_CPU_FLAG_MMX) pp = postProcess_MMX; yading@11: #elif HAVE_ALTIVEC yading@11: if (c->cpuCaps & AV_CPU_FLAG_ALTIVEC) pp = postProcess_altivec; yading@11: #endif yading@11: #else /* CONFIG_RUNTIME_CPUDETECT */ yading@11: #if HAVE_SSE2_INLINE yading@11: pp = postProcess_SSE2; yading@11: #elif HAVE_MMXEXT_INLINE yading@11: pp = postProcess_MMX2; yading@11: #elif HAVE_AMD3DNOW_INLINE yading@11: pp = postProcess_3DNow; yading@11: #elif HAVE_MMX_INLINE yading@11: pp = postProcess_MMX; yading@11: #elif HAVE_ALTIVEC yading@11: pp = postProcess_altivec; yading@11: #endif yading@11: #endif /* !CONFIG_RUNTIME_CPUDETECT */ yading@11: } yading@11: yading@11: pp(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); yading@11: } yading@11: yading@11: /* -pp Command line Help yading@11: */ yading@11: const char pp_help[] = yading@11: "Available postprocessing filters:\n" yading@11: "Filters Options\n" yading@11: "short long name short long option Description\n" yading@11: "* * a autoq CPU power dependent enabler\n" yading@11: " c chrom chrominance filtering enabled\n" yading@11: " y nochrom chrominance filtering disabled\n" yading@11: " n noluma luma filtering disabled\n" yading@11: "hb hdeblock (2 threshold) horizontal deblocking filter\n" yading@11: " 1. difference factor: default=32, higher -> more deblocking\n" yading@11: " 2. flatness threshold: default=39, lower -> more deblocking\n" yading@11: " the h & v deblocking filters share these\n" yading@11: " so you can't set different thresholds for h / v\n" yading@11: "vb vdeblock (2 threshold) vertical deblocking filter\n" yading@11: "ha hadeblock (2 threshold) horizontal deblocking filter\n" yading@11: "va vadeblock (2 threshold) vertical deblocking filter\n" yading@11: "h1 x1hdeblock experimental h deblock filter 1\n" yading@11: "v1 x1vdeblock experimental v deblock filter 1\n" yading@11: "dr dering deringing filter\n" yading@11: "al autolevels automatic brightness / contrast\n" yading@11: " f fullyrange stretch luminance to (0..255)\n" yading@11: "lb linblenddeint linear blend deinterlacer\n" yading@11: "li linipoldeint linear interpolating deinterlace\n" yading@11: "ci cubicipoldeint cubic interpolating deinterlacer\n" yading@11: "md mediandeint median deinterlacer\n" yading@11: "fd ffmpegdeint ffmpeg deinterlacer\n" yading@11: "l5 lowpass5 FIR lowpass deinterlacer\n" yading@11: "de default hb:a,vb:a,dr:a\n" yading@11: "fa fast h1:a,v1:a,dr:a\n" yading@11: "ac ha:a:128:7,va:a,dr:a\n" yading@11: "tn tmpnoise (3 threshold) temporal noise reducer\n" yading@11: " 1. <= 2. <= 3. larger -> stronger filtering\n" yading@11: "fq forceQuant force quantizer\n" yading@11: "Usage:\n" yading@11: "[: