diff options
author | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2013-07-22 14:32:39 +0200 |
---|---|---|
committer | Lionel Landwerlin <llandwerlin@gmail.com> | 2013-07-22 17:10:27 +0100 |
commit | c8d47454a4073ff197da886a033787438bfe145b (patch) | |
tree | fc92f810fba47a4c6b406f02d4f12499ac35d216 | |
parent | 96f7b15624147dd9fcfec16f14e6824dc329f973 (diff) | |
download | clutter-gst-c8d47454a4073ff197da886a033787438bfe145b.tar.gz |
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>
-rw-r--r-- | 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); |