summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-12-24 09:24:22 +0100
committerwm4 <wm4@nowhere>2019-12-24 09:24:22 +0100
commit380f01567d183a4dd5c4f86a58470145a29f578d (patch)
tree9146b216d3ad249744e8a63ce9b6ad6b45b092a4 /video
parente7add205d8fdfcb31a569e282284b10db83130b9 (diff)
downloadmpv-380f01567d183a4dd5c4f86a58470145a29f578d.tar.bz2
mpv-380f01567d183a4dd5c4f86a58470145a29f578d.tar.xz
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.
Diffstat (limited to 'video')
-rw-r--r--video/decode/vd_lavc.c66
1 files changed, 49 insertions, 17 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 3f0eedc47c..985a2b6d2e 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -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;