summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <bilboed@bilboed.com>2010-05-17 15:04:48 +0200
committerEdward Hervey <bilboed@bilboed.com>2010-06-14 17:08:14 +0200
commitdc38e75d88bd8921895821f7afed01cab30e46c9 (patch)
treef37e186ad44492082adb9af6f4ab8eacd2f6d735
parent4a5552bf15924d959fe9faa0292208e98a139a07 (diff)
GstPad: Add GST_PAD_NEGOTIABLE GstPadFlag
A pad is 'negotiable' when its container element is in a state greater than GST_STATE_READY API:gst_pad_is_negotiable API:gst_pad_set_negotiable API:GST_PAD_NEGOTIABLE https://bugzilla.gnome.org/show_bug.cgi?id=618644
-rw-r--r--docs/gst/gstreamer-sections.txt6
-rw-r--r--gst/gstelement.c60
-rw-r--r--gst/gstpad.c56
-rw-r--r--gst/gstpad.h9
-rw-r--r--win32/common/libgstreamer.def2
5 files changed, 132 insertions, 1 deletions
diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt
index 79f6064178..fcd3b0f2bb 100644
--- a/docs/gst/gstreamer-sections.txt
+++ b/docs/gst/gstreamer-sections.txt
@@ -1372,6 +1372,9 @@ gst_pad_use_fixed_caps
gst_pad_is_active
+gst_pad_is_negotiable
+gst_pad_set_negotiable
+
gst_pad_set_blocked
gst_pad_set_blocked_async
gst_pad_set_blocked_async_full
@@ -1561,6 +1564,9 @@ GST_PAD_IS_BLOCKED
GST_PAD_IS_BLOCKING
GST_PAD_IS_IN_SETCAPS
GST_PAD_SET_FLUSHING
+GST_PAD_IS_NEGOTIABLE
+GST_PAD_SET_NEGOTIABLE
+GST_PAD_UNSET_NEGOTIABLE
GST_PAD_TASK
GST_PAD_UNSET_FLUSHING
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);
diff --git a/gst/gstpad.c b/gst/gstpad.c
index 90c8577a90..5cd434fd29 100644
--- a/gst/gstpad.c
+++ b/gst/gstpad.c
@@ -984,6 +984,62 @@ gst_pad_is_active (GstPad * pad)
}
/**
+ * gst_pad_is_negotiable:
+ * @pad: the #GstPad to query
+ *
+ * Query if a pad is negotiable
+ *
+ * Returns: TRUE if the pad is negotiable.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.30
+ */
+gboolean
+gst_pad_is_negotiable (GstPad * pad)
+{
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+
+ GST_OBJECT_LOCK (pad);
+ result = GST_PAD_IS_NEGOTIABLE (pad);
+ GST_OBJECT_UNLOCK (pad);
+
+ return result;
+}
+
+/**
+ * gst_pad_set_negotiable:
+ * @pad: the #GstPad to set negotiable or not
+ * @negotiable: whether or not the pad should be set negotiable or not
+ *
+ * Sets a pad 'negotiable' if @negotiable is TRUE. A pad in that state will
+ * forward pad queries. Pads are set to negotiable by their container element in
+ * GST_STATE_READY and unset in GST_STATE_NULL.
+ *
+ * MT safe.
+ *
+ * Returns: #TRUE if the operation was successfull.
+ *
+ * Since: 0.10.30
+ */
+gboolean
+gst_pad_set_negotiable (GstPad * pad, gboolean negotiable)
+{
+ g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+
+ GST_OBJECT_LOCK (pad);
+ if (negotiable)
+ GST_PAD_SET_NEGOTIABLE (pad);
+ else
+ GST_PAD_UNSET_NEGOTIABLE (pad);
+ GST_OBJECT_UNLOCK (pad);
+
+ return TRUE;
+}
+
+/**
* gst_pad_set_blocked_async_full:
* @pad: the #GstPad to block or unblock
* @blocked: boolean indicating whether the pad should be blocked or unblocked
diff --git a/gst/gstpad.h b/gst/gstpad.h
index 56e4320b01..979dce9647 100644
--- a/gst/gstpad.h
+++ b/gst/gstpad.h
@@ -541,6 +541,7 @@ typedef enum {
* @GST_PAD_IN_GETCAPS: GstPadGetCapsFunction() is running now
* @GST_PAD_IN_SETCAPS: GstPadSetCapsFunction() is running now
* @GST_PAD_BLOCKING: is pad currently blocking on a buffer or event
+ * @GST_PAD_NEGOTIABLE: can pad handle caps requests. Since 0.10.30
* @GST_PAD_FLAG_LAST: offset to define more flags
*
* Pad state flags
@@ -551,6 +552,7 @@ typedef enum {
GST_PAD_IN_GETCAPS = (GST_OBJECT_FLAG_LAST << 2),
GST_PAD_IN_SETCAPS = (GST_OBJECT_FLAG_LAST << 3),
GST_PAD_BLOCKING = (GST_OBJECT_FLAG_LAST << 4),
+ GST_PAD_NEGOTIABLE = (GST_OBJECT_FLAG_LAST << 5),
/* padding */
GST_PAD_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 8)
} GstPadFlags;
@@ -746,12 +748,16 @@ struct _GstPadClass {
#define GST_PAD_IS_FLUSHING(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLUSHING))
#define GST_PAD_IS_IN_GETCAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_GETCAPS))
#define GST_PAD_IS_IN_SETCAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_SETCAPS))
+#define GST_PAD_IS_NEGOTIABLE(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_NEGOTIABLE))
#define GST_PAD_IS_SRC(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SRC)
#define GST_PAD_IS_SINK(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SINK)
#define GST_PAD_SET_FLUSHING(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLUSHING))
#define GST_PAD_UNSET_FLUSHING(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLUSHING))
+#define GST_PAD_SET_NEGOTIABLE(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_NEGOTIABLE))
+#define GST_PAD_UNSET_NEGOTIABLE(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_NEGOTIABLE))
+
/**
* GST_PAD_GET_STREAM_LOCK:
* @pad: a #GstPad
@@ -971,6 +977,9 @@ gboolean gst_pad_query_default (GstPad *pad, GstQuery *query);
gboolean gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch,
gpointer data);
+gboolean gst_pad_is_negotiable (GstPad *pad);
+gboolean gst_pad_set_negotiable (GstPad *pad, gboolean negotiable);
+
#ifndef GST_DISABLE_LOADSAVE
void gst_pad_load_and_link (xmlNodePtr self, GstObject *parent);
#endif
diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def
index 1146b2ae37..30e5496e7e 100644
--- a/win32/common/libgstreamer.def
+++ b/win32/common/libgstreamer.def
@@ -612,6 +612,7 @@ EXPORTS
gst_pad_is_blocked
gst_pad_is_blocking
gst_pad_is_linked
+ gst_pad_is_negotiable
gst_pad_iterate_internal_links
gst_pad_iterate_internal_links_default
gst_pad_link
@@ -665,6 +666,7 @@ EXPORTS
gst_pad_set_internal_link_function
gst_pad_set_iterate_internal_links_function
gst_pad_set_link_function
+ gst_pad_set_negotiable
gst_pad_set_query_function
gst_pad_set_query_type_function
gst_pad_set_setcaps_function