Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save voltmtr/32f6d50037bb017a62c81e7c5bb55bb5 to your computer and use it in GitHub Desktop.
Save voltmtr/32f6d50037bb017a62c81e7c5bb55bb5 to your computer and use it in GitHub Desktop.
Super-xBR tweakable antiringing patch for mpv
From e7acb9ce6e1785b2c2166ddad9705fea779e3e14 Mon Sep 17 00:00:00 2001
From: example <example@example.com>
Date: Mon, 9 May 2016 17:23:50 +0300
Subject: [PATCH] vo_opengl: Super-xBR: add antiring and offset-bias suboptions
Add Hyllian's tweakable antiringing algorithm. superxbr-antiring
suboption can be between 0.0 and 1.0 (default=0). Add offset-bias
setting to tweak how Super-xBR is applied, setting this to lower values
can help with having thinner edges.
superxbr-offset-bias suboption can be between 0.01 and 1.0
(default=1.0).
---
DOCS/man/vo.rst | 5 +++--
video/out/opengl/superxbr.c | 48 ++++++++++++++++++++++++++++-----------------
2 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst
index bf3fb2e..8be6dd2 100644
--- a/DOCS/man/vo.rst
+++ b/DOCS/man/vo.rst
@@ -593,8 +593,9 @@ Available video output drivers are:
``superxbr``
A relatively fast prescaler originally developed for pixel art.
- Some parameters can be tuned with ``superxbr-sharpness`` and
- ``superxbr-edge-strength`` options.
+ Some parameters that can be tuned with are
+ ``superxbr-sharpness``, ``superxbr-edge-strength``,
+ ``superxbr-antiring`` and ``superxbr-offset-bias`` options.
``nnedi3``
An artificial neural network based deinterlacer, which can be used
diff --git a/video/out/opengl/superxbr.c b/video/out/opengl/superxbr.c
index 323ed18..0df04f0 100644
--- a/video/out/opengl/superxbr.c
+++ b/video/out/opengl/superxbr.c
@@ -27,11 +27,15 @@
struct superxbr_opts {
float sharpness;
float edge_strength;
+ float antiring;
+ float offset_bias;
};
const struct superxbr_opts superxbr_opts_def = {
.sharpness = 1.0f,
.edge_strength = 0.6f,
+ .antiring = 0.0f,
+ .offset_bias = 1.0f,
};
#define OPT_BASE_STRUCT struct superxbr_opts
@@ -39,6 +43,8 @@ const struct m_sub_options superxbr_conf = {
.opts = (const m_option_t[]) {
OPT_FLOATRANGE("sharpness", sharpness, 0, 0.0, 2.0),
OPT_FLOATRANGE("edge-strength", edge_strength, 0, 0.0, 1.0),
+ OPT_FLOATRANGE("antiring", antiring, 0, 0.0, 1.0),
+ OPT_FLOATRANGE("offset-bias", offset_bias, 0, 0.01, 1.0),
{0}
},
.size = sizeof(struct superxbr_opts),
@@ -137,17 +143,17 @@ static void superxbr_step_h(struct gl_shader_cache *sc,
for (int y = 0; y < 3; y++) {
if (mask->d1[x][y]) {
// 1-distance diagonal neighbours
- GLSLHF("d_edge += %d * abs(i(%d,%d) - i(%d,%d));\n",
- mask->d1[x][y], x+1, y, x, y+1);
- GLSLHF("d_edge -= %d * abs(i(%d,%d) - i(%d,%d));\n",
- mask->d1[x][y], 3-y, x+1, 3-(y+1), x); // rotated
+ GLSLHF("d_edge += %d * abs(i(%d,%d) - i(%d,%d)) * %f;\n",
+ mask->d1[x][y], x+1, y, x, y+1, conf->offset_bias);
+ GLSLHF("d_edge -= %d * abs(i(%d,%d) - i(%d,%d)) * %f;\n",
+ mask->d1[x][y], 3-y, x+1, 3-(y+1), x, conf->offset_bias); // rotated
}
if (x < 2 && y < 2 && mask->d2[x][y]) {
// 2-distance diagonal neighbours
- GLSLHF("d_edge += %d * abs(i(%d,%d) - i(%d,%d));\n",
- mask->d2[x][y], x+2, y, x, y+2);
- GLSLHF("d_edge -= %d * abs(i(%d,%d) - i(%d,%d));\n",
- mask->d2[x][y], 3-y, x+2, 3-(y+2), x); // rotated
+ GLSLHF("d_edge += %d * abs(i(%d,%d) - i(%d,%d)) * %f;\n",
+ mask->d2[x][y], x+2, y, x, y+2, conf->offset_bias);
+ GLSLHF("d_edge -= %d * abs(i(%d,%d) - i(%d,%d)) * %f;\n",
+ mask->d2[x][y], 3-y, x+2, 3-(y+2), x, conf->offset_bias); // rotated
}
}
}
@@ -158,17 +164,17 @@ static void superxbr_step_h(struct gl_shader_cache *sc,
for (int y = 0; y < 3; y++) {
if (mask->o1[y]) {
// 1-distance neighbours
- GLSLHF("o_edge += %d * abs(i(%d,%d) - i(%d,%d));\n",
- mask->o1[y], x, y, x, y+1); // vertical
- GLSLHF("o_edge -= %d * abs(i(%d,%d) - i(%d,%d));\n",
- mask->o1[y], y, x, y+1, x); // horizontal
+ GLSLHF("o_edge += %d * abs(i(%d,%d) - i(%d,%d)) * %f;\n",
+ mask->o1[y], x, y, x, y+1, conf->offset_bias); // vertical
+ GLSLHF("o_edge -= %d * abs(i(%d,%d) - i(%d,%d)) * %f;\n",
+ mask->o1[y], y, x, y+1, x, conf->offset_bias); // horizontal
}
if (y < 2 && mask->o2[y]) {
// 2-distance neighbours
- GLSLHF("o_edge += %d * abs(i(%d,%d) - i(%d,%d));\n",
- mask->o2[y], x, y, x, y+2); // vertical
- GLSLHF("o_edge -= %d * abs(i(%d,%d) - i(%d,%d));\n",
- mask->o2[x], y, x, y+2, x); // horizontal
+ GLSLHF("o_edge += %d * abs(i(%d,%d) - i(%d,%d)) * %f;\n",
+ mask->o2[y], x, y, x, y+2, conf->offset_bias); // vertical
+ GLSLHF("o_edge -= %d * abs(i(%d,%d) - i(%d,%d)) * %f;\n",
+ mask->o2[x], y, x, y+2, x, conf->offset_bias); // horizontal
}
}
}
@@ -180,8 +186,14 @@ static void superxbr_step_h(struct gl_shader_cache *sc,
mix(hc, vc, step(0.0, o_edge)), 1.0 - str);)
// Anti-ringing using center square
- GLSLH(float lo = min(min( i(1,1), i(2,1) ), min( i(1,2), i(2,2) ));)
- GLSLH(float hi = max(max( i(1,1), i(2,1) ), max( i(1,2), i(2,2) ));)
+ GLSLHF("float lo = min(min( i(1,1), i(2,1) ), min( i(1,2), i(2,2) )) \
+ + %f * mix(( i(0,3) - i(1,2) ) * ( i(2,1) - i(3,0) ), \
+ ( i(0,0) - i(1,1) ) * ( i(2,2) - i(3,3) ), \
+ step(0.0, d_edge));", conf->antiring);
+ GLSLHF("float hi = max(max( i(1,1), i(2,1) ), max( i(1,2), i(2,2) )) \
+ - %f * mix(( i(0,3) - i(1,2) ) * ( i(2,1)- i(3,0) ), \
+ ( i(0,0) - i(1,1) ) * ( i(2,2) - i(3,3) ), \
+ step(0.0, d_edge));", conf->antiring);
GLSLH(res = clamp(res, lo, hi);)
GLSLHF("} // step\n");
--
2.5.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment