summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-01-17 14:51:08 +0100
committerwm4 <wm4@nowhere>2017-01-17 15:48:56 +0100
commit9d68d8fb0f806f25408435c09ac5dbbe34b95462 (patch)
tree843619ba2650487042d661f37b203cb6853495af /video
parente94890a5d650d3db4c038adf0b0d1a5e9cce3462 (diff)
downloadmpv-9d68d8fb0f806f25408435c09ac5dbbe34b95462.tar.bz2
mpv-9d68d8fb0f806f25408435c09ac5dbbe34b95462.tar.xz
vo_opengl, vo_opengl_cb: better hwdec interop backend selection
Introduce the --opengl-hwdec-interop option, which replaces --hwdec-preload. The new option allows explicit selection of the interop backend. This is relatively complex, and I would have preferred not to add this, but it's probably useful to debug certain problems. In exchange, the "new" option documents that pretty much any but the simplest use of it will not be forward compatible.
Diffstat (limited to 'video')
-rw-r--r--video/out/opengl/hwdec.c63
-rw-r--r--video/out/opengl/hwdec.h8
-rw-r--r--video/out/vo_opengl.c11
-rw-r--r--video/out/vo_opengl_cb.c10
4 files changed, 76 insertions, 16 deletions
diff --git a/video/out/opengl/hwdec.c b/video/out/opengl/hwdec.c
index 261931a8d4..ab365df8ff 100644
--- a/video/out/opengl/hwdec.c
+++ b/video/out/opengl/hwdec.c
@@ -22,6 +22,7 @@
#include "common/common.h"
#include "common/msg.h"
+#include "options/m_config.h"
#include "hwdec.h"
extern const struct gl_hwdec_driver gl_hwdec_vaegl;
@@ -110,6 +111,68 @@ struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl,
return NULL;
}
+// Load by option name.
+struct gl_hwdec *gl_hwdec_load(struct mp_log *log, GL *gl,
+ struct mpv_global *g,
+ struct mp_hwdec_devices *devs,
+ const char *name)
+{
+ int g_hwdec_api;
+ mp_read_option_raw(g, "hwdec", &m_option_type_choice, &g_hwdec_api);
+ if (!name || !name[0])
+ name = m_opt_choice_str(mp_hwdec_names, g_hwdec_api);
+
+ int api_id = HWDEC_NONE;
+ for (int n = 0; mp_hwdec_names[n].name; n++) {
+ if (name && strcmp(mp_hwdec_names[n].name, name) == 0)
+ api_id = mp_hwdec_names[n].value;
+ }
+
+ for (int n = 0; mpgl_hwdec_drivers[n]; n++) {
+ const struct gl_hwdec_driver *drv = mpgl_hwdec_drivers[n];
+ if (name && strcmp(drv->name, name) == 0) {
+ struct gl_hwdec *r = load_hwdec_driver(log, gl, g, devs, drv, false);
+ if (r)
+ return r;
+ }
+ }
+
+ return gl_hwdec_load_api(log, gl, g, devs, api_id);
+}
+
+int gl_hwdec_validate_opt(struct mp_log *log, const m_option_t *opt,
+ struct bstr name, struct bstr param)
+{
+ bool help = bstr_equals0(param, "help");
+ if (help)
+ mp_info(log, "Available hwdecs:\n");
+ for (int n = 0; mpgl_hwdec_drivers[n]; n++) {
+ const struct gl_hwdec_driver *drv = mpgl_hwdec_drivers[n];
+ const char *api_name = m_opt_choice_str(mp_hwdec_names, drv->api);
+ if (help) {
+ mp_info(log, " %s [%s]\n", drv->name, api_name);
+ } else if (bstr_equals0(param, drv->name) ||
+ bstr_equals0(param, api_name))
+ {
+ return 1;
+ }
+ }
+ if (help) {
+ mp_info(log, " auto (loads best)\n"
+ " (other --hwdec values)\n"
+ "Setting an empty string means use --hwdec.\n");
+ return M_OPT_EXIT;
+ }
+ if (!param.len)
+ return 1; // "" is treated specially
+ for (int n = 0; mp_hwdec_names[n].name; n++) {
+ if (bstr_equals0(param, mp_hwdec_names[n].name))
+ return 1;
+ }
+ mp_fatal(log, "No hwdec backend named '%.*s' found!\n", BSTR_P(param));
+ return M_OPT_INVALID;
+}
+
void gl_hwdec_uninit(struct gl_hwdec *hwdec)
{
if (hwdec)
diff --git a/video/out/opengl/hwdec.h b/video/out/opengl/hwdec.h
index 6a1bb98bff..948b42bc74 100644
--- a/video/out/opengl/hwdec.h
+++ b/video/out/opengl/hwdec.h
@@ -81,6 +81,14 @@ struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl,
struct mp_hwdec_devices *devs,
enum hwdec_type api);
+struct gl_hwdec *gl_hwdec_load(struct mp_log *log, GL *gl,
+ struct mpv_global *g,
+ struct mp_hwdec_devices *devs,
+ const char *name);
+
+int gl_hwdec_validate_opt(struct mp_log *log, const m_option_t *opt,
+ struct bstr name, struct bstr param);
+
void gl_hwdec_uninit(struct gl_hwdec *hwdec);
bool gl_hwdec_test_format(struct gl_hwdec *hwdec, int imgfmt);
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index 7f65a1eafc..be187f63c3 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -411,14 +411,9 @@ static int preinit(struct vo *vo)
hwdec_devices_set_loader(vo->hwdec_devs, call_request_hwdec_api, vo);
- int hwdec = vo->opts->hwdec_preload_api;
- if (hwdec == HWDEC_NONE)
- hwdec = vo->global->opts->hwdec_api;
- if (hwdec != HWDEC_NONE) {
- p->hwdec = gl_hwdec_load_api(p->vo->log, p->gl, vo->global,
- vo->hwdec_devs, hwdec);
- gl_video_set_hwdec(p->renderer, p->hwdec);
- }
+ p->hwdec = gl_hwdec_load(p->vo->log, p->gl, vo->global,
+ vo->hwdec_devs, vo->opts->gl_hwdec_interop);
+ gl_video_set_hwdec(p->renderer, p->hwdec);
return 0;
diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c
index c2c0f795e1..9ecdf5eaed 100644
--- a/video/out/vo_opengl_cb.c
+++ b/video/out/vo_opengl_cb.c
@@ -167,15 +167,9 @@ int mpv_opengl_cb_init_gl(struct mpv_opengl_cb_context *ctx, const char *exts,
m_config_cache_update(ctx->vo_opts_cache);
- int g_hwdec_api;
- mp_read_option_raw(ctx->global, "hwdec", &m_option_type_choice, &g_hwdec_api);
-
ctx->hwdec_devs = hwdec_devices_create();
- int hwdec_api = ctx->vo_opts->hwdec_preload_api;
- if (hwdec_api == HWDEC_NONE)
- hwdec_api = g_hwdec_api;
- ctx->hwdec = gl_hwdec_load_api(ctx->log, ctx->gl, ctx->global,
- ctx->hwdec_devs, hwdec_api);
+ ctx->hwdec = gl_hwdec_load(ctx->log, ctx->gl, ctx->global,
+ ctx->hwdec_devs, ctx->vo_opts->gl_hwdec_interop);
gl_video_set_hwdec(ctx->renderer, ctx->hwdec);
pthread_mutex_lock(&ctx->lock);