diff options
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/filter_kernels.c | 20 | ||||
-rw-r--r-- | video/out/filter_kernels.h | 5 | ||||
-rw-r--r-- | video/out/opengl/video.c | 3 | ||||
-rw-r--r-- | video/out/opengl/video_shaders.c | 4 |
4 files changed, 20 insertions, 12 deletions
diff --git a/video/out/filter_kernels.c b/video/out/filter_kernels.c index 68f03ac2e3..11680a064a 100644 --- a/video/out/filter_kernels.c +++ b/video/out/filter_kernels.c @@ -28,6 +28,7 @@ #include <assert.h> #include "filter_kernels.h" +#include "common/common.h" // NOTE: all filters are designed for discrete convolution @@ -60,19 +61,20 @@ bool mp_init_filter(struct filter_kernel *filter, const int *sizes, { assert(filter->f.radius > 0); // Only downscaling requires widening the filter - filter->inv_scale = inv_scale >= 1.0 ? inv_scale : 1.0; - filter->f.radius *= filter->inv_scale; + filter->filter_scale = MPMAX(1.0, inv_scale); + double src_radius = filter->f.radius * filter->filter_scale; // Polar filters are dependent solely on the radius if (filter->polar) { - filter->size = 1; + filter->size = 1; // Not meaningful for EWA/polar scalers. // Safety precaution to avoid generating a gigantic shader - if (filter->f.radius > 16.0) { - filter->f.radius = 16.0; + if (src_radius > 16.0) { + src_radius = 16.0; + filter->filter_scale = src_radius / filter->f.radius; return false; } return true; } - int size = ceil(2.0 * filter->f.radius); + int size = ceil(2.0 * src_radius); // round up to smallest available size that's still large enough if (size < sizes[0]) size = sizes[0]; @@ -87,7 +89,7 @@ bool mp_init_filter(struct filter_kernel *filter, const int *sizes, // largest filter available. This is incorrect, but better than refusing // to do anything. filter->size = cursize[-1]; - filter->inv_scale *= (filter->size/2.0) / filter->f.radius; + filter->filter_scale = (filter->size/2.0) / filter->f.radius; return false; } } @@ -115,7 +117,7 @@ static double sample_filter(struct filter_kernel *filter, double x) { // The window is always stretched to the entire kernel double w = sample_window(&filter->w, x / filter->f.radius * filter->w.radius); - double k = sample_window(&filter->f, x / filter->inv_scale); + double k = sample_window(&filter->f, x); return filter->clamp ? fmax(0.0, fmin(1.0, w * k)) : w * k; } @@ -130,7 +132,7 @@ static void mp_compute_weights(struct filter_kernel *filter, double f, double sum = 0; for (int n = 0; n < filter->size; n++) { double x = f - (n - filter->size / 2 + 1); - double w = sample_filter(filter, x); + double w = sample_filter(filter, x / filter->filter_scale); out_w[n] = w; sum += w; } diff --git a/video/out/filter_kernels.h b/video/out/filter_kernels.h index fc90a1cdde..74cc3eb148 100644 --- a/video/out/filter_kernels.h +++ b/video/out/filter_kernels.h @@ -34,7 +34,10 @@ struct filter_kernel { bool polar; // whether or not the filter uses polar coordinates // The following values are set by mp_init_filter() at runtime. int size; // number of coefficients (may depend on radius) - double inv_scale; // scale factor (<1.0 is upscale, >1.0 downscale) + double filter_scale; // Factor to convert the mathematical filter + // function radius to the possibly wider + // (in the case of downsampling) filter sample + // radius. }; extern const struct filter_window mp_filter_windows[]; diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index 013d27c291..3a19858953 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -3400,6 +3400,9 @@ void gl_video_configure_queue(struct gl_video *p, struct vo *vo) const struct filter_kernel *kernel = mp_find_filter_kernel(p->opts.scaler[SCALER_TSCALE].kernel.name); if (kernel) { + // filter_scale wouldn't be correctly initialized were we to use it here. + // This is fine since we're always upsampling, but beware if downsampling + // is added! double radius = kernel->f.radius; radius = radius > 0 ? radius : p->opts.scaler[SCALER_TSCALE].radius; queue_size += 1 + ceil(radius); diff --git a/video/out/opengl/video_shaders.c b/video/out/opengl/video_shaders.c index 7d668dc4b8..5421589d06 100644 --- a/video/out/opengl/video_shaders.c +++ b/video/out/opengl/video_shaders.c @@ -107,8 +107,8 @@ void pass_sample_separated_gen(struct gl_shader_cache *sc, struct scaler *scaler void pass_sample_polar(struct gl_shader_cache *sc, struct scaler *scaler) { - double radius = scaler->kernel->f.radius; - int bound = (int)ceil(radius); + double radius = scaler->kernel->f.radius * scaler->kernel->filter_scale; + int bound = ceil(radius); bool use_ar = scaler->conf.antiring > 0; GLSL(color = vec4(0.0);) GLSLF("{\n"); |