diff options
author | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-08-01 15:44:02 +0200 |
---|---|---|
committer | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-08-01 16:40:17 +0200 |
commit | 657f0a4a6f76e121043d022c0f8be1cfdb4834d9 (patch) | |
tree | 73189a4ff2052921d6ef57f2b9a7de403f5eb78d /gst-libs/gst | |
parent | 7070961202ea7026fb5acdc8dbfa1f1764261d56 (diff) |
Add initial support for VA/DRM.
Diffstat (limited to 'gst-libs/gst')
-rw-r--r-- | gst-libs/gst/vaapi/Makefile.am | 55 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay.c | 4 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay.h | 2 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 532 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 97 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 55 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiwindow_drm.c | 161 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiwindow_drm.h | 85 |
8 files changed, 991 insertions, 0 deletions
diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index b9fc07de..5719222f 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -1,5 +1,9 @@ lib_LTLIBRARIES = libgstvaapi-@GST_MAJORMINOR@.la +if USE_DRM +lib_LTLIBRARIES += libgstvaapi-drm-@GST_MAJORMINOR@.la +endif + if USE_X11 lib_LTLIBRARIES += libgstvaapi-x11-@GST_MAJORMINOR@.la endif @@ -115,6 +119,23 @@ libgstvaapi_source_c += gstvaapidecoder_jpeg.c libgstvaapi_source_h += gstvaapidecoder_jpeg.h endif +libgstvaapi_drm_source_c = \ + gstvaapidisplay_drm.c \ + gstvaapiwindow_drm.c \ + gstvaapiutils.c \ + $(NULL) + +libgstvaapi_drm_source_h = \ + gstvaapidisplay_drm.h \ + gstvaapiwindow_drm.h \ + $(NULL) + +libgstvaapi_drm_source_priv_h = \ + gstvaapicompat.h \ + gstvaapidisplay_drm_priv.h \ + gstvaapiutils.h \ + $(NULL) + libgstvaapi_x11_source_c = \ gstvaapidisplay_x11.c \ gstvaapiutils.c \ @@ -207,6 +228,40 @@ libgstvaapi_@GST_MAJORMINOR@_la_LDFLAGS = \ $(GST_ALL_LDFLAGS) \ $(NULL) +libgstvaapi_drm_@GST_MAJORMINOR@_la_SOURCES = \ + $(libgstvaapi_drm_source_c) \ + $(libgstvaapi_drm_source_priv_h) \ + $(NULL) + +libgstvaapi_drm_@GST_MAJORMINOR@include_HEADERS = \ + $(libgstvaapi_drm_source_h) \ + $(NULL) + +libgstvaapi_drm_@GST_MAJORMINOR@includedir = \ + $(libgstvaapi_includedir) + +libgstvaapi_drm_@GST_MAJORMINOR@_la_CFLAGS = \ + -DGST_USE_UNSTABLE_API \ + -I$(top_srcdir)/gst-libs \ + $(GLIB_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(UDEV_CFLAGS) \ + $(DRM_CFLAGS) \ + $(LIBVA_DRM_CFLAGS) \ + $(NULL) + +libgstvaapi_drm_@GST_MAJORMINOR@_la_LIBADD = \ + $(GLIB_LIBS) \ + $(UDEV_LIBS) \ + $(DRM_LIBS) \ + $(LIBVA_DRM_LIBS) \ + libgstvaapi-@GST_MAJORMINOR@.la \ + $(NULL) + +libgstvaapi_drm_@GST_MAJORMINOR@_la_LDFLAGS = \ + $(GST_ALL_LDFLAGS) \ + $(NULL) + libgstvaapi_x11_@GST_MAJORMINOR@_la_SOURCES = \ $(libgstvaapi_x11_source_c) \ $(libgstvaapi_x11_source_priv_h) \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 7238518f..6f9c75f4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -102,6 +102,10 @@ gst_vaapi_display_type_get_type(void) { GST_VAAPI_DISPLAY_TYPE_WAYLAND, "VA/Wayland display", "wayland" }, #endif +#if USE_DRM + { GST_VAAPI_DISPLAY_TYPE_DRM, + "VA/DRM display", "drm" }, +#endif { 0, NULL, NULL }, }; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index d8fa9a38..2b826665 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -66,12 +66,14 @@ typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; * @GST_VAAPI_DISPLAY_TYPE_X11: VA/X11 display. * @GST_VAAPI_DISPLAY_TYPE_GLX: VA/GLX display. * @GST_VAAPI_DISPLAY_TYPE_WAYLAND: VA/Wayland display. + * @GST_VAAPI_DISPLAY_TYPE_DRM: VA/DRM display. */ enum _GstVaapiDisplayType { GST_VAAPI_DISPLAY_TYPE_ANY = 0, GST_VAAPI_DISPLAY_TYPE_X11, GST_VAAPI_DISPLAY_TYPE_GLX, GST_VAAPI_DISPLAY_TYPE_WAYLAND, + GST_VAAPI_DISPLAY_TYPE_DRM, }; #define GST_VAAPI_TYPE_DISPLAY_TYPE \ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c new file mode 100644 index 00000000..6a1d1482 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -0,0 +1,532 @@ +/* + * gstvaapidisplay_drm.c - VA/DRM display abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/** + * SECTION:gstvaapidisplay_drm + * @short_description: VA/DRM display abstraction + */ + +#include "sysdeps.h" +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <libudev.h> +#include <xf86drm.h> +#include <va/va_drm.h> +#include "gstvaapiutils.h" +#include "gstvaapidisplay_priv.h" +#include "gstvaapidisplay_drm.h" +#include "gstvaapidisplay_drm_priv.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiDisplayDRM, + gst_vaapi_display_drm, + GST_VAAPI_TYPE_DISPLAY); + +enum { + PROP_0, + + PROP_DEVICE_PATH, + PROP_DRM_DEVICE +}; + +#define NAME_PREFIX "DRM:" +#define NAME_PREFIX_LENGTH 4 + +static inline gboolean +is_device_path(const gchar *device_path) +{ + return strncmp(device_path, NAME_PREFIX, NAME_PREFIX_LENGTH) == 0; +} + +static gboolean +compare_device_path(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const gchar *cached_name = a; + const gchar *tested_name = b; + + if (!cached_name || !is_device_path(cached_name)) + return FALSE; + g_return_val_if_fail(tested_name && is_device_path(tested_name), FALSE); + + cached_name += NAME_PREFIX_LENGTH; + tested_name += NAME_PREFIX_LENGTH; + return strcmp(cached_name, tested_name) == 0; +} + +static void +gst_vaapi_display_drm_finalize(GObject *object) +{ + G_OBJECT_CLASS(gst_vaapi_display_drm_parent_class)->finalize(object); +} + +/* Get default device path. Actually, the first match in the DRM subsystem */ +static const gchar * +get_default_device_path(gpointer ptr) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(ptr); + GstVaapiDisplayDRMPrivate * const priv = display->priv; + const gchar *syspath, *devpath; + struct udev *udev = NULL; + struct udev_device *device, *parent; + struct udev_enumerate *e = NULL; + struct udev_list_entry *l; + int fd; + + if (!priv->device_path_default) { + udev = udev_new(); + if (!udev) + goto end; + + e = udev_enumerate_new(udev); + if (!e) + goto end; + + udev_enumerate_add_match_subsystem(e, "drm"); + udev_enumerate_scan_devices(e); + udev_list_entry_foreach(l, udev_enumerate_get_list_entry(e)) { + syspath = udev_list_entry_get_name(l); + device = udev_device_new_from_syspath(udev, syspath); + parent = udev_device_get_parent(device); + if (strcmp(udev_device_get_subsystem(parent), "pci") != 0) { + udev_device_unref(device); + continue; + } + + devpath = udev_device_get_devnode(device); + fd = open(devpath, O_RDWR|O_CLOEXEC); + if (fd < 0) { + udev_device_unref(device); + continue; + } + + priv->device_path_default = g_strdup(devpath); + close(fd); + udev_device_unref(device); + break; + } + + end: + if (e) + udev_enumerate_unref(e); + if (udev) + udev_unref(udev); + } + return priv->device_path_default; +} + +/* Reconstruct a device path without our prefix */ +static const gchar * +get_device_path(gpointer ptr) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(ptr); + const gchar *device_path = display->priv->device_path; + + if (!device_path) + return NULL; + + g_return_val_if_fail(is_device_path(device_path), NULL); + + device_path += NAME_PREFIX_LENGTH; + if (*device_path == '\0') + return NULL; + return device_path; +} + +/* Mangle device path with our prefix */ +static void +set_device_path(GstVaapiDisplayDRM *display, const gchar *device_path) +{ + GstVaapiDisplayDRMPrivate * const priv = display->priv; + + g_free(priv->device_path); + priv->device_path = NULL; + + if (!device_path) { + device_path = get_default_device_path(display); + if (!device_path) + return; + } + priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, device_path); +} + +/* Set device path from file descriptor */ +static void +set_device_path_from_fd(GstVaapiDisplayDRM *display, gint drm_device) +{ + GstVaapiDisplayDRMPrivate * const priv = display->priv; + const gchar *busid, *path, *str; + gsize busid_length, path_length; + struct udev *udev = NULL; + struct udev_device *device; + struct udev_enumerate *e = NULL; + struct udev_list_entry *l; + + g_free(priv->device_path); + priv->device_path = NULL; + + if (drm_device < 0) + return; + + busid = drmGetBusid(drm_device); + if (!busid) + return; + if (strncmp(busid, "pci:", 4) != 0) + return; + busid += 4; + busid_length = strlen(busid); + + udev = udev_new(); + if (!udev) + goto end; + + e = udev_enumerate_new(udev); + if (!e) + goto end; + + udev_enumerate_add_match_subsystem(e, "drm"); + udev_enumerate_scan_devices(e); + udev_list_entry_foreach(l, udev_enumerate_get_list_entry(e)) { + path = udev_list_entry_get_name(l); + str = strstr(path, busid); + if (!str || str <= path || str[-1] != '/') + continue; + + path_length = strlen(path); + if (str + busid_length >= path + path_length) + continue; + if (strncmp(&str[busid_length], "/drm/card", 9) != 0) + continue; + + device = udev_device_new_from_syspath(udev, path); + if (!device) + continue; + + path = udev_device_get_devnode(device); + priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, path); + udev_device_unref(device); + break; + } + +end: + if (e) + udev_enumerate_unref(e); + if (udev) + udev_unref(udev); +} + +static void +gst_vaapi_display_drm_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); + + switch (prop_id) { + case PROP_DEVICE_PATH: + set_device_path(display, g_value_get_string(value)); + break; + case PROP_DRM_DEVICE: + display->priv->drm_device = g_value_get_int(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_display_drm_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); + + switch (prop_id) { + case PROP_DEVICE_PATH: + g_value_set_string(value, get_device_path(display)); + break; + case PROP_DRM_DEVICE: + g_value_set_int(value, display->priv->drm_device); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_vaapi_display_drm_constructed(GObject *object) +{ + GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); + GstVaapiDisplayDRMPrivate * const priv = display->priv; + GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); + const GstVaapiDisplayInfo *info; + GObjectClass *parent_class; + + priv->create_display = priv->drm_device < 0; + + /* Don't create DRM display if there is one in the cache already */ + if (priv->create_display) { + info = gst_vaapi_display_cache_lookup_by_name( + cache, + priv->device_path, + compare_device_path, NULL + ); + if (info) { + priv->drm_device = GPOINTER_TO_INT(info->native_display); + priv->create_display = FALSE; + } + } + + /* Reset device-path if the user provided his own DRM display */ + if (!priv->create_display) + set_device_path_from_fd(display, priv->drm_device); + + parent_class = G_OBJECT_CLASS(gst_vaapi_display_drm_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static gboolean +gst_vaapi_display_drm_open_display(GstVaapiDisplay *display) +{ + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM(display)->priv; + + if (priv->create_display) { + const gchar *device_path = get_device_path(display); + if (!device_path) + return FALSE; + priv->drm_device = open(device_path, O_RDWR|O_CLOEXEC); + if (priv->drm_device < 0) + return FALSE; + } + if (priv->drm_device < 0) + return FALSE; + return TRUE; +} + +static void +gst_vaapi_display_drm_close_display(GstVaapiDisplay *display) +{ + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM(display)->priv; + + if (priv->drm_device >= 0) { + if (priv->create_display) + close(priv->drm_device); + priv->drm_device = -1; + } + + if (priv->device_path) { + g_free(priv->device_path); + priv->device_path = NULL; + } + + if (priv->device_path_default) { + g_free(priv->device_path_default); + priv->device_path_default = NULL; + } +} + +static gboolean +gst_vaapi_display_drm_get_display_info( + GstVaapiDisplay *display, + GstVaapiDisplayInfo *info +) +{ + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM(display)->priv; + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *cached_info; + + /* Return any cached info even if child has its own VA display */ + cache = gst_vaapi_display_get_cache(); + if (!cache) + return FALSE; + cached_info = gst_vaapi_display_cache_lookup_by_native_display( + cache, GINT_TO_POINTER(priv->drm_device)); + if (cached_info) { + *info = *cached_info; + return TRUE; + } + + /* Otherwise, create VA display if there is none already */ + info->native_display = GINT_TO_POINTER(priv->drm_device); + info->display_name = priv->device_path; + if (!info->va_display) { + info->va_display = vaGetDisplayDRM(priv->drm_device); + if (!info->va_display) + return FALSE; + info->display_type = GST_VAAPI_DISPLAY_TYPE_DRM; + } + return TRUE; +} + +static void +gst_vaapi_display_drm_class_init(GstVaapiDisplayDRMClass *klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GstVaapiDisplayDRMPrivate)); + + object_class->finalize = gst_vaapi_display_drm_finalize; + object_class->set_property = gst_vaapi_display_drm_set_property; + object_class->get_property = gst_vaapi_display_drm_get_property; + object_class->constructed = gst_vaapi_display_drm_constructed; + + dpy_class->open_display = gst_vaapi_display_drm_open_display; + dpy_class->close_display = gst_vaapi_display_drm_close_display; + dpy_class->get_display = gst_vaapi_display_drm_get_display_info; + + /** + * GstVaapiDisplayDRM:drm-device: + * + * The DRM device (file descriptor). + */ + g_object_class_install_property + (object_class, + PROP_DRM_DEVICE, + g_param_spec_int("drm-device", + "DRM device", + "DRM device", + -1, G_MAXINT32, -1, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + /** + * GstVaapiDisplayDRM:device-path: + * + * The DRM device path. + */ + g_object_class_install_property + (object_class, + PROP_DEVICE_PATH, + g_param_spec_string("device-path", + "DRM device path", + "DRM device path", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gst_vaapi_display_drm_init(GstVaapiDisplayDRM *display) +{ + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(display); + + display->priv = priv; + priv->device_path_default = NULL; + priv->device_path = NULL; + priv->drm_device = -1; + priv->create_display = TRUE; +} + +/** + * gst_vaapi_display_drm_new: + * @device_path: the DRM device path + * + * Opens an DRM file descriptor using @device_path and returns a newly + * allocated #GstVaapiDisplay object. The DRM display will be cloed + * when the reference count of the object reaches zero. + * + * If @device_path is NULL, the DRM device path will be automatically + * determined as the first positive match in the list of available DRM + * devices. + * + * Return value: a newly allocated #GstVaapiDisplay object + */ +GstVaapiDisplay * +gst_vaapi_display_drm_new(const gchar *device_path) +{ + return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, + "device-path", device_path, + NULL); +} + +/** + * gst_vaapi_display_drm_new_with_device: + * @device: an open DRM device (file descriptor) + * + * Creates a #GstVaapiDisplay based on the open DRM @device. The + * caller still owns the device file descriptor and must call close() + * when all #GstVaapiDisplay references are released. Doing so too + * early can yield undefined behaviour. + * + * Return value: a newly allocated #GstVaapiDisplay object + */ +GstVaapiDisplay * +gst_vaapi_display_drm_new_with_device(gint device) +{ + g_return_val_if_fail(device >= 0, NULL); + + return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, + "drm-device", device, + NULL); +} + +/** + * gst_vaapi_display_drm_get_device: + * @display: a #GstVaapiDisplayDRM + * + * Returns the underlying DRM device file descriptor that was created + * by gst_vaapi_display_drm_new() or that was bound from + * gst_vaapi_display_drm_new_with_device(). + * + * Return value: the DRM file descriptor attached to @display + */ +gint +gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), -1); + + return display->priv->drm_device; +} + +/** + * gst_vaapi_display_drm_get_device_path: + * @display: a #GstVaapiDisplayDRM + * + * Returns the underlying DRM device path name was created by + * gst_vaapi_display_drm_new() or that was bound from + * gst_vaapi_display_drm_new_with_device(). + * + * Note: the #GstVaapiDisplayDRM object owns the resulting string, so + * it shall not be deallocated. + * + * Return value: the DRM device path name attached to @display + */ +const gchar * +gst_vaapi_display_drm_get_device_path(GstVaapiDisplayDRM *display) +{ + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), NULL); + + return display->priv->device_path; +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h new file mode 100644 index 00000000..fad0d530 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -0,0 +1,97 @@ +/* + * gstvaapidisplay_drm.h - VA/DRM display abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef GST_VAAPI_DISPLAY_DRM_H +#define GST_VAAPI_DISPLAY_DRM_H + +#include <gst/vaapi/gstvaapidisplay.h> + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_DISPLAY_DRM \ + (gst_vaapi_display_drm_get_type()) + +#define GST_VAAPI_DISPLAY_DRM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_DISPLAY_DRM, \ + GstVaapiDisplayDRM)) + +#define GST_VAAPI_DISPLAY_DRM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_DISPLAY_DRM, \ + GstVaapiDisplayDRMClass)) + +#define GST_VAAPI_IS_DISPLAY_DRM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_DRM)) + +#define GST_VAAPI_IS_DISPLAY_DRM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_DRM)) + +#define GST_VAAPI_DISPLAY_DRM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_DISPLAY_DRM, \ + GstVaapiDisplayDRMClass)) + +typedef struct _GstVaapiDisplayDRM GstVaapiDisplayDRM; +typedef struct _GstVaapiDisplayDRMPrivate GstVaapiDisplayDRMPrivate; +typedef struct _GstVaapiDisplayDRMClass GstVaapiDisplayDRMClass; + +/** + * GstVaapiDisplayDRM: + * + * VA/DRM display wrapper. + */ +struct _GstVaapiDisplayDRM { + /*< private >*/ + GstVaapiDisplay parent_instance; + + GstVaapiDisplayDRMPrivate *priv; +}; + + +/** + * GstVaapiDisplayDRMClass: + * + * VA/DRM display wrapper clas. + */ +struct _GstVaapiDisplayDRMClass { + /*< private >*/ + GstVaapiDisplayClass parent_class; +}; + +GType +gst_vaapi_display_drm_get_type(void) G_GNUC_CONST; + +GstVaapiDisplay * +gst_vaapi_display_drm_new(const gchar *device_path); + +GstVaapiDisplay * +gst_vaapi_display_drm_new_with_device(gint device); + +gint +gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display); + +const gchar * +gst_vaapi_display_drm_get_device_path(GstVaapiDisplayDRM *display); + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_DRM_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h new file mode 100644 index 00000000..f6211a73 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -0,0 +1,55 @@ +/* + * gstvaapidisplay_drm_priv.h - Internal VA/DRM interface + * + * Copyright (C) 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef GST_VAAPI_DISPLAY_DRM_PRIV_H +#define GST_VAAPI_DISPLAY_DRM_PRIV_H + +#include <gst/vaapi/gstvaapidisplay_drm.h> + +G_BEGIN_DECLS + +#define GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + GST_VAAPI_TYPE_DISPLAY_DRM, \ + GstVaapiDisplayDRMPrivate)) + +#define GST_VAAPI_DISPLAY_DRM_CAST(display) ((GstVaapiDisplayDRM *)(display)) + +/** + * GST_VAAPI_DISPLAY_DRM_DEVICE: + * @display: a #GstVaapiDisplay + * + * Macro that evaluates to the underlying DRM file descriptor of @display + */ +#undef GST_VAAPI_DISPLAY_DRM_DEVICE +#define GST_VAAPI_DISPLAY_DRM_DEVICE(display) \ + GST_VAAPI_DISPLAY_DRM_CAST(display)->priv->drm_device + +struct _GstVaapiDisplayDRMPrivate { + gchar *device_path_default; + gchar *device_path; + gint drm_device; + guint create_display : 1; +}; + +G_END_DECLS + +#endif /* GST_VAAPI_DISPLAY_DRM_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.c b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c new file mode 100644 index 00000000..6303480e --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.c @@ -0,0 +1,161 @@ +/* + * gstvaapiwindow_drm.c - VA/DRM window abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/** + * SECTION:gstvaapiwindow_drm + * @short_description: VA/DRM dummy window abstraction + */ + +#include "sysdeps.h" +#include "gstvaapiwindow_drm.h" + +#define DEBUG 1 +#include "gstvaapidebug.h" + +G_DEFINE_TYPE(GstVaapiWindowDRM, + gst_vaapi_window_drm, + GST_VAAPI_TYPE_WINDOW); + +static gboolean +gst_vaapi_window_drm_show(GstVaapiWindow *window) +{ + return TRUE; +} + +static gboolean +gst_vaapi_window_drm_hide(GstVaapiWindow *window) +{ + return TRUE; +} + +static gboolean +gst_vaapi_window_drm_create( + GstVaapiWindow *window, + guint *width, + guint *height +) +{ + return TRUE; +} + +static void +gst_vaapi_window_drm_destroy(GstVaapiWindow * window) +{ +} + +static gboolean +gst_vaapi_window_drm_resize( + GstVaapiWindow * window, + guint width, + guint height +) +{ + return TRUE; +} + +static gboolean +gst_vaapi_window_drm_render( + GstVaapiWindow *window, + GstVaapiSurface *surface, + const GstVaapiRectangle *src_rect, + const GstVaapiRectangle *dst_rect, + guint flags +) +{ + return TRUE; +} + +static void +gst_vaapi_window_drm_finalize(GObject *object) +{ + G_OBJECT_CLASS(gst_vaapi_window_drm_parent_class)->finalize(object); +} + +static void +gst_vaapi_window_drm_constructed(GObject *object) +{ + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS(gst_vaapi_window_drm_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static void +gst_vaapi_window_drm_class_init(GstVaapiWindowDRMClass * klass) +{ + GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiWindowClass * const window_class = GST_VAAPI_WINDOW_CLASS(klass); + + object_class->finalize = gst_vaapi_window_drm_finalize; + object_class->constructed = gst_vaapi_window_drm_constructed; + + window_class->create = gst_vaapi_window_drm_create; + window_class->destroy = gst_vaapi_window_drm_destroy; + window_class->show = gst_vaapi_window_drm_show; + window_class->hide = gst_vaapi_window_drm_hide; + window_class->render = gst_vaapi_window_drm_render; + window_class->resize = gst_vaapi_window_drm_resize; +} + +static void +gst_vaapi_window_drm_init(GstVaapiWindowDRM * window) +{ +} + +/** + * gst_vaapi_window_drm_new: + * @display: a #GstVaapiDisplay + * @width: the requested window width, in pixels (unused) + * @height: the requested windo height, in pixels (unused) + * + * Creates a dummy window. The window will be attached to the @display. + * All rendering functions will return success since VA/DRM is a + * renderless API. + * + * Note: this dummy window object is only necessary to fulfill cases + * where the client application wants to automatically determine the + * best display to use for the current system. As such, it provides + * utility functions with the same API (function arguments) to help + * implement uniform function tables. + * + * Return value: the newly allocated #GstVaapiWindow object + */ +GstVaapiWindow * +gst_vaapi_window_drm_new( + GstVaapiDisplay *display, + guint width, + guint height +) +{ + GST_DEBUG("new window, size %ux%u", width, height); + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(width > 0, NULL); + g_return_val_if_fail(height > 0, NULL); + + return g_object_new(GST_VAAPI_TYPE_WINDOW_DRM, + "display", display, + "id", GST_VAAPI_ID(0), + "width", width, + "height", height, + NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_drm.h b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h new file mode 100644 index 00000000..47e053a3 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiwindow_drm.h @@ -0,0 +1,85 @@ +/* + * gstvaapiwindow_drm.h - VA/DRM window abstraction + * + * Copyright (C) 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef GST_VAAPI_WINDOW_DRM_H +#define GST_VAAPI_WINDOW_DRM_H + +#include <gst/vaapi/gstvaapidisplay.h> +#include <gst/vaapi/gstvaapiwindow.h> + +G_BEGIN_DECLS + +#define GST_VAAPI_TYPE_WINDOW_DRM \ + (gst_vaapi_window_drm_get_type()) + +#define GST_VAAPI_WINDOW_DRM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_VAAPI_TYPE_WINDOW_DRM, \ + GstVaapiWindowDRM)) + +#define GST_VAAPI_WINDOW_DRM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_VAAPI_TYPE_WINDOW_DRM, \ + GstVaapiWindowDRMClass)) + +#define GST_VAAPI_IS_WINDOW_DRM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_DRM)) + +#define GST_VAAPI_IS_WINDOW_DRM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_DRM)) + +#define GST_VAAPI_WINDOW_DRM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GST_VAAPI_TYPE_WINDOW_DRM, \ + GstVaapiWindowDRMClass)) + +typedef struct _GstVaapiWindowDRM GstVaapiWindowDRM; +typedef struct _GstVaapiWindowDRMClass GstVaapiWindowDRMClass; + +/** + * GstVaapiWindowDRM: + * + * A dummy DRM window abstraction. + */ +struct _GstVaapiWindowDRM { + /*< private >*/ + GstVaapiWindow parent_instance; +}; + +/** + * GstVaapiWindowDRMClass: + * + * A DRM window class. + */ +struct _GstVaapiWindowDRMClass { + /*< private >*/ + GstVaapiWindowClass parent_class; +}; + +GType +gst_vaapi_window_drm_get_type(void) G_GNUC_CONST; + +GstVaapiWindow * +gst_vaapi_window_drm_new(GstVaapiDisplay *display, guint width, guint height); + +G_END_DECLS + +#endif /* GST_VAAPI_WINDOW_DRM_H */ |