gobject_class->get_property = gst_bin_get_property;
/**
- * GstBin:async-handling
+ * GstBin:async-handling:
*
* If set to #TRUE, the bin will handle asynchronous state changes.
* This should be used only if the bin subclass is modifying the state
* of its children on its own.
- *
- * Since: 0.10.13
*/
g_object_class_install_property (gobject_class, PROP_ASYNC_HANDLING,
g_param_spec_boolean ("async-handling", "Async Handling",
* Connect to this signal if the default latency calculations are not
* sufficient, like when you need different latencies for different sinks in
* the same pipeline.
- *
- * Since: 0.10.22
*/
gst_bin_signals[DO_LATENCY] =
g_signal_new ("do-latency", G_TYPE_FROM_CLASS (klass),
G_TYPE_BOOLEAN, 0, G_TYPE_NONE);
/**
- * GstBin:message-forward
+ * GstBin:message-forward:
*
* Forward all children messages, even those that would normally be filtered by
* the bin. This can be interesting when one wants to be notified of the EOS
* source. The structure of the message is named 'GstBinForwarded' and contains
* a field named 'message' of type GST_TYPE_MESSAGE that contains the original
* forwarded message.
- *
- * Since: 0.10.31
*/
g_object_class_install_property (gobject_class, PROP_MESSAGE_FORWARD,
g_param_spec_boolean ("message-forward", "Message Forward",
bin->child_bus = bus;
GST_DEBUG_OBJECT (bin, "using bus %" GST_PTR_FORMAT " to listen to children",
bus);
- gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin);
+ gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin,
+ NULL);
bin->priv = GST_BIN_GET_PRIVATE (bin);
bin->priv->asynchandling = DEFAULT_ASYNC_HANDLING;
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)
{
GstIterator *iter;
gboolean fold_ok;
- GST_DEBUG_OBJECT (bin, "src_pads_activate with active %d", active);
+ GST_DEBUG_OBJECT (bin, "%s pads", active ? "activate" : "deactivate");
iter = gst_element_iterate_src_pads ((GstElement *) bin);
fold_ok = iterator_activate_fold_with_resync (iter, &active);
if (G_UNLIKELY (!fold_ok))
goto failed;
- GST_DEBUG_OBJECT (bin, "pads_activate successful");
+ GST_DEBUG_OBJECT (bin, "pad %sactivation successful", active ? "" : "de");
return TRUE;
/* ERRORS */
failed:
{
- GST_DEBUG_OBJECT (bin, "source pads_activate failed");
+ GST_DEBUG_OBJECT (bin, "pad %sactivation failed", active ? "" : "de");
return FALSE;
}
}
* calculations will be performed.
*
* Returns: %TRUE if the latency could be queried and reconfigured.
- *
- * Since: 0.10.22.
*/
gboolean
gst_bin_recalculate_latency (GstBin * bin)
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)))
}
}
+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
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");