1
0
mirror of https://github.com/mpv-player/mpv synced 2025-04-16 20:31:06 +00:00

vo_opengl: add macros for scaler units

There was no real point in hard-coding these all over the place,
especially since the order was sort of arbitrary and confusing.
This commit is contained in:
Niklas Haas 2016-03-05 09:42:57 +01:00 committed by wm4
parent 93546f0c2f
commit 8ac6f6acf0
2 changed files with 42 additions and 34 deletions

View File

@ -207,8 +207,8 @@ struct gl_video {
bool is_interpolated; bool is_interpolated;
bool output_fbo_valid; bool output_fbo_valid;
// state for luma (0), luma-down(1), chroma (2) and temporal (3) scalers // state for configured scalers
struct scaler scaler[4]; struct scaler scaler[SCALER_COUNT];
struct mp_csp_equalizer video_eq; struct mp_csp_equalizer video_eq;
@ -433,10 +433,10 @@ const struct m_sub_options gl_video_conf = {
OPT_CHOICE_C("target-prim", target_prim, 0, mp_csp_prim_names), OPT_CHOICE_C("target-prim", target_prim, 0, mp_csp_prim_names),
OPT_CHOICE_C("target-trc", target_trc, 0, mp_csp_trc_names), OPT_CHOICE_C("target-trc", target_trc, 0, mp_csp_trc_names),
OPT_FLAG("pbo", pbo, 0), OPT_FLAG("pbo", pbo, 0),
SCALER_OPTS("scale", 0), SCALER_OPTS("scale", SCALER_SCALE),
SCALER_OPTS("dscale", 1), SCALER_OPTS("dscale", SCALER_DSCALE),
SCALER_OPTS("cscale", 2), SCALER_OPTS("cscale", SCALER_CSCALE),
SCALER_OPTS("tscale", 3), SCALER_OPTS("tscale", SCALER_TSCALE),
OPT_INTRANGE("scaler-lut-size", scaler_lut_size, 0, 4, 10), OPT_INTRANGE("scaler-lut-size", scaler_lut_size, 0, 4, 10),
OPT_FLAG("scaler-resizes-only", scaler_resizes_only, 0), OPT_FLAG("scaler-resizes-only", scaler_resizes_only, 0),
OPT_FLAG("linear-scaling", linear_scaling, 0), OPT_FLAG("linear-scaling", linear_scaling, 0),
@ -654,7 +654,7 @@ static void uninit_rendering(struct gl_video *p)
{ {
GL *gl = p->gl; GL *gl = p->gl;
for (int n = 0; n < 4; n++) for (int n = 0; n < SCALER_COUNT; n++)
uninit_scaler(p, &p->scaler[n]); uninit_scaler(p, &p->scaler[n]);
gl->DeleteTextures(1, &p->dither_texture); gl->DeleteTextures(1, &p->dither_texture);
@ -1476,11 +1476,11 @@ static void pass_read_video(struct gl_video *p)
case PLANE_RGB: case PLANE_RGB:
case PLANE_LUMA: case PLANE_LUMA:
case PLANE_XYZ: case PLANE_XYZ:
scaler_id[i] = 0; // scale scaler_id[i] = SCALER_SCALE;
break; break;
case PLANE_CHROMA: case PLANE_CHROMA:
scaler_id[i] = 2; // cscale scaler_id[i] = SCALER_CSCALE;
break; break;
case PLANE_ALPHA: // always use bilinear for alpha case PLANE_ALPHA: // always use bilinear for alpha
@ -1775,17 +1775,17 @@ static void pass_scale_main(struct gl_video *p)
bool upscaling = !downscaling && (xy[0] > 1.0 || xy[1] > 1.0); bool upscaling = !downscaling && (xy[0] > 1.0 || xy[1] > 1.0);
double scale_factor = 1.0; double scale_factor = 1.0;
struct scaler *scaler = &p->scaler[0]; struct scaler *scaler = &p->scaler[SCALER_SCALE];
struct scaler_config scaler_conf = p->opts.scaler[0]; struct scaler_config scaler_conf = p->opts.scaler[SCALER_SCALE];
if (p->opts.scaler_resizes_only && !downscaling && !upscaling) { if (p->opts.scaler_resizes_only && !downscaling && !upscaling) {
scaler_conf.kernel.name = "bilinear"; scaler_conf.kernel.name = "bilinear";
// bilinear is going to be used, just remove all sub-pixel offsets. // bilinear is going to be used, just remove all sub-pixel offsets.
p->texture_offset.t[0] = (int)p->texture_offset.t[0]; p->texture_offset.t[0] = (int)p->texture_offset.t[0];
p->texture_offset.t[1] = (int)p->texture_offset.t[1]; p->texture_offset.t[1] = (int)p->texture_offset.t[1];
} }
if (downscaling && p->opts.scaler[1].kernel.name) { if (downscaling && p->opts.scaler[SCALER_DSCALE].kernel.name) {
scaler_conf = p->opts.scaler[1]; scaler_conf = p->opts.scaler[SCALER_DSCALE];
scaler = &p->scaler[1]; scaler = &p->scaler[SCALER_DSCALE];
} }
// When requesting correct-downscaling and the clip is anamorphic, and // When requesting correct-downscaling and the clip is anamorphic, and
@ -2194,8 +2194,8 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t,
// look like this: _ A [B] C D _ // look like this: _ A [B] C D _
// A is surface_bse, B is surface_now, C is surface_now+1 and D is // A is surface_bse, B is surface_now, C is surface_now+1 and D is
// surface_end. // surface_end.
struct scaler *tscale = &p->scaler[3]; struct scaler *tscale = &p->scaler[SCALER_TSCALE];
reinit_scaler(p, tscale, &p->opts.scaler[3], 1, tscale_sizes); reinit_scaler(p, tscale, &p->opts.scaler[SCALER_TSCALE], 1, tscale_sizes);
bool oversample = strcmp(tscale->conf.kernel.name, "oversample") == 0; bool oversample = strcmp(tscale->conf.kernel.name, "oversample") == 0;
int size; int size;
@ -2558,12 +2558,14 @@ static bool check_dumb_mode(struct gl_video *p)
o->correct_downscaling || o->sigmoid_upscaling || o->interpolation || o->correct_downscaling || o->sigmoid_upscaling || o->interpolation ||
o->blend_subs || o->deband || o->unsharp || o->prescale) o->blend_subs || o->deband || o->unsharp || o->prescale)
return false; return false;
// check scale, dscale, cscale (tscale is already implicitly excluded above) // check remaining scalers (tscale is already implicitly excluded above)
for (int i = 0; i < 3; i++) { for (int i = 0; i < SCALER_COUNT; i++) {
if (i != SCALER_TSCALE) {
const char *name = o->scaler[i].kernel.name; const char *name = o->scaler[i].kernel.name;
if (name && strcmp(name, "bilinear") != 0) if (name && strcmp(name, "bilinear") != 0)
return false; return false;
} }
}
if (o->pre_shaders && o->pre_shaders[0]) if (o->pre_shaders && o->pre_shaders[0])
return false; return false;
if (o->post_shaders && o->post_shaders[0]) if (o->post_shaders && o->post_shaders[0])
@ -2618,13 +2620,9 @@ static void check_gl_features(struct gl_video *p)
.use_rectangle = p->opts.use_rectangle, .use_rectangle = p->opts.use_rectangle,
.background = p->opts.background, .background = p->opts.background,
.dither_algo = -1, .dither_algo = -1,
.scaler = {
gl_video_opts_def.scaler[0],
gl_video_opts_def.scaler[1],
gl_video_opts_def.scaler[2],
gl_video_opts_def.scaler[3],
},
}; };
for (int n = 0; n < SCALER_COUNT; n++)
new_opts.scaler[n] = gl_video_opts_def.scaler[n];
assign_options(&p->opts, &new_opts); assign_options(&p->opts, &new_opts);
p->opts.deband_opts = m_config_alloc_struct(NULL, &deband_conf); p->opts.deband_opts = m_config_alloc_struct(NULL, &deband_conf);
return; return;
@ -2635,7 +2633,7 @@ static void check_gl_features(struct gl_video *p)
// because they will be slow (not critically slow, but still slower). // because they will be slow (not critically slow, but still slower).
// Without FP textures, we must always disable them. // Without FP textures, we must always disable them.
// I don't know if luminance alpha float textures exist, so disregard them. // I don't know if luminance alpha float textures exist, so disregard them.
for (int n = 0; n < 4; n++) { for (int n = 0; n < SCALER_COUNT; n++) {
const struct filter_kernel *kernel = const struct filter_kernel *kernel =
mp_find_filter_kernel(p->opts.scaler[n].kernel.name); mp_find_filter_kernel(p->opts.scaler[n].kernel.name);
if (kernel) { if (kernel) {
@ -2986,9 +2984,10 @@ struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct mpv_global *g)
.opts = gl_video_opts_def, .opts = gl_video_opts_def,
.gl_target = GL_TEXTURE_2D, .gl_target = GL_TEXTURE_2D,
.texture_16bit_depth = 16, .texture_16bit_depth = 16,
.scaler = {{.index = 0}, {.index = 1}, {.index = 2}, {.index = 3}},
.sc = gl_sc_create(gl, log), .sc = gl_sc_create(gl, log),
}; };
for (int n = 0; n < SCALER_COUNT; n++)
p->scaler[n] = (struct scaler){.index = n};
gl_video_set_debug(p, true); gl_video_set_debug(p, true);
init_gl(p); init_gl(p);
recreate_osd(p); recreate_osd(p);
@ -3051,9 +3050,10 @@ static void assign_options(struct gl_video_opts *dst, struct gl_video_opts *src)
src->nnedi3_opts); src->nnedi3_opts);
} }
for (int n = 0; n < 4; n++) { for (int n = 0; n < SCALER_COUNT; n++) {
dst->scaler[n].kernel.name = dst->scaler[n].kernel.name =
(char *)handle_scaler_opt(dst->scaler[n].kernel.name, n == 3); (char *)handle_scaler_opt(dst->scaler[n].kernel.name,
n == SCALER_TSCALE);
} }
dst->scale_shader = talloc_strdup(NULL, dst->scale_shader); dst->scale_shader = talloc_strdup(NULL, dst->scale_shader);
@ -3085,10 +3085,10 @@ void gl_video_configure_queue(struct gl_video *p, struct vo *vo)
// the radius, the earlier we need to queue frames. // the radius, the earlier we need to queue frames.
if (p->opts.interpolation) { if (p->opts.interpolation) {
const struct filter_kernel *kernel = const struct filter_kernel *kernel =
mp_find_filter_kernel(p->opts.scaler[3].kernel.name); mp_find_filter_kernel(p->opts.scaler[SCALER_TSCALE].kernel.name);
if (kernel) { if (kernel) {
double radius = kernel->f.radius; double radius = kernel->f.radius;
radius = radius > 0 ? radius : p->opts.scaler[3].radius; radius = radius > 0 ? radius : p->opts.scaler[SCALER_TSCALE].radius;
queue_size += 1 + ceil(radius); queue_size += 1 + ceil(radius);
} else { } else {
// Oversample case // Oversample case

View File

@ -31,7 +31,7 @@
// Other texture units are reserved for specific purposes // Other texture units are reserved for specific purposes
#define TEXUNIT_SCALERS TEXUNIT_VIDEO_NUM #define TEXUNIT_SCALERS TEXUNIT_VIDEO_NUM
#define TEXUNIT_3DLUT (TEXUNIT_SCALERS+4) #define TEXUNIT_3DLUT (TEXUNIT_SCALERS+SCALER_COUNT)
#define TEXUNIT_DITHER (TEXUNIT_3DLUT+1) #define TEXUNIT_DITHER (TEXUNIT_3DLUT+1)
struct lut3d { struct lut3d {
@ -69,6 +69,14 @@ struct scaler {
struct filter_kernel kernel_storage; struct filter_kernel kernel_storage;
}; };
enum scaler_unit {
SCALER_SCALE, // luma/video
SCALER_DSCALE, // luma-video downscaling
SCALER_CSCALE, // chroma upscaling
SCALER_TSCALE, // temporal scaling (interpolation)
SCALER_COUNT
};
struct gl_video_opts { struct gl_video_opts {
int dumb_mode; int dumb_mode;
struct scaler_config scaler[4]; struct scaler_config scaler[4];