Port to GstVideoContext interface.
authorNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Fri, 4 Nov 2011 20:50:15 +0000 (16:50 -0400)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 8 Dec 2011 13:58:58 +0000 (14:58 +0100)
This new interface allows for upstream and downstream display sharing
that works in both static and dynamic pipelines.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
configure.ac
gst-libs/gst/vaapi/Makefile.am
gst-libs/gst/vaapi/gstvaapiutils_gst.c [deleted file]
gst/vaapi/Makefile.am
gst/vaapi/gstvaapiconvert.c
gst/vaapi/gstvaapidecode.c
gst/vaapi/gstvaapipluginutil.c [new file with mode: 0644]
gst/vaapi/gstvaapipluginutil.h [moved from gst-libs/gst/vaapi/gstvaapiutils_gst.h with 62% similarity]
gst/vaapi/gstvaapisink.c
gst/vaapi/gstvaapisink.h

index 9baa50c..4334d75 100644 (file)
@@ -29,6 +29,13 @@ m4_define([gst_plugins_base_version],
 m4_define([va_api_x11_version], [0.31.0])
 m4_define([va_api_glx_version], [0.32.0])
 
+# gst plugins-bad version number
+m4_define([gst_plugins_bad_major_version], [0])
+m4_define([gst_plugins_bad_minor_version], [10])
+m4_define([gst_plugins_bad_micro_version], [22])
+m4_define([gst_plugins_bad_version],
+          [gst_plugins_bad_major_version.gst_plugins_bad_minor_version.gst_plugins_bad_micro_version])
+
 # libva package version number
 m4_define([libva_x11_package_version], [1.0.3])
 m4_define([libva_glx_package_version], [1.0.9])
@@ -61,6 +68,7 @@ dnl Versions for GStreamer and plugins-base
 GST_MAJORMINOR=gst_major_minor_version
 GST_VERSION_REQUIRED=gst_version
 GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version
+GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version
 AC_SUBST(GST_MAJORMINOR)
 AC_SUBST(GST_VERSION_REQUIRED)
 AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED)
@@ -168,6 +176,13 @@ PKG_CHECK_MODULES([GST_VIDEO],
 AC_SUBST(GST_VIDEO_CFLAGS)
 AC_SUBST(GST_VIDEO_LIBS)
 
+dnl Check for GStreamer basevideo
+PKG_CHECK_MODULES([GST_BASEVIDEO],
+    [gstreamer-basevideo-$GST_MAJORMINOR >= $GST_PLUGINS_BAD_VERSION_REQUIRED]
+)
+AC_SUBST(GST_BASEVIDEO_CFLAGS)
+AC_SUBST(GST_BASEVIDEO_LIBS)
+
 dnl Check for GStreamer interfaces
 PKG_CHECK_MODULES([GST_INTERFACES],
     [gstreamer-interfaces-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED]
index 1feca33..17ead8b 100644 (file)
@@ -37,7 +37,6 @@ libgstvaapi_source_c =                                \
        gstvaapisurfacepool.c                   \
        gstvaapisurfaceproxy.c                  \
        gstvaapiutils.c                         \
-       gstvaapiutils_gst.c                     \
        gstvaapivalue.c                         \
        gstvaapivideobuffer.c                   \
        gstvaapivideopool.c                     \
@@ -77,7 +76,6 @@ libgstvaapi_source_priv_h =                   \
        gstvaapidisplay_priv.h                  \
        gstvaapiobject_priv.h                   \
        gstvaapiutils.h                         \
-       gstvaapiutils_gst.h                     \
        $(libgst_vaapi_ffmpeg_source_priv_h)    \
        $(NULL)
 
diff --git a/gst-libs/gst/vaapi/gstvaapiutils_gst.c b/gst-libs/gst/vaapi/gstvaapiutils_gst.c
deleted file mode 100644 (file)
index 7a0e7da..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *  gstvaapiutils_gst.c - GST utilties
- *
- *  gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems
- *
- *  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 "config.h"
-#include "gstvaapiutils_gst.h"
-#include "gstvaapivideosink.h"
-#include "gstvaapivideobuffer.h"
-
-#define DEBUG 1
-#include "gstvaapidebug.h"
-
-static GstVaapiDisplay *
-lookup_through_vaapisink_iface(GstElement *element)
-{
-    GstVaapiDisplay *display;
-    GstVaapiVideoSink *sink;
-
-    GST_DEBUG("looking for a downstream vaapisink");
-
-    /* Look for a downstream vaapisink */
-    sink = gst_vaapi_video_sink_lookup(element);
-    if (!sink)
-        return NULL;
-
-    display = gst_vaapi_video_sink_get_display(sink);
-    GST_DEBUG("  found display %p", display);
-    return display;
-}
-
-static GstVaapiDisplay *
-lookup_through_peer_buffer(GstElement *element)
-{
-    GstVaapiDisplay *display;
-    GstPad *pad;
-    GstBuffer *buffer;
-    GstFlowReturn ret;
-
-    GST_DEBUG("looking for a GstVaapiVideoBuffer from peer");
-
-    /* Look for a GstVaapiVideoBuffer from peer */
-    pad = gst_element_get_static_pad(element, "src");
-    if (!pad)
-        return NULL;
-
-    buffer = NULL;
-    ret = gst_pad_alloc_buffer(pad, 0, 0, GST_PAD_CAPS(pad), &buffer);
-    g_object_unref(pad);
-    if (ret != GST_FLOW_OK || !buffer)
-        return NULL;
-
-    display = GST_VAAPI_IS_VIDEO_BUFFER(buffer) ?
-        gst_vaapi_video_buffer_get_display(GST_VAAPI_VIDEO_BUFFER(buffer)) :
-        NULL;
-    gst_buffer_unref(buffer);
-
-    GST_DEBUG("  found display %p", display);
-    return display;
-}
-
-/**
- * gst_vaapi_display_lookup_downstream:
- * @element: a #GstElement
- *
- * Finds a suitable #GstVaapiDisplay downstream from @element.
- *
- *   1. Check whether a downstream element implements the
- *      #GstVaapiVideoSinkInterface interface.
- *
- *   2. Check whether the @element peer implements a custom
- *      buffer_alloc() function that allocates #GstVaapiVideoBuffer
- *      buffers.
- *
- * Return value: a downstream allocated #GstVaapiDisplay object, or
- *   %NULL if none was found
- */
-GstVaapiDisplay *
-gst_vaapi_display_lookup_downstream(GstElement *element)
-{
-    GstVaapiDisplay *display;
-
-    display = lookup_through_vaapisink_iface(element);
-    if (display)
-        return display;
-
-    display = lookup_through_peer_buffer(element);
-    if (display)
-        return display;
-
-    return NULL;
-}
index 3e842dc..0b18d08 100644 (file)
@@ -2,6 +2,7 @@ plugin_LTLIBRARIES = libgstvaapi.la
 
 libgstvaapi_CFLAGS = \
        $(LIBVA_CFLAGS)         \
+       -DGST_USE_UNSTABLE_API  \
        -I$(top_srcdir)/gst-libs
 
 if USE_VAAPI_GLX
@@ -16,12 +17,14 @@ libgstvaapi_la_SOURCES =    \
        gstvaapi.c              \
        gstvaapiconvert.c       \
        gstvaapidecode.c        \
+       gstvaapipluginutil.c    \
        gstvaapisink.c          \
        $(NULL)
 
 noinst_HEADERS =               \
        gstvaapiconvert.h       \
        gstvaapidecode.h        \
+       gstvaapipluginutil.h    \
        gstvaapisink.h          \
        $(NULL)
 
@@ -31,6 +34,7 @@ libgstvaapi_la_CFLAGS =       \
        $(GST_BASE_CFLAGS)      \
        $(GST_VIDEO_CFLAGS)     \
        $(GST_INTERFACES_CFLAGS) \
+       $(GST_BASEVIDEO_CFLAGS) \
        $(GST_PLUGINS_BASE_CFLAGS)
 
 libgstvaapi_la_LIBADD =        \
@@ -39,6 +43,7 @@ libgstvaapi_la_LIBADD =       \
        $(GST_BASE_LIBS)        \
        $(GST_VIDEO_LIBS)       \
        $(GST_INTERFACES_LIBS)  \
+       $(GST_BASEVIDEO_LIBS)   \
        $(GST_PLUGINS_BASE_LIBS)
 
 libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
index 8c2896c..f871940 100644 (file)
  */
 
 #include "config.h"
+
 #include <gst/gst.h>
 #include <gst/video/video.h>
+#include <gst/video/videocontext.h>
 #include <gst/vaapi/gstvaapivideosink.h>
 #include <gst/vaapi/gstvaapivideobuffer.h>
-#include <gst/vaapi/gstvaapiutils_gst.h>
+
+#include "gstvaapipluginutil.h"
 #include "gstvaapiconvert.h"
 
 #define GST_PLUGIN_NAME "vaapiconvert"
@@ -73,11 +76,15 @@ static GstStaticPadTemplate gst_vaapiconvert_src_factory =
         GST_PAD_ALWAYS,
         GST_STATIC_CAPS(gst_vaapiconvert_vaapi_caps_str));
 
-GST_BOILERPLATE(
+#define GstVideoContextClass GstVideoContextInterface
+GST_BOILERPLATE_WITH_INTERFACE(
     GstVaapiConvert,
     gst_vaapiconvert,
     GstBaseTransform,
-    GST_TYPE_BASE_TRANSFORM);
+    GST_TYPE_BASE_TRANSFORM,
+    GstVideoContext,
+    GST_TYPE_VIDEO_CONTEXT,
+    gst_video_context);
 
 /*
  * Direct rendering levels (direct-rendering)
@@ -145,6 +152,34 @@ gst_vaapiconvert_prepare_output_buffer(
     GstBuffer       **poutbuf
 );
 
+static gboolean
+gst_vaapiconvert_query(
+    GstPad   *pad,
+    GstQuery *query
+);
+
+/* GstVideoContext interface */
+
+static void
+gst_vaapiconvert_set_video_context(GstVideoContext *context, const gchar *type,
+    const GValue *value)
+{
+  GstVaapiConvert *convert = GST_VAAPICONVERT (context);
+  gst_vaapi_set_display (type, value, &convert->display);
+}
+
+static gboolean
+gst_video_context_supported (GstVaapiConvert *convert, GType iface_type)
+{
+  return (iface_type == GST_TYPE_VIDEO_CONTEXT);
+}
+
+static void
+gst_video_context_interface_init(GstVideoContextInterface *iface)
+{
+    iface->set_context = gst_vaapiconvert_set_video_context;
+}
+
 static void
 gst_vaapiconvert_destroy(GstVaapiConvert *convert)
 {
@@ -289,7 +324,7 @@ gst_vaapiconvert_class_init(GstVaapiConvertClass *klass)
 static void
 gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass)
 {
-    GstPad *sinkpad;
+    GstPad *sinkpad, *srcpad;
 
     convert->display                    = NULL;
     convert->images                     = NULL;
@@ -310,20 +345,20 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass)
         gst_vaapiconvert_sinkpad_buffer_alloc
     );
     g_object_unref(sinkpad);
+
+    /* Override query on src pad */
+    srcpad = gst_element_get_static_pad(GST_ELEMENT(convert), "src");
+    gst_pad_set_query_function(srcpad, gst_vaapiconvert_query);
 }
 
 static gboolean
 gst_vaapiconvert_start(GstBaseTransform *trans)
 {
     GstVaapiConvert * const convert = GST_VAAPICONVERT(trans);
-    GstVaapiDisplay *display;
 
-    /* Look for a downstream display */
-    display = gst_vaapi_display_lookup_downstream(GST_ELEMENT(trans));
-    if (!display)
+    if (!gst_vaapi_ensure_display(convert, &convert->display))
         return FALSE;
 
-    convert->display = g_object_ref(display);
     return TRUE;
 }
 
@@ -766,3 +801,20 @@ gst_vaapiconvert_prepare_output_buffer(
     *poutbuf = buffer;
     return GST_FLOW_OK;
 }
+
+static gboolean
+gst_vaapiconvert_query(GstPad *pad, GstQuery *query)
+{
+  GstVaapiConvert *convert = GST_VAAPICONVERT (gst_pad_get_parent_element (pad));
+  gboolean res;
+
+  GST_DEBUG ("sharing display %p", convert->display);
+
+  if (gst_vaapi_reply_to_query (query, convert->display))
+    res = TRUE;
+  else
+    res = gst_pad_query_default (pad, query);
+
+  g_object_unref (convert);
+  return res;
+}
index 19f0e91..716c352 100644 (file)
  */
 
 #include "config.h"
-#include "gstvaapidecode.h"
-#include <gst/vaapi/gstvaapidisplay_x11.h>
+
+#include <gst/vaapi/gstvaapidisplay.h>
 #include <gst/vaapi/gstvaapivideosink.h>
 #include <gst/vaapi/gstvaapivideobuffer.h>
 #include <gst/vaapi/gstvaapidecoder_ffmpeg.h>
-#include <gst/vaapi/gstvaapiutils_gst.h>
+#include <gst/video/videocontext.h>
+
+#include "gstvaapidecode.h"
+#include "gstvaapipluginutil.h"
 
 #define GST_PLUGIN_NAME "vaapidecode"
 #define GST_PLUGIN_DESC "A VA-API based video decoder"
@@ -80,11 +83,15 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory =
         GST_PAD_ALWAYS,
         GST_STATIC_CAPS(gst_vaapidecode_src_caps_str));
 
-GST_BOILERPLATE(
+#define GstVideoContextClass GstVideoContextInterface
+GST_BOILERPLATE_WITH_INTERFACE(
     GstVaapiDecode,
     gst_vaapidecode,
     GstElement,
-    GST_TYPE_ELEMENT);
+    GST_TYPE_ELEMENT,
+    GstVideoContext,
+    GST_TYPE_VIDEO_CONTEXT,
+    gst_video_context);
 
 enum {
     PROP_0,
@@ -257,24 +264,10 @@ error_commit_buffer:
     }
 }
 
-static inline gboolean
-gst_vaapidecode_ensure_display(GstVaapiDecode *decode)
-{
-    GstVaapiDisplay *display;
-
-    if (!decode->display) {
-        display = gst_vaapi_display_lookup_downstream(GST_ELEMENT(decode));
-        if (!display)
-            return FALSE;
-        decode->display = g_object_ref(display);
-    }
-    return TRUE;
-}
-
 static gboolean
 gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps)
 {
-    if (!gst_vaapidecode_ensure_display(decode))
+    if (!gst_vaapi_ensure_display(decode, &decode->display))
         return FALSE;
 
     decode->decoder_mutex = g_mutex_new();
@@ -339,6 +332,28 @@ gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps)
     return gst_vaapidecode_create(decode, caps);
 }
 
+/* GstVideoContext interface */
+
+static void
+gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type,
+    const GValue *value)
+{
+    GstVaapiDecode *decode = GST_VAAPIDECODE (context);
+    gst_vaapi_set_display (type, value, &decode->display);
+}
+
+static gboolean
+gst_video_context_supported (GstVaapiDecode *decode, GType iface_type)
+{
+  return (iface_type == GST_TYPE_VIDEO_CONTEXT);
+}
+
+static void
+gst_video_context_interface_init(GstVideoContextInterface *iface)
+{
+    iface->set_context = gst_vaapidecode_set_video_context;
+}
+
 static void
 gst_vaapidecode_base_init(gpointer klass)
 {
@@ -494,15 +509,10 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
     if (decode->allowed_caps)
         return TRUE;
 
-    if (gst_vaapidecode_ensure_display(decode))
-        display = g_object_ref(decode->display);
-    else {
-        display = gst_vaapi_display_x11_new(NULL);
-        if (!display)
-            goto error_no_display;
-    }
+    if (!gst_vaapi_ensure_display(decode, &decode->display))
+        goto error_no_display;
 
-    decode_caps = gst_vaapi_display_get_decode_caps(display);
+    decode_caps = gst_vaapi_display_get_decode_caps(decode->display);
     if (!decode_caps)
         goto error_no_decode_caps;
     n_decode_caps = gst_caps_get_size(decode_caps);
@@ -530,7 +540,6 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
     }
 
     gst_caps_unref(decode_caps);
-    g_object_unref(display);
     return TRUE;
 
     /* ERRORS */
@@ -542,14 +551,12 @@ error_no_display:
 error_no_decode_caps:
     {
         GST_DEBUG("failed to retrieve VA decode caps");
-        g_object_unref(display);
         return FALSE;
     }
 error_no_memory:
     {
         GST_DEBUG("failed to allocate allowed-caps set");
         gst_caps_unref(decode_caps);
-        g_object_unref(display);
         return FALSE;
     }
 }
@@ -621,6 +628,22 @@ gst_vaapidecode_src_event(GstPad *pad, GstEvent *event)
     return gst_pad_push_event(decode->sinkpad, event);
 }
 
+static gboolean
+gst_vaapidecode_query (GstPad *pad, GstQuery *query) {
+    GstVaapiDecode *decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad));
+    gboolean res;
+
+    GST_DEBUG ("sharing display %p", decode->display);
+
+    if (gst_vaapi_reply_to_query (query, decode->display))
+      res = TRUE;
+    else
+      res = gst_pad_query_default (pad, query);
+
+    g_object_unref (decode);
+    return res;
+}
+
 static void
 gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass)
 {
@@ -656,5 +679,6 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass)
 
     gst_pad_use_fixed_caps(decode->srcpad);
     gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event);
+    gst_pad_set_query_function(decode->srcpad, gst_vaapidecode_query);
     gst_element_add_pad(GST_ELEMENT(decode), decode->srcpad);
 }
diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c
new file mode 100644 (file)
index 0000000..a95fb8c
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ *  gstvaapipluginutil.h - VA-API plugin helpers
+ *
+ *  Copyright (C) 2011 Intel Corporation
+ *  Copyright (C) 2011 Collabora
+ *    Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ *
+ *  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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gstvaapipluginutil.h"
+
+#include <string.h>
+
+#ifdef USE_VAAPI_GLX
+#include <gst/vaapi/gstvaapidisplay_glx.h>
+#else
+#include <gst/vaapi/gstvaapidisplay_x11.h>
+#endif
+
+/* Preferred first */
+static const char *display_types[] = {
+  "gst-vaapi-display",
+  "vaapi-display",
+  "x11-display",
+  "x11-display-name",
+  NULL
+};
+
+gboolean
+gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display)
+{
+  GstVideoContext *context;
+
+  g_return_val_if_fail (GST_IS_VIDEO_CONTEXT (element), FALSE);
+  g_return_val_if_fail (display != NULL, FALSE);
+
+  /* Already exist ? */
+  if (*display)
+    return TRUE;
+
+  context = GST_VIDEO_CONTEXT (element);
+  gst_video_context_prepare (context, display_types);
+
+  /* If no neighboor, or application not interested, use system default */
+  if (!*display)
+#if USE_VAAPI_GLX
+    *display = gst_vaapi_display_glx_new ("");
+#else
+    *display = gst_vaapi_display_x11_new ("");
+#endif
+
+  /* FIXME allocator should return NULL in case of failure */
+  if (*display && !gst_vaapi_display_get_display(*display)) {
+    g_object_unref (*display);
+    *display = NULL;
+  }
+
+  return (*display != NULL);
+}
+
+void
+gst_vaapi_set_display (const gchar *type,
+    const GValue *value,
+    GstVaapiDisplay **display)
+{
+  GstVaapiDisplay *dpy = NULL;
+
+  if (!strcmp (type, "x11-display-name")) {
+    g_return_if_fail (G_VALUE_HOLDS_STRING (value));
+#if USE_VAAPI_GLX
+    dpy = gst_vaapi_display_glx_new (g_value_get_string (value));
+#else
+    dpy = gst_vaapi_display_x11_new (g_value_get_string (value));
+#endif
+  } else if (!strcmp (type, "x11-display")) {
+    g_return_if_fail (G_VALUE_HOLDS_POINTER (value));
+#if USE_VAAPI_GLX
+    dpy = gst_vaapi_display_glx_new_with_display (g_value_get_pointer (value));
+#else
+    dpy = gst_vaapi_display_x11_new_with_display (g_value_get_pointer (value));
+#endif
+  } else if (!strcmp (type, "vaapi-display")) {
+    g_return_if_fail (G_VALUE_HOLDS_POINTER (value));
+    dpy = gst_vaapi_display_new_with_display (g_value_get_pointer (value));
+  } else if (!strcmp (type, "gst-vaapi-display")) {
+    g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
+    dpy = g_value_dup_object (value);
+  }
+
+  if (dpy) {
+    if (*display)
+      g_object_unref (*display);
+    *display = dpy;
+  }
+}
+
+gboolean
+gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display)
+{
+  const gchar **types;
+  const gchar *type;
+  gint i;
+  gboolean res = FALSE;
+
+  if (!display)
+    return FALSE;
+
+  types = gst_video_context_query_get_supported_types (query);
+
+  if (!types)
+    return FALSE;
+
+  for (i = 0; types[i]; i++) {
+    type = types[i];
+
+    if (!strcmp (type, "gst-vaapi-display")) {
+      gst_video_context_query_set_object (query, type, G_OBJECT (display));
+
+    } else if (!strcmp (type, "vaapi-display")) {
+      VADisplay vadpy = gst_vaapi_display_get_display(display);
+      gst_video_context_query_set_pointer (query, type, vadpy);
+
+    } else if (!strcmp (type, "x11-display") &&
+        GST_VAAPI_IS_DISPLAY_X11(display)) {
+      GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11 (display);
+      Display *x11dpy = gst_vaapi_display_x11_get_display (xvadpy);
+      gst_video_context_query_set_pointer (query, type, x11dpy);
+
+    } else if (!strcmp (type, "x11-display-name") &&
+        GST_VAAPI_IS_DISPLAY_X11(display)) {
+      GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11 (display);
+      Display *x11dpy = gst_vaapi_display_x11_get_display (xvadpy);
+      gst_video_context_query_set_string (query, type, DisplayString(x11dpy));
+
+    } else {
+      continue;
+    }
+
+    res = TRUE;
+    break;
+  }
+
+  return res;
+}
similarity index 62%
rename from gst-libs/gst/vaapi/gstvaapiutils_gst.h
rename to gst/vaapi/gstvaapipluginutil.h
index 350f20a..3d31938 100644 (file)
@@ -1,7 +1,9 @@
 /*
- *  gstvaapiutils_gst.h - GST utilties
+ *  gstvaapipluginutil.h - VA-API plugins private helper
  *
- *  gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems
+ *  Copyright (C) 2011 Intel Corporation
+ *  Copyright (C) 2011 Collabora
+ *    Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public License
  *  Boston, MA 02110-1301 USA
  */
 
-#ifndef GST_VAAPI_UTILS_GST_H
-#define GST_VAAPI_UTILS_GST_H
-
 #include <gst/gst.h>
+#include <gst/video/videocontext.h>
 #include <gst/vaapi/gstvaapidisplay.h>
 
-GstVaapiDisplay *
-gst_vaapi_display_lookup_downstream(GstElement *element);
-
-#endif /* GST_VAAPI_UTILS_GST_H */
+gboolean gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display);
+void gst_vaapi_set_display (const gchar *type, const GValue *value, GstVaapiDisplay **display);
+gboolean gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display);
index 35c2af3..b2477c3 100644 (file)
@@ -31,8 +31,9 @@
 
 #include "config.h"
 #include <gst/gst.h>
-#include <gst/video/video.h>
 #include <gst/gstutils_version.h>
+#include <gst/video/video.h>
+#include <gst/video/videocontext.h>
 #include <gst/vaapi/gstvaapivideobuffer.h>
 #include <gst/vaapi/gstvaapivideosink.h>
 #include <gst/vaapi/gstvaapidisplay_x11.h>
 #include <gst/vaapi/gstvaapidisplay_glx.h>
 #include <gst/vaapi/gstvaapiwindow_glx.h>
 #endif
-#include "gstvaapisink.h"
 
 /* Supported interfaces */
 #include <gst/interfaces/xoverlay.h>
 
+#include "gstvaapisink.h"
+#include "gstvaapipluginutil.h"
+
 #define HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE \
     GST_PLUGINS_BASE_CHECK_VERSION(0,10,31)
 
@@ -84,7 +87,6 @@ enum {
     PROP_0,
 
     PROP_USE_GLX,
-    PROP_DISPLAY,
     PROP_FULLSCREEN,
     PROP_SYNCHRONOUS,
     PROP_USE_REFLECTION
@@ -98,7 +100,7 @@ gst_vaapisink_implements_interface_supported(
     GType                   type
 )
 {
-    return (type == GST_VAAPI_TYPE_VIDEO_SINK ||
+    return (type == GST_TYPE_VIDEO_CONTEXT ||
             type == GST_TYPE_X_OVERLAY);
 }
 
@@ -110,19 +112,18 @@ gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface)
 
 /* GstVaapiVideoSink interface */
 
-static GstVaapiDisplay *
-gst_vaapisink_get_display(GstVaapiSink *sink);
-
-static GstVaapiDisplay *
-gst_vaapi_video_sink_do_get_display(GstVaapiVideoSink *sink)
+static void
+gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type,
+    const GValue *value)
 {
-    return gst_vaapisink_get_display(GST_VAAPISINK(sink));
+  GstVaapiSink *sink = GST_VAAPISINK (context);
+  gst_vaapi_set_display (type, value, &sink->display);
 }
 
 static void
-gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface)
+gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface)
 {
-    iface->get_display = gst_vaapi_video_sink_do_get_display;
+    iface->set_context = gst_vaapisink_set_video_context;
 }
 
 /* GstXOverlay interface */
@@ -191,8 +192,8 @@ gst_vaapisink_iface_init(GType type)
 
     G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE,
                           gst_vaapisink_implements_iface_init);
-    G_IMPLEMENT_INTERFACE(GST_VAAPI_TYPE_VIDEO_SINK,
-                          gst_vaapi_video_sink_iface_init);
+    G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT,
+                          gst_vaapisink_video_context_iface_init);
     G_IMPLEMENT_INTERFACE(GST_TYPE_X_OVERLAY,
                           gst_vaapisink_xoverlay_iface_init);
 }
@@ -204,11 +205,6 @@ gst_vaapisink_destroy(GstVaapiSink *sink)
         g_object_unref(sink->display);
         sink->display = NULL;
     }
-
-    if (sink->display_name) {
-        g_free(sink->display_name);
-        sink->display_name = NULL;
-    }
 }
 
 /* Checks whether a ConfigureNotify event is in the queue */
@@ -262,23 +258,6 @@ configure_notify_event_pending(
     return args.match;
 }
 
-static inline gboolean
-gst_vaapisink_ensure_display(GstVaapiSink *sink)
-{
-    if (!sink->display) {
-#if USE_VAAPISINK_GLX
-        if (sink->use_glx)
-            sink->display = gst_vaapi_display_glx_new(sink->display_name);
-        else
-#endif
-            sink->display = gst_vaapi_display_x11_new(sink->display_name);
-        if (!sink->display || !gst_vaapi_display_get_display(sink->display))
-            return FALSE;
-        g_object_set(sink, "synchronous", sink->synchronous, NULL);
-    }
-    return sink->display != NULL;
-}
-
 static gboolean
 gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height)
 {
@@ -384,7 +363,7 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id)
     int x, y;
     XID xid = window_id;
 
-    if (!gst_vaapisink_ensure_display(sink))
+    if (!gst_vaapi_ensure_display(sink, &sink->display))
         return FALSE;
 
     gst_vaapi_display_lock(sink->display);
@@ -427,8 +406,6 @@ gst_vaapisink_start(GstBaseSink *base_sink)
 {
     GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
 
-    if (!gst_vaapisink_ensure_display(sink))
-        return FALSE;
     return TRUE;
 }
 
@@ -471,6 +448,9 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
     sink->video_par_d  = video_par_d;
     GST_DEBUG("video pixel-aspect-ratio %d/%d", video_par_n, video_par_d);
 
+    if (!gst_vaapi_ensure_display(sink, &sink->display))
+        return FALSE;
+
     gst_vaapi_display_get_size(sink->display, &display_width, &display_height);
     if (!gst_vaapisink_ensure_render_rect(sink, display_width, display_height))
         return FALSE;
@@ -515,6 +495,9 @@ gst_vaapisink_buffer_alloc(
     GstStructure *structure;
     GstBuffer *buffer;
 
+    if (!gst_vaapi_ensure_display(sink, &sink->display))
+        goto error_ensure_display;
+
     structure = gst_caps_get_structure(caps, 0);
     if (!gst_structure_has_name(structure, "video/x-vaapi-surface"))
         goto error_invalid_caps;
@@ -528,6 +511,11 @@ gst_vaapisink_buffer_alloc(
     return GST_FLOW_OK;
 
     /* ERRORS */
+error_ensure_display:
+    {
+        GST_ERROR("failed to ensure display");
+        return GST_FLOW_UNEXPECTED;
+    }
 error_invalid_caps:
     {
         GST_ERROR("failed to validate input caps");
@@ -719,6 +707,12 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer)
     guint flags;
     gboolean success;
 
+    if (sink->display != gst_vaapi_video_buffer_get_display (vbuffer)) {
+      if (sink->display)
+        g_object_unref (sink->display);
+      sink->display = g_object_ref (gst_vaapi_video_buffer_get_display (vbuffer));
+    }
+
     if (!sink->window)
         return GST_FLOW_UNEXPECTED;
 
@@ -740,6 +734,14 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer)
     return success ? GST_FLOW_OK : GST_FLOW_UNEXPECTED;
 }
 
+static gboolean
+gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query)
+{
+    GstVaapiSink *sink = GST_VAAPISINK(base_sink);
+    GST_DEBUG ("sharing display %p", sink->display);
+    return gst_vaapi_reply_to_query (query, sink->display);
+}
+
 static void
 gst_vaapisink_finalize(GObject *object)
 {
@@ -762,10 +764,6 @@ gst_vaapisink_set_property(
     case PROP_USE_GLX:
         sink->use_glx = g_value_get_boolean(value);
         break;
-    case PROP_DISPLAY:
-        g_free(sink->display_name);
-        sink->display_name = g_strdup(g_value_get_string(value));
-        break;
     case PROP_FULLSCREEN:
         sink->fullscreen = g_value_get_boolean(value);
         break;
@@ -795,9 +793,6 @@ gst_vaapisink_get_property(
     case PROP_USE_GLX:
         g_value_set_boolean(value, sink->use_glx);
         break;
-    case PROP_DISPLAY:
-        g_value_set_string(value, sink->display_name);
-        break;
     case PROP_FULLSCREEN:
         g_value_set_boolean(value, sink->fullscreen);
         break;
@@ -845,6 +840,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass)
     basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc;
     basesink_class->preroll      = gst_vaapisink_show_frame;
     basesink_class->render       = gst_vaapisink_show_frame;
+    basesink_class->query        = gst_vaapisink_query;
 
 #if USE_VAAPISINK_GLX
     g_object_class_install_property
@@ -868,15 +864,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass)
 
     g_object_class_install_property
         (object_class,
-         PROP_DISPLAY,
-         g_param_spec_string("display",
-                             "X11 display name",
-                             "X11 display name",
-                             "",
-                             G_PARAM_READWRITE));
-
-    g_object_class_install_property
-        (object_class,
          PROP_FULLSCREEN,
          g_param_spec_boolean("fullscreen",
                               "Fullscreen",
@@ -903,7 +890,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass)
 static void
 gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass)
 {
-    sink->display_name   = NULL;
     sink->display        = NULL;
     sink->window         = NULL;
     sink->window_width   = 0;
@@ -919,11 +905,3 @@ gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass)
     sink->use_glx        = USE_VAAPISINK_GLX;
     sink->use_reflection = FALSE;
 }
-
-GstVaapiDisplay *
-gst_vaapisink_get_display(GstVaapiSink *sink)
-{
-    if (!gst_vaapisink_ensure_display(sink))
-        return NULL;
-    return sink->display;
-}
index d30692d..221e452 100644 (file)
@@ -67,7 +67,6 @@ struct _GstVaapiSink {
     /*< private >*/
     GstVideoSink parent_instance;
 
-    gchar              *display_name;
     GstVaapiDisplay    *display;
     GstVaapiWindow     *window;
     guint               window_width;