summaryrefslogtreecommitdiffstats
path: root/video/vaapi.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-01-11 16:07:53 +0100
committerwm4 <wm4@nowhere>2017-01-11 16:34:18 +0100
commit9fd986b53a319d449ae09a51729ca7dc89146941 (patch)
tree0c0e8dd8ab9e5592179f7c34707ff1e950bac20f /video/vaapi.c
parent7dc74ee03721e8ccfa09122c56e76a9c62c68db4 (diff)
downloadmpv-9fd986b53a319d449ae09a51729ca7dc89146941.tar.bz2
mpv-9fd986b53a319d449ae09a51729ca7dc89146941.tar.xz
vaapi: move standalone display creation code to common code
Preparation for the following commits.
Diffstat (limited to 'video/vaapi.c')
-rw-r--r--video/vaapi.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/video/vaapi.c b/video/vaapi.c
index 3db82d21fc..3545c32837 100644
--- a/video/vaapi.c
+++ b/video/vaapi.c
@@ -199,6 +199,9 @@ void va_destroy(struct mp_vaapi_ctx *ctx)
if (ctx->display)
vaTerminate(ctx->display);
+ if (ctx->destroy_native_ctx)
+ ctx->destroy_native_ctx(ctx->native_ctx);
+
pthread_mutex_lock(&va_log_mutex);
for (int n = 0; n < num_va_mpv_clients; n++) {
if (va_mpv_clients[n] == ctx) {
@@ -610,3 +613,115 @@ bool va_guess_if_emulated(struct mp_vaapi_ctx *ctx)
va_unlock(ctx);
return s && strstr(s, "VDPAU backend");
}
+
+struct va_native_display {
+ void (*create)(VADisplay **out_display, void **out_native_ctx);
+ void (*destroy)(void *native_ctx);
+};
+
+#if HAVE_VAAPI_X11
+#include <X11/Xlib.h>
+#include <va/va_x11.h>
+
+static void x11_destroy(void *native_ctx)
+{
+ XCloseDisplay(native_ctx);
+}
+
+static void x11_create(VADisplay **out_display, void **out_native_ctx)
+{
+ void *native_display = XOpenDisplay(NULL);
+ if (!native_display)
+ return;
+ *out_display = vaGetDisplay(native_display);
+ if (*out_display) {
+ *out_native_ctx = native_display;
+ } else {
+ XCloseDisplay(native_display);
+ }
+}
+
+static const struct va_native_display disp_x11 = {
+ .create = x11_create,
+ .destroy = x11_destroy,
+};
+#endif
+
+#if HAVE_VAAPI_DRM
+#include <unistd.h>
+#include <fcntl.h>
+#include <va/va_drm.h>
+
+struct va_native_display_drm {
+ int drm_fd;
+};
+
+static void drm_destroy(void *native_ctx)
+{
+ struct va_native_display_drm *ctx = native_ctx;
+ close(ctx->drm_fd);
+ talloc_free(ctx);
+}
+
+static void drm_create(VADisplay **out_display, void **out_native_ctx)
+{
+ 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;
+ }
+
+ close(drm_fd);
+ talloc_free(ctx);
+ }
+}
+
+static const struct va_native_display disp_drm = {
+ .create = drm_create,
+ .destroy = drm_destroy,
+};
+#endif
+
+static const struct va_native_display *const native_displays[] = {
+#if HAVE_VAAPI_DRM
+ &disp_drm,
+#endif
+#if HAVE_VAAPI_X11
+ &disp_x11,
+#endif
+ NULL
+};
+
+struct mp_vaapi_ctx *va_create_standalone(struct mp_log *plog, bool probing)
+{
+ for (int n = 0; native_displays[n]; n++) {
+ VADisplay *display = NULL;
+ void *native_ctx = NULL;
+ native_displays[n]->create(&display, &native_ctx);
+ if (display) {
+ struct mp_vaapi_ctx *ctx = va_initialize(display, plog, probing);
+ if (!ctx) {
+ vaTerminate(display);
+ native_displays[n]->destroy(native_ctx);
+ return NULL;
+ }
+ ctx->native_ctx = native_ctx;
+ ctx->destroy_native_ctx = native_displays[n]->destroy;
+ return ctx;
+ }
+ }
+ return NULL;
+}