summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRostislav Pehlivanov <atomnuker@gmail.com>2018-03-29 22:23:27 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-03-30 14:16:07 -0700
commite3e2c794efcff035615ac93f8a4cd9ab2cef4d97 (patch)
treeed2a56b914f67fb99034c8bd6a7e2b6473693d5d
parentaf9c6c11339c685c217a8ed5a75bb10049a460c2 (diff)
downloadmpv-e3e2c794efcff035615ac93f8a4cd9ab2cef4d97.tar.bz2
mpv-e3e2c794efcff035615ac93f8a4cd9ab2cef4d97.tar.xz
vaapi: add option to select a non-default device path
On machines with multiple GPUs, /dev/dri/renderD128 isn't guaranteed to point to a valid vaapi device. This just adds the option to specify what path to use. The old fallback /dev/dri/card0 is gone but that's not a loss as its a legacy interface no longer accepted as valid by libva. Fixes #4320
-rw-r--r--options/options.c5
-rw-r--r--options/options.h1
-rw-r--r--video/vaapi.c73
3 files changed, 52 insertions, 27 deletions
diff --git a/options/options.c b/options/options.c
index a2322e7bb1..679133dbb3 100644
--- a/options/options.c
+++ b/options/options.c
@@ -89,6 +89,7 @@ extern const struct m_sub_options angle_conf;
extern const struct m_sub_options cocoa_conf;
extern const struct m_sub_options macos_conf;
extern const struct m_sub_options android_conf;
+extern const struct m_sub_options vaapi_conf;
static const struct m_sub_options screenshot_conf = {
.opts = image_writer_opts,
@@ -756,6 +757,10 @@ const m_option_t mp_opts[] = {
0, INT_MAX, ({"auto", -1})),
#endif
+#if HAVE_VAAPI
+ OPT_SUBSTRUCT("vaapi", vaapi_opts, vaapi_conf, 0),
+#endif
+
#if HAVE_ENCODING
OPT_SUBSTRUCT("", encode_opts, encode_config, 0),
#endif
diff --git a/options/options.h b/options/options.h
index ac852b6484..1e95e78e80 100644
--- a/options/options.h
+++ b/options/options.h
@@ -347,6 +347,7 @@ typedef struct MPOpts {
struct macos_opts *macos_opts;
struct android_opts *android_opts;
struct dvd_opts *dvd_opts;
+ struct vaapi_opts *vaapi_opts;
int cuda_device;
} MPOpts;
diff --git a/video/vaapi.c b/video/vaapi.c
index 152b52f60c..8f097539f6 100644
--- a/video/vaapi.c
+++ b/video/vaapi.c
@@ -26,10 +26,27 @@
#include "mp_image.h"
#include "img_format.h"
#include "mp_image_pool.h"
+#include "options/m_config.h"
#include <libavutil/hwcontext.h>
#include <libavutil/hwcontext_vaapi.h>
+struct vaapi_opts {
+ char *path;
+};
+
+#define OPT_BASE_STRUCT struct vaapi_opts
+const struct m_sub_options vaapi_conf = {
+ .opts = (const struct m_option[]) {
+ OPT_STRING("device", path, 0),
+ {0},
+ },
+ .defaults = &(const struct vaapi_opts) {
+ .path = "/dev/dri/renderD128",
+ },
+ .size = sizeof(struct vaapi_opts),
+};
+
int va_get_colorspace_flag(enum mp_csp csp)
{
switch (csp) {
@@ -216,7 +233,8 @@ bool va_guess_if_emulated(struct mp_vaapi_ctx *ctx)
}
struct va_native_display {
- void (*create)(VADisplay **out_display, void **out_native_ctx);
+ void (*create)(VADisplay **out_display, void **out_native_ctx,
+ const char *path);
void (*destroy)(void *native_ctx);
};
@@ -229,7 +247,8 @@ static void x11_destroy(void *native_ctx)
XCloseDisplay(native_ctx);
}
-static void x11_create(VADisplay **out_display, void **out_native_ctx)
+static void x11_create(VADisplay **out_display, void **out_native_ctx,
+ const char *path)
{
void *native_display = XOpenDisplay(NULL);
if (!native_display)
@@ -264,30 +283,23 @@ static void drm_destroy(void *native_ctx)
talloc_free(ctx);
}
-static void drm_create(VADisplay **out_display, void **out_native_ctx)
+static void drm_create(VADisplay **out_display, void **out_native_ctx,
+ const char *path)
{
- static const char *drm_device_paths[] = {
- "/dev/dri/renderD128",
- "/dev/dri/card0",
- NULL
- };
-
- for (int i = 0; drm_device_paths[i]; i++) {
- int drm_fd = open(drm_device_paths[i], O_RDWR);
- if (drm_fd < 0)
- continue;
-
- struct va_native_display_drm *ctx = talloc_ptrtype(NULL, ctx);
- ctx->drm_fd = drm_fd;
- *out_display = vaGetDisplayDRM(drm_fd);
- if (out_display) {
- *out_native_ctx = ctx;
- return;
- }
+ int drm_fd = open(path, O_RDWR);
+ if (drm_fd < 0)
+ return;
- close(drm_fd);
- talloc_free(ctx);
+ struct va_native_display_drm *ctx = talloc_ptrtype(NULL, ctx);
+ ctx->drm_fd = drm_fd;
+ *out_display = vaGetDisplayDRM(drm_fd);
+ if (out_display) {
+ *out_native_ctx = ctx;
+ return;
}
+
+ close(drm_fd);
+ talloc_free(ctx);
}
static const struct va_native_display disp_drm = {
@@ -309,24 +321,31 @@ static const struct va_native_display *const native_displays[] = {
static struct AVBufferRef *va_create_standalone(struct mpv_global *global,
struct mp_log *log, struct hwcontext_create_dev_params *params)
{
+ struct AVBufferRef *ret = NULL;
+ struct vaapi_opts *opts = mp_get_config_group(NULL, global, &vaapi_conf);
+
for (int n = 0; native_displays[n]; n++) {
VADisplay *display = NULL;
void *native_ctx = NULL;
- native_displays[n]->create(&display, &native_ctx);
+ native_displays[n]->create(&display, &native_ctx, opts->path);
if (display) {
struct mp_vaapi_ctx *ctx =
va_initialize(display, log, params->probing);
if (!ctx) {
vaTerminate(display);
native_displays[n]->destroy(native_ctx);
- return NULL;
+ goto end;
}
ctx->native_ctx = native_ctx;
ctx->destroy_native_ctx = native_displays[n]->destroy;
- return ctx->hwctx.av_device_ref;
+ ret = ctx->hwctx.av_device_ref;
+ goto end;
}
}
- return NULL;
+
+end:
+ talloc_free(opts);
+ return ret;
}
const struct hwcontext_fns hwcontext_fns_vaapi = {