videoaggregator: Move GstChildProxy implementations into leaf classes
authorSebastian Dröge <sebastian@centricular.com>
Fri, 4 May 2018 14:13:16 +0000 (16:13 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 4 May 2018 14:13:16 +0000 (16:13 +0200)
Not every subclass will want to expose the pads via the interface.

https://bugzilla.gnome.org/show_bug.cgi?id=739011

ext/gl/gstglmosaic.c
ext/gl/gstglstereomix.c
ext/gl/gstglvideomixer.c
gst-libs/gst/video/gstvideoaggregator.c
gst/compositor/compositor.c

index 77aec59..63075ba 100644 (file)
@@ -55,10 +55,15 @@ enum
   PROP_0,
 };
 
+static void gst_gl_mosaic_child_proxy_init (gpointer g_iface,
+    gpointer iface_data);
+
 #define DEBUG_INIT \
     GST_DEBUG_CATEGORY_INIT (gst_gl_mosaic_debug, "glmosaic", 0, "glmosaic element");
 
 G_DEFINE_TYPE_WITH_CODE (GstGLMosaic, gst_gl_mosaic, GST_TYPE_GL_MIXER,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
+        gst_gl_mosaic_child_proxy_init);
     DEBUG_INIT);
 
 static void gst_gl_mosaic_set_property (GObject * object, guint prop_id,
@@ -66,6 +71,10 @@ static void gst_gl_mosaic_set_property (GObject * object, guint prop_id,
 static void gst_gl_mosaic_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
+static GstPad *gst_gl_mosaic_request_new_pad (GstElement * element,
+    GstPadTemplate * temp, const gchar * req_name, const GstCaps * caps);
+static void gst_gl_mosaic_release_pad (GstElement * element, GstPad * pad);
+
 static void gst_gl_mosaic_reset (GstGLMixer * mixer);
 static gboolean gst_gl_mosaic_init_shader (GstGLMixer * mixer,
     GstCaps * outcaps);
@@ -128,6 +137,10 @@ gst_gl_mosaic_class_init (GstGLMosaicClass * klass)
   gobject_class->set_property = gst_gl_mosaic_set_property;
   gobject_class->get_property = gst_gl_mosaic_get_property;
 
+  element_class->request_new_pad =
+      GST_DEBUG_FUNCPTR (gst_gl_mosaic_request_new_pad);
+  element_class->release_pad = GST_DEBUG_FUNCPTR (gst_gl_mosaic_release_pad);
+
   gst_element_class_set_metadata (element_class, "OpenGL mosaic",
       "Filter/Effect/Video", "OpenGL mosaic",
       "Julien Isorce <julien.isorce@gmail.com>");
@@ -171,6 +184,44 @@ gst_gl_mosaic_get_property (GObject * object, guint prop_id,
   }
 }
 
+static GstPad *
+gst_gl_mosaic_request_new_pad (GstElement * element, GstPadTemplate * templ,
+    const gchar * req_name, const GstCaps * caps)
+{
+  GstPad *newpad;
+
+  newpad = (GstPad *)
+      GST_ELEMENT_CLASS (gst_gl_mosaic_parent_class)->request_new_pad (element,
+      templ, req_name, caps);
+
+  if (newpad == NULL)
+    goto could_not_create;
+
+  gst_child_proxy_child_added (GST_CHILD_PROXY (element), G_OBJECT (newpad),
+      GST_OBJECT_NAME (newpad));
+
+  return newpad;
+
+could_not_create:
+  {
+    GST_DEBUG_OBJECT (element, "could not create/add pad");
+    return NULL;
+  }
+}
+
+static void
+gst_gl_mosaic_release_pad (GstElement * element, GstPad * pad)
+{
+  GstGLMosaic *gl_mosaic = GST_GL_MOSAIC (element);
+
+  GST_DEBUG_OBJECT (gl_mosaic, "release pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+
+  gst_child_proxy_child_removed (GST_CHILD_PROXY (gl_mosaic), G_OBJECT (pad),
+      GST_OBJECT_NAME (pad));
+
+  GST_ELEMENT_CLASS (gst_gl_mosaic_parent_class)->release_pad (element, pad);
+}
+
 static void
 gst_gl_mosaic_reset (GstGLMixer * mixer)
 {
@@ -356,3 +407,43 @@ gst_gl_mosaic_callback (gpointer stuff)
 
   return TRUE;
 }
+
+/* GstChildProxy implementation */
+static GObject *
+gst_gl_mosaic_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
+    guint index)
+{
+  GstGLMosaic *gl_mosaic = GST_GL_MOSAIC (child_proxy);
+  GObject *obj = NULL;
+
+  GST_OBJECT_LOCK (gl_mosaic);
+  obj = g_list_nth_data (GST_ELEMENT_CAST (gl_mosaic)->sinkpads, index);
+  if (obj)
+    gst_object_ref (obj);
+  GST_OBJECT_UNLOCK (gl_mosaic);
+
+  return obj;
+}
+
+static guint
+gst_gl_mosaic_child_proxy_get_children_count (GstChildProxy * child_proxy)
+{
+  guint count = 0;
+  GstGLMosaic *gl_mosaic = GST_GL_MOSAIC (child_proxy);
+
+  GST_OBJECT_LOCK (gl_mosaic);
+  count = GST_ELEMENT_CAST (gl_mosaic)->numsinkpads;
+  GST_OBJECT_UNLOCK (gl_mosaic);
+  GST_INFO_OBJECT (gl_mosaic, "Children Count: %d", count);
+
+  return count;
+}
+
+static void
+gst_gl_mosaic_child_proxy_init (gpointer g_iface, gpointer iface_data)
+{
+  GstChildProxyInterface *iface = g_iface;
+
+  iface->get_child_by_index = gst_gl_mosaic_child_proxy_get_child_by_index;
+  iface->get_children_count = gst_gl_mosaic_child_proxy_get_children_count;
+}
index 42020a2..4d72dfa 100644 (file)
@@ -78,8 +78,13 @@ gst_gl_stereo_mix_pad_init (GstGLStereoMixPad * pad)
 {
 }
 
+static void gst_gl_stereo_mix_child_proxy_init (gpointer g_iface,
+    gpointer iface_data);
+
 #define gst_gl_stereo_mix_parent_class parent_class
-G_DEFINE_TYPE (GstGLStereoMix, gst_gl_stereo_mix, GST_TYPE_GL_MIXER);
+G_DEFINE_TYPE_WITH_CODE (GstGLStereoMix, gst_gl_stereo_mix, GST_TYPE_GL_MIXER,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
+        gst_gl_stereo_mix_child_proxy_init));
 
 static GstCaps *_update_caps (GstVideoAggregator * vagg, GstCaps * caps);
 static gboolean _negotiated_caps (GstAggregator * aggregator, GstCaps * caps);
@@ -133,6 +138,10 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%u",
         "; " GST_VIDEO_CAPS_MAKE (GST_GL_COLOR_CONVERT_FORMATS))
     );
 
+static GstPad *gst_gl_stereo_mix_request_new_pad (GstElement * element,
+    GstPadTemplate * temp, const gchar * req_name, const GstCaps * caps);
+static void gst_gl_stereo_mix_release_pad (GstElement * element, GstPad * pad);
+
 static GstFlowReturn gst_gl_stereo_mix_get_output_buffer (GstVideoAggregator *
     videoaggregator, GstBuffer ** outbuf);
 static gboolean gst_gl_stereo_mix_stop (GstAggregator * agg);
@@ -184,6 +193,11 @@ gst_gl_stereo_mix_class_init (GstGLStereoMixClass * klass)
   gst_element_class_add_static_pad_template_with_gtype (element_class,
       &sink_factory, GST_TYPE_GL_STEREO_MIX_PAD);
 
+  element_class->request_new_pad =
+      GST_DEBUG_FUNCPTR (gst_gl_stereo_mix_request_new_pad);
+  element_class->release_pad =
+      GST_DEBUG_FUNCPTR (gst_gl_stereo_mix_release_pad);
+
   agg_class->stop = gst_gl_stereo_mix_stop;
   agg_class->start = gst_gl_stereo_mix_start;
   agg_class->src_query = gst_gl_stereo_mix_src_query;
@@ -399,6 +413,42 @@ gst_gl_stereo_mix_set_property (GObject * object,
   }
 }
 
+static GstPad *
+gst_gl_stereo_mix_request_new_pad (GstElement * element, GstPadTemplate * templ,
+    const gchar * req_name, const GstCaps * caps)
+{
+  GstPad *newpad;
+
+  newpad = (GstPad *)
+      GST_ELEMENT_CLASS (parent_class)->request_new_pad (element,
+      templ, req_name, caps);
+
+  if (newpad == NULL)
+    goto could_not_create;
+
+  gst_child_proxy_child_added (GST_CHILD_PROXY (element), G_OBJECT (newpad),
+      GST_OBJECT_NAME (newpad));
+
+  return GST_PAD_CAST (newpad);
+
+could_not_create:
+  {
+    GST_DEBUG_OBJECT (element, "could not create/add pad");
+    return NULL;
+  }
+}
+
+static void
+gst_gl_stereo_mix_release_pad (GstElement * element, GstPad * pad)
+{
+  GST_DEBUG_OBJECT (element, "release pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+
+  gst_child_proxy_child_removed (GST_CHILD_PROXY (element), G_OBJECT (pad),
+      GST_OBJECT_NAME (pad));
+
+  GST_ELEMENT_CLASS (parent_class)->release_pad (element, pad);
+}
+
 static gboolean
 gst_gl_stereo_mix_start (GstAggregator * agg)
 {
@@ -696,3 +746,43 @@ gst_gl_stereo_mix_process_frames (GstGLStereoMix * mixer)
 
   return TRUE;
 }
+
+/* GstChildProxy implementation */
+static GObject *
+gst_gl_stereo_mix_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
+    guint index)
+{
+  GstGLStereoMix *gl_stereo_mix = GST_GL_STEREO_MIX (child_proxy);
+  GObject *obj = NULL;
+
+  GST_OBJECT_LOCK (gl_stereo_mix);
+  obj = g_list_nth_data (GST_ELEMENT_CAST (gl_stereo_mix)->sinkpads, index);
+  if (obj)
+    gst_object_ref (obj);
+  GST_OBJECT_UNLOCK (gl_stereo_mix);
+
+  return obj;
+}
+
+static guint
+gst_gl_stereo_mix_child_proxy_get_children_count (GstChildProxy * child_proxy)
+{
+  guint count = 0;
+  GstGLStereoMix *gl_stereo_mix = GST_GL_STEREO_MIX (child_proxy);
+
+  GST_OBJECT_LOCK (gl_stereo_mix);
+  count = GST_ELEMENT_CAST (gl_stereo_mix)->numsinkpads;
+  GST_OBJECT_UNLOCK (gl_stereo_mix);
+  GST_INFO_OBJECT (gl_stereo_mix, "Children Count: %d", count);
+
+  return count;
+}
+
+static void
+gst_gl_stereo_mix_child_proxy_init (gpointer g_iface, gpointer iface_data)
+{
+  GstChildProxyInterface *iface = g_iface;
+
+  iface->get_child_by_index = gst_gl_stereo_mix_child_proxy_get_child_by_index;
+  iface->get_children_count = gst_gl_stereo_mix_child_proxy_get_children_count;
+}
index 78b5d06..602aace 100644 (file)
@@ -451,11 +451,16 @@ enum
   PROP_BACKGROUND,
 };
 
+static void gst_gl_video_mixer_child_proxy_init (gpointer g_iface,
+    gpointer iface_data);
+
 #define DEBUG_INIT \
     GST_DEBUG_CATEGORY_INIT (gst_gl_video_mixer_debug, "glvideomixer", 0, "glvideomixer element");
 
 #define gst_gl_video_mixer_parent_class parent_class
 G_DEFINE_TYPE_WITH_CODE (GstGLVideoMixer, gst_gl_video_mixer, GST_TYPE_GL_MIXER,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
+        gst_gl_video_mixer_child_proxy_init);
     DEBUG_INIT);
 
 static void gst_gl_video_mixer_set_property (GObject * object, guint prop_id,
@@ -837,11 +842,39 @@ _del_buffer (GstGLContext * context, GLuint * pBuffer)
   context->gl_vtable->DeleteBuffers (1, pBuffer);
 }
 
+static GstPad *
+gst_gl_video_mixer_request_new_pad (GstElement * element,
+    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
+{
+  GstPad *newpad;
+
+  newpad = (GstPad *)
+      GST_ELEMENT_CLASS (parent_class)->request_new_pad (element,
+      templ, req_name, caps);
+
+  if (newpad == NULL)
+    goto could_not_create;
+
+  gst_child_proxy_child_added (GST_CHILD_PROXY (element), G_OBJECT (newpad),
+      GST_OBJECT_NAME (newpad));
+
+  return newpad;
+
+could_not_create:
+  {
+    GST_DEBUG_OBJECT (element, "could not create/add  pad");
+    return NULL;
+  }
+}
+
 static void
 gst_gl_video_mixer_release_pad (GstElement * element, GstPad * p)
 {
   GstGLVideoMixerPad *pad = GST_GL_VIDEO_MIXER_PAD (p);
 
+  gst_child_proxy_child_removed (GST_CHILD_PROXY (element), G_OBJECT (pad),
+      GST_OBJECT_NAME (pad));
+
   /* we call the base class first as this will remove the pad from
    * the aggregator, thus stopping misc callbacks from being called,
    * one of which (process_textures) will recreate the vertex_buffer
@@ -867,6 +900,7 @@ gst_gl_video_mixer_class_init (GstGLVideoMixerClass * klass)
 
   gobject_class = (GObjectClass *) klass;
   element_class = GST_ELEMENT_CLASS (klass);
+  element_class->request_new_pad = gst_gl_video_mixer_request_new_pad;
   element_class->release_pad = gst_gl_video_mixer_release_pad;
 
   gobject_class->set_property = gst_gl_video_mixer_set_property;
@@ -1590,3 +1624,43 @@ gst_gl_video_mixer_callback (gpointer stuff)
 
   return TRUE;
 }
+
+/* GstChildProxy implementation */
+static GObject *
+gst_gl_video_mixer_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
+    guint index)
+{
+  GstGLVideoMixer *gl_video_mixer = GST_GL_VIDEO_MIXER (child_proxy);
+  GObject *obj = NULL;
+
+  GST_OBJECT_LOCK (gl_video_mixer);
+  obj = g_list_nth_data (GST_ELEMENT_CAST (gl_video_mixer)->sinkpads, index);
+  if (obj)
+    gst_object_ref (obj);
+  GST_OBJECT_UNLOCK (gl_video_mixer);
+
+  return obj;
+}
+
+static guint
+gst_gl_video_mixer_child_proxy_get_children_count (GstChildProxy * child_proxy)
+{
+  guint count = 0;
+  GstGLVideoMixer *gl_video_mixer = GST_GL_VIDEO_MIXER (child_proxy);
+
+  GST_OBJECT_LOCK (gl_video_mixer);
+  count = GST_ELEMENT_CAST (gl_video_mixer)->numsinkpads;
+  GST_OBJECT_UNLOCK (gl_video_mixer);
+  GST_INFO_OBJECT (gl_video_mixer, "Children Count: %d", count);
+
+  return count;
+}
+
+static void
+gst_gl_video_mixer_child_proxy_init (gpointer g_iface, gpointer iface_data)
+{
+  GstChildProxyInterface *iface = g_iface;
+
+  iface->get_child_by_index = gst_gl_video_mixer_child_proxy_get_child_by_index;
+  iface->get_children_count = gst_gl_video_mixer_child_proxy_get_children_count;
+}
index 93fa0cc..f5556fe 100644 (file)
@@ -369,51 +369,6 @@ gst_video_aggregator_pad_init (GstVideoAggregatorPad * vaggpad)
   vaggpad->priv->convert = NULL;
 }
 
-/*********************************
- * GstChildProxy implementation  *
- *********************************/
-static GObject *
-gst_video_aggregator_child_proxy_get_child_by_index (GstChildProxy *
-    child_proxy, guint index)
-{
-  GObject *obj;
-  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (child_proxy);
-
-  GST_OBJECT_LOCK (vagg);
-  if ((obj = g_list_nth_data (GST_ELEMENT (vagg)->sinkpads, index)))
-    g_object_ref (obj);
-  GST_OBJECT_UNLOCK (vagg);
-
-  return obj;
-}
-
-static guint
-gst_video_aggregator_child_proxy_get_children_count (GstChildProxy *
-    child_proxy)
-{
-  guint count = 0;
-
-  GST_OBJECT_LOCK (child_proxy);
-  count = GST_ELEMENT (child_proxy)->numsinkpads;
-  GST_OBJECT_UNLOCK (child_proxy);
-
-  GST_INFO_OBJECT (child_proxy, "Children Count: %d", count);
-
-  return count;
-}
-
-static void
-gst_video_aggregator_child_proxy_init (gpointer g_iface, gpointer iface_data)
-{
-  GstChildProxyInterface *iface = g_iface;
-
-  GST_INFO ("intializing child proxy interface");
-  iface->get_child_by_index =
-      gst_video_aggregator_child_proxy_get_child_by_index;
-  iface->get_children_count =
-      gst_video_aggregator_child_proxy_get_children_count;
-}
-
 /**************************************
  * GstVideoAggregator implementation  *
  **************************************/
@@ -479,10 +434,6 @@ gst_video_aggregator_get_type (void)
         sizeof (GstVideoAggregator),
         (GInstanceInitFunc) gst_video_aggregator_init,
         (GTypeFlags) G_TYPE_FLAG_ABSTRACT);
-    {
-      G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
-          gst_video_aggregator_child_proxy_init);
-    }
     g_once_init_leave (&g_define_type_id_volatile, g_define_type_id);
   }
   return g_define_type_id_volatile;
@@ -1902,9 +1853,6 @@ gst_video_aggregator_request_new_pad (GstElement * element,
       (GCompareFunc) pad_zorder_compare);
   GST_OBJECT_UNLOCK (vagg);
 
-  gst_child_proxy_child_added (GST_CHILD_PROXY (vagg), G_OBJECT (vaggpad),
-      GST_OBJECT_NAME (vaggpad));
-
   return GST_PAD (vaggpad);
 }
 
@@ -1929,9 +1877,6 @@ gst_video_aggregator_release_pad (GstElement * element, GstPad * pad)
 
   gst_buffer_replace (&vaggpad->buffer, NULL);
 
-  gst_child_proxy_child_removed (GST_CHILD_PROXY (vagg), G_OBJECT (vaggpad),
-      GST_OBJECT_NAME (vaggpad));
-
   GST_ELEMENT_CLASS (gst_video_aggregator_parent_class)->release_pad
       (GST_ELEMENT (vagg), pad);
 
index caa19f8..66cf36c 100644 (file)
@@ -120,6 +120,9 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%u",
     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (FORMATS))
     );
 
+static void gst_compositor_child_proxy_init (gpointer g_iface,
+    gpointer iface_data);
+
 #define DEFAULT_PAD_XPOS   0
 #define DEFAULT_PAD_YPOS   0
 #define DEFAULT_PAD_WIDTH  0
@@ -731,7 +734,9 @@ gst_compositor_set_property (GObject * object,
 }
 
 #define gst_compositor_parent_class parent_class
-G_DEFINE_TYPE (GstCompositor, gst_compositor, GST_TYPE_VIDEO_AGGREGATOR);
+G_DEFINE_TYPE_WITH_CODE (GstCompositor, gst_compositor,
+    GST_TYPE_VIDEO_AGGREGATOR, G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
+        gst_compositor_child_proxy_init));
 
 static gboolean
 set_functions (GstCompositor * self, GstVideoInfo * info)
@@ -1168,6 +1173,46 @@ gst_compositor_aggregate_frames (GstVideoAggregator * vagg, GstBuffer * outbuf)
   return GST_FLOW_OK;
 }
 
+static GstPad *
+gst_compositor_request_new_pad (GstElement * element, GstPadTemplate * templ,
+    const gchar * req_name, const GstCaps * caps)
+{
+  GstPad *newpad;
+
+  newpad = (GstPad *)
+      GST_ELEMENT_CLASS (parent_class)->request_new_pad (element,
+      templ, req_name, caps);
+
+  if (newpad == NULL)
+    goto could_not_create;
+
+  gst_child_proxy_child_added (GST_CHILD_PROXY (element), G_OBJECT (newpad),
+      GST_OBJECT_NAME (newpad));
+
+  return newpad;
+
+could_not_create:
+  {
+    GST_DEBUG_OBJECT (element, "could not create/add pad");
+    return NULL;
+  }
+}
+
+static void
+gst_compositor_release_pad (GstElement * element, GstPad * pad)
+{
+  GstCompositor *compositor;
+
+  compositor = GST_COMPOSITOR (element);
+
+  GST_DEBUG_OBJECT (compositor, "release pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+
+  gst_child_proxy_child_removed (GST_CHILD_PROXY (compositor), G_OBJECT (pad),
+      GST_OBJECT_NAME (pad));
+
+  GST_ELEMENT_CLASS (parent_class)->release_pad (element, pad);
+}
+
 static gboolean
 _sink_query (GstAggregator * agg, GstAggregatorPad * bpad, GstQuery * query)
 {
@@ -1223,6 +1268,10 @@ gst_compositor_class_init (GstCompositorClass * klass)
   gobject_class->get_property = gst_compositor_get_property;
   gobject_class->set_property = gst_compositor_set_property;
 
+  gstelement_class->request_new_pad =
+      GST_DEBUG_FUNCPTR (gst_compositor_request_new_pad);
+  gstelement_class->release_pad =
+      GST_DEBUG_FUNCPTR (gst_compositor_release_pad);
   agg_class->sink_query = _sink_query;
   agg_class->fixate_src_caps = _fixate_caps;
   agg_class->negotiated_src_caps = _negotiated_caps;
@@ -1251,6 +1300,46 @@ gst_compositor_init (GstCompositor * self)
   self->background = DEFAULT_BACKGROUND;
 }
 
+/* GstChildProxy implementation */
+static GObject *
+gst_compositor_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
+    guint index)
+{
+  GstCompositor *compositor = GST_COMPOSITOR (child_proxy);
+  GObject *obj = NULL;
+
+  GST_OBJECT_LOCK (compositor);
+  obj = g_list_nth_data (GST_ELEMENT_CAST (compositor)->sinkpads, index);
+  if (obj)
+    gst_object_ref (obj);
+  GST_OBJECT_UNLOCK (compositor);
+
+  return obj;
+}
+
+static guint
+gst_compositor_child_proxy_get_children_count (GstChildProxy * child_proxy)
+{
+  guint count = 0;
+  GstCompositor *compositor = GST_COMPOSITOR (child_proxy);
+
+  GST_OBJECT_LOCK (compositor);
+  count = GST_ELEMENT_CAST (compositor)->numsinkpads;
+  GST_OBJECT_UNLOCK (compositor);
+  GST_INFO_OBJECT (compositor, "Children Count: %d", count);
+
+  return count;
+}
+
+static void
+gst_compositor_child_proxy_init (gpointer g_iface, gpointer iface_data)
+{
+  GstChildProxyInterface *iface = g_iface;
+
+  iface->get_child_by_index = gst_compositor_child_proxy_get_child_by_index;
+  iface->get_children_count = gst_compositor_child_proxy_get_children_count;
+}
+
 /* Element registration */
 static gboolean
 plugin_init (GstPlugin * plugin)