/**
* gst_event_new_tag:
- * @name: (transfer none): the name of the event
* @taglist: (transfer full): metadata list. The event will take ownership
* of the taglist.
*
* Generates a metadata tag event from the given @taglist.
*
- * Since the TAG event has the %GST_EVENT_TYPE_STICKY_MULTI flag set, the
- * @name will be used to keep track of multiple tag events.
+ * The scope of the taglist specifies if the taglist applies to the
+ * complete medium or only to this specific stream. As the tag event
+ * is a sticky event, elements should merge tags received from
+ * upstream with a given scope with their own tags with the same
+ * scope and create a new tag event from it.
*
* Returns: (transfer full): a new #GstEvent
*/
GstEvent *
-gst_event_new_tag (const gchar * name, GstTagList * taglist)
+gst_event_new_tag (GstTagList * taglist)
{
GstStructure *s;
GValue val = G_VALUE_INIT;
+ const gchar *names[] = { "GstTagList-stream", "GstTagList-global" };
g_return_val_if_fail (taglist != NULL, NULL);
- s = gst_structure_new_empty (name);
+ s = gst_structure_new_empty (names[gst_tag_list_get_scope (taglist)]);
g_value_init (&val, GST_TYPE_TAG_LIST);
g_value_take_boxed (&val, taglist);
gst_structure_id_take_value (s, GST_QUARK (TAGLIST), &val);
void gst_event_copy_segment (GstEvent *event, GstSegment *segment);
/* tag event */
-GstEvent* gst_event_new_tag (const gchar *name, GstTagList *taglist) G_GNUC_MALLOC;
+GstEvent* gst_event_new_tag (GstTagList *taglist) G_GNUC_MALLOC;
void gst_event_parse_tag (GstEvent *event, GstTagList **taglist);
/* TOC event */
GstTagList taglist;
GstStructure *structure;
+ GstTagScope scope;
} GstTagListImpl;
#define GST_TAG_LIST_STRUCTURE(taglist) ((GstTagListImpl*)(taglist))->structure
+#define GST_TAG_LIST_SCOPE(taglist) ((GstTagListImpl*)(taglist))->scope
typedef struct
{
(GstMiniObjectFreeFunction) __gst_tag_list_free);
GST_TAG_LIST_STRUCTURE (tag_list) = s;
+ GST_TAG_LIST_SCOPE (tag_list) = GST_TAG_SCOPE_STREAM;
#ifdef DEBUG_REFCOUNT
GST_CAT_TRACE (GST_CAT_TAGS, "created taglist %p", tag_list);
}
/**
+ * gst_tag_list_set_scope:
+ * @list: a #GstTagList
+ * @scope: new scope for @list
+ *
+ * Sets the scope of @list to @scope. By default the scope
+ * of a taglist is #GST_TAG_SCOPE_STREAM.
+ *
+ */
+void
+gst_tag_list_set_scope (GstTagList * list, GstTagScope scope)
+{
+ g_return_if_fail (GST_IS_TAG_LIST (list));
+ g_return_if_fail (gst_tag_list_is_writable (list));
+
+ GST_TAG_LIST_SCOPE (list) = scope;
+}
+
+/**
+ * gst_tag_list_get_scope:
+ * @list: a #GstTagList
+ *
+ * Gets the scope of @list.
+ *
+ * Returns: The scope of @list
+ */
+GstTagScope
+gst_tag_list_get_scope (const GstTagList * list)
+{
+ g_return_val_if_fail (GST_IS_TAG_LIST (list), GST_TAG_SCOPE_STREAM);
+
+ return GST_TAG_LIST_SCOPE (list);
+}
+
+/**
* gst_tag_list_to_string:
* @list: a #GstTagList
*
gboolean gst_tag_is_fixed (const gchar * tag);
/* tag lists */
+
+/**
+ * GstTagEventScope:
+ * @GST_TAG_SCOPE_STREAM: tags specific to this single stream
+ * @GST_TAG_SCOPE_GLOBAL: global tags for the complete medium
+ *
+ * GstTagScope specifies if a taglist applies to the complete
+ * medium or only to one single stream.
+ */
+typedef enum {
+ GST_TAG_SCOPE_STREAM,
+ GST_TAG_SCOPE_GLOBAL
+} GstTagScope;
+
GstTagList * gst_tag_list_new_empty (void) G_GNUC_MALLOC;
GstTagList * gst_tag_list_new (const gchar * tag, ...) G_GNUC_MALLOC;
GstTagList * gst_tag_list_new_valist (va_list var_args) G_GNUC_MALLOC;
+void gst_tag_list_set_scope (GstTagList * list, GstTagScope scope);
+GstTagScope gst_tag_list_get_scope (const GstTagList * list);
+
gchar * gst_tag_list_to_string (const GstTagList * list) G_GNUC_MALLOC;
GstTagList * gst_tag_list_new_from_string (const gchar * str) G_GNUC_MALLOC;
parse->priv->max_bitrate);
if (taglist != NULL) {
- gst_pad_push_event (parse->srcpad, gst_event_new_tag ("GstParser",
- taglist));
+ gst_pad_push_event (parse->srcpad, gst_event_new_tag (taglist));
}
}
gst_event_parse_tag (event, &taglist);
+ /* We only care about stream tags here */
+ if (gst_tag_list_get_scope (taglist) != GST_TAG_SCOPE_STREAM)
+ return;
+
if (gst_tag_list_get_uint (taglist, GST_TAG_MINIMUM_BITRATE, &tmp)) {
GST_DEBUG_OBJECT (parse, "upstream min bitrate %d", tmp);
parse->priv->post_min_bitrate = FALSE;
GstTagList *taglist = gst_tag_list_new_empty ();
GstTagList *tl2 = NULL;
- event = gst_event_new_tag ("test", taglist);
+ event = gst_event_new_tag (taglist);
fail_if (taglist == NULL);
fail_if (event == NULL);
fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
srcpad = gst_element_get_static_pad (fakesrc, "src");
- gst_pad_push_event (srcpad, gst_event_new_tag ("test", list));
+ gst_pad_push_event (srcpad, gst_event_new_tag (list));
gst_object_unref (srcpad);
bus = gst_element_get_bus (pipeline);