aboutsummaryrefslogtreecommitdiffstats
path: root/libavutil/hwcontext_vaapi.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-05-19 19:19:20 +0200
committerAnton Khirnov <anton@khirnov.net>2016-05-26 15:40:34 +0200
commitb8bf9194af602cf3a4bcd19a5e278e3d6d69f8fa (patch)
tree0f266e9b5dc0c1a3899951d8a2a0e9d2d98a740d /libavutil/hwcontext_vaapi.c
parent8e70385a8ed06f96f1e9e35cf7b6788a5c56eded (diff)
downloadffmpeg-b8bf9194af602cf3a4bcd19a5e278e3d6d69f8fa.tar.gz
hwcontext_vaapi: implement device creation
Diffstat (limited to 'libavutil/hwcontext_vaapi.c')
-rw-r--r--libavutil/hwcontext_vaapi.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 1a385ba514..4563e147f6 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -16,6 +16,21 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
+
+#if HAVE_VAAPI_X11
+# include <va/va_x11.h>
+#endif
+#if HAVE_VAAPI_DRM
+# include <va/va_drm.h>
+#endif
+
+#include <fcntl.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+
#include "avassert.h"
#include "buffer.h"
#include "common.h"
@@ -26,6 +41,14 @@
#include "pixdesc.h"
#include "pixfmt.h"
+typedef struct VAAPIDevicePriv {
+#if HAVE_VAAPI_X11
+ Display *x11_display;
+#endif
+
+ int drm_fd;
+} VAAPIDevicePriv;
+
typedef struct VAAPISurfaceFormat {
enum AVPixelFormat pix_fmt;
VAImageFormat image_format;
@@ -823,6 +846,105 @@ fail:
return err;
}
+static void vaapi_device_free(AVHWDeviceContext *ctx)
+{
+ AVVAAPIDeviceContext *hwctx = ctx->hwctx;
+ VAAPIDevicePriv *priv = ctx->user_opaque;
+
+ if (hwctx->display)
+ vaTerminate(hwctx->display);
+
+#if HAVE_VAAPI_X11
+ if (priv->x11_display)
+ XCloseDisplay(priv->x11_display);
+#endif
+
+ if (priv->drm_fd >= 0)
+ close(priv->drm_fd);
+
+ av_freep(&priv);
+}
+
+static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device,
+ AVDictionary *opts, int flags)
+{
+ AVVAAPIDeviceContext *hwctx = ctx->hwctx;
+ VAAPIDevicePriv *priv;
+ VADisplay display = 0;
+ VAStatus vas;
+ int major, minor;
+
+ priv = av_mallocz(sizeof(*priv));
+ if (!priv)
+ return AVERROR(ENOMEM);
+
+ priv->drm_fd = -1;
+
+ ctx->user_opaque = priv;
+ ctx->free = vaapi_device_free;
+
+#if HAVE_VAAPI_X11
+ if (!display && !(device && device[0] == '/')) {
+ // Try to open the device as an X11 display.
+ priv->x11_display = XOpenDisplay(device);
+ if (!priv->x11_display) {
+ av_log(ctx, AV_LOG_VERBOSE, "Cannot open X11 display "
+ "%s.\n", XDisplayName(device));
+ } else {
+ display = vaGetDisplay(priv->x11_display);
+ if (!display) {
+ av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display "
+ "from X11 display %s.\n", XDisplayName(device));
+ return AVERROR_UNKNOWN;
+ }
+
+ av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via "
+ "X11 display %s.\n", XDisplayName(device));
+ }
+ }
+#endif
+
+#if HAVE_VAAPI_DRM
+ if (!display && device) {
+ // Try to open the device as a DRM path.
+ priv->drm_fd = open(device, O_RDWR);
+ if (priv->drm_fd < 0) {
+ av_log(ctx, AV_LOG_VERBOSE, "Cannot open DRM device %s.\n",
+ device);
+ } else {
+ display = vaGetDisplayDRM(priv->drm_fd);
+ if (!display) {
+ av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display "
+ "from DRM device %s.\n", device);
+ return AVERROR_UNKNOWN;
+ }
+
+ av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via "
+ "DRM device %s.\n", device);
+ }
+ }
+#endif
+
+ if (!display) {
+ av_log(ctx, AV_LOG_ERROR, "No VA display found for "
+ "device: %s.\n", device ? device : "");
+ return AVERROR(EINVAL);
+ }
+
+ hwctx->display = display;
+
+ vas = vaInitialize(display, &major, &minor);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI "
+ "connection: %d (%s).\n", vas, vaErrorStr(vas));
+ return AVERROR(EIO);
+ }
+ av_log(ctx, AV_LOG_VERBOSE, "Initialised VAAPI connection: "
+ "version %d.%d\n", major, minor);
+
+ return 0;
+}
+
const HWContextType ff_hwcontext_type_vaapi = {
.type = AV_HWDEVICE_TYPE_VAAPI,
.name = "VAAPI",
@@ -833,6 +955,7 @@ const HWContextType ff_hwcontext_type_vaapi = {
.frames_hwctx_size = sizeof(AVVAAPIFramesContext),
.frames_priv_size = sizeof(VAAPIFramesContext),
+ .device_create = &vaapi_device_create,
.device_init = &vaapi_device_init,
.device_uninit = &vaapi_device_uninit,
.frames_get_constraints = &vaapi_frames_get_constraints,