From c955eeae14c2fc2924c20eb840488b1d055e655c Mon Sep 17 00:00:00 2001 From: michael Date: Mon, 21 Jan 2002 15:22:28 +0000 Subject: [PATCH] a few filters (should be removed/merged when arpis videofilter stuff is finished) -ssf cgb= -> chrominance gaussian blur (nice to improve picture quality) -ssf lgb= -> luminance gaussian blur (dunno what its good for) -ssf chs= -> shift chrominance horizontally -ssf cvs= -> shift chrominance vertically these will only work if the swscaler is used at all git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4295 b3059339-0415-0410-9bf9-f77b7e298cf2 --- cfg-common.h | 14 ++++++ postproc/swscale.c | 113 ++++++++++++++++++++++++++++++++++++--------- postproc/swscale.h | 9 ++-- 3 files changed, 109 insertions(+), 27 deletions(-) diff --git a/cfg-common.h b/cfg-common.h index 0290b0d91c..580e59a9dd 100644 --- a/cfg-common.h +++ b/cfg-common.h @@ -77,6 +77,7 @@ {"oldpp", "MPlayer was compiled without opendivx library\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL}, #endif {"sws", &sws_flags, CONF_TYPE_INT, 0, 0, 2, NULL}, + {"ssf", scaler_filter_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #ifdef USE_TV {"tv", tvopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, @@ -109,6 +110,19 @@ struct config tvopts_conf[]={ }; #endif +extern int sws_chr_vshift; +extern int sws_chr_hshift; +extern float sws_chr_gblur; +extern float sws_lum_gblur; + +struct config scaler_filter_conf[]={ + {"lgb", &sws_lum_gblur, CONF_TYPE_FLOAT, 0, 0, 100.0, NULL}, + {"cgb", &sws_chr_gblur, CONF_TYPE_FLOAT, 0, 0, 100.0, NULL}, + {"cvs", &sws_chr_vshift, CONF_TYPE_INT, 0, 0, 0, NULL}, + {"chs", &sws_chr_hshift, CONF_TYPE_INT, 0, 0, 0, NULL}, + {NULL, NULL, 0, 0, 0, 0, NULL} +}; + /* VIVO demuxer options: */ extern int vivo_param_version; extern char *vivo_param_acodec; diff --git a/postproc/swscale.c b/postproc/swscale.c index d4c9197ee1..405e3f1af7 100644 --- a/postproc/swscale.c +++ b/postproc/swscale.c @@ -60,7 +60,6 @@ TODO more intelligent missalignment avoidance for the horizontal scaler dither in C change the distance of the u & v buffer -Move static / global vars into a struct so multiple scalers can be used write special vertical cubic upscale version Optimize C code (yv12 / minmax) */ @@ -144,6 +143,14 @@ static int clip_yuvtab_40cf[768]; //global sws_flags from the command line int sws_flags=0; +//global srcFilter +SwsFilter src_filter= {NULL, NULL, NULL, NULL}; + +float sws_lum_gblur= 0.0; +float sws_chr_gblur= 0.0; +int sws_chr_vshift= 0; +int sws_chr_hshift= 0; + /* cpuCaps combined from cpudetect and whats actually compiled in (if there is no support for something compiled in it wont appear here) */ static CpuCaps cpuCaps; @@ -151,6 +158,8 @@ static CpuCaps cpuCaps; void (*swScale)(SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[])=NULL; +static SwsVector *getConvVec(SwsVector *a, SwsVector *b); + #ifdef CAN_COMPILE_X86_ASM void in_asm_used_var_warning_killer() { @@ -454,31 +463,39 @@ void SwScale_YV12slice(unsigned char* src[], int srcStride[], int srcSliceY , int flags=0; static int firstTime=1; int dstStride3[3]= {dstStride, dstStride>>1, dstStride>>1}; - static SwsFilter srcFilter={NULL, NULL, NULL, NULL}; if(firstTime) { flags= SWS_PRINT_INFO; firstTime=0; -{/* - SwsVector *g= getGaussianVec(1.7, 2); - SwsVector *id= getIdentityVec(); - scaleVec(g, 0.2); + if(src_filter.lumH) free(src_filter.lumH); + if(src_filter.lumV) free(src_filter.lumV); + if(src_filter.chrH) free(src_filter.chrH); + if(src_filter.chrV) free(src_filter.chrV); -// srcFilter.chrH= diffVec(id, g); -// srcFilter.chrH= shiftVec(id, 20); - srcFilter.chrH= g; -// freeVec(g); - freeVec(id); + if(sws_lum_gblur!=0.0){ + src_filter.lumH= getGaussianVec(sws_lum_gblur, 3.0); + src_filter.lumV= getGaussianVec(sws_lum_gblur, 3.0); + }else{ + src_filter.lumH= getIdentityVec(); + src_filter.lumV= getIdentityVec(); + } - normalizeVec(srcFilter.chrH, 1.0); - printVec(srcFilter.chrH); + if(sws_chr_gblur!=0.0){ + src_filter.chrH= getGaussianVec(sws_chr_gblur, 3.0); + src_filter.chrV= getGaussianVec(sws_chr_gblur, 3.0); + }else{ + src_filter.chrH= getIdentityVec(); + src_filter.chrV= getIdentityVec(); + } + + if(sws_chr_hshift) + shiftVec(src_filter.chrH, sws_chr_hshift); + + if(sws_chr_vshift) + shiftVec(src_filter.chrV, sws_chr_vshift); - srcFilter.lumV= srcFilter.lumH= srcFilter.chrV= srcFilter.chrH; - srcFilter.lumH = srcFilter.lumV = NULL; -// srcFilter.chrH = srcFilter.chrV = NULL; -*/} } switch(dstbpp) @@ -501,7 +518,7 @@ void SwScale_YV12slice(unsigned char* src[], int srcStride[], int srcSliceY , default:flags|= SWS_BILINEAR; break; } - if(!context) context=getSwsContext(srcW, srcH, IMGFMT_YV12, dstW, dstH, dstFormat, flags, &srcFilter, NULL); + if(!context) context=getSwsContext(srcW, srcH, IMGFMT_YV12, dstW, dstH, dstFormat, flags, &src_filter, NULL); swScale(context, src, srcStride, srcSliceY, srcSliceH, dst, dstStride3); @@ -660,7 +677,7 @@ static inline void initFilter(int16_t **outFilter, int16_t **filterPos, int *out scaleFilter.coeff= filter + i*filterSize; scaleFilter.length= filterSize; - if(srcFilter) outVec= convVec(srcFilter, &scaleFilter); + if(srcFilter) outVec= getConvVec(srcFilter, &scaleFilter); else outVec= &scaleFilter; ASSERT(outVec->length == filter2Size) @@ -945,6 +962,11 @@ SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int i; SwsFilter dummyFilter= {NULL, NULL, NULL, NULL}; +#ifdef ARCH_X86 + if(gCpuCaps.hasMMX) + asm volatile("emms\n\t"::: "memory"); +#endif + if(swScale==NULL) globalInit(); /* sanity check */ @@ -1243,7 +1265,7 @@ void scaleVec(SwsVector *a, double scalar){ a->coeff[i]*= scalar; } -SwsVector *convVec(SwsVector *a, SwsVector *b){ +static SwsVector *getConvVec(SwsVector *a, SwsVector *b){ int length= a->length + b->length - 1; double *coeff= memalign(sizeof(double), length*sizeof(double)); int i, j; @@ -1265,7 +1287,7 @@ SwsVector *convVec(SwsVector *a, SwsVector *b){ return vec; } -SwsVector *sumVec(SwsVector *a, SwsVector *b){ +static SwsVector *sumVec(SwsVector *a, SwsVector *b){ int length= MAX(a->length, b->length); double *coeff= memalign(sizeof(double), length*sizeof(double)); int i; @@ -1282,7 +1304,7 @@ SwsVector *sumVec(SwsVector *a, SwsVector *b){ return vec; } -SwsVector *diffVec(SwsVector *a, SwsVector *b){ +static SwsVector *diffVec(SwsVector *a, SwsVector *b){ int length= MAX(a->length, b->length); double *coeff= memalign(sizeof(double), length*sizeof(double)); int i; @@ -1300,7 +1322,7 @@ SwsVector *diffVec(SwsVector *a, SwsVector *b){ } /* shift left / or right if "shift" is negative */ -SwsVector *shiftVec(SwsVector *a, int shift){ +static SwsVector *getShiftedVec(SwsVector *a, int shift){ int length= a->length + ABS(shift)*2; double *coeff= memalign(sizeof(double), length*sizeof(double)); int i, j; @@ -1319,6 +1341,51 @@ SwsVector *shiftVec(SwsVector *a, int shift){ return vec; } +void shiftVec(SwsVector *a, int shift){ + SwsVector *shifted= getShiftedVec(a, shift); + free(a->coeff); + a->coeff= shifted->coeff; + a->length= shifted->length; + free(shifted); +} + +void addVec(SwsVector *a, SwsVector *b){ + SwsVector *sum= sumVec(a, b); + free(a->coeff); + a->coeff= sum->coeff; + a->length= sum->length; + free(sum); +} + +void subVec(SwsVector *a, SwsVector *b){ + SwsVector *diff= diffVec(a, b); + free(a->coeff); + a->coeff= diff->coeff; + a->length= diff->length; + free(diff); +} + +void convVec(SwsVector *a, SwsVector *b){ + SwsVector *conv= getConvVec(a, b); + free(a->coeff); + a->coeff= conv->coeff; + a->length= conv->length; + free(conv); +} + +SwsVector *cloneVec(SwsVector *a){ + double *coeff= memalign(sizeof(double), a->length*sizeof(double)); + int i; + SwsVector *vec= malloc(sizeof(SwsVector)); + + vec->coeff= coeff; + vec->length= a->length; + + for(i=0; ilength; i++) coeff[i]= a->coeff[i]; + + return vec; +} + void printVec(SwsVector *a){ int i; double max=0; diff --git a/postproc/swscale.h b/postproc/swscale.h index d88a0b79fa..fd91ff052f 100644 --- a/postproc/swscale.h +++ b/postproc/swscale.h @@ -94,10 +94,11 @@ SwsVector *getGaussianVec(double variance, double quality); SwsVector *getIdentityVec(void); void scaleVec(SwsVector *a, double scalar); void normalizeVec(SwsVector *a, double height); -SwsVector *convVec(SwsVector *a, SwsVector *b); -SwsVector *sumVec(SwsVector *a, SwsVector *b); -SwsVector *diffVec(SwsVector *a, SwsVector *b); -SwsVector *shiftVec(SwsVector *a, int shift); +void convVec(SwsVector *a, SwsVector *b); +void addVec(SwsVector *a, SwsVector *b); +void subVec(SwsVector *a, SwsVector *b); +void shiftVec(SwsVector *a, int shift); +SwsVector *cloneVec(SwsVector *a); void printVec(SwsVector *a); void freeVec(SwsVector *a);