From e3e2c794efcff035615ac93f8a4cd9ab2cef4d97 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Thu, 29 Mar 2018 22:23:27 +0100 Subject: 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 --- options/options.c | 5 ++++ options/options.h | 1 + video/vaapi.c | 73 +++++++++++++++++++++++++++++++++++-------------------- 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 #include +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 = { -- cgit v1.2.3