X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstelement.c;h=e186a09353c68a47149ac73982d768be2f645271;hb=335826a3eb640224ba466964db128eb7a422862b;hp=4333d536971fe7087cc6e789ffedff4215a43cc9;hpb=7a0f4422fa1692dfdd8df9580676c8125be4280b;p=platform%2Fupstream%2Fgstreamer.git
diff --git a/gst/gstelement.c b/gst/gstelement.c
index 4333d53..e186a09 100644
--- a/gst/gstelement.c
+++ b/gst/gstelement.c
@@ -22,6 +22,7 @@
/**
* SECTION:gstelement
+ * @title: GstElement
* @short_description: Abstract base class for all pipeline elements
* @see_also: #GstElementFactory, #GstPad
*
@@ -345,6 +346,7 @@ gst_element_release_request_pad (GstElement * element, GstPad * pad)
g_return_if_fail (GST_PAD_PAD_TEMPLATE (pad) == NULL ||
GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad)) ==
GST_PAD_REQUEST);
+ g_return_if_fail (GST_PAD_PARENT (pad) == element);
oclass = GST_ELEMENT_GET_CLASS (element);
@@ -361,8 +363,8 @@ gst_element_release_request_pad (GstElement * element, GstPad * pad)
* @element: a #GstElement to query
*
* Get the clock provided by the given element.
- * An element is only required to provide a clock in the PAUSED
- * state. Some elements can provide a clock in other states.
+ * > An element is only required to provide a clock in the PAUSED
+ * > state. Some elements can provide a clock in other states.
*
* Returns: (transfer full) (nullable): the GstClock provided by the
* element or %NULL if no clock could be provided. Unref after usage.
@@ -401,7 +403,7 @@ gst_element_set_clock_func (GstElement * element, GstClock * clock)
/**
* gst_element_set_clock:
* @element: a #GstElement to set the clock for.
- * @clock: the #GstClock to set for the element.
+ * @clock: (transfer none) (allow-none): the #GstClock to set for the element.
*
* Sets the clock for the element. This function increases the
* refcount on the clock. Any previously set clock on the object
@@ -442,7 +444,7 @@ gst_element_set_clock (GstElement * element, GstClock * clock)
* Elements in a pipeline will only have their clock set when the
* pipeline is in the PLAYING state.
*
- * Returns: (transfer full): the #GstClock of the element. unref after usage.
+ * Returns: (transfer full) (nullable): the #GstClock of the element. unref after usage.
*
* MT safe.
*/
@@ -633,14 +635,13 @@ gst_element_get_index (GstElement * element)
/**
* gst_element_add_pad:
* @element: a #GstElement to add the pad to.
- * @pad: (transfer full): the #GstPad to add to the element.
+ * @pad: (transfer floating): the #GstPad to add to the element.
*
* Adds a pad (link point) to @element. @pad's parent will be set to @element;
* see gst_object_set_parent() for refcounting information.
*
- * Pads are not automatically activated so elements should perform the needed
- * steps to activate the pad in case this pad is added in the PAUSED or PLAYING
- * state. See gst_pad_set_active() for more information about activating pads.
+ * Pads are automatically activated when added in the PAUSED or PLAYING
+ * state.
*
* The pad and the element should be unlocked when calling this function.
*
@@ -683,9 +684,6 @@ gst_element_add_pad (GstElement * element, GstPad * pad)
/* check for active pads */
if (!active && (GST_STATE (element) > GST_STATE_READY ||
GST_STATE_NEXT (element) == GST_STATE_PAUSED)) {
- g_warning ("adding inactive pad '%s' to running element '%s', you need to "
- "use gst_pad_set_active(pad,TRUE) before adding it.",
- GST_STR_NULL (pad_name), GST_ELEMENT_NAME (element));
gst_pad_set_active (pad, TRUE);
}
@@ -721,6 +719,8 @@ name_exists:
pad_name, GST_ELEMENT_NAME (element));
GST_OBJECT_UNLOCK (element);
g_free (pad_name);
+ gst_object_ref_sink (pad);
+ gst_object_unref (pad);
return FALSE;
}
had_parent:
@@ -747,7 +747,7 @@ no_direction:
/**
* gst_element_remove_pad:
* @element: a #GstElement to remove pad from.
- * @pad: (transfer full): the #GstPad to remove from the element.
+ * @pad: (transfer none): the #GstPad to remove from the element.
*
* Removes @pad from @element. @pad will be destroyed if it has not been
* referenced elsewhere using gst_object_unparent().
@@ -920,52 +920,138 @@ gst_element_get_static_pad (GstElement * element, const gchar * name)
return result;
}
-static GstPad *
-_gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
- const gchar * name, const GstCaps * caps)
+static gboolean
+gst_element_is_valid_request_template_name (const gchar * templ_name,
+ const gchar * name)
{
- GstPad *newpad = NULL;
- GstElementClass *oclass;
+ gchar *endptr;
+ const gchar *templ_name_ptr, *name_ptr;
+ gboolean next_specifier;
+ guint templ_postfix_len = 0, name_postfix_len = 0;
- oclass = GST_ELEMENT_GET_CLASS (element);
+ g_return_val_if_fail (templ_name != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
-#ifndef G_DISABLE_CHECKS
- /* Some sanity checking here */
- if (name) {
- GstPad *pad;
+ /* Is this the template name? */
+ if (strcmp (templ_name, name) == 0)
+ return TRUE;
- /* Is this the template name? */
- if (strstr (name, "%") || !strchr (templ->name_template, '%')) {
- g_return_val_if_fail (strcmp (name, templ->name_template) == 0, NULL);
- } else {
- const gchar *str, *data;
- gchar *endptr;
+ /* otherwise check all the specifiers */
+ do {
+ /* Because of sanity checks in gst_pad_template_new(), we know that %s
+ * and %d and %u, occurring at the template_name */
+ templ_name_ptr = strchr (templ_name, '%');
+
+ /* check characters ahead of the specifier */
+ if (!templ_name_ptr || strlen (name) <= templ_name_ptr - templ_name
+ || strncmp (templ_name, name, templ_name_ptr - templ_name) != 0) {
+ return FALSE;
+ }
+
+ /* %s is not allowed for multiple specifiers, just a single specifier can be
+ * accepted in gst_pad_template_new() and can not be mixed with other
+ * specifier '%u' and '%d' */
+ if (*(templ_name_ptr + 1) == 's' && g_strcmp0 (templ_name, name) == 0) {
+ return TRUE;
+ }
+
+ name_ptr = name + (templ_name_ptr - templ_name);
+
+ /* search next specifier, each of specifier should be separated by '_' */
+ templ_name = strchr (templ_name_ptr, '_');
+ name = strchr (name_ptr, '_');
+
+ /* don't match the number of specifiers */
+ if ((templ_name && !name) || (!templ_name && name))
+ return FALSE;
+
+ if (templ_name && name)
+ next_specifier = TRUE;
+ else
+ next_specifier = FALSE;
+
+ /* check characters followed by the specifier */
+ if (*(templ_name_ptr + 2) != '\0' && *(templ_name_ptr + 2) != '_') {
+ if (next_specifier) {
+ templ_postfix_len = templ_name - (templ_name_ptr + 2);
+ name_postfix_len = name - name_ptr;
+ } else {
+ templ_postfix_len = strlen (templ_name_ptr + 2);
+ name_postfix_len = strlen (name_ptr);
+ }
- /* Otherwise check if it's a valid name for the name template */
- str = strchr (templ->name_template, '%');
- g_return_val_if_fail (str != NULL, NULL);
- g_return_val_if_fail (strncmp (templ->name_template, name,
- str - templ->name_template) == 0, NULL);
- g_return_val_if_fail (strlen (name) > str - templ->name_template, NULL);
+ if (strncmp (templ_name_ptr + 2,
+ name_ptr + name_postfix_len - templ_postfix_len,
+ templ_postfix_len) != 0) {
+ return FALSE;
+ }
+ }
+
+ /* verify the specifier */
+ if (*(name_ptr) == '%') {
+ guint len;
+
+ len = (next_specifier) ? name - name_ptr : strlen (name_ptr);
- data = name + (str - templ->name_template);
+ if (strncmp (name_ptr, templ_name_ptr, len) != 0)
+ return FALSE;
- /* Can either be %s or %d or %u, do sanity checking for %d */
- if (*(str + 1) == 'd') {
+ } else {
+ const gchar *specifier;
+ gchar *target = NULL;
+
+ /* extract specifier when it has postfix characters */
+ if (name_postfix_len > templ_postfix_len) {
+ target = g_strndup (name_ptr, name_postfix_len - templ_postfix_len);
+ }
+ specifier = target ? target : name_ptr;
+
+ if (*(templ_name_ptr + 1) == 'd') {
gint64 tmp;
/* it's an int */
- tmp = g_ascii_strtoll (data, &endptr, 10);
- g_return_val_if_fail (tmp >= G_MININT && tmp <= G_MAXINT
- && *endptr == '\0', NULL);
- } else if (*(str + 1) == 'u') {
+ tmp = g_ascii_strtoll (specifier, &endptr, 10);
+ if (tmp < G_MININT || tmp > G_MAXINT || (*endptr != '\0'
+ && *endptr != '_'))
+ return FALSE;
+ } else if (*(templ_name_ptr + 1) == 'u') {
guint64 tmp;
/* it's an int */
- tmp = g_ascii_strtoull (data, &endptr, 10);
- g_return_val_if_fail (tmp <= G_MAXUINT && *endptr == '\0', NULL);
+ tmp = g_ascii_strtoull (specifier, &endptr, 10);
+ if (tmp > G_MAXUINT || (*endptr != '\0' && *endptr != '_'))
+ return FALSE;
}
+
+ g_free (target);
+ }
+
+ /* otherwise we increment these from NULL to 1 */
+ if (next_specifier) {
+ templ_name++;
+ name++;
}
+ } while (next_specifier);
+
+ return TRUE;
+}
+
+static GstPad *
+_gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
+ const gchar * name, const GstCaps * caps)
+{
+ GstPad *newpad = NULL;
+ GstElementClass *oclass;
+
+ oclass = GST_ELEMENT_GET_CLASS (element);
+
+#ifndef G_DISABLE_CHECKS
+ /* Some sanity checking here */
+ if (name) {
+ GstPad *pad;
+
+ g_return_val_if_fail (gst_element_is_valid_request_template_name
+ (templ->name_template, name), NULL);
pad = gst_element_get_static_pad (element, name);
if (pad) {
@@ -1011,8 +1097,6 @@ gst_element_get_request_pad (GstElement * element, const gchar * name)
const gchar *req_name = NULL;
gboolean templ_found = FALSE;
GList *list;
- const gchar *data;
- gchar *str, *endptr = NULL;
GstElementClass *class;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
@@ -1020,13 +1104,10 @@ gst_element_get_request_pad (GstElement * element, const gchar * name)
class = GST_ELEMENT_GET_CLASS (element);
- /* if the name contains a %, we assume it's the complete template name. Get
- * the template and try to get a pad */
- if (strstr (name, "%")) {
- templ = gst_element_class_get_request_pad_template (class, name);
- req_name = NULL;
- if (templ)
- templ_found = TRUE;
+ templ = gst_element_class_get_request_pad_template (class, name);
+ if (templ) {
+ req_name = strstr (name, "%") ? NULL : name;
+ templ_found = TRUE;
} else {
/* there is no % in the name, try to find a matching template */
list = class->padtemplates;
@@ -1035,48 +1116,12 @@ gst_element_get_request_pad (GstElement * element, const gchar * name)
if (templ->presence == GST_PAD_REQUEST) {
GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
templ->name_template);
- /* see if we find an exact match */
- if (strcmp (name, templ->name_template) == 0) {
+ if (gst_element_is_valid_request_template_name (templ->name_template,
+ name)) {
templ_found = TRUE;
req_name = name;
break;
}
- /* Because of sanity checks in gst_pad_template_new(), we know that %s
- and %d and %u, occurring at the end of the name_template, are the only
- possibilities. */
- else if ((str = strchr (templ->name_template, '%'))
- && strncmp (templ->name_template, name,
- str - templ->name_template) == 0
- && strlen (name) > str - templ->name_template) {
- data = name + (str - templ->name_template);
- if (*(str + 1) == 'd') {
- glong tmp;
-
- /* it's an int */
- tmp = strtol (data, &endptr, 10);
- if (tmp != G_MINLONG && tmp != G_MAXLONG && endptr &&
- *endptr == '\0') {
- templ_found = TRUE;
- req_name = name;
- break;
- }
- } else if (*(str + 1) == 'u') {
- gulong tmp;
-
- /* it's an int */
- tmp = strtoul (data, &endptr, 10);
- if (tmp != G_MAXULONG && endptr && *endptr == '\0') {
- templ_found = TRUE;
- req_name = name;
- break;
- }
- } else {
- /* it's a string */
- templ_found = TRUE;
- req_name = name;
- break;
- }
- }
}
list = list->next;
}
@@ -1198,15 +1243,133 @@ gst_element_iterate_sink_pads (GstElement * element)
return gst_element_iterate_pad_list (element, &element->sinkpads);
}
+static gboolean
+gst_element_do_foreach_pad (GstElement * element,
+ GstElementForeachPadFunc func, gpointer user_data,
+ GList ** p_pads, guint16 * p_npads)
+{
+ gboolean ret = TRUE;
+ GstPad **pads;
+ guint n_pads, i;
+ GList *l;
+
+ g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
+ g_return_val_if_fail (func != NULL, FALSE);
+
+ GST_OBJECT_LOCK (element);
+ n_pads = *p_npads;
+ pads = g_newa (GstPad *, n_pads + 1);
+ for (l = *p_pads, i = 0; l != NULL; l = l->next) {
+ g_assert (i < n_pads);
+ pads[i++] = gst_object_ref (l->data);
+ }
+ GST_OBJECT_UNLOCK (element);
+
+ if (n_pads == 0)
+ return FALSE;
+
+ for (i = 0; i < n_pads; ++i) {
+ ret = func (element, pads[i], user_data);
+ if (!ret)
+ break;
+ }
+
+ for (i = 0; i < n_pads; ++i)
+ gst_object_unref (pads[i]);
+
+ return ret;
+}
+
+/**
+ * gst_element_foreach_sink_pad:
+ * @element: a #GstElement to iterate sink pads of
+ * @func: (scope call): function to call for each sink pad
+ * @user_data: (closure): user data passed to @func
+ *
+ * Call @func with @user_data for each of @element's sink pads. @func will be
+ * called exactly once for each sink pad that exists at the time of this call,
+ * unless one of the calls to @func returns %FALSE in which case we will stop
+ * iterating pads and return early. If new sink pads are added or sink pads
+ * are removed while the sink pads are being iterated, this will not be taken
+ * into account until next time this function is used.
+ *
+ * Returns: %FALSE if @element had no sink pads or if one of the calls to @func
+ * returned %FALSE.
+ *
+ * Since: 1.14
+ */
+gboolean
+gst_element_foreach_sink_pad (GstElement * element,
+ GstElementForeachPadFunc func, gpointer user_data)
+{
+ return gst_element_do_foreach_pad (element, func, user_data,
+ &element->sinkpads, &element->numsinkpads);
+}
+
+/**
+ * gst_element_foreach_src_pad:
+ * @element: a #GstElement to iterate source pads of
+ * @func: (scope call): function to call for each source pad
+ * @user_data: (closure): user data passed to @func
+ *
+ * Call @func with @user_data for each of @element's source pads. @func will be
+ * called exactly once for each source pad that exists at the time of this call,
+ * unless one of the calls to @func returns %FALSE in which case we will stop
+ * iterating pads and return early. If new source pads are added or source pads
+ * are removed while the source pads are being iterated, this will not be taken
+ * into account until next time this function is used.
+ *
+ * Returns: %FALSE if @element had no source pads or if one of the calls
+ * to @func returned %FALSE.
+ *
+ * Since: 1.14
+ */
+gboolean
+gst_element_foreach_src_pad (GstElement * element,
+ GstElementForeachPadFunc func, gpointer user_data)
+{
+ return gst_element_do_foreach_pad (element, func, user_data,
+ &element->srcpads, &element->numsrcpads);
+}
+
+/**
+ * gst_element_foreach_pad:
+ * @element: a #GstElement to iterate pads of
+ * @func: (scope call): function to call for each pad
+ * @user_data: (closure): user data passed to @func
+ *
+ * Call @func with @user_data for each of @element's pads. @func will be called
+ * exactly once for each pad that exists at the time of this call, unless
+ * one of the calls to @func returns %FALSE in which case we will stop
+ * iterating pads and return early. If new pads are added or pads are removed
+ * while pads are being iterated, this will not be taken into account until
+ * next time this function is used.
+ *
+ * Returns: %FALSE if @element had no pads or if one of the calls to @func
+ * returned %FALSE.
+ *
+ * Since: 1.14
+ */
+gboolean
+gst_element_foreach_pad (GstElement * element, GstElementForeachPadFunc func,
+ gpointer user_data)
+{
+ return gst_element_do_foreach_pad (element, func, user_data,
+ &element->pads, &element->numpads);
+}
+
/**
* gst_element_class_add_pad_template:
* @klass: the #GstElementClass to add the pad template to.
- * @templ: (transfer full): a #GstPadTemplate to add to the element class.
+ * @templ: (transfer floating): a #GstPadTemplate to add to the element class.
*
* Adds a padtemplate to an element class. This is mainly used in the _class_init
* functions of classes. If a pad template with the same name as an already
* existing one is added the old one is replaced by the new one.
*
+ * @templ's reference count will be incremented, and any floating
+ * reference will be removed (see gst_object_ref_sink())
+ *
*/
void
gst_element_class_add_pad_template (GstElementClass * klass,
@@ -1224,6 +1387,7 @@ gst_element_class_add_pad_template (GstElementClass * klass,
/* Found pad with the same name, replace and return */
if (strcmp (templ->name_template, padtempl->name_template) == 0) {
+ gst_object_ref_sink (padtempl);
gst_object_unref (padtempl);
template_list->data = templ;
return;
@@ -1259,6 +1423,28 @@ gst_element_class_add_static_pad_template (GstElementClass * klass,
}
/**
+ * gst_element_class_add_static_pad_template_with_gtype:
+ * @klass: the #GstElementClass to add the pad template to.
+ * @static_templ: #GstStaticPadTemplate to add as pad template to the element class.
+ * @pad_type: The #GType of the pad to create
+ *
+ * Adds a pad template to an element class based on the static pad template
+ * @templ. This is mainly used in the _class_init functions of element
+ * implementations. If a pad template with the same name already exists,
+ * the old one is replaced by the new one.
+ *
+ * Since: 1.14
+ */
+void
+gst_element_class_add_static_pad_template_with_gtype (GstElementClass * klass,
+ GstStaticPadTemplate * static_templ, GType pad_type)
+{
+ gst_element_class_add_pad_template (klass,
+ gst_pad_template_new_from_static_pad_template_with_gtype (static_templ,
+ pad_type));
+}
+
+/**
* gst_element_class_add_metadata:
* @klass: class to set metadata for
* @key: the key to set
@@ -1319,7 +1505,7 @@ gst_element_class_add_static_metadata (GstElementClass * klass,
* multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>"
*
* Sets the detailed information for a #GstElementClass.
- * This function is for use in _class_init functions only.
+ * > This function is for use in _class_init functions only.
*/
void
gst_element_class_set_metadata (GstElementClass * klass,
@@ -1352,7 +1538,8 @@ gst_element_class_set_metadata (GstElementClass * klass,
* multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>"
*
* Sets the detailed information for a #GstElementClass.
- * This function is for use in _class_init functions only.
+ *
+ * > This function is for use in _class_init functions only.
*
* Same as gst_element_class_set_metadata(), but @longname, @classification,
* @description, and @author must be static strings or inlined strings, as
@@ -1408,14 +1595,34 @@ gst_element_class_get_metadata (GstElementClass * klass, const gchar * key)
}
/**
+ * gst_element_get_metadata:
+ * @element: class to get metadata for
+ * @key: the key to get
+ *
+ * Get metadata with @key in @klass.
+ *
+ * Returns: the metadata for @key.
+ *
+ * Since: 1.14
+ */
+const gchar *
+gst_element_get_metadata (GstElement * element, const gchar * key)
+{
+ g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ return gst_element_class_get_metadata (GST_ELEMENT_GET_CLASS (element), key);
+}
+
+/**
* gst_element_class_get_pad_template_list:
* @element_class: a #GstElementClass to get pad templates of.
*
* Retrieves a list of the pad templates associated with @element_class. The
* list must not be modified by the calling code.
- * If you use this function in the #GInstanceInitFunc of an object class
- * that has subclasses, make sure to pass the g_class parameter of the
- * #GInstanceInitFunc here.
+ * > If you use this function in the #GInstanceInitFunc of an object class
+ * > that has subclasses, make sure to pass the g_class parameter of the
+ * > #GInstanceInitFunc here.
*
* Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
* pad templates.
@@ -1429,14 +1636,35 @@ gst_element_class_get_pad_template_list (GstElementClass * element_class)
}
/**
+ * gst_element_get_pad_template_list:
+ * @element: a #GstElement to get pad templates of.
+ *
+ * Retrieves a list of the pad templates associated with @element. The
+ * list must not be modified by the calling code.
+ *
+ * Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
+ * pad templates.
+ *
+ * Since: 1.14
+ */
+GList *
+gst_element_get_pad_template_list (GstElement * element)
+{
+ g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+
+ return
+ gst_element_class_get_pad_template_list (GST_ELEMENT_GET_CLASS (element));
+}
+
+/**
* gst_element_class_get_pad_template:
* @element_class: a #GstElementClass to get the pad template of.
* @name: the name of the #GstPadTemplate to get.
*
* Retrieves a padtemplate from @element_class with the given name.
- * If you use this function in the #GInstanceInitFunc of an object class
- * that has subclasses, make sure to pass the g_class parameter of the
- * #GInstanceInitFunc here.
+ * > If you use this function in the #GInstanceInitFunc of an object class
+ * > that has subclasses, make sure to pass the g_class parameter of the
+ * > #GInstanceInitFunc here.
*
* Returns: (transfer none) (nullable): the #GstPadTemplate with the
* given name, or %NULL if none was found. No unreferencing is
@@ -1465,6 +1693,29 @@ gst_element_class_get_pad_template (GstElementClass *
return NULL;
}
+/**
+ * gst_element_get_pad_template:
+ * @element: a #GstElement to get the pad template of.
+ * @name: the name of the #GstPadTemplate to get.
+ *
+ * Retrieves a padtemplate from @element with the given name.
+ *
+ * Returns: (transfer none) (nullable): the #GstPadTemplate with the
+ * given name, or %NULL if none was found. No unreferencing is
+ * necessary.
+ *
+ * Since: 1.14
+ */
+GstPadTemplate *
+gst_element_get_pad_template (GstElement * element, const gchar * name)
+{
+ g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ return gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (element),
+ name);
+}
+
static GstPadTemplate *
gst_element_class_get_request_pad_template (GstElementClass *
element_class, const gchar * name)
@@ -1479,7 +1730,7 @@ gst_element_class_get_request_pad_template (GstElementClass *
}
/* get a random pad on element of the given direction.
- * The pad is random in a sense that it is the first pad that is (optionaly) linked.
+ * The pad is random in a sense that it is the first pad that is (optionally) linked.
*/
static GstPad *
gst_element_get_random_pad (GstElement * element,
@@ -1819,7 +2070,7 @@ _gst_element_error_printf (const gchar * format, ...)
}
/**
- * gst_element_message_full:
+ * gst_element_message_full_with_details:
* @element: a #GstElement to send message from
* @type: the #GstMessageType
* @domain: the GStreamer GError domain this message belongs to
@@ -1833,18 +2084,20 @@ _gst_element_error_printf (const gchar * format, ...)
* @file: the source code file where the error was generated
* @function: the source code function where the error was generated
* @line: the source code line where the error was generated
+ * @structure:(transfer full): optional details structure
*
* Post an error, warning or info message on the bus from inside an element.
*
* @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
* #GST_MESSAGE_INFO.
*
- * MT safe.
+ * Since: 1.10
*/
-void gst_element_message_full
+void gst_element_message_full_with_details
(GstElement * element, GstMessageType type,
GQuark domain, gint code, gchar * text,
- gchar * debug, const gchar * file, const gchar * function, gint line)
+ gchar * debug, const gchar * file, const gchar * function, gint line,
+ GstStructure * structure)
{
GError *gerror = NULL;
gchar *name;
@@ -1891,20 +2144,24 @@ void gst_element_message_full
switch (type) {
case GST_MESSAGE_ERROR:
message =
- gst_message_new_error (GST_OBJECT_CAST (element), gerror, sent_debug);
+ gst_message_new_error_with_details (GST_OBJECT_CAST (element), gerror,
+ sent_debug, structure);
break;
case GST_MESSAGE_WARNING:
- message = gst_message_new_warning (GST_OBJECT_CAST (element), gerror,
- sent_debug);
+ message =
+ gst_message_new_warning_with_details (GST_OBJECT_CAST (element),
+ gerror, sent_debug, structure);
break;
case GST_MESSAGE_INFO:
- message = gst_message_new_info (GST_OBJECT_CAST (element), gerror,
- sent_debug);
+ message =
+ gst_message_new_info_with_details (GST_OBJECT_CAST (element), gerror,
+ sent_debug, structure);
break;
default:
g_assert_not_reached ();
break;
}
+
gst_element_post_message (element, message);
GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted %s message: %s",
@@ -1917,6 +2174,38 @@ void gst_element_message_full
}
/**
+ * gst_element_message_full:
+ * @element: a #GstElement to send message from
+ * @type: the #GstMessageType
+ * @domain: the GStreamer GError domain this message belongs to
+ * @code: the GError code belonging to the domain
+ * @text: (allow-none) (transfer full): an allocated text string to be used
+ * as a replacement for the default message connected to code,
+ * or %NULL
+ * @debug: (allow-none) (transfer full): an allocated debug message to be
+ * used as a replacement for the default debugging information,
+ * or %NULL
+ * @file: the source code file where the error was generated
+ * @function: the source code function where the error was generated
+ * @line: the source code line where the error was generated
+ *
+ * Post an error, warning or info message on the bus from inside an element.
+ *
+ * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
+ * #GST_MESSAGE_INFO.
+ *
+ * MT safe.
+ */
+void gst_element_message_full
+ (GstElement * element, GstMessageType type,
+ GQuark domain, gint code, gchar * text,
+ gchar * debug, const gchar * file, const gchar * function, gint line)
+{
+ gst_element_message_full_with_details (element, type, domain, code, text,
+ debug, file, function, line, NULL);
+}
+
+/**
* gst_element_is_locked_state:
* @element: a #GstElement.
*
@@ -1952,6 +2241,10 @@ gst_element_is_locked_state (GstElement * element)
* Locks the state of an element, so state changes of the parent don't affect
* this element anymore.
*
+ * Note that this is racy if the state lock of the parent bin is not taken.
+ * The parent bin might've just checked the flag in another thread and as the
+ * next step proceed to change the child element's state.
+ *
* MT safe.
*
* Returns: %TRUE if the state was changed, %FALSE if bad parameters were given
@@ -2155,7 +2448,7 @@ interrupted:
if (pending)
*pending = GST_STATE_VOID_PENDING;
- GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interruped");
+ GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interrupted");
GST_OBJECT_UNLOCK (element);
@@ -2310,6 +2603,8 @@ _priv_gst_element_state_changed (GstElement * element, GstState oldstate,
* This method is used internally and should normally not be called by plugins
* or applications.
*
+ * This function must be called with STATE_LOCK held.
+ *
* Returns: The result of the commit state change.
*
* MT safe.
@@ -2691,14 +2986,14 @@ gst_element_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_SUCCESS:
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"element changed state SUCCESS");
- /* we can commit the state now which will proceeed to
+ /* we can commit the state now which will proceed to
* the next state */
ret = gst_element_continue_state (element, ret);
break;
case GST_STATE_CHANGE_NO_PREROLL:
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"element changed state NO_PREROLL");
- /* we can commit the state now which will proceeed to
+ /* we can commit the state now which will proceed to
* the next state */
ret = gst_element_continue_state (element, ret);
break;
@@ -3059,7 +3354,7 @@ gst_element_set_bus_func (GstElement * element, GstBus * bus)
/**
* gst_element_set_bus:
* @element: a #GstElement to set the bus of.
- * @bus: (transfer none): the #GstBus to set.
+ * @bus: (transfer none) (allow-none): the #GstBus to set.
*
* Sets the bus of the element. Increases the refcount on the bus.
* For internal use only, unless you're testing elements.
@@ -3086,7 +3381,8 @@ gst_element_set_bus (GstElement * element, GstBus * bus)
* Returns the bus of the element. Note that only a #GstPipeline will provide a
* bus for the application.
*
- * Returns: (transfer full): the element's #GstBus. unref after usage.
+ * Returns: (transfer full) (nullable): the element's #GstBus. unref after
+ * usage.
*
* MT safe.
*/
@@ -3114,15 +3410,18 @@ gst_element_set_context_default (GstElement * element, GstContext * context)
const gchar *context_type;
GList *l;
- GST_OBJECT_LOCK (element);
+ g_return_if_fail (GST_IS_CONTEXT (context));
context_type = gst_context_get_context_type (context);
+ g_return_if_fail (context_type != NULL);
+
+ GST_OBJECT_LOCK (element);
for (l = element->contexts; l; l = l->next) {
GstContext *tmp = l->data;
const gchar *tmp_type = gst_context_get_context_type (tmp);
/* Always store newest context but never replace
* a persistent one by a non-persistent one */
- if (strcmp (context_type, tmp_type) == 0 &&
+ if (g_strcmp0 (context_type, tmp_type) == 0 &&
(gst_context_is_persistent (context) ||
!gst_context_is_persistent (tmp))) {
gst_context_replace ((GstContext **) & l->data, context);
@@ -3152,6 +3451,7 @@ gst_element_set_context (GstElement * element, GstContext * context)
GstElementClass *oclass;
g_return_if_fail (GST_IS_ELEMENT (element));
+ g_return_if_fail (GST_IS_CONTEXT (context));
oclass = GST_ELEMENT_GET_CLASS (element);
@@ -3206,7 +3506,7 @@ _match_context_type (GstContext * c1, const gchar * context_type)
*
* Gets the context with @context_type set on the element or NULL.
*
- * Returns: (transfer full): A #GstContext or NULL
+ * Returns: (transfer full) (nullable): A #GstContext or NULL
*
* Since: 1.8
*/
@@ -3439,3 +3739,19 @@ _priv_gst_element_cleanup (void)
gst_element_setup_thread_pool ();
}
}
+
+GstStructure *
+gst_make_element_message_details (const char *name, ...)
+{
+ GstStructure *structure;
+ va_list varargs;
+
+ if (name == NULL)
+ return NULL;
+
+ va_start (varargs, name);
+ structure = gst_structure_new_valist ("details", name, varargs);
+ va_end (varargs);
+
+ return structure;
+}