[clutter-gst/clutter-gst-2.0] video-sink: add support for x11-pixmap GstSurfaceMeta.



commit c8d47454a4073ff197da886a033787438bfe145b
Author: Gwenole Beauchesne <gwenole beauchesne intel com>
Date:   Mon Jul 22 14:32:39 2013 +0200

    video-sink: add support for x11-pixmap GstSurfaceMeta.
    
    Add support for hardware decoders that accept a video converter to
    X11 pixmap. This could improve performance on platforms that can
    bind a pixmap to a texture, e.g. GLX_EXT_texture_from_pixmap.
    
    We could also create pixmap of smaller size than the actual screen
    size, thus further saving memory bandwidth.
    
    Signed-off-by: Gwenole Beauchesne <gwenole beauchesne intel com>

 clutter-gst/clutter-gst-video-sink.c |   69 +++++++++++++++++++++++++++++++++-
 1 files changed, 67 insertions(+), 2 deletions(-)
---
diff --git a/clutter-gst/clutter-gst-video-sink.c b/clutter-gst/clutter-gst-video-sink.c
index acf47d0..e216863 100644
--- a/clutter-gst/clutter-gst-video-sink.c
+++ b/clutter-gst/clutter-gst-video-sink.c
@@ -59,6 +59,11 @@
 #include <gst/video/navigation.h>
 #include <gst/riff/riff-ids.h>
 
+#ifdef CLUTTER_WINDOWING_X11
+#include <cogl/cogl-texture-pixmap-x11.h>
+#include <clutter/x11/clutter-x11.h>
+#endif
+
 #ifdef HAVE_HW_DECODER_SUPPORT
 #define GST_USE_UNSTABLE_API 1
 #include <gst/video/gstsurfacemeta.h>
@@ -213,6 +218,10 @@ struct _ClutterGstVideoSinkPrivate
 
 #ifdef HAVE_HW_DECODER_SUPPORT
   GstSurfaceConverter *converter;
+
+#ifdef CLUTTER_WINDOWING_X11
+  Pixmap pixmap;
+#endif
 #endif
 };
 
@@ -1095,8 +1104,7 @@ clutter_gst_hw_init_texture (ClutterGstVideoSink * sink,
   if (!tex)
     return FALSE;
 
-  if (!clutter_gst_hw_set_texture (sink, tex))
-  {
+  if (!clutter_gst_hw_set_texture (sink, tex)) {
     cogl_object_unref (tex);
     return FALSE;
   }
@@ -1111,6 +1119,54 @@ clutter_gst_hw_init_texture (ClutterGstVideoSink * sink,
   return priv->converter != NULL;
 }
 
+static gboolean
+clutter_gst_hw_init_pixmap (ClutterGstVideoSink * sink,
+    GstSurfaceMeta * surface, GstBuffer * buffer)
+{
+#ifdef CLUTTER_WINDOWING_X11
+  ClutterGstVideoSinkPrivate * const priv = sink->priv;
+  Display * const dpy = clutter_x11_get_default_display ();
+  int screen = clutter_x11_get_default_screen ();
+  ClutterBackend *backend;
+  CoglContext *context;
+  CoglHandle tex;
+  GValue value = { 0 };
+
+  priv->pixmap = XCreatePixmap(dpy, clutter_x11_get_root_window (),
+      priv->info.width, priv->info.height, DefaultDepth (dpy, screen));
+  if (!priv->pixmap)
+    return FALSE;
+
+  backend = clutter_get_default_backend ();
+  context = clutter_backend_get_cogl_context (backend);
+  tex = cogl_texture_pixmap_x11_new (context, priv->pixmap, FALSE, NULL);
+  if (!tex)
+    goto error;
+  if (!cogl_texture_pixmap_x11_is_using_tfp_extension (tex))
+    goto error;
+  if (!clutter_gst_hw_set_texture (sink, tex))
+    goto error;
+
+  g_value_init (&value, G_TYPE_UINT);
+  g_value_set_uint (&value, priv->pixmap);
+
+  priv->converter =
+    gst_surface_meta_create_converter (surface, "x11-pixmap", &value);
+  if (!priv->converter)
+    goto error;
+  return TRUE;
+
+  /* ERRORS */
+ error:
+  if (tex)
+    cogl_object_unref (tex);
+  XFreePixmap (dpy, priv->pixmap);
+  priv->pixmap = None;
+  return FALSE;
+#endif
+  return FALSE;
+}
+
 static void
 clutter_gst_hw_init (ClutterGstVideoSink * sink)
 {
@@ -1121,6 +1177,13 @@ clutter_gst_hw_deinit (ClutterGstVideoSink * sink)
 {
   ClutterGstVideoSinkPrivate *priv = sink->priv;
 
+#ifdef CLUTTER_WINDOWING_X11
+  if (priv->pixmap != None) {
+    XFreePixmap (clutter_x11_get_default_display (), priv->pixmap);
+    priv->pixmap = None;
+  }
+#endif
+
   if (priv->converter != NULL)
     g_object_unref (priv->converter);
   priv->converter = NULL;
@@ -1136,6 +1199,8 @@ clutter_gst_hw_upload (ClutterGstVideoSink * sink, GstBuffer * buffer)
 
   if (G_UNLIKELY (priv->converter == NULL)) {
     do {
+      if (clutter_gst_hw_init_pixmap (sink, surface, buffer))
+        break;
       if (clutter_gst_hw_init_texture (sink, surface, buffer))
         break;
     } while (0);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]