+
+/**
+ * gst_event_new_stream_start:
+ * @stream_id: Identifier for this stream
+ *
+ * Create a new STREAM_START event. The stream start event can only
+ * travel downstream synchronized with the buffer flow. It is expected
+ * to be the first event that is sent for a new stream.
+ *
+ * Source elements, demuxers and other elements that create new streams
+ * are supposed to send this event as the first event of a new stream. It
+ * should not be sent after a flushing seek or in similar situations
+ * and is used to mark the beginning of a new logical stream. Elements
+ * combining multiple streams must ensure that this event is only forwarded
+ * downstream once and not for every single input stream.
+ *
+ * The @stream_id should be a unique string that consists of the upstream
+ * stream-id, / as separator and a unique stream-id for this specific
+ * stream. A new stream-id should only be created for a stream if the upstream
+ * stream is split into (potentially) multiple new streams, e.g. in a demuxer,
+ * but not for every single element in the pipeline.
+ * gst_pad_create_stream_id() or gst_pad_create_stream_id_printf() can be
+ * used to create a stream-id. There are no particular semantics for the
+ * stream-id, though it should be deterministic (to support stream matching)
+ * and it might be used to order streams (besides any information conveyed by
+ * stream flags).
+ *
+ * Returns: (transfer full): the new STREAM_START event.
+ */
+GstEvent *
+gst_event_new_stream_start (const gchar * stream_id)
+{
+ GstStructure *s;
+
+ g_return_val_if_fail (stream_id != NULL, NULL);
+
+ s = gst_structure_new_id (GST_QUARK (EVENT_STREAM_START),
+ GST_QUARK (STREAM_ID), G_TYPE_STRING, stream_id,
+ GST_QUARK (FLAGS), GST_TYPE_STREAM_FLAGS, GST_STREAM_FLAG_NONE, NULL);
+
+ return gst_event_new_custom (GST_EVENT_STREAM_START, s);
+}
+
+/**
+ * gst_event_parse_stream_start:
+ * @event: a stream-start event.
+ * @stream_id: (out) (transfer none): pointer to store the stream-id
+ *
+ * Parse a stream-id @event and store the result in the given @stream_id
+ * location. The string stored in @stream_id must not be modified and will
+ * remain valid only until @event gets freed. Make a copy if you want to
+ * modify it or store it for later use.
+ */
+void
+gst_event_parse_stream_start (GstEvent * event, const gchar ** stream_id)
+{
+ const GstStructure *structure;
+ const GValue *val;
+
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
+
+ structure = gst_event_get_structure (event);
+ val = gst_structure_id_get_value (structure, GST_QUARK (STREAM_ID));
+
+ if (stream_id)
+ *stream_id = g_value_get_string (val);
+}
+
+/**
+ * gst_event_set_stream:
+ * @event: a stream-start event
+ * @stream: (transfer none): the stream object to set
+ *
+ * Set the @stream on the stream-start @event
+ *
+ * Since: 1.10
+ */
+void
+gst_event_set_stream (GstEvent * event, GstStream * stream)
+{
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
+ g_return_if_fail (gst_event_is_writable (event));
+
+ gst_structure_id_set (GST_EVENT_STRUCTURE (event),
+ GST_QUARK (STREAM), GST_TYPE_STREAM, stream, NULL);
+}
+
+/**
+ * gst_event_parse_stream:
+ * @event: a stream-start event
+ * @stream: (out) (transfer full): address of variable to store the stream
+ *
+ * Parse a stream-start @event and extract the #GstStream from it.
+ *
+ * Since: 1.10
+ */
+void
+gst_event_parse_stream (GstEvent * event, GstStream ** stream)
+{
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
+
+ if (stream) {
+ gst_structure_id_get (GST_EVENT_STRUCTURE (event),
+ GST_QUARK (STREAM), GST_TYPE_STREAM, stream, NULL);
+ }
+
+}
+
+/**
+ * gst_event_set_stream_flags:
+ * @event: a stream-start event
+ * @flags: the stream flags to set
+ *
+ * Since: 1.2
+ */
+void
+gst_event_set_stream_flags (GstEvent * event, GstStreamFlags flags)
+{
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
+ g_return_if_fail (gst_event_is_writable (event));
+
+ gst_structure_id_set (GST_EVENT_STRUCTURE (event),
+ GST_QUARK (FLAGS), GST_TYPE_STREAM_FLAGS, flags, NULL);
+}
+
+/**
+ * gst_event_parse_stream_flags:
+ * @event: a stream-start event
+ * @flags: (out): address of variable where to store the stream flags
+ *
+ * Since: 1.2
+ */
+void
+gst_event_parse_stream_flags (GstEvent * event, GstStreamFlags * flags)
+{
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
+
+ if (flags) {
+ gst_structure_id_get (GST_EVENT_STRUCTURE (event),
+ GST_QUARK (FLAGS), GST_TYPE_STREAM_FLAGS, flags, NULL);
+ }
+}
+
+/**
+ * gst_event_set_group_id:
+ * @event: a stream-start event
+ * @group_id: the group id to set
+ *
+ * All streams that have the same group id are supposed to be played
+ * together, i.e. all streams inside a container file should have the
+ * same group id but different stream ids. The group id should change
+ * each time the stream is started, resulting in different group ids
+ * each time a file is played for example.
+ *
+ * Use gst_util_group_id_next() to get a new group id.
+ *
+ * Since: 1.2
+ */
+void
+gst_event_set_group_id (GstEvent * event, guint group_id)
+{
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
+ g_return_if_fail (gst_event_is_writable (event));
+
+ gst_structure_id_set (GST_EVENT_STRUCTURE (event),
+ GST_QUARK (GROUP_ID), G_TYPE_UINT, group_id, NULL);
+}
+
+/**
+ * gst_event_parse_group_id:
+ * @event: a stream-start event
+ * @group_id: (out): address of variable where to store the group id
+ *
+ * Returns: %TRUE if a group id was set on the event and could be parsed,
+ * %FALSE otherwise.
+ *
+ * Since: 1.2
+ */
+gboolean
+gst_event_parse_group_id (GstEvent * event, guint * group_id)
+{
+ g_return_val_if_fail (event != NULL, FALSE);
+ g_return_val_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START,
+ FALSE);
+
+ if (group_id) {
+ return gst_structure_id_get (GST_EVENT_STRUCTURE (event),
+ GST_QUARK (GROUP_ID), G_TYPE_UINT, group_id, NULL);
+ }
+
+ return TRUE;
+}
+
+/**
+ * gst_event_new_stream_collection:
+ * @collection: Active collection for this data flow
+ *
+ * Create a new STREAM_COLLECTION event. The stream collection event can only
+ * travel downstream synchronized with the buffer flow.
+ *
+ * Source elements, demuxers and other elements that manage collections
+ * of streams and post #GstStreamCollection messages on the bus also send
+ * this event downstream on each pad involved in the collection, so that
+ * activation of a new collection can be tracked through the downstream
+ * data flow.
+ *
+ * Returns: (transfer full): the new STREAM_COLLECTION event.
+ *
+ * Since: 1.10
+ */
+GstEvent *
+gst_event_new_stream_collection (GstStreamCollection * collection)
+{
+ GstStructure *s;
+
+ g_return_val_if_fail (collection != NULL, NULL);
+ g_return_val_if_fail (GST_IS_STREAM_COLLECTION (collection), NULL);
+
+ s = gst_structure_new_id (GST_QUARK (EVENT_STREAM_COLLECTION),
+ GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
+
+ return gst_event_new_custom (GST_EVENT_STREAM_COLLECTION, s);
+}
+
+/**
+ * gst_event_parse_stream_collection:
+ * @event: a stream-collection event
+ * @collection: (out): pointer to store the collection
+ *
+ * Retrieve new #GstStreamCollection from STREAM_COLLECTION event @event.
+ *
+ * Since: 1.10
+ */
+void
+gst_event_parse_stream_collection (GstEvent * event,
+ GstStreamCollection ** collection)
+{
+ const GstStructure *structure;
+
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_COLLECTION);
+
+ structure = gst_event_get_structure (event);
+
+ if (collection) {
+ gst_structure_id_get (structure,
+ GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
+ }
+}
+
+/**
+ * gst_event_new_toc:
+ * @toc: (transfer none): #GstToc structure.
+ * @updated: whether @toc was updated or not.
+ *
+ * Generate a TOC event from the given @toc. The purpose of the TOC event is to
+ * inform elements that some kind of the TOC was found.
+ *
+ * Returns: (transfer full): a new #GstEvent.
+ */
+GstEvent *
+gst_event_new_toc (GstToc * toc, gboolean updated)
+{
+ GstStructure *toc_struct;
+ GQuark id;
+
+ g_return_val_if_fail (toc != NULL, NULL);
+
+ GST_CAT_INFO (GST_CAT_EVENT, "creating toc event");
+
+ /* need different structure names so sticky_multi event stuff on pads
+ * works, i.e. both TOC events are kept around */
+ if (gst_toc_get_scope (toc) == GST_TOC_SCOPE_GLOBAL)
+ id = GST_QUARK (EVENT_TOC_GLOBAL);
+ else
+ id = GST_QUARK (EVENT_TOC_CURRENT);
+
+ toc_struct = gst_structure_new_id (id,
+ GST_QUARK (TOC), GST_TYPE_TOC, toc,
+ GST_QUARK (UPDATED), G_TYPE_BOOLEAN, updated, NULL);
+
+ return gst_event_new_custom (GST_EVENT_TOC, toc_struct);
+}
+
+/**
+ * gst_event_parse_toc:
+ * @event: a TOC event.
+ * @toc: (out) (transfer full): pointer to #GstToc structure.
+ * @updated: (out): pointer to store TOC updated flag.
+ *
+ * Parse a TOC @event and store the results in the given @toc and @updated locations.
+ */
+void
+gst_event_parse_toc (GstEvent * event, GstToc ** toc, gboolean * updated)
+{
+ const GstStructure *structure;
+
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TOC);
+ g_return_if_fail (toc != NULL);
+
+ structure = gst_event_get_structure (event);
+
+ gst_structure_id_get (structure,
+ GST_QUARK (TOC), GST_TYPE_TOC, toc,
+ GST_QUARK (UPDATED), G_TYPE_BOOLEAN, updated, NULL);
+}
+
+/**
+ * gst_event_new_toc_select:
+ * @uid: UID in the TOC to start playback from.
+ *
+ * Generate a TOC select event with the given @uid. The purpose of the
+ * TOC select event is to start playback based on the TOC's entry with the
+ * given @uid.
+ *
+ * Returns: a new #GstEvent.
+ */
+GstEvent *
+gst_event_new_toc_select (const gchar * uid)
+{
+ GstStructure *structure;
+
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ GST_CAT_INFO (GST_CAT_EVENT, "creating toc select event for UID: %s", uid);
+
+ structure = gst_structure_new_id (GST_QUARK (EVENT_TOC_SELECT),
+ GST_QUARK (UID), G_TYPE_STRING, uid, NULL);
+
+ return gst_event_new_custom (GST_EVENT_TOC_SELECT, structure);
+}
+
+/**
+ * gst_event_parse_toc_select:
+ * @event: a TOC select event.
+ * @uid: (out) (transfer full) (allow-none): storage for the selection UID.
+ *
+ * Parse a TOC select @event and store the results in the given @uid location.
+ */
+void
+gst_event_parse_toc_select (GstEvent * event, gchar ** uid)
+{
+ const GstStructure *structure;
+ const GValue *val;
+
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TOC_SELECT);
+
+ structure = gst_event_get_structure (event);
+ val = gst_structure_id_get_value (structure, GST_QUARK (UID));
+
+ if (uid != NULL)
+ *uid = g_strdup (g_value_get_string (val));
+
+}
+
+/**
+ * gst_event_new_protection:
+ * @system_id: (transfer none): a string holding a UUID that uniquely
+ * identifies a protection system.
+ * @data: (transfer none): a #GstBuffer holding protection system specific
+ * information. The reference count of the buffer will be incremented by one.
+ * @origin: a string indicating where the protection
+ * information carried in the event was extracted from. The allowed values
+ * of this string will depend upon the protection scheme.
+ *
+ * Creates a new event containing information specific to a particular
+ * protection system (uniquely identified by @system_id), by which that
+ * protection system can acquire key(s) to decrypt a protected stream.
+ *
+ * In order for a decryption element to decrypt media
+ * protected using a specific system, it first needs all the
+ * protection system specific information necessary to acquire the decryption
+ * key(s) for that stream. The functions defined here enable this information
+ * to be passed in events from elements that extract it
+ * (e.g., ISOBMFF demuxers, MPEG DASH demuxers) to protection decrypter
+ * elements that use it.
+ *
+ * Events containing protection system specific information are created using
+ * #gst_event_new_protection, and they can be parsed by downstream elements
+ * using #gst_event_parse_protection.
+ *
+ * In Common Encryption, protection system specific information may be located
+ * within ISOBMFF files, both in movie (moov) boxes and movie fragment (moof)
+ * boxes; it may also be contained in ContentProtection elements within MPEG
+ * DASH MPDs. The events created by #gst_event_new_protection contain data
+ * identifying from which of these locations the encapsulated protection system
+ * specific information originated. This origin information is required as
+ * some protection systems use different encodings depending upon where the
+ * information originates.
+ *
+ * The events returned by gst_event_new_protection() are implemented
+ * in such a way as to ensure that the most recently-pushed protection info
+ * event of a particular @origin and @system_id will
+ * be stuck to the output pad of the sending element.
+ *
+ * Returns: a #GST_EVENT_PROTECTION event, if successful; %NULL
+ * if unsuccessful.
+ *
+ * Since: 1.6
+ */
+GstEvent *
+gst_event_new_protection (const gchar * system_id,
+ GstBuffer * data, const gchar * origin)
+{
+ gchar *event_name;
+ GstEvent *event;
+ GstStructure *s;
+
+ g_return_val_if_fail (system_id != NULL, NULL);
+ g_return_val_if_fail (data != NULL, NULL);
+
+ event_name =
+ g_strconcat ("GstProtectionEvent", origin ? "-" : "",
+ origin ? origin : "", "-", system_id, NULL);
+
+ GST_CAT_INFO (GST_CAT_EVENT, "creating protection event %s", event_name);
+
+ s = gst_structure_new (event_name, "data", GST_TYPE_BUFFER, data,
+ "system_id", G_TYPE_STRING, system_id, NULL);
+ if (origin)
+ gst_structure_set (s, "origin", G_TYPE_STRING, origin, NULL);
+ event = gst_event_new_custom (GST_EVENT_PROTECTION, s);
+
+ g_free (event_name);
+ return event;
+}
+
+/**
+ * gst_event_parse_protection:
+ * @event: a #GST_EVENT_PROTECTION event.
+ * @system_id: (out) (allow-none) (transfer none): pointer to store the UUID
+ * string uniquely identifying a content protection system.
+ * @data: (out) (allow-none) (transfer none): pointer to store a #GstBuffer
+ * holding protection system specific information.
+ * @origin: (out) (allow-none) (transfer none): pointer to store a value that
+ * indicates where the protection information carried by @event was extracted
+ * from.
+ *
+ * Parses an event containing protection system specific information and stores
+ * the results in @system_id, @data and @origin. The data stored in @system_id,
+ * @origin and @data are valid until @event is released.
+ *
+ * Since: 1.6
+ */
+void
+gst_event_parse_protection (GstEvent * event, const gchar ** system_id,
+ GstBuffer ** data, const gchar ** origin)
+{
+ const GstStructure *s;
+
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_IS_EVENT (event));
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_PROTECTION);
+
+ s = gst_event_get_structure (event);
+
+ if (origin)
+ *origin = gst_structure_get_string (s, "origin");
+
+ if (system_id)
+ *system_id = gst_structure_get_string (s, "system_id");
+
+ if (data) {
+ const GValue *value = gst_structure_get_value (s, "data");
+ *data = gst_value_get_buffer (value);
+ }
+}
+
+/**
+ * gst_event_new_segment_done:
+ * @format: The format of the position being done
+ * @position: The position of the segment being done
+ *
+ * Create a new segment-done event. This event is sent by elements that
+ * finish playback of a segment as a result of a segment seek.
+ *
+ * Returns: (transfer full): a new #GstEvent
+ */
+GstEvent *
+gst_event_new_segment_done (GstFormat format, gint64 position)
+{
+ GstEvent *event;
+ GstStructure *structure;
+
+ GST_CAT_INFO (GST_CAT_EVENT, "creating segment-done event");
+
+ structure = gst_structure_new_id (GST_QUARK (EVENT_SEGMENT_DONE),
+ GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
+ GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
+
+ event = gst_event_new_custom (GST_EVENT_SEGMENT_DONE, structure);
+
+ return event;
+}
+
+/**
+ * gst_event_parse_segment_done:
+ * @event: A valid #GstEvent of type GST_EVENT_SEGMENT_DONE.
+ * @format: (out) (allow-none): Result location for the format, or %NULL
+ * @position: (out) (allow-none): Result location for the position, or %NULL
+ *
+ * Extracts the position and format from the segment done message.
+ *
+ */
+void
+gst_event_parse_segment_done (GstEvent * event, GstFormat * format,
+ gint64 * position)
+{
+ const GstStructure *structure;
+ const GValue *val;
+
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT_DONE);
+
+ structure = gst_event_get_structure (event);
+
+ val = gst_structure_id_get_value (structure, GST_QUARK (FORMAT));
+ if (format != NULL)
+ *format = g_value_get_enum (val);
+
+ val = gst_structure_id_get_value (structure, GST_QUARK (POSITION));
+ if (position != NULL)
+ *position = g_value_get_int64 (val);
+}