plugins: add support for "x11-pixmap" video converter type.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Mon, 22 Jul 2013 09:58:33 +0000 (11:58 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Mon, 22 Jul 2013 13:45:10 +0000 (15:45 +0200)
Install a new video converter that supports X11 pixmap targets for X11
backends only, or make the GLX converter creation function chain up to
the X11 converter whenever requested.

gst/vaapi/Makefile.am
gst/vaapi/gstvaapivideobuffer.c
gst/vaapi/gstvaapivideoconverter_glx.c
gst/vaapi/gstvaapivideoconverter_x11.c [new file with mode: 0644]
gst/vaapi/gstvaapivideoconverter_x11.h [new file with mode: 0644]

index bd9dedd..1b89467 100644 (file)
@@ -50,6 +50,14 @@ libgstvaapi_source_h = \
        gstvaapivideometa.h     \
        $(NULL)
 
+libgstvaapi_x11_source_c = gstvaapivideoconverter_x11.c
+libgstvaapi_x11_source_h = gstvaapivideoconverter_x11.h
+
+if USE_X11
+libgstvaapi_source_c += $(libgstvaapi_x11_source_c)
+libgstvaapi_source_h += $(libgstvaapi_x11_source_h)
+endif
+
 libgstvaapi_glx_source_c = gstvaapivideoconverter_glx.c
 libgstvaapi_glx_source_h = gstvaapivideoconverter_glx.h
 
index 1d4ec80..583f49f 100644 (file)
@@ -27,6 +27,9 @@
 
 #include "gst/vaapi/sysdeps.h"
 #include "gstvaapivideobuffer.h"
+#if USE_X11
+# include "gstvaapivideoconverter_x11.h"
+#endif
 #if USE_GLX
 # include "gstvaapivideoconverter_glx.h"
 #endif
@@ -50,6 +53,21 @@ gst_vaapi_surface_meta_get_info(void);
 typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc)(
     GstSurfaceMeta *meta, const gchar *type, GValue *dest);
 
+#if USE_X11
+static GstSurfaceConverter *
+gst_vaapi_surface_create_converter_x11(GstSurfaceMeta *base_meta,
+    const gchar *type, GValue *dest)
+{
+    GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta);
+
+    return gst_vaapi_video_converter_x11_new(meta->buffer, type, dest);
+}
+
+#undef  gst_vaapi_video_converter_x11_new
+#define gst_vaapi_video_converter_x11_new \
+    gst_vaapi_surface_create_converter_x11
+#endif
+
 #if USE_GLX
 static GstSurfaceConverter *
 gst_vaapi_surface_create_converter_glx(GstSurfaceMeta *base_meta,
@@ -60,7 +78,7 @@ gst_vaapi_surface_create_converter_glx(GstSurfaceMeta *base_meta,
     return gst_vaapi_video_converter_glx_new(meta->buffer, type, dest);
 }
 
-#undef gst_vaapi_video_converter_glx_new
+#undef  gst_vaapi_video_converter_glx_new
 #define gst_vaapi_video_converter_glx_new \
     gst_vaapi_surface_create_converter_glx
 #endif
@@ -244,6 +262,11 @@ get_surface_converter(GstVaapiDisplay *display)
     GFunc func;
 
     switch (gst_vaapi_display_get_display_type(display)) {
+#if USE_X11
+    case GST_VAAPI_DISPLAY_TYPE_X11:
+        func = (GFunc)gst_vaapi_video_converter_x11_new;
+        break;
+#endif
 #if USE_GLX
     case GST_VAAPI_DISPLAY_TYPE_GLX:
         func = (GFunc)gst_vaapi_video_converter_glx_new;
index aaa9c35..f2c5c5d 100644 (file)
@@ -24,6 +24,7 @@
 #include "gst/vaapi/sysdeps.h"
 #include <gst/vaapi/gstvaapitexture.h>
 #include "gstvaapivideoconverter_glx.h"
+#include "gstvaapivideoconverter_x11.h"
 #include "gstvaapipluginutil.h"
 #include "gstvaapivideometa.h"
 
@@ -112,9 +113,9 @@ gst_vaapi_video_converter_glx_new(GstBuffer *buffer, const gchar *type,
     GstVaapiTexture *texture;
     GstVaapiVideoConverterGLX *converter;
 
-    /* We only support Open GL texture conversion */
+    /* Check for "opengl" request, or chain up to X11 converter */
     if (strcmp(type, "opengl") != 0 || !G_VALUE_HOLDS_UINT(dest))
-        return NULL;
+        return gst_vaapi_video_converter_x11_new(buffer, type, dest);
 
     /* FIXME Should we assume target and format ? */
     texture = gst_vaapi_texture_new_with_texture(
diff --git a/gst/vaapi/gstvaapivideoconverter_x11.c b/gst/vaapi/gstvaapivideoconverter_x11.c
new file mode 100644 (file)
index 0000000..18f4e56
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ *  gstvaapivideoconverter_x11.h - VA video converter to X11 pixmap
+ *
+ *  Copyright (C) 2013 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
+ */
+
+#include "gst/vaapi/sysdeps.h"
+#include <gst/vaapi/gstvaapipixmap_x11.h>
+#include "gstvaapivideoconverter_x11.h"
+#include "gstvaapipluginutil.h"
+#include "gstvaapivideometa.h"
+
+#if GST_CHECK_VERSION(1,0,0)
+typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *,
+    GstBuffer *);
+#else
+typedef gboolean (*GstSurfaceUploadFunction)(GstSurfaceConverter *,
+    GstSurfaceBuffer *);
+#endif
+
+static void
+gst_vaapi_video_converter_x11_iface_init(GstSurfaceConverterInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(
+    GstVaapiVideoConverterX11,
+    gst_vaapi_video_converter_x11,
+    G_TYPE_OBJECT,
+    G_IMPLEMENT_INTERFACE(GST_TYPE_SURFACE_CONVERTER,
+                          gst_vaapi_video_converter_x11_iface_init))
+
+#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE(obj)  \
+    (G_TYPE_INSTANCE_GET_PRIVATE((obj),                 \
+        GST_VAAPI_TYPE_VIDEO_CONVERTER_X11,             \
+        GstVaapiVideoConverterX11Private))
+
+struct _GstVaapiVideoConverterX11Private {
+    GstVaapiPixmap     *pixmap;
+    XID                 pixmap_id;
+};
+
+static gboolean
+gst_vaapi_video_converter_x11_upload(GstSurfaceConverter *self,
+    GstBuffer *buffer);
+
+static void
+gst_vaapi_video_converter_x11_dispose(GObject *object)
+{
+    GstVaapiVideoConverterX11Private * const priv =
+        GST_VAAPI_VIDEO_CONVERTER_X11(object)->priv;
+
+    gst_vaapi_pixmap_replace(&priv->pixmap, NULL);
+
+    G_OBJECT_CLASS(gst_vaapi_video_converter_x11_parent_class)->dispose(object);
+}
+
+static void
+gst_vaapi_video_converter_x11_class_init(GstVaapiVideoConverterX11Class *klass)
+{
+    GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+
+    g_type_class_add_private(klass, sizeof(GstVaapiVideoConverterX11Private));
+
+    object_class->dispose = gst_vaapi_video_converter_x11_dispose;
+}
+
+static void
+gst_vaapi_video_converter_x11_init(GstVaapiVideoConverterX11 *buffer)
+{
+    buffer->priv = GST_VAAPI_VIDEO_CONVERTER_X11_GET_PRIVATE(buffer);
+}
+
+static void
+gst_vaapi_video_converter_x11_iface_init(GstSurfaceConverterInterface *iface)
+{
+    iface->upload = (GstSurfaceUploadFunction)
+        gst_vaapi_video_converter_x11_upload;
+}
+
+static gboolean
+set_pixmap(GstVaapiVideoConverterX11 *converter, GstVaapiDisplay *display,
+    XID pixmap_id)
+{
+    GstVaapiVideoConverterX11Private * const priv = converter->priv;
+    GstVaapiPixmap *pixmap;
+
+    pixmap = gst_vaapi_pixmap_x11_new_with_xid(display, pixmap_id);
+    if (!pixmap)
+        return FALSE;
+
+    gst_vaapi_pixmap_replace(&priv->pixmap, pixmap);
+    gst_vaapi_pixmap_unref(pixmap);
+    priv->pixmap_id = pixmap_id;
+    return TRUE;
+}
+
+/**
+ * gst_vaapi_video_converter_x11_new:
+ * @surface: the #GstSurfaceBuffer
+ * @type: type of the target buffer (must be "x11-pixmap")
+ * @dest: target of the conversion (must be an X11 pixmap id)
+ *
+ * Creates an empty #GstBuffer. The caller is responsible for
+ * completing the initialization of the buffer with the
+ * gst_vaapi_video_converter_x11_set_*() functions.
+ *
+ * Return value: the newly allocated #GstBuffer, or %NULL on error
+ */
+GstSurfaceConverter *
+gst_vaapi_video_converter_x11_new(GstBuffer *buffer, const gchar *type,
+    GValue *dest)
+{
+    GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer);
+    GstVaapiVideoConverterX11 *converter;
+
+    /* We only support X11 pixmap conversion */
+    if (strcmp(type, "x11-pixmap") != 0 || !G_VALUE_HOLDS_UINT(dest))
+        return NULL;
+
+    converter = g_object_new(GST_VAAPI_TYPE_VIDEO_CONVERTER_X11, NULL);
+    if (!converter)
+        return NULL;
+
+    if (!set_pixmap(converter, gst_vaapi_video_meta_get_display(meta),
+            g_value_get_uint(dest)))
+        goto error;
+    return GST_SURFACE_CONVERTER(converter);
+
+error:
+    g_object_unref(converter);
+    return NULL;
+}
+
+gboolean
+gst_vaapi_video_converter_x11_upload(GstSurfaceConverter *self,
+    GstBuffer *buffer)
+{
+    GstVaapiVideoConverterX11 * const converter =
+        GST_VAAPI_VIDEO_CONVERTER_X11(self);
+    GstVaapiVideoConverterX11Private * const priv = converter->priv;
+    GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer);
+    GstVaapiSurface *surface;
+    GstVaapiDisplay *old_display, *new_display;
+
+    g_return_val_if_fail(meta != NULL, FALSE);
+
+    surface = gst_vaapi_video_meta_get_surface(meta);
+    if (!surface)
+        return FALSE;
+
+    old_display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(priv->pixmap));
+    new_display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface));
+
+    if (old_display != new_display) {
+        if (!set_pixmap(converter, new_display, priv->pixmap_id))
+            return FALSE;
+    }
+
+    if (!gst_vaapi_apply_composition(surface, buffer))
+        GST_WARNING("could not update subtitles");
+
+    /* XXX: handle video cropping */
+    return gst_vaapi_pixmap_put_surface(priv->pixmap, surface, NULL,
+        gst_vaapi_video_meta_get_render_flags(meta));
+}
diff --git a/gst/vaapi/gstvaapivideoconverter_x11.h b/gst/vaapi/gstvaapivideoconverter_x11.h
new file mode 100644 (file)
index 0000000..be991b3
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  gstvaapivideoconverter_x11.h - VA video converter to X11 pixmap
+ *
+ *  Copyright (C) 2013 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_VIDEO_CONVERTER_X11_H
+#define GST_VAAPI_VIDEO_CONVERTER_X11_H
+
+#include <gst/video/gstsurfaceconverter.h>
+#include "gstvaapivideobuffer.h"
+
+G_BEGIN_DECLS
+
+#define GST_VAAPI_TYPE_VIDEO_CONVERTER_X11 \
+    (gst_vaapi_video_converter_x11_get_type ())
+
+#define GST_VAAPI_VIDEO_CONVERTER_X11(obj)              \
+    (G_TYPE_CHECK_INSTANCE_CAST((obj),                  \
+        GST_VAAPI_TYPE_VIDEO_CONVERTER_X11,             \
+        GstVaapiVideoConverterX11))
+
+#define GST_VAAPI_VIDEO_CONVERTER_X11_CLASS(klass)      \
+    (G_TYPE_CHECK_CLASS_CAST((klass),                   \
+        GST_VAAPI_TYPE_VIDEO_CONVERTER_X11,             \
+        GstVaapiVideoConverterX11Class))
+
+#define GST_VAAPI_IS_VIDEO_CONVERTER_X11(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11))
+
+#define GST_VAAPI_IS_VIDEO_CONVERTER_X11_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_CONVERTER_X11))
+
+#define GST_VAAPI_VIDEO_CONVERTER_X11_GET_CLASS(obj)    \
+    (G_TYPE_INSTANCE_GET_CLASS((obj),                   \
+        GST_VAAPI_TYPE_VIDEO_CONVERTER_X11,             \
+        GstVaapiVideoConverterX11Class))
+
+typedef struct _GstVaapiVideoConverterX11        GstVaapiVideoConverterX11;
+typedef struct _GstVaapiVideoConverterX11Private GstVaapiVideoConverterX11Private;
+typedef struct _GstVaapiVideoConverterX11Class   GstVaapiVideoConverterX11Class;
+
+/**
+ * GstVaapiVideoConverterX11:
+ *
+ * Converter to transform VA buffers into GL textures.
+ */
+struct _GstVaapiVideoConverterX11 {
+    /*< private >*/
+    GObject parent_instance;
+
+    GstVaapiVideoConverterX11Private *priv;
+};
+
+/**
+ * GstVaapiVideoConverterX11Class:
+ *
+ * Converter class to transform VA buffers into GL textures.
+ */
+struct _GstVaapiVideoConverterX11Class {
+    /*< private >*/
+    GObjectClass parent_class;
+};
+
+G_GNUC_INTERNAL
+GType
+gst_vaapi_video_converter_x11_get_type(void) G_GNUC_CONST;
+
+G_GNUC_INTERNAL
+GstSurfaceConverter *
+gst_vaapi_video_converter_x11_new(GstBuffer *buffer, const gchar *type,
+    GValue *dest);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_VIDEO_CONVERTER_X11_H */