diff options
Diffstat (limited to 'video/out/opengl/video.c')
-rw-r--r-- | video/out/opengl/video.c | 253 |
1 files changed, 158 insertions, 95 deletions
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index a89ee4e73a..ff4c7a25aa 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -33,6 +33,8 @@ #include "misc/bstr.h" #include "options/m_config.h" +#include "common/global.h" +#include "options/options.h" #include "common.h" #include "utils.h" #include "hwdec.h" @@ -47,9 +49,6 @@ #include "video/out/dither.h" #include "video/out/vo.h" -// Pixel width of 1D lookup textures. -#define LOOKUP_TEXTURE_SIZE 256 - // Maximal number of passes that prescaler can be applied. #define MAX_PRESCALE_PASSES 5 @@ -164,12 +163,14 @@ struct gl_video { struct mp_imgfmt_desc image_desc; int plane_count; - bool is_yuv, is_rgb, is_packed_yuv; + bool is_yuv, is_packed_yuv; bool has_alpha; char color_swizzle[5]; struct video_image image; + bool dumb_mode; + struct fbotex chroma_merge_fbo; struct fbotex chroma_deband_fbo; struct fbotex indirect_fbo; @@ -223,6 +224,8 @@ struct gl_video { struct gl_hwdec *hwdec; bool hwdec_active; + + bool dsi_warned; }; struct fmt_entry { @@ -332,15 +335,17 @@ const struct gl_video_opts gl_video_opts_def = { .dither_depth = -1, .dither_size = 6, .temporal_dither_period = 1, - .fbo_format = GL_RGBA16, + .fbo_format = 0, .sigmoid_center = 0.75, .sigmoid_slope = 6.5, .scaler = { {{"bilinear", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // scale {{NULL, .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // dscale {{"bilinear", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // cscale - {{"oversample", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // tscale + {{"mitchell", .params={NAN, NAN}}, {.params = {NAN, NAN}}, + .clamp = 1, }, // tscale }, + .scaler_lut_size = 6, .alpha_mode = 2, .background = {0, 0, 0, 255}, .gamma = 1.0f, @@ -352,7 +357,7 @@ const struct gl_video_opts gl_video_opts_hq_def = { .dither_depth = 0, .dither_size = 6, .temporal_dither_period = 1, - .fbo_format = GL_RGBA16, + .fbo_format = 0, .correct_downscaling = 1, .sigmoid_center = 0.75, .sigmoid_slope = 6.5, @@ -361,8 +366,10 @@ const struct gl_video_opts gl_video_opts_hq_def = { {{"spline36", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // scale {{"mitchell", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // dscale {{"spline36", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // cscale - {{"oversample", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // tscale + {{"mitchell", .params={NAN, NAN}}, {.params = {NAN, NAN}}, + .clamp = 1, }, // tscale }, + .scaler_lut_size = 6, .alpha_mode = 2, .background = {0, 0, 0, 255}, .gamma = 1.0f, @@ -404,6 +411,7 @@ const struct m_sub_options gl_video_conf = { SCALER_OPTS("dscale", 1), SCALER_OPTS("cscale", 2), SCALER_OPTS("tscale", 3), + OPT_INTRANGE("scaler-lut-size", scaler_lut_size, 0, 4, 10), OPT_FLAG("scaler-resizes-only", scaler_resizes_only, 0), OPT_FLAG("linear-scaling", linear_scaling, 0), OPT_FLAG("correct-downscaling", correct_downscaling, 0), @@ -414,6 +422,7 @@ const struct m_sub_options gl_video_conf = { ({"rgb", GL_RGB}, {"rgba", GL_RGBA}, {"rgb8", GL_RGB8}, + {"rgba8", GL_RGBA8}, {"rgb10", GL_RGB10}, {"rgb10_a2", GL_RGB10_A2}, {"rgb16", GL_RGB16}, @@ -422,7 +431,8 @@ const struct m_sub_options gl_video_conf = { {"rgba12", GL_RGBA12}, {"rgba16", GL_RGBA16}, {"rgba16f", GL_RGBA16F}, - {"rgba32f", GL_RGBA32F})), + {"rgba32f", GL_RGBA32F}, + {"auto", 0})), OPT_CHOICE_OR_INT("dither-depth", dither_depth, 0, -1, 16, ({"no", -1}, {"auto", 0})), OPT_CHOICE("dither", dither_algo, 0, @@ -449,8 +459,11 @@ const struct m_sub_options gl_video_conf = { OPT_FLOAT("sharpen", unsharp, 0), OPT_CHOICE("prescale", prescale, 0, ({"none", 0}, - {"superxbr", 1}, - {"nnedi3", 2})), + {"superxbr", 1} +#if HAVE_NNEDI + , {"nnedi3", 2} +#endif + )), OPT_INTRANGE("prescale-passes", prescale_passes, 0, 1, MAX_PRESCALE_PASSES), OPT_FLOATRANGE("prescale-downscaling-threshold", @@ -559,9 +572,8 @@ void gl_video_set_debug(struct gl_video *p, bool enable) static void gl_video_reset_surfaces(struct gl_video *p) { - for (int i = 0; i < FBOSURFACES_MAX; i++) { + for (int i = 0; i < FBOSURFACES_MAX; i++) p->surfaces[i].pts = MP_NOPTS_VALUE; - } p->surface_idx = 0; p->surface_now = 0; p->frames_drawn = 0; @@ -642,8 +654,10 @@ void gl_video_set_lut3d(struct gl_video *p, struct lut3d *lut3d) return; } - if (!(gl->mpgl_caps & MPGL_CAP_3D_TEX)) + if (!(gl->mpgl_caps & MPGL_CAP_3D_TEX) || gl->es) { + MP_ERR(p, "16 bit fixed point 3D textures not available.\n"); return; + } if (!p->lut_3d_texture) gl->GenTextures(1, &p->lut_3d_texture); @@ -1040,7 +1054,7 @@ static void reinit_scaler(struct gl_video *p, struct scaler *scaler, scaler->insufficient = !mp_init_filter(scaler->kernel, sizes, scale_factor); - if (scaler->kernel->polar) { + if (scaler->kernel->polar && (gl->mpgl_caps & MPGL_CAP_1D_TEX)) { scaler->gl_target = GL_TEXTURE_1D; } else { scaler->gl_target = GL_TEXTURE_2D; @@ -1067,14 +1081,16 @@ static void reinit_scaler(struct gl_video *p, struct scaler *scaler, gl->BindTexture(target, scaler->gl_lut); - float *weights = talloc_array(NULL, float, LOOKUP_TEXTURE_SIZE * size); - mp_compute_lut(scaler->kernel, LOOKUP_TEXTURE_SIZE, weights); + scaler->lut_size = 1 << p->opts.scaler_lut_size; + + float *weights = talloc_array(NULL, float, scaler->lut_size * size); + mp_compute_lut(scaler->kernel, scaler->lut_size, weights); if (target == GL_TEXTURE_1D) { - gl->TexImage1D(target, 0, fmt->internal_format, LOOKUP_TEXTURE_SIZE, + gl->TexImage1D(target, 0, fmt->internal_format, scaler->lut_size, 0, fmt->format, GL_FLOAT, weights); } else { - gl->TexImage2D(target, 0, fmt->internal_format, width, LOOKUP_TEXTURE_SIZE, + gl->TexImage2D(target, 0, fmt->internal_format, width, scaler->lut_size, 0, fmt->format, GL_FLOAT, weights); } @@ -1311,9 +1327,9 @@ static void pass_read_video(struct gl_video *p) struct gl_transform chromafix; pass_set_image_textures(p, &p->image, &chromafix); - int in_bits = p->image_desc.component_bits, - tx_bits = (in_bits + 7) & ~7; - float tex_mul = ((1 << tx_bits) - 1.0) / ((1 << in_bits) - 1.0); + float tex_mul = 1 / mp_get_csp_mul(p->image_params.colorspace, + p->image_desc.component_bits, + p->image_desc.component_full_bits); struct src_tex prescaled_tex; struct gl_transform offset = {{{0}}}; @@ -1449,7 +1465,7 @@ static void pass_convert_yuv(struct gl_video *p) struct mp_csp_params cparams = MP_CSP_PARAMS_DEFAULTS; cparams.gray = p->is_yuv && !p->is_packed_yuv && p->plane_count == 1; cparams.input_bits = p->image_desc.component_bits; - cparams.texture_bits = (cparams.input_bits + 7) & ~7; + cparams.texture_bits = p->image_desc.component_full_bits; mp_csp_set_image_params(&cparams, &p->image_params); mp_csp_copy_equalizer_values(&cparams, &p->video_eq); p->user_gamma = 1.0 / (cparams.gamma * p->opts.gamma); @@ -1460,32 +1476,21 @@ static void pass_convert_yuv(struct gl_video *p) GLSLF("color = color.%s;\n", p->color_swizzle); // Pre-colormatrix input gamma correction - if (p->image_desc.flags & MP_IMGFLAG_XYZ) { - cparams.colorspace = MP_CSP_XYZ; - - // Pre-colormatrix input gamma correction. Note that this results in - // linear light - GLSL(color.rgb = pow(color.rgb, vec3(2.6));) - } + if (cparams.colorspace == MP_CSP_XYZ) + GLSL(color.rgb = pow(color.rgb, vec3(2.6));) // linear light - // Something already took care of expansion + // Something already took care of expansion - disable it. if (p->use_normalized_range) - cparams.input_bits = cparams.texture_bits; - - // Conversion from Y'CbCr or other linear spaces to RGB - if (!p->is_rgb) { - struct mp_cmat m = {{{0}}}; - if (p->image_desc.flags & MP_IMGFLAG_XYZ) { - struct mp_csp_primaries csp = mp_get_csp_primaries(p->image_params.primaries); - mp_get_xyz2rgb_coeffs(&cparams, csp, MP_INTENT_RELATIVE_COLORIMETRIC, &m); - } else { - mp_get_yuv2rgb_coeffs(&cparams, &m); - } - gl_sc_uniform_mat3(sc, "colormatrix", true, &m.m[0][0]); - gl_sc_uniform_vec3(sc, "colormatrix_c", m.c); + cparams.input_bits = cparams.texture_bits = 0; - GLSL(color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;) - } + // Conversion to RGB. For RGB itself, this still applies e.g. brightness + // and contrast controls, or expansion of e.g. LSB-packed 10 bit data. + struct mp_cmat m = {{{0}}}; + mp_get_csp_matrix(&cparams, &m); + gl_sc_uniform_mat3(sc, "colormatrix", true, &m.m[0][0]); + gl_sc_uniform_vec3(sc, "colormatrix_c", m.c); + + GLSL(color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;) if (p->image_params.colorspace == MP_CSP_BT_2020_C) { // Conversion for C'rcY'cC'bc via the BT.2020 CL system: @@ -1726,9 +1731,16 @@ static void pass_dither(struct gl_video *p) p->last_dither_matrix_size = size; } + const struct fmt_entry *fmt = find_tex_format(gl, 2, 1); tex_size = size; - tex_iformat = gl_float16_formats[0].internal_format; - tex_format = gl_float16_formats[0].format; + // Prefer R16 texture since they provide higher precision. + if (fmt->internal_format) { + tex_iformat = fmt->internal_format; + tex_format = fmt->format; + } else { + tex_iformat = gl_float16_formats[0].internal_format; + tex_format = gl_float16_formats[0].format; + } tex_type = GL_FLOAT; tex_data = p->last_dither_matrix; } else { @@ -1771,7 +1783,7 @@ static void pass_dither(struct gl_video *p) gl_sc_uniform_sampler(p->sc, "dither", GL_TEXTURE_2D, TEXUNIT_DITHER); - GLSLF("vec2 dither_pos = gl_FragCoord.xy / %d;\n", p->dither_size); + GLSLF("vec2 dither_pos = gl_FragCoord.xy / %d.0;\n", p->dither_size); if (p->opts.temporal_dither) { int phase = (p->frames_rendered / p->opts.temporal_dither_period) % 8u; @@ -1786,8 +1798,8 @@ static void pass_dither(struct gl_video *p) } GLSL(float dither_value = texture(dither, dither_pos).r;) - GLSLF("color = floor(color * %d + dither_value + 0.5 / (%d * %d)) / %d;\n", - dither_quantization, p->dither_size, p->dither_size, + GLSLF("color = floor(color * %d.0 + dither_value + 0.5 / %d.0) / %d.0;\n", + dither_quantization, p->dither_size * p->dither_size, dither_quantization); } @@ -1878,7 +1890,7 @@ static void pass_render_frame(struct gl_video *p) p->texture_h = p->image_params.h; p->texture_offset = (struct gl_transform){{{1.0,0.0}, {0.0,1.0}}, {0.0,0.0}}; - if (p->opts.dumb_mode) + if (p->dumb_mode) return; p->use_linear = p->opts.linear_scaling || p->opts.sigmoid_upscaling; @@ -1947,7 +1959,7 @@ static void pass_render_frame(struct gl_video *p) static void pass_draw_to_screen(struct gl_video *p, int fbo) { - if (p->opts.dumb_mode) + if (p->dumb_mode) pass_render_frame_dumb(p, fbo); // Adjust the overall gamma before drawing to screen @@ -2002,7 +2014,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, // Figure out the queue size. For illustration, a filter radius of 2 would // look like this: _ A [B] C D _ - // A is surface_bse, B is surface_now, C is surface_nxt and D is + // A is surface_bse, B is surface_now, C is surface_now+1 and D is // surface_end. struct scaler *tscale = &p->scaler[3]; reinit_scaler(p, tscale, &p->opts.scaler[3], 1, tscale_sizes); @@ -2019,7 +2031,6 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, int radius = size/2; int surface_now = p->surface_now; - int surface_nxt = fbosurface_wrap(surface_now + 1); int surface_bse = fbosurface_wrap(surface_now - (radius-1)); int surface_end = fbosurface_wrap(surface_now + radius); assert(fbosurface_wrap(surface_bse + size-1) == surface_end); @@ -2040,7 +2051,6 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, continue; if (f->pts > p->surfaces[p->surface_idx].pts) { - MP_STATS(p, "new-pts"); gl_video_upload_image(p, f); pass_render_frame(p); finish_pass_fbo(p, &p->surfaces[surface_dst].fbotex, @@ -2079,10 +2089,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, GLSL(vec4 color = texture(texture0, texcoord0);) p->is_interpolated = false; } else { - double pts_now = p->surfaces[surface_now].pts, - pts_nxt = p->surfaces[surface_nxt].pts; - - double mix = (t->vsync_offset / 1e6) / (pts_nxt - pts_now); + double mix = t->vsync_offset / t->ideal_frame_duration; // The scaler code always wants the fcoord to be between 0 and 1, // so we try to adjust by using the previous set of N frames instead // (which requires some extra checking to make sure it's valid) @@ -2101,7 +2108,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, // Blend the frames together if (oversample) { - double vsync_dist = t->vsync_interval / 1e6 / (pts_nxt - pts_now), + double vsync_dist = t->vsync_interval / t->ideal_frame_duration, threshold = tscale->conf.kernel.params[0]; threshold = isnan(threshold) ? 0.0 : threshold; mix = (1 - mix) / vsync_dist; @@ -2123,9 +2130,8 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, vp_w, vp_h, i); } - MP_STATS(p, "frame-mix"); - MP_DBG(p, "inter frame pts: %lld, vsync: %lld, mix: %f\n", - (long long)t->pts, (long long)t->vsync_interval, mix); + MP_DBG(p, "inter frame dur: %f vsync: %f, mix: %f\n", + t->ideal_frame_duration, t->vsync_interval, mix); p->is_interpolated = true; } pass_draw_to_screen(p, fbo); @@ -2154,37 +2160,47 @@ void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, int fbo) if (has_frame) { gl_sc_set_vao(p->sc, &p->vao); - if (p->opts.interpolation && (p->frames_drawn || !frame->still)) { + if (p->opts.interpolation && frame->display_synced && + (p->frames_drawn || !frame->still)) + { gl_video_interpolate_frame(p, frame, fbo); } else { - // For the non-interplation case, we draw to a single "cache" - // FBO to speed up subsequent re-draws (if any exist) - int vp_w = p->dst_rect.x1 - p->dst_rect.x0, - vp_h = p->dst_rect.y1 - p->dst_rect.y0; - bool is_new = !frame->redraw && !frame->repeat; if (is_new || !p->output_fbo_valid) { + p->output_fbo_valid = false; + gl_video_upload_image(p, frame->current); pass_render_frame(p); - if (frame->num_vsyncs == 1 || !frame->display_synced || - p->opts.dumb_mode) + // For the non-interplation case, we draw to a single "cache" + // FBO to speed up subsequent re-draws (if any exist) + int dest_fbo = fbo; + if (frame->num_vsyncs > 1 && frame->display_synced && + !p->dumb_mode && gl->BlitFramebuffer) { - // Disable output_fbo_valid to signal that this frame - // does not require any redraws from the FBO. - pass_draw_to_screen(p, fbo); - p->output_fbo_valid = false; - } else { - finish_pass_fbo(p, &p->output_fbo, vp_w, vp_h, 0, FBOTEX_FUZZY); + fbotex_change(&p->output_fbo, p->gl, p->log, + p->vp_w, abs(p->vp_h), + p->opts.fbo_format, 0); + dest_fbo = p->output_fbo.fbo; p->output_fbo_valid = true; } + pass_draw_to_screen(p, dest_fbo); } // "output fbo valid" and "output fbo needed" are equivalent if (p->output_fbo_valid) { - pass_load_fbotex(p, &p->output_fbo, vp_w, vp_h, 0); - GLSL(vec4 color = texture(texture0, texcoord0);) - pass_draw_to_screen(p, fbo); + gl->BindFramebuffer(GL_READ_FRAMEBUFFER, p->output_fbo.fbo); + gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + struct mp_rect rc = p->dst_rect; + if (p->vp_h < 0) { + rc.y1 = -p->vp_h - p->dst_rect.y0; + rc.y0 = -p->vp_h - p->dst_rect.y1; + } + gl->BlitFramebuffer(rc.x0, rc.y0, rc.x1, rc.y1, + rc.x0, rc.y0, rc.x1, rc.y1, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + gl->BindFramebuffer(GL_READ_FRAMEBUFFER, 0); + gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } } } @@ -2340,26 +2356,62 @@ static bool test_fbo(struct gl_video *p) return success; } +// Return whether dumb-mode can be used without disabling any features. +// Essentially, vo_opengl with mostly default settings will return true. +static bool check_dumb_mode(struct gl_video *p) +{ + struct gl_video_opts *o = &p->opts; + if (o->dumb_mode) + 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) + return false; + // check scale, dscale, cscale (tscale is already implicitly excluded above) + for (int i = 0; i < 3; i++) { + const char *name = o->scaler[i].kernel.name; + if (name && strcmp(name, "bilinear") != 0) + return false; + } + if (o->pre_shaders && o->pre_shaders[0]) + return false; + if (o->post_shaders && o->post_shaders[0]) + return false; + if (p->use_lut_3d) + return false; + return true; +} + // Disable features that are not supported with the current OpenGL version. static void check_gl_features(struct gl_video *p) { GL *gl = p->gl; bool have_float_tex = gl->mpgl_caps & MPGL_CAP_FLOAT_TEX; bool have_fbo = gl->mpgl_caps & MPGL_CAP_FB; - bool have_1d_tex = gl->mpgl_caps & MPGL_CAP_1D_TEX; bool have_3d_tex = gl->mpgl_caps & MPGL_CAP_3D_TEX; bool have_mix = gl->glsl_version >= 130; + bool have_texrg = gl->mpgl_caps & MPGL_CAP_TEX_RG; + + if (have_fbo) { + if (!p->opts.fbo_format) + p->opts.fbo_format = gl->es ? GL_RGB10_A2 : GL_RGBA16; + have_fbo = test_fbo(p); + } if (gl->es && p->opts.pbo) { p->opts.pbo = 0; MP_WARN(p, "Disabling PBOs (GLES unsupported).\n"); } - if (p->opts.dumb_mode || gl->es || !have_fbo || !test_fbo(p)) { - if (!p->opts.dumb_mode) { + bool voluntarily_dumb = check_dumb_mode(p); + if (p->opts.dumb_mode || !have_fbo || !have_texrg || voluntarily_dumb) { + if (voluntarily_dumb) { + MP_VERBOSE(p, "No advanced processing required. Enabling dumb mode.\n"); + } else if (!p->opts.dumb_mode) { MP_WARN(p, "High bit depth FBOs unsupported. Enabling dumb mode.\n" "Most extended features will be disabled.\n"); } + p->dumb_mode = true; p->use_lut_3d = false; // Most things don't work, so whitelist all options that still work. struct gl_video_opts new_opts = { @@ -2371,12 +2423,18 @@ static void check_gl_features(struct gl_video *p) .use_rectangle = p->opts.use_rectangle, .background = p->opts.background, .dither_algo = -1, - .dumb_mode = 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], + }, }; assign_options(&p->opts, &new_opts); p->opts.deband_opts = m_config_alloc_struct(NULL, &deband_conf); return; } + p->dumb_mode = false; // Normally, we want to disable them by default if FBOs are unavailable, // because they will be slow (not critically slow, but still slower). @@ -2389,8 +2447,6 @@ static void check_gl_features(struct gl_video *p) char *reason = NULL; if (!have_float_tex) reason = "(float tex. missing)"; - if (!have_1d_tex && kernel->polar) - reason = "(1D tex. missing)"; if (reason) { p->opts.scaler[n].kernel.name = "bilinear"; MP_WARN(p, "Disabling scaler #%d %s.\n", n, reason); @@ -2428,14 +2484,18 @@ static void check_gl_features(struct gl_video *p) if (p->opts.prescale == 2) { if (p->opts.nnedi3_opts->upload == NNEDI3_UPLOAD_UBO) { // Check features for uniform buffer objects. - if (!p->gl->BindBufferBase || !p->gl->GetUniformBlockIndex) { - MP_WARN(p, "Disabling NNEDI3 (OpenGL 3.1 required).\n"); + if (!gl->BindBufferBase || !gl->GetUniformBlockIndex) { + MP_WARN(p, "Disabling NNEDI3 (%s required).\n", + gl->es ? "OpenGL ES 3.0" : "OpenGL 3.1"); p->opts.prescale = 0; } } else if (p->opts.nnedi3_opts->upload == NNEDI3_UPLOAD_SHADER) { // Check features for hard coding approach. - if (p->gl->glsl_version < 330) { - MP_WARN(p, "Disabling NNEDI3 (OpenGL 3.3 required).\n"); + if ((!gl->es && gl->glsl_version < 330) || + (gl->es && gl->glsl_version < 300)) + { + MP_WARN(p, "Disabling NNEDI3 (%s required).\n", + gl->es ? "OpenGL ES 3.0" : "OpenGL 3.3"); p->opts.prescale = 0; } } @@ -2583,8 +2643,6 @@ static bool init_format(int fmt, struct gl_video *init) // YUV/half-packed if (fmt == IMGFMT_NV12 || fmt == IMGFMT_NV21) { - if (!(init->gl->mpgl_caps & MPGL_CAP_TEX_RG)) - return false; plane_format[0] = find_tex_format(gl, 1, 1); plane_format[1] = find_tex_format(gl, 1, 2); if (fmt == IMGFMT_NV21) @@ -2659,7 +2717,6 @@ supported: } init->is_yuv = desc.flags & MP_IMGFLAG_YUV; - init->is_rgb = desc.flags & MP_IMGFLAG_RGB; init->plane_count = desc.num_planes; init->image_desc = desc; @@ -2799,6 +2856,12 @@ void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts) check_gl_features(p); uninit_rendering(p); + + if (p->opts.interpolation && !p->global->opts->video_sync && !p->dsi_warned) { + MP_WARN(p, "Interpolation now requires enabling display-sync mode.\n" + "E.g.: --video-sync=display-resample\n"); + p->dsi_warned = true; + } } void gl_video_configure_queue(struct gl_video *p, struct vo *vo) @@ -2820,7 +2883,7 @@ void gl_video_configure_queue(struct gl_video *p, struct vo *vo) } } - vo_set_queue_params(vo, 0, p->opts.interpolation, queue_size); + vo_set_queue_params(vo, 0, queue_size); } struct mp_csp_equalizer *gl_video_eq_ptr(struct gl_video *p) |