summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/filter_kernels.c20
-rw-r--r--video/out/filter_kernels.h5
-rw-r--r--video/out/opengl/video.c3
-rw-r--r--video/out/opengl/video_shaders.c4
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");