From 3647442ccd22751bcd5fab60e739aab0bd76c73b Mon Sep 17 00:00:00 2001 From: Hans-Christian Ebke Date: Thu, 3 Jan 2013 18:04:19 +0000 Subject: auto-sink: Ensure the IS_SINK flag The ClutterGstAutoVideoSink sets its GST_ELEMENT_IS_SINK flag in its init method. However, in contrast to the ClutterGstVideoSink, this class is not based on GstBaseSink but on GstBin instead. The problem is that GstBin automatically sets its GST_ELEMENT_IS_SINK flag whenever a sink is added. It also automatically unsets it whenever the last sink is removed from the bin. Now, after the first video clip is finished and the pipeline leaves the PLAYING state, the encapsulated ClutterGstVideoSink is removed from the ClutterGstAutoVideoSink leaving it without any sinks and thus making it lose its GST_ELEMENT_IS_SINK flag. Apparently this happens even before the EOS signal is broadcast in the pipeline. Interestingly, the ClutterGstAutoVideoSink does receive the EOS signal and forwards it to its parent, the vbin of the playsink. But the vbin ignores the signal because in bin_do_eos (gstbin.c) the is_eos check fails. This check, in turn, fails because the bin_element_is_sink check fails on its child, the ClutterGstAutoVideoSink (because its GST_ELEMENT_IS_SINK flag isn't set anymore). Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=679611 --- clutter-gst/clutter-gst-auto-video-sink.c | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/clutter-gst/clutter-gst-auto-video-sink.c b/clutter-gst/clutter-gst-auto-video-sink.c index a689280..bb83429 100644 --- a/clutter-gst/clutter-gst-auto-video-sink.c +++ b/clutter-gst/clutter-gst-auto-video-sink.c @@ -60,6 +60,9 @@ enum #define DEFAULT_TS_OFFSET 0 +static gboolean clutter_gst_auto_video_sink_add_func (GstBin * bin, GstElement * element); +static gboolean clutter_gst_auto_video_sink_remove_func (GstBin * bin, GstElement * element); + GST_BOILERPLATE (ClutterGstAutoVideoSink, clutter_gst_auto_video_sink, GstBin, @@ -649,6 +652,35 @@ activate_failed: } } +/* + * Call the base class implementation and make + * sure that the GST_ELEMENT_IS_SINK flag is still + * set afterwards. + */ +static gboolean +clutter_gst_auto_video_sink_add_func (GstBin * bin, GstElement * element) +{ + gboolean result; + + result = GST_BIN_CLASS (parent_class)->add_element (bin, element); + GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_IS_SINK); + return result; +} + +/* + * Call the base class implementation and make + * sure that the GST_ELEMENT_IS_SINK flag is still + * set afterwards. + */ +static gboolean +clutter_gst_auto_video_sink_remove_func (GstBin * bin, GstElement * element) { + gboolean result; + + result = GST_BIN_CLASS (parent_class)->remove_element (bin, element); + GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_IS_SINK); + return result; +} + static void clutter_gst_auto_video_sink_dispose (GObject *object) { @@ -768,6 +800,7 @@ clutter_gst_auto_video_sink_class_init (ClutterGstAutoVideoSinkClass *klass) { GObjectClass *oclass = G_OBJECT_CLASS (klass); GstElementClass *gstelement_class; + GstBinClass *gstbin_class; GParamSpec *pspec; oclass->dispose = clutter_gst_auto_video_sink_dispose; @@ -799,6 +832,10 @@ clutter_gst_auto_video_sink_class_init (ClutterGstAutoVideoSinkClass *klass) gstelement_class = (GstElementClass *)klass; gstelement_class->change_state = GST_DEBUG_FUNCPTR (clutter_gst_auto_video_sink_change_state); + + gstbin_class = (GstBinClass *)klass; + gstbin_class->add_element = GST_DEBUG_FUNCPTR (clutter_gst_auto_video_sink_add_func); + gstbin_class->remove_element = GST_DEBUG_FUNCPTR (clutter_gst_auto_video_sink_remove_func); } static void -- cgit v1.2.1