summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorNiklas Haas <git@nand.wakku.to>2015-01-18 18:57:12 +0100
committerNiklas Haas <git@nand.wakku.to>2015-01-22 19:39:58 +0100
commit2d182fdea0a068cbbbe88b575963cbb480444f31 (patch)
tree407176b7db120a82106ccb05dbdce06917c635f8 /video
parent6c250505fedc54a3918788f70445f5fff9d2569a (diff)
downloadmpv-2d182fdea0a068cbbbe88b575963cbb480444f31.tar.bz2
mpv-2d182fdea0a068cbbbe88b575963cbb480444f31.tar.xz
vo_opengl: implement naive anti-ringing
This is not quite the same thing as madVR's antiringing algorithm, but it essentially does something similar. Porting madVR's approach to elliptic coordinates will take some amount of thought.
Diffstat (limited to 'video')
-rw-r--r--video/out/gl_video.c18
-rw-r--r--video/out/gl_video.h1
-rw-r--r--video/out/gl_video_shaders.glsl23
3 files changed, 32 insertions, 10 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 7400ffba0f..ddccd3a3e5 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -105,6 +105,7 @@ struct scaler {
int index;
const char *name;
float params[2];
+ float antiring;
struct filter_kernel *kernel;
GLuint gl_lut;
const char *lut_name;
@@ -367,6 +368,8 @@ const struct m_sub_options gl_video_conf = {
OPT_FLOAT("cparam2", scaler_params[1][1], 0),
OPT_FLOATRANGE("lradius", scaler_radius[0], 0, 1.0, 16.0),
OPT_FLOATRANGE("cradius", scaler_radius[1], 0, 1.0, 16.0),
+ OPT_FLOATRANGE("lantiring", scaler_antiring[0], 0, 0.0, 1.0),
+ OPT_FLOATRANGE("cantiring", scaler_antiring[1], 0, 0.0, 1.0),
OPT_FLAG("scaler-resizes-only", scaler_resizes_only, 0),
OPT_FLAG("fancy-downscaling", fancy_downscaling, 0),
OPT_FLAG("sigmoid-upscaling", sigmoid_upscaling, 0),
@@ -955,9 +958,9 @@ static void shader_setup_scaler(char **shader, struct scaler *scaler, int pass)
char lut_fn[40];
if (scaler->kernel->polar) {
int radius = (int)scaler->kernel->radius;
- // SAMPLE_CONVOLUTION_POLAR_R(NAME, R, LUT)
- APPENDF(shader, "SAMPLE_CONVOLUTION_POLAR_R(%s, %d, %s, WEIGHTS%d)\n",
- name, radius, lut_tex, unit);
+ // SAMPLE_CONVOLUTION_POLAR_R(NAME, R, LUT, WEIGHTS_FN, ANTIRING)
+ APPENDF(shader, "SAMPLE_CONVOLUTION_POLAR_R(%s, %d, %s, WEIGHTS%d, %f)\n",
+ name, radius, lut_tex, unit, scaler->antiring);
// Pre-compute unrolled weights matrix
APPENDF(shader, "#define WEIGHTS%d(LUT) \\\n ", unit);
@@ -971,7 +974,12 @@ static void shader_setup_scaler(char **shader, struct scaler *scaler, int pass)
// Samples outside the radius are unnecessary
if (d < radius) {
- APPENDF(shader, "SAMPLE_POLAR(LUT, %f, %d, %d) \\\n ",
+ APPENDF(shader, "SAMPLE_POLAR_%s(LUT, %f, %d, %d) \\\n ",
+ // The center 4 coefficients are the primary
+ // contributors, used to clamp the result for
+ // anti-ringing
+ (x >= 0 && y >= 0 && x <= 1 && y <= 1)
+ ? "PRIMARY" : "HELPER",
(double)radius, x, y);
}
}
@@ -1316,6 +1324,8 @@ static void init_scaler(struct gl_video *p, struct scaler *scaler)
scaler->kernel->params[n] = p->opts.scaler_params[scaler->index][n];
}
+ scaler->antiring = p->opts.scaler_antiring[scaler->index];
+
if (scaler->kernel->radius < 0) {
float radius = p->opts.scaler_radius[scaler->index];
if (!isnan(radius))
diff --git a/video/out/gl_video.h b/video/out/gl_video.h
index b3c5d5abe5..980f237a15 100644
--- a/video/out/gl_video.h
+++ b/video/out/gl_video.h
@@ -33,6 +33,7 @@ struct gl_video_opts {
char *dscaler;
float scaler_params[2][2];
float scaler_radius[2];
+ float scaler_antiring[2];
int indirect;
float gamma;
int srgb;
diff --git a/video/out/gl_video_shaders.glsl b/video/out/gl_video_shaders.glsl
index fa9bfa2e95..d3cbbb7c41 100644
--- a/video/out/gl_video_shaders.glsl
+++ b/video/out/gl_video_shaders.glsl
@@ -188,6 +188,7 @@ uniform float dither_quantization;
uniform float dither_center;
uniform float filter_param1_l;
uniform float filter_param1_c;
+uniform float antiring_factor;
uniform vec2 dither_size;
in vec2 texcoord;
@@ -298,21 +299,31 @@ float[6] weights6(sampler2D lookup, float f) {
return res; \
}
-#define SAMPLE_POLAR(LUT, R, X, Y) \
+#define SAMPLE_POLAR_HELPER(LUT, R, X, Y) \
w = texture1D(LUT, length(vec2(X, Y) - fcoord)/R).r; \
+ c = texture(tex, base + pt * vec2(X, Y)); \
wsum += w; \
- res += w * texture(tex, base + pt * vec2(X, Y)); \
+ res += w * c; \
-#define SAMPLE_CONVOLUTION_POLAR_R(NAME, R, LUT, WEIGHTS_FN) \
+#define SAMPLE_POLAR_PRIMARY(LUT, R, X, Y) \
+ SAMPLE_POLAR_HELPER(LUT, R, X, Y) \
+ lo = min(lo, c); \
+ hi = max(hi, c); \
+
+#define SAMPLE_CONVOLUTION_POLAR_R(NAME, R, LUT, WEIGHTS_FN, ANTIRING) \
vec4 NAME(VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord) { \
vec2 pt = vec2(1.0) / texsize; \
vec2 fcoord = fract(texcoord * texsize - vec2(0.5)); \
vec2 base = texcoord - fcoord * pt; \
- vec4 res = vec4(0); \
- float wsum = 0; \
+ vec4 res = vec4(0.0); \
+ vec4 lo = vec4(1.0); \
+ vec4 hi = vec4(0.0); \
+ float wsum = 0.0; \
float w; \
+ vec4 c; \
WEIGHTS_FN(LUT); \
- return res / wsum; \
+ res /= wsum; \
+ return mix(res, clamp(res, lo, hi), ANTIRING); \
}
#ifdef DEF_SCALER0