videoaggregator: Move GstChildProxy implementations into leaf classes

Not every subclass will want to expose the pads via the interface.

https://bugzilla.gnome.org/show_bug.cgi?id=739011
This commit is contained in:
Sebastian Dröge 2018-05-04 16:13:16 +02:00
parent e27083211c
commit e34d4e9bf4
5 changed files with 346 additions and 57 deletions

View 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;
}

View 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;
}

View 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;
}

View 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);

View 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)