From 67a6203ce0a6b2f22132a5d30b0aa5b4980e6510 Mon Sep 17 00:00:00 2001 From: Bin Jin Date: Fri, 10 Jun 2016 12:35:09 +0000 Subject: vo_opengl: remove prescaling framework with superxbr prescaler Signed-off-by: wm4 --- DOCS/interface-changes.rst | 1 + DOCS/man/vo.rst | 32 ------ video/out/opengl/superxbr.c | 243 -------------------------------------------- video/out/opengl/superxbr.h | 31 ------ video/out/opengl/video.c | 70 +------------ video/out/opengl/video.h | 9 -- wscript_build.py | 1 - 7 files changed, 3 insertions(+), 384 deletions(-) delete mode 100644 video/out/opengl/superxbr.c delete mode 100644 video/out/opengl/superxbr.h diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index e29cf6b714..7ffbbd60e0 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -34,6 +34,7 @@ Interface changes such as well. - the VO opengl fbo-format sub-option does not accept "rgb" or "rgba" anymore + - all VO opengl prescalers have been removed (replaced by user scripts) --- mpv 0.17.0 --- - deprecate "track-list/N/audio-channels" property (use "track-list/N/demux-channel-count" instead) diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst index d59ddbba18..bdc317fc8f 100644 --- a/DOCS/man/vo.rst +++ b/DOCS/man/vo.rst @@ -582,38 +582,6 @@ Available video output drivers are: better than without it) since it will extend the size to match only the milder of the scale factors between the axes. - ``prescale-luma=`` - Apply additional pre-scaling (image doubling) on the luma plane - (if present). As the name implies, these will run before the main - upscaling pass. - - ``none`` - Disable all prescalers. This is the default. - - ``superxbr`` - A relatively fast prescaler originally developed for pixel art. - - Some parameters can be tuned with ``superxbr-sharpness`` and - ``superxbr-edge-strength`` options. - - ``prescale-passes=<1..5>`` - The number of passes to apply the prescaler (defaults to be 1). Setting - it to 2 will perform a 4x upscaling. - - ``prescale-downscaling-threshold=<0..32>`` - This option prevents "overkill" use of prescalers, which can be caused - by misconfiguration, or user trying to play a video with much larger - size. With this option, user can specify the maximal allowed downscaling - ratio in both dimension. To satisfy it, the number of passes for - prescaler will be reduced, and if necessary prescaler could also be - disabled. - - The default value is 2.0, and should be able to prevent most seemingly - unreasonable use of prescalers. Most user would probably want to set it - to a smaller value between 1.0 and 1.5 for better performance. - - A value less than 1.0 will disable the check. - ``pre-shaders=``, ``post-shaders=``, ``scale-shader=`` Custom GLSL fragment shaders. diff --git a/video/out/opengl/superxbr.c b/video/out/opengl/superxbr.c deleted file mode 100644 index 5c838ec51c..0000000000 --- a/video/out/opengl/superxbr.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * This file is part of mpv. - * - * mpv is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * mpv is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with mpv. If not, see . - */ - -#include "superxbr.h" - -#include - -#define GLSL(x) gl_sc_add(sc, #x "\n"); -#define GLSLF(...) gl_sc_addf(sc, __VA_ARGS__) -#define GLSLH(x) gl_sc_hadd(sc, #x "\n"); -#define GLSLHF(...) gl_sc_haddf(sc, __VA_ARGS__) - -struct superxbr_opts { - float sharpness; - float edge_strength; -}; - -const struct superxbr_opts superxbr_opts_def = { - .sharpness = 1.0f, - .edge_strength = 0.6f, -}; - -#define OPT_BASE_STRUCT struct superxbr_opts -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), - {0} - }, - .size = sizeof(struct superxbr_opts), - .defaults = &superxbr_opts_def, -}; - -/* - - ******* Super XBR Shader ******* - - Copyright (c) 2015 Hyllian - sergiogdb@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -*/ - -struct step_params { - const float dstr, ostr; // sharpness strength modifiers - const int d1[3][3]; // 1-distance diagonal mask - const int d2[2][2]; // 2-distance diagonal mask - const int o1[3]; // 1-distance orthogonal mask - const int o2[3]; // 2-distance orthogonal mask -}; - -const struct step_params params[3] = { - { .dstr = 0.129633, - .ostr = 0.175068, - .d1 = {{0, 1, 0}, - {1, 2, 1}, - {0, 1, 0}}, - .d2 = {{-1, 0}, - { 0, -1}}, - - .o1 = {1, 2, 1}, - .o2 = { 0, 0}, - }, { - .dstr = 0.175068, - .ostr = 0.129633, - .d1 = {{0, 1, 0}, - {1, 4, 1}, - {0, 1, 0}}, - .d2 = {{ 0, 0}, - { 0, 0}}, - - .o1 = {1, 4, 1}, - .o2 = { 0, 0}, - } -}; - -// Compute a single step of the superxbr process, assuming the input can be -// sampled using i(x,y). Dumps its output into 'res' -static void superxbr_step_h(struct gl_shader_cache *sc, - const struct superxbr_opts *conf, - const struct step_params *mask) -{ - GLSLHF("{ // step\n"); - - // Convolute along the diagonal and orthogonal lines - GLSLH(vec4 d1 = vec4( i(0,0), i(1,1), i(2,2), i(3,3) );) - GLSLH(vec4 d2 = vec4( i(0,3), i(1,2), i(2,1), i(3,0) );) - GLSLH(vec4 h1 = vec4( i(0,1), i(1,1), i(2,1), i(3,1) );) - GLSLH(vec4 h2 = vec4( i(0,2), i(1,2), i(2,2), i(3,2) );) - GLSLH(vec4 v1 = vec4( i(1,0), i(1,1), i(1,2), i(1,3) );) - GLSLH(vec4 v2 = vec4( i(2,0), i(2,1), i(2,2), i(2,3) );) - - GLSLHF("float dw = %f;\n", conf->sharpness * mask->dstr); - GLSLHF("float ow = %f;\n", conf->sharpness * mask->ostr); - GLSLH(vec4 dk = vec4(-dw, dw+0.5, dw+0.5, -dw);) // diagonal kernel - GLSLH(vec4 ok = vec4(-ow, ow+0.5, ow+0.5, -ow);) // ortho kernel - - // Convoluted results - GLSLH(float d1c = dot(d1, dk);) - GLSLH(float d2c = dot(d2, dk);) - GLSLH(float vc = dot(v1+v2, ok)/2.0;) - GLSLH(float hc = dot(h1+h2, ok)/2.0;) - - // Compute diagonal edge strength using diagonal mask - GLSLH(float d_edge = 0.0;) - for (int x = 0; x < 3; x++) { - for (int y = 0; y < 3; y++) { - if (mask->d1[x][y]) { - // 1-distance diagonal neighbours - GLSLHF("d_edge += %d.0 * abs(i(%d,%d) - i(%d,%d));\n", - mask->d1[x][y], x+1, y, x, y+1); - GLSLHF("d_edge -= %d.0 * abs(i(%d,%d) - i(%d,%d));\n", - mask->d1[x][y], 3-y, x+1, 3-(y+1), x); // rotated - } - if (x < 2 && y < 2 && mask->d2[x][y]) { - // 2-distance diagonal neighbours - GLSLHF("d_edge += %d.0 * abs(i(%d,%d) - i(%d,%d));\n", - mask->d2[x][y], x+2, y, x, y+2); - GLSLHF("d_edge -= %d.0 * abs(i(%d,%d) - i(%d,%d));\n", - mask->d2[x][y], 3-y, x+2, 3-(y+2), x); // rotated - } - } - } - - // Compute orthogonal edge strength using orthogonal mask - GLSLH(float o_edge = 0.0;) - for (int x = 1; x < 3; x++) { - for (int y = 0; y < 3; y++) { - if (mask->o1[y]) { - // 1-distance neighbours - GLSLHF("o_edge += %d.0 * abs(i(%d,%d) - i(%d,%d));\n", - mask->o1[y], x, y, x, y+1); // vertical - GLSLHF("o_edge -= %d.0 * abs(i(%d,%d) - i(%d,%d));\n", - mask->o1[y], y, x, y+1, x); // horizontal - } - if (y < 2 && mask->o2[y]) { - // 2-distance neighbours - GLSLHF("o_edge += %d.0 * abs(i(%d,%d) - i(%d,%d));\n", - mask->o2[y], x, y, x, y+2); // vertical - GLSLHF("o_edge -= %d.0 * abs(i(%d,%d) - i(%d,%d));\n", - mask->o2[x], y, x, y+2, x); // horizontal - } - } - } - - // Pick the two best directions and mix them together - GLSLHF("float str = smoothstep(0.0, %f + 1e-6, abs(d_edge));\n", - conf->edge_strength); - GLSLH(res = mix(mix(d2c, d1c, step(0.0, d_edge)), \ - 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) ));) - GLSLH(res = clamp(res, lo, hi);) - - GLSLHF("} // step\n"); -} - -void pass_superxbr(struct gl_shader_cache *sc, int step, - const struct superxbr_opts *conf, - struct gl_transform *transform) -{ - if (!conf) - conf = &superxbr_opts_def; - - assert(0 <= step && step < 2); - GLSLF("// superxbr (step %d)\n", step); - - // We use a sub-function in the header so we can return early - GLSLHF("float superxbr() {\n"); - GLSLH(float i[4*4];) - GLSLH(float res;) - GLSLH(#define i(x,y) i[(x)*4+(y)]) - - if (step == 0) { - *transform = (struct gl_transform){{{2.0,0.0}, {0.0,2.0}}, {-0.5,-0.5}}; - GLSLH(vec2 dir = fract(HOOKED_pos * HOOKED_size) - 0.5;) - GLSLH(dir = transpose(HOOKED_rot) * dir;) - - // Optimization: Discard (skip drawing) unused pixels, except those - // at the edge. - GLSLH(vec2 dist = HOOKED_size * min(HOOKED_pos, vec2(1.0) - HOOKED_pos);) - GLSLH(if (dir.x * dir.y < 0.0 && dist.x > 1.0 && dist.y > 1.0) - return 0.0;) - - GLSLH(if (dir.x < 0.0 || dir.y < 0.0 || dist.x < 1.0 || dist.y < 1.0) - return HOOKED_texOff(-dir).x;) - - // Load the input samples - GLSLH(for (int x = 0; x < 4; x++)) - GLSLH(for (int y = 0; y < 4; y++)) - GLSLH(i(x,y) = HOOKED_texOff(vec2(float(x)-1.25, float(y)-1.25)).x;) - } else { - *transform = (struct gl_transform){{{1.0,0.0}, {0.0,1.0}}, {0.0,0.0}}; - - // This is the second pass, so it will never be rotated - GLSLH(vec2 dir = fract(HOOKED_pos * HOOKED_size / 2.0) - 0.5;) - - GLSLH(if (dir.x * dir.y > 0.0) - return HOOKED_texOff(0).x;) - - GLSLH(for (int x = 0; x < 4; x++)) - GLSLH(for (int y = 0; y < 4; y++)) - GLSLH(i(x,y) = HOOKED_texOff(vec2(x+y-3, y-x)).x;) - } - - superxbr_step_h(sc, conf, ¶ms[step]); - GLSLH(return res;) - GLSLHF("}\n"); - - GLSL(color.x = superxbr();) -} diff --git a/video/out/opengl/superxbr.h b/video/out/opengl/superxbr.h deleted file mode 100644 index f9888d37e4..0000000000 --- a/video/out/opengl/superxbr.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of mpv. - * - * mpv is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * mpv is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with mpv. If not, see . - */ - -#ifndef MP_GL_SUPERXBR_H -#define MP_GL_SUPERXBR_H - -#include "common.h" -#include "utils.h" - -extern const struct superxbr_opts superxbr_opts_def; -extern const struct m_sub_options superxbr_conf; - -void pass_superxbr(struct gl_shader_cache *sc, int step, - const struct superxbr_opts *conf, - struct gl_transform *transform); - -#endif diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index 48d777b207..62bbfd1d05 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -37,7 +37,6 @@ #include "hwdec.h" #include "osd.h" #include "stream/stream.h" -#include "superxbr.h" #include "video_shaders.h" #include "user_shaders.h" #include "video/out/filter_kernels.h" @@ -46,9 +45,6 @@ #include "video/out/dither.h" #include "video/out/vo.h" -// Maximal number of passes that prescaler can be applied. -#define MAX_PRESCALE_PASSES 5 - // Maximal number of saved textures (for user script purposes) #define MAX_TEXTURE_HOOKS 16 #define MAX_SAVED_TEXTURES 32 @@ -323,8 +319,6 @@ const struct gl_video_opts gl_video_opts_def = { .alpha_mode = ALPHA_BLEND_TILES, .background = {0, 0, 0, 255}, .gamma = 1.0f, - .prescale_passes = 1, - .prescale_downscaling_threshold = 2.0f, .target_brightness = 250, .hdr_tone_mapping = TONE_MAPPING_HABLE, .tone_mapping_param = NAN, @@ -354,8 +348,6 @@ const struct gl_video_opts gl_video_opts_hq_def = { .background = {0, 0, 0, 255}, .gamma = 1.0f, .deband = 1, - .prescale_passes = 1, - .prescale_downscaling_threshold = 2.0f, .target_brightness = 250, .hdr_tone_mapping = TONE_MAPPING_HABLE, .tone_mapping_param = NAN, @@ -449,15 +441,6 @@ const struct m_sub_options gl_video_conf = { OPT_FLAG("deband", deband, 0), OPT_SUBSTRUCT("deband", deband_opts, deband_conf, 0), OPT_FLOAT("sharpen", unsharp, 0), - OPT_CHOICE("prescale-luma", prescale_luma, 0, - ({"none", PRESCALE_NONE}, - {"superxbr", PRESCALE_SUPERXBR} - )), - OPT_INTRANGE("prescale-passes", - prescale_passes, 0, 1, MAX_PRESCALE_PASSES), - OPT_FLOATRANGE("prescale-downscaling-threshold", - prescale_downscaling_threshold, 0, 0.0, 32.0), - OPT_SUBSTRUCT("superxbr", superxbr_opts, superxbr_conf, 0), OPT_SUBSTRUCT("", icc_opts, mp_icc_conf, 0), OPT_REMOVED("approx-gamma", "this is always enabled now"), @@ -466,6 +449,7 @@ const struct m_sub_options gl_video_conf = { OPT_REMOVED("indirect", "this is set automatically whenever sane"), OPT_REMOVED("srgb", "use target-prim=bt709:target-trc=srgb instead"), OPT_REMOVED("source-shader", "use :deband to enable debanding"), + OPT_REMOVED("prescale-luma", "use user shaders for prescaling"), OPT_REPLACED("lscale", "scale"), OPT_REPLACED("lscale-down", "scale-down"), @@ -481,7 +465,6 @@ const struct m_sub_options gl_video_conf = { OPT_REPLACED("smoothmotion-threshold", "tscale-param1"), OPT_REPLACED("scale-down", "dscale"), OPT_REPLACED("fancy-downscaling", "correct-downscaling"), - OPT_REPLACED("prescale", "prescale-luma"), {0} }, @@ -1482,34 +1465,6 @@ static void pass_sample(struct gl_video *p, struct img_tex tex, skip_unused(p, tex.components); } -// Get the number of passes for prescaler, with given display size. -static int get_prescale_passes(struct gl_video *p) -{ - if (p->opts.prescale_luma == PRESCALE_NONE) - return 0; - - // The downscaling threshold check is turned off. - if (p->opts.prescale_downscaling_threshold < 1.0f) - return p->opts.prescale_passes; - - double scale_factors[2]; - get_scale_factors(p, true, scale_factors); - - int passes = 0; - for (; passes < p->opts.prescale_passes; passes ++) { - // The scale factor happens to be the same for superxbr and nnedi3. - scale_factors[0] /= 2; - scale_factors[1] /= 2; - - if (1.0f / scale_factors[0] > p->opts.prescale_downscaling_threshold) - break; - if (1.0f / scale_factors[1] > p->opts.prescale_downscaling_threshold) - break; - } - - return passes; -} - // Returns true if two img_texs are semantically equivalent (same metadata) static bool img_tex_equiv(struct img_tex a, struct img_tex b) { @@ -1556,13 +1511,6 @@ static void deband_hook(struct gl_video *p, struct img_tex tex, pass_sample_deband(p->sc, p->opts.deband_opts, &p->lfg); } -static void superxbr_hook(struct gl_video *p, struct img_tex tex, - struct gl_transform *trans, void *priv) -{ - int step = (uintptr_t)priv; - pass_superxbr(p->sc, step, p->opts.superxbr_opts, trans); -} - static void unsharp_hook(struct gl_video *p, struct img_tex tex, struct gl_transform *trans, void *priv) { @@ -1796,20 +1744,6 @@ static void gl_video_setup_hooks(struct gl_video *p) HOOKS("LUMA", "CHROMA", "RGB", "XYZ")); } - int prescale_passes = get_prescale_passes(p); - if (p->opts.prescale_luma == PRESCALE_SUPERXBR) { - for (int i = 0; i < prescale_passes; i++) { - for (int step = 0; step < 2; step++) { - pass_add_hook(p, (struct tex_hook) { - .hook_tex = "LUMA", - .bind_tex = {"HOOKED"}, - .hook = superxbr_hook, - .priv = (void *)(uintptr_t)step, - }); - } - } - } - if (p->opts.unsharp != 0.0) { pass_add_hook(p, (struct tex_hook) { .hook_tex = "MAIN", @@ -3098,7 +3032,7 @@ static bool check_dumb_mode(struct gl_video *p) return true; if (o->target_prim || o->target_trc || o->linear_scaling || o->correct_downscaling || o->sigmoid_upscaling || o->interpolation || - o->blend_subs || o->deband || o->unsharp || o->prescale_luma) + o->blend_subs || o->deband || o->unsharp) return false; // check remaining scalers (tscale is already implicitly excluded above) for (int i = 0; i < SCALER_COUNT; i++) { diff --git a/video/out/opengl/video.h b/video/out/opengl/video.h index 09d05ce449..140a4682c8 100644 --- a/video/out/opengl/video.h +++ b/video/out/opengl/video.h @@ -92,11 +92,6 @@ enum blend_subs_mode { BLEND_SUBS_VIDEO, }; -enum prescalers { - PRESCALE_NONE = 0, - PRESCALE_SUPERXBR, -}; - enum tone_mapping { TONE_MAPPING_CLIP, TONE_MAPPING_REINHARD, @@ -142,10 +137,6 @@ struct gl_video_opts { int deband; struct deband_opts *deband_opts; float unsharp; - int prescale_luma; - int prescale_passes; - float prescale_downscaling_threshold; - struct superxbr_opts *superxbr_opts; struct mp_icc_opts *icc_opts; }; diff --git a/wscript_build.py b/wscript_build.py index 209df5f624..54518b3861 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -353,7 +353,6 @@ def build(ctx): ( "video/out/opengl/hwdec_vdpau.c", "vdpau-gl-x11" ), ( "video/out/opengl/lcms.c", "gl" ), ( "video/out/opengl/osd.c", "gl" ), - ( "video/out/opengl/superxbr.c", "gl" ), ( "video/out/opengl/user_shaders.c", "gl" ), ( "video/out/opengl/utils.c", "gl" ), ( "video/out/opengl/video.c", "gl" ), -- cgit v1.2.3