summaryrefslogtreecommitdiff
path: root/gst/gstelement.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/gstelement.c')
-rw-r--r--gst/gstelement.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/gst/gstelement.c b/gst/gstelement.c
index 0db67a3fcf..e4e149b396 100644
--- a/gst/gstelement.c
+++ b/gst/gstelement.c
@@ -686,7 +686,7 @@ gboolean
gst_element_add_pad (GstElement * element, GstPad * pad)
{
gchar *pad_name;
- gboolean flushing;
+ gboolean flushing, negotiable;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
@@ -697,6 +697,7 @@ gst_element_add_pad (GstElement * element, GstPad * pad)
GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
GST_STR_NULL (pad_name));
flushing = GST_PAD_IS_FLUSHING (pad);
+ negotiable = GST_PAD_IS_NEGOTIABLE (pad);
GST_OBJECT_UNLOCK (pad);
/* then check to see if there's already a pad by that name here */
@@ -709,6 +710,14 @@ gst_element_add_pad (GstElement * element, GstPad * pad)
GST_OBJECT_CAST (element))))
goto had_parent;
+ /* sync pad state with element */
+ if (!negotiable && (GST_STATE (element) > GST_STATE_NULL ||
+ GST_STATE_NEXT (element) == GST_STATE_READY)) {
+ GST_OBJECT_LOCK (pad);
+ GST_PAD_SET_NEGOTIABLE (pad);
+ GST_OBJECT_UNLOCK (pad);
+ }
+
/* check for flushing pads */
if (flushing && (GST_STATE (element) > GST_STATE_READY ||
GST_STATE_NEXT (element) == GST_STATE_PAUSED)) {
@@ -2668,6 +2677,51 @@ done:
return g_value_get_boolean (&ret);
}
+static gboolean
+negotiable_pads (GstPad * pad, GValue * ret, gboolean * active)
+{
+ if (!gst_pad_set_negotiable (pad, *active))
+ g_value_set_boolean (ret, FALSE);
+
+ /* unref the object that was reffed for us by _fold */
+ gst_object_unref (pad);
+ return TRUE;
+}
+
+/* is called with STATE_LOCK */
+static gboolean
+gst_element_pads_negotiable (GstElement * element, gboolean negotiable)
+{
+ GstIterator *iter;
+ gboolean res;
+
+ GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
+ "pads_negotiable with negotiable %d", negotiable);
+
+ /* clear the caps on all pads, this should never fail */
+ iter = gst_element_iterate_pads (element);
+ res =
+ iterator_activate_fold_with_resync (iter,
+ (GstIteratorFoldFunction) negotiable_pads, &negotiable);
+ gst_iterator_free (iter);
+ if (G_UNLIKELY (!res))
+ goto negotiable_failed;
+
+ GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
+ "pads_negotiable successful");
+
+ return TRUE;
+
+ /* ERRORS */
+negotiable_failed:
+ {
+ GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
+ "failed to set pads to 'negotiable'");
+ return FALSE;
+ }
+}
+
+
/* is called with STATE_LOCK
*
* Pads are activated from source pads to sinkpads.
@@ -2758,6 +2812,9 @@ gst_element_change_state_func (GstElement * element, GstStateChange transition)
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
+ if (!gst_element_pads_negotiable (element, TRUE)) {
+ result = GST_STATE_CHANGE_FAILURE;
+ }
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
if (!gst_element_pads_activate (element, TRUE)) {
@@ -2777,6 +2834,7 @@ gst_element_change_state_func (GstElement * element, GstStateChange transition)
} else {
gst_element_set_base_time (element, 0);
}
+ gst_element_pads_negotiable (element, FALSE);
/* In null state release the reference to the clock */
GST_OBJECT_LOCK (element);