mirror of
https://github.com/mpv-player/mpv
synced 2025-01-13 18:45:25 +00:00
vd_lavc: more hwdec autoselect nonsense
Add an "auto-safe" mode, mostly triggered by Ubuntu's nonsense to force hwdec=vaapi in the global config file in their mpv package. But to be honest it's probably something more people want. This is implemented as explicit whitelist. On Windows, HEVC/Intel is sometimes broken, but it's still whitelisted, and in theory we'd need a detailed whitelist of device names etc. (like for example browsers tend to do). On OSX, videotoolbox is a pretty bad choice, but unfortunately the only one, so it's whitelisted too. There may be a larger number of hwdec wrappers that work anyway, and I'm for example ignoring Android.
This commit is contained in:
parent
e7add205d8
commit
380f01567d
@ -998,7 +998,10 @@ Video
|
||||
|
||||
Always enabling HW decoding by putting it into the config file is
|
||||
discouraged. If you use the Ubuntu package, delete ``/etc/mpv/mpv.conf``,
|
||||
as the package tries to enable HW decoding by default.
|
||||
as the package tries to enable HW decoding by default by setting
|
||||
``hwdec=vaapi`` (which is less than ideal, and may even cause
|
||||
sub-optimal wrappers to be used). Or at least change it to
|
||||
``hwdec=auto-safe``.
|
||||
|
||||
Use one of the auto modes if you want to enable hardware decoding.
|
||||
Explicitly selecting the mode is mostly meant for testing and debugging.
|
||||
@ -1010,11 +1013,25 @@ Video
|
||||
Even if enabled, hardware decoding is still only white-listed for some
|
||||
codecs. See ``--hwdec-codecs`` to enable hardware decoding in more cases.
|
||||
|
||||
.. admonition:: Which method to choose?
|
||||
|
||||
- If you only want to enable hardware decoding at runtime, don't set the
|
||||
parameter, or put ``hwdec=no`` into your ``mpv.conf`` (relevant on
|
||||
distros which force-enable it by default, such as on Ubuntu). Use the
|
||||
``Ctrl+h`` default binding to enable it at runtime.
|
||||
- If you're not sure, but want hardware decoding always enabled by
|
||||
default, put ``hwdec=auto-safe`` into your ``mpv.conf``, and
|
||||
acknowledge that this use case is not "really" supported and may cause
|
||||
problems.
|
||||
- If you want to test available hardware decoding methods, pass
|
||||
``--hwdec=auto --hwdec-codecs`` and look at the terminal output.
|
||||
|
||||
``<api>`` can be one of the following:
|
||||
|
||||
:no: always use software decoding (default)
|
||||
:auto: enable best hw decoder (see below)
|
||||
:auto: forcibly enable any hw decoder found (see below)
|
||||
:yes: exactly the same as ``auto``
|
||||
:auto-safe: enable any whitelisted hw decoder (see below)
|
||||
:auto-copy: enable best hw decoder with copy-back (see below)
|
||||
:vdpau: requires ``--vo=gpu`` with X11, or ``--vo=vdpau`` (Linux only)
|
||||
:vdpau-copy: copies video back into system RAM (Linux with some GPUs only)
|
||||
@ -1048,6 +1065,20 @@ Video
|
||||
work, it will always fall back to software decoding, instead of trying the
|
||||
next method (might matter on some Linux systems).
|
||||
|
||||
``auto-safe`` is similar to ``auto``, but allows only whitelisted methods
|
||||
that are considered "safe". This is supposed to be a reasonable way to
|
||||
enable hardware decdoding by default in a config file (even though you
|
||||
shouldn't do that anyway; prefer runtime enabling with ``Ctrl+h``). Unlike
|
||||
``auto``, this will not try to enable unknown or known-to-be-bad methods. In
|
||||
addition, this may disable hardware decoding in other situations when it's
|
||||
known to cause problems, but currently this mechanism is quite primitive.
|
||||
(As an example for something that still causes problems: certain
|
||||
combinations of HEVC and Intel chips on Windows tend to cause mpv to crash,
|
||||
most likely due to driver bugs.)
|
||||
|
||||
``auto-copy-safe`` selects the union of methods selected with ``auto-safe``
|
||||
and ``auto-copy``.
|
||||
|
||||
``auto-copy`` selects only modes that copy the video data back to system
|
||||
memory after decoding. This selects modes like ``vaapi-copy`` (and so on).
|
||||
If none of these work, hardware decoding is disabled. This mode is usually
|
||||
@ -1074,8 +1105,9 @@ Video
|
||||
output path. To use this deinterlacing you must pass the option:
|
||||
``vd-lavc-o=deint=[weave|bob|adaptive]``.
|
||||
Pass ``weave`` (or leave the option unset) to not attempt any
|
||||
deinterlacing. ``cuda`` should always be preferred unless the ``gpu``
|
||||
vo is not being used or filters are required.
|
||||
deinterlacing. ``cuda`` should always be preferred over ``cuda-copy`` unless
|
||||
the ``gpu`` vo is not being used or filters are required. Using ``nvdec``
|
||||
should be preferred on Nvidia hardware.
|
||||
|
||||
``nvdec`` is a newer implementation of CUVID/CUDA decoding, which uses the
|
||||
FFmpeg decoders for file parsing. Experimental, is known not to correctly
|
||||
|
@ -155,6 +155,7 @@ struct hwdec_info {
|
||||
enum AVPixelFormat pix_fmt; // if not NONE, select in get_format
|
||||
bool use_hw_frames; // set AVCodecContext.hw_frames_ctx
|
||||
bool use_hw_device; // set AVCodecContext.hw_device_ctx
|
||||
unsigned int flags; // HWDEC_FLAG_*
|
||||
|
||||
// for internal sorting
|
||||
int auto_pos;
|
||||
@ -216,19 +217,33 @@ typedef struct lavc_ctx {
|
||||
struct mp_decoder public;
|
||||
} vd_ffmpeg_ctx;
|
||||
|
||||
enum {
|
||||
HWDEC_FLAG_AUTO = (1 << 0), // prioritize in autoprobe order
|
||||
HWDEC_FLAG_WHITELIST = (1 << 1), // whitelist for auto-safe
|
||||
};
|
||||
|
||||
struct autoprobe_info {
|
||||
const char *method_name;
|
||||
unsigned int flags; // HWDEC_FLAG_*
|
||||
};
|
||||
|
||||
// Things not included in this list will be tried last, in random order.
|
||||
static const char *const hwdec_autoprobe_order[] = {
|
||||
"d3d11va",
|
||||
"dxva2",
|
||||
"dxva2-copy",
|
||||
"d3d11va-copy",
|
||||
"nvdec",
|
||||
"nvdec-copy",
|
||||
"vaapi",
|
||||
"vaapi-copy",
|
||||
"vdpau",
|
||||
"vdpau-copy",
|
||||
0
|
||||
const struct autoprobe_info hwdec_autoprobe_info[] = {
|
||||
{"d3d11va", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"dxva2", HWDEC_FLAG_AUTO},
|
||||
{"dxva2-copy", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"d3d11va-copy", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"nvdec", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"nvdec-copy", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"vaapi", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"vaapi-copy", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"vdpau", HWDEC_FLAG_AUTO},
|
||||
{"vdpau-copy", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"mmal", HWDEC_FLAG_AUTO},
|
||||
{"mmal-copy", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"videotoolbox", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{"videotoolbox-copy", HWDEC_FLAG_AUTO | HWDEC_FLAG_WHITELIST},
|
||||
{0}
|
||||
};
|
||||
|
||||
static int hwdec_compare(const void *p1, const void *p2)
|
||||
@ -266,9 +281,14 @@ static void add_hwdec_item(struct hwdec_info **infos, int *num_infos,
|
||||
|
||||
info.rank = *num_infos;
|
||||
info.auto_pos = INT_MAX;
|
||||
for (int x = 0; hwdec_autoprobe_order[x]; x++) {
|
||||
if (strcmp(hwdec_autoprobe_order[x], info.method_name) == 0)
|
||||
info.auto_pos = x;
|
||||
|
||||
for (int x = 0; hwdec_autoprobe_info[x].method_name; x++) {
|
||||
const struct autoprobe_info *entry = &hwdec_autoprobe_info[x];
|
||||
if (strcmp(entry->method_name, info.method_name) == 0) {
|
||||
info.flags |= entry->flags;
|
||||
if (info.flags & HWDEC_FLAG_AUTO)
|
||||
info.auto_pos = x;
|
||||
}
|
||||
}
|
||||
|
||||
MP_TARRAY_APPEND(NULL, *infos, *num_infos, info);
|
||||
@ -434,8 +454,11 @@ static void select_and_set_hwdec(struct mp_filter *vd)
|
||||
bool hwdec_auto_all = bstr_equals0(opt, "auto") ||
|
||||
bstr_equals0(opt, "yes") ||
|
||||
bstr_equals0(opt, "");
|
||||
bool hwdec_auto_copy = bstr_equals0(opt, "auto-copy");
|
||||
bool hwdec_auto = hwdec_auto_all || hwdec_auto_copy;
|
||||
bool hwdec_auto_safe = bstr_equals0(opt, "auto-safe") ||
|
||||
bstr_equals0(opt, "auto-copy-safe");
|
||||
bool hwdec_auto_copy = bstr_equals0(opt, "auto-copy") ||
|
||||
bstr_equals0(opt, "auto-copy-safe");
|
||||
bool hwdec_auto = hwdec_auto_all || hwdec_auto_copy || hwdec_auto_safe;
|
||||
|
||||
if (!hwdec_requested) {
|
||||
MP_VERBOSE(vd, "No hardware decoding requested.\n");
|
||||
@ -460,6 +483,9 @@ static void select_and_set_hwdec(struct mp_filter *vd)
|
||||
bstr_equals0(opt, hwdec->name)))
|
||||
continue;
|
||||
|
||||
if (hwdec_auto_safe && !(hwdec->flags & HWDEC_FLAG_WHITELIST))
|
||||
continue;
|
||||
|
||||
MP_VERBOSE(vd, "Looking at hwdec %s...\n", hwdec->name);
|
||||
|
||||
if (hwdec_auto_copy && !hwdec->copying) {
|
||||
@ -530,6 +556,12 @@ static int hwdec_validate_opt(struct mp_log *log, const m_option_t *opt,
|
||||
|
||||
talloc_free(hwdecs);
|
||||
|
||||
mp_info(log, " auto (yes '')\n");
|
||||
mp_info(log, " no\n");
|
||||
mp_info(log, " auto-safe\n");
|
||||
mp_info(log, " auto-copy\n");
|
||||
mp_info(log, " auto-copy-safe\n");
|
||||
|
||||
return M_OPT_EXIT;
|
||||
}
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user