From: Edward Hervey Date: Mon, 9 Jul 2012 18:27:44 +0000 (+0200) Subject: gstbin: collect and aggregate STREAM_START messages X-Git-Tag: RELEASE-0.11.93~131 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=94bd61b72dab8c406addf47384d74f130f8f6baf;p=platform%2Fupstream%2Fgstreamer.git gstbin: collect and aggregate STREAM_START messages when all sinks have posted a STREAM_START, the bin will forward a new STREAM_START message to the parent bin or application --- diff --git a/gst/gstbin.c b/gst/gstbin.c index 0c7cbfa..51fa75d 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -1009,6 +1009,43 @@ is_eos (GstBin * bin, guint32 * seqnum) return result && n_eos > 0; } + +/* Check if the bin is STREAM_START. We do this by scanning all sinks and + * checking if they posted an STREAM_START message. + * + * call with bin LOCK */ +static gboolean +is_stream_start (GstBin * bin, guint32 * seqnum) +{ + gboolean result; + gint n_stream_start = 0; + GList *walk, *msgs; + + result = TRUE; + for (walk = bin->children; walk; walk = g_list_next (walk)) { + GstElement *element; + + element = GST_ELEMENT_CAST (walk->data); + if (bin_element_is_sink (element, bin) == 0) { + /* check if element posted STREAM_START */ + if ((msgs = + find_message (bin, GST_OBJECT_CAST (element), + GST_MESSAGE_STREAM_START))) { + GST_DEBUG ("sink '%s' posted STREAM_START", GST_ELEMENT_NAME (element)); + *seqnum = gst_message_get_seqnum (GST_MESSAGE_CAST (msgs->data)); + n_stream_start++; + } else { + GST_DEBUG ("sink '%s' did not post STREAM_START yet", + GST_ELEMENT_NAME (element)); + result = FALSE; + break; + } + } + } + + return result; +} + static void unlink_pads (const GValue * item, gpointer user_data) { @@ -2518,6 +2555,8 @@ gst_bin_change_state_func (GstElement * element, GstStateChange transition) GST_DEBUG_OBJECT (element, "clearing EOS elements"); bin_remove_messages (bin, NULL, GST_MESSAGE_EOS); bin->priv->posted_eos = FALSE; + if (current == GST_STATE_READY) + bin_remove_messages (bin, NULL, GST_MESSAGE_STREAM_START); GST_OBJECT_UNLOCK (bin); if (current == GST_STATE_READY) if (!(gst_bin_src_pads_activate (bin, TRUE))) @@ -3126,6 +3165,35 @@ bin_do_eos (GstBin * bin) } } +static void +bin_do_stream_start (GstBin * bin) +{ + guint32 seqnum = 0; + gboolean stream_start; + + GST_OBJECT_LOCK (bin); + /* If all sinks are STREAM_START we forward the STREAM_START message + * to the parent bin or application + */ + stream_start = is_stream_start (bin, &seqnum); + GST_OBJECT_UNLOCK (bin); + + if (stream_start) { + GstMessage *tmessage; + + GST_OBJECT_LOCK (bin); + bin_remove_messages (bin, NULL, GST_MESSAGE_STREAM_START); + GST_OBJECT_UNLOCK (bin); + + tmessage = gst_message_new_stream_start (GST_OBJECT_CAST (bin)); + gst_message_set_seqnum (tmessage, seqnum); + GST_DEBUG_OBJECT (bin, + "all sinks posted STREAM_START, posting seqnum #%" G_GUINT32_FORMAT, + seqnum); + gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage); + } +} + /* must be called with the object lock. This function releases the lock to post * the message. */ static void @@ -3245,6 +3313,18 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message) bin_do_eos (bin); break; } + case GST_MESSAGE_STREAM_START: + { + + /* collect all stream_start messages from the children */ + GST_OBJECT_LOCK (bin); + /* ref message for future use */ + bin_replace_message (bin, message, GST_MESSAGE_STREAM_START); + GST_OBJECT_UNLOCK (bin); + + bin_do_stream_start (bin); + break; + } case GST_MESSAGE_STATE_DIRTY: { GST_WARNING_OBJECT (bin, "received deprecated STATE_DIRTY message");