mirror of
https://github.com/mpv-player/mpv
synced 2024-12-26 00:42:57 +00:00
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.
This commit is contained in:
parent
e94890a5d6
commit
9d68d8fb0f
@ -19,6 +19,12 @@ Interface changes
|
||||
|
||||
::
|
||||
|
||||
--- mpv 0.24.0 ---
|
||||
- deprecate --hwdec-api and replace it with --opengl-hwdec-interop.
|
||||
The new option accepts both --hwdec values, as well as named backends.
|
||||
A minor difference is that --hwdec-api=no (which used to be the default)
|
||||
now actually does not preload any interop layer, while the new default
|
||||
("") uses the value of --hwdec.
|
||||
--- mpv 0.23.0 ---
|
||||
- remove deprecated vf_vdpaurb (use "--hwdec=vdpau-copy" instead)
|
||||
- the following properties now have new semantics:
|
||||
|
@ -1331,8 +1331,8 @@ Property list
|
||||
This is known only once the VO has opened (and possibly later). With some
|
||||
VOs (like ``opengl``), this might be never known in advance, but only when
|
||||
the decoder attempted to create the hw decoder successfully. (Using
|
||||
``--hwdec-preload`` can load it eagerly.) If there are multiple drivers
|
||||
loaded, they will be separated by ``,``.
|
||||
``--opengl-hwdec-interop`` can load it eagerly.) If there are multiple
|
||||
drivers loaded, they will be separated by ``,``.
|
||||
|
||||
If no VO is active or no interop driver is known, this property is
|
||||
unavailable.
|
||||
@ -1341,6 +1341,9 @@ Property list
|
||||
multiple interop drivers for the same hardware decoder, depending on
|
||||
platform and VO.
|
||||
|
||||
This is somewhat similar to the ``--opengl-hwdec-interop`` option, but
|
||||
it returns the actually loaded backend, not the value of this option.
|
||||
|
||||
``video-format``
|
||||
Video format as string.
|
||||
|
||||
|
@ -746,12 +746,12 @@ Video
|
||||
In particular, ``auto-copy`` will only select safe modes
|
||||
(although potentially slower than other methods).
|
||||
|
||||
``--hwdec-preload=<api>``
|
||||
``--opengl-hwdec-interop=<name>``
|
||||
This is useful for the ``opengl`` and ``opengl-cb`` VOs for creating the
|
||||
hardware decoding OpenGL interop context, but without actually enabling
|
||||
hardware decoding itself (like ``--hwdec`` does).
|
||||
|
||||
If set to ``no`` (default), the ``--hwdec`` option is used.
|
||||
If set to an empty string (default), the ``--hwdec`` option is used.
|
||||
|
||||
For ``opengl``, if set, do not create the interop context on demand, but
|
||||
when the VO is created.
|
||||
@ -762,6 +762,19 @@ Video
|
||||
to temporarily set the ``hwdec`` option just during OpenGL context
|
||||
initialization with ``mpv_opengl_cb_init_gl()``.
|
||||
|
||||
See ``--opengl-hwdec-interop=help`` for accepted values. This lists the
|
||||
interop backend, with the ``--hwdec`` alias after it in ``[...]``. Consider
|
||||
all values except the proper interop backend name, ``auto``, and ``no`` as
|
||||
silently deprecated and subject to change. Also, if you use this in
|
||||
application code (e.g. via libmpv), any value other than ``auto`` and ``no``
|
||||
should be avoided, as backends can change.
|
||||
|
||||
Currently the option sets a single value. It is possible that the option
|
||||
type changes to a list in the future.
|
||||
|
||||
The old alias ``--hwdec-preload`` has different behavior if the option value
|
||||
is ``no``.
|
||||
|
||||
``--videotoolbox-format=<name>``
|
||||
Set the internal pixel format used by ``--hwdec=videotoolbox`` on OSX. The
|
||||
choice of the format can influence performance considerably. On the other
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "stream/stream.h"
|
||||
#include "video/csputils.h"
|
||||
#include "video/hwdec.h"
|
||||
#include "video/out/opengl/hwdec.h"
|
||||
#include "video/image_writer.h"
|
||||
#include "sub/osd.h"
|
||||
#include "audio/filter/af.h"
|
||||
@ -150,7 +151,6 @@ const struct m_sub_options stream_cache_conf = {
|
||||
|
||||
static const m_option_t mp_vo_opt_list[] = {
|
||||
OPT_SETTINGSLIST("vo", video_driver_list, 0, &vo_obj_list, ),
|
||||
OPT_CHOICE_C("hwdec-preload", hwdec_preload_api, 0, mp_hwdec_names),
|
||||
OPT_SUBSTRUCT("sws", sws_opts, sws_conf, 0),
|
||||
OPT_FLAG("taskbar-progress", taskbar_progress, 0),
|
||||
OPT_FLAG("ontop", ontop, 0),
|
||||
@ -199,7 +199,11 @@ static const m_option_t mp_vo_opt_list[] = {
|
||||
0, drm_validate_connector_opt),
|
||||
OPT_INT("drm-mode", drm_mode_id, 0),
|
||||
#endif
|
||||
|
||||
#if HAVE_GL
|
||||
OPT_STRING_VALIDATE("opengl-hwdec-interop", gl_hwdec_interop, 0,
|
||||
gl_hwdec_validate_opt),
|
||||
OPT_REPLACED("hwdec-preload", "opengl-hwdec-interop"),
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -50,7 +50,7 @@ typedef struct mp_vo_opts {
|
||||
// vo_wayland, vo_drm
|
||||
struct sws_opts *sws_opts;
|
||||
// vo_opengl, vo_opengl_cb
|
||||
int hwdec_preload_api;
|
||||
char *gl_hwdec_interop;
|
||||
// vo_drm
|
||||
char *drm_connector_spec;
|
||||
int drm_mode_id;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user