From c8d47454a4073ff197da886a033787438bfe145b Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 22 Jul 2013 14:32:39 +0200 Subject: 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 --- clutter-gst/clutter-gst-video-sink.c | 69 ++++++++++++++++++++++++++++++++++-- 1 file 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 #include +#ifdef CLUTTER_WINDOWING_X11 +#include +#include +#endif + #ifdef HAVE_HW_DECODER_SUPPORT #define GST_USE_UNSTABLE_API 1 #include @@ -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); -- cgit v1.2.1