mirror of
https://github.com/mpv-player/mpv
synced 2024-12-23 15:22:09 +00:00
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
This commit is contained in:
parent
af9c6c1133
commit
e3e2c794ef
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
int drm_fd = open(path, O_RDWR);
|
||||
if (drm_fd < 0)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user