Commit 63f6f05d authored by Edward Hervey's avatar Edward Hervey 🤘 Committed by Edward Hervey

gst: New Stream listing/selection system

* GstStream
* GstStreamCollection
* GST_EVENT_SELECT_STREAMS
* GST_MESSAGE_STREAM_COLLECTION
parent 241d0f16
This diff is collapsed.
......@@ -99,6 +99,8 @@ Windows. It is released under the GNU Library General Public License
<xi:include href="xml/gstquery.xml" />
<xi:include href="xml/gstregistry.xml" />
<xi:include href="xml/gstsegment.xml" />
<xi:include href="xml/gststreams.xml" />
<xi:include href="xml/gststreamcollection.xml" />
<xi:include href="xml/gststructure.xml" />
<xi:include href="xml/gstsystemclock.xml" />
<xi:include href="xml/gsttaglist.xml" />
......
......@@ -1123,6 +1123,9 @@ gst_event_parse_stream_flags
gst_event_set_group_id
gst_event_parse_group_id
gst_event_set_stream
gst_event_parse_stream
gst_event_new_segment
gst_event_parse_segment
gst_event_copy_segment
......@@ -1169,6 +1172,12 @@ gst_event_parse_segment_done
gst_event_new_protection
gst_event_parse_protection
gst_event_new_select_streams
gst_event_parse_select_streams
gst_event_new_stream_collection
gst_event_parse_stream_collection
<SUBSECTION Standard>
GstEventClass
GST_EVENT
......@@ -1621,6 +1630,8 @@ gst_message_new_stream_start
gst_message_set_group_id
gst_message_parse_group_id
gst_message_new_stream_collection
gst_message_parse_stream_collection
GstStructureChangeType
gst_message_new_structure_change
gst_message_parse_structure_change
......@@ -1649,6 +1660,13 @@ gst_message_parse_device_removed
gst_message_new_property_notify
gst_message_parse_property_notify
gst_message_new_streams_selected
gst_message_parse_streams_selected
gst_message_streams_selected_add
gst_message_streams_selected_get_size
gst_message_streams_selected_get_stream
<SUBSECTION Standard>
GstMessageClass
GST_MESSAGE
......@@ -1977,6 +1995,7 @@ gst_pad_create_stream_id_printf
gst_pad_create_stream_id_printf_valist
gst_pad_get_stream_id
gst_pad_get_stream
GstPadForwardFunction
gst_pad_forward
......@@ -2616,6 +2635,60 @@ gst_segment_flags_get_type
<SUBSECTION Private>
</SECTION>
<SECTION>
<FILE>gststreams</FILE>
<TITLE>GstStream</TITLE>
GstStream
GstStreamClass
GstStreamType
gst_stream_new
gst_stream_get_caps
gst_stream_get_stream_flags
gst_stream_get_stream_id
gst_stream_get_stream_type
gst_stream_get_tags
gst_stream_set_caps
gst_stream_set_stream_flags
gst_stream_set_stream_type
gst_stream_set_tags
gst_stream_type_get_name
<SUBSECTION Standard>
GST_IS_STREAM
GST_IS_STREAM_CLASS
GST_STREAM
GST_STREAM_CAST
GST_STREAM_CLASS
GST_STREAM_GET_CLASS
GST_TYPE_STREAM
GST_TYPE_STREAM_TYPE
gst_stream_get_type
gst_stream_type_get_type
<SUBSECTION Private>
GstStreamPrivate
</SECTION>
<SECTION>
<FILE>gststreamcollection</FILE>
<TITLE>GstStreamCollection</TITLE>
GstStreamCollection
GstStreamCollectionClass
gst_stream_collection_new
gst_stream_collection_add_stream
gst_stream_collection_get_upstream_id
gst_stream_collection_get_size
gst_stream_collection_get_stream
<SUBSECTION Standard>
gst_stream_collection_get_type
GST_IS_STREAM_COLLECTION
GST_IS_STREAM_COLLECTION_CLASS
GST_STREAM_COLLECTION
GST_STREAM_COLLECTION_CAST
GST_STREAM_COLLECTION_CLASS
GST_STREAM_COLLECTION_GET_CLASS
GST_TYPE_STREAM_COLLECTION
<SUBSECTION Private>
GstStreamCollectionPrivate
</SECTION>
<SECTION>
<FILE>gststructure</FILE>
......
......@@ -106,6 +106,8 @@ libgstreamer_@GST_API_VERSION@_la_SOURCES = \
gstregistrychunks.c \
gstsample.c \
gstsegment.c \
gststreamcollection.c \
gststreams.c \
gststructure.c \
gstsystemclock.c \
gsttaglist.c \
......@@ -214,6 +216,8 @@ gst_headers = \
gstquery.h \
gstsample.h \
gstsegment.h \
gststreamcollection.h \
gststreams.h \
gststructure.h \
gstsystemclock.h \
gsttaglist.h \
......
......@@ -684,6 +684,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
g_type_class_ref (gst_lock_flags_get_type ());
g_type_class_ref (gst_allocator_flags_get_type ());
g_type_class_ref (gst_stream_flags_get_type ());
g_type_class_ref (gst_stream_type_get_type ());
_priv_gst_event_initialize ();
_priv_gst_buffer_initialize ();
......@@ -1123,6 +1124,7 @@ gst_deinit (void)
g_type_class_unref (g_type_class_peek (gst_pad_probe_return_get_type ()));
g_type_class_unref (g_type_class_peek (gst_segment_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_scheduling_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_stream_type_get_type ()));
g_type_class_unref (g_type_class_peek (gst_control_binding_get_type ()));
g_type_class_unref (g_type_class_peek (gst_control_source_get_type ()));
......
......@@ -58,6 +58,7 @@
#include <gst/gstmeta.h>
#include <gst/gstminiobject.h>
#include <gst/gstobject.h>
#include <gst/gststreamcollection.h>
#include <gst/gstpad.h>
#include <gst/gstparamspecs.h>
#include <gst/gstpipeline.h>
......@@ -69,6 +70,7 @@
#include <gst/gstregistry.h>
#include <gst/gstsample.h>
#include <gst/gstsegment.h>
#include <gst/gststreams.h>
#include <gst/gststructure.h>
#include <gst/gstsystemclock.h>
#include <gst/gsttaglist.h>
......
......@@ -104,7 +104,9 @@ static GstEventQuarks event_quarks[] = {
{GST_EVENT_UNKNOWN, "unknown", 0},
{GST_EVENT_FLUSH_START, "flush-start", 0},
{GST_EVENT_FLUSH_STOP, "flush-stop", 0},
{GST_EVENT_SELECT_STREAMS, "select-streams", 0},
{GST_EVENT_STREAM_START, "stream-start", 0},
{GST_EVENT_STREAM_COLLECTION, "stream-collection", 0},
{GST_EVENT_CAPS, "caps", 0},
{GST_EVENT_SEGMENT, "segment", 0},
{GST_EVENT_TAG, "tag", 0},
......@@ -575,6 +577,77 @@ gst_event_parse_flush_stop (GstEvent * event, gboolean * reset_time)
GST_QUARK (RESET_TIME)));
}
/**
* gst_event_new_select_streams:
* @streams: (element-type gchar) (transfer none): the list of streams to
* activate
*
* Allocate a new select-streams event.
*
* The select-streams event requests the specified @streams to be activated.
*
* The list of @streams corresponds to the "Stream ID" of each stream to be
* activated. Those ID can be obtained via the #GstStream objects present
* in #GST_EVENT_STREAM_START, #GST_EVENT_STREAM_COLLECTION or
* #GST_MESSSAGE_STREAM_COLLECTION.
*
* Returns: (transfer full): a new select-streams event.
*/
GstEvent *
gst_event_new_select_streams (GList * streams)
{
GstEvent *event;
GValue val = G_VALUE_INIT;
GstStructure *struc;
GList *tmpl;
GST_CAT_INFO (GST_CAT_EVENT, "Creating new select-streams event");
struc = gst_structure_new_id_empty (GST_QUARK (EVENT_SELECT_STREAMS));
g_value_init (&val, GST_TYPE_LIST);
/* Fill struc with streams */
for (tmpl = streams; tmpl; tmpl = tmpl->next) {
GValue strval = G_VALUE_INIT;
const gchar *str = (const gchar *) tmpl->data;
g_value_init (&strval, G_TYPE_STRING);
g_value_set_string (&strval, str);
gst_value_list_append_and_take_value (&val, &strval);
}
gst_structure_id_take_value (struc, GST_QUARK (STREAMS), &val);
event = gst_event_new_custom (GST_EVENT_SELECT_STREAMS, struc);
return event;
}
/**
* gst_event_parse_select_streams:
* @event: The event to parse
* @streams: (out) (element-type gchar) (transfer full): the streams
*
* Parse the SELECT_STREAMS event and retrieve the contained streams.
*/
void
gst_event_parse_select_streams (GstEvent * event, GList ** streams)
{
GstStructure *structure;
GList *res = NULL;
g_return_if_fail (GST_IS_EVENT (event));
g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SELECT_STREAMS);
structure = GST_EVENT_STRUCTURE (event);
if (G_LIKELY (streams)) {
const GValue *vlist =
gst_structure_id_get_value (structure, GST_QUARK (STREAMS));
guint i, sz = gst_value_list_get_size (vlist);
for (i = 0; i < sz; i++) {
const GValue *strv = gst_value_list_get_value (vlist, i);
res = g_list_append (res, g_value_dup_string (strv));
}
*streams = res;
}
}
/**
* gst_event_new_eos:
*
......@@ -1507,6 +1580,44 @@ gst_event_parse_stream_start (GstEvent * event, const gchar ** 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
**/
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): adress of variable to store the stream
*
* Parse a stream-start @event and extract the #GstStream from it.
**/
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
......@@ -1595,6 +1706,52 @@ gst_event_parse_group_id (GstEvent * event, guint * group_id)
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.
*/
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);
}
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.
......
......@@ -79,6 +79,7 @@ typedef enum {
* from the pipeline and unblock all streaming threads.
* @GST_EVENT_FLUSH_STOP: Stop a flush operation. This event resets the
* running-time of the pipeline.
* @GST_EVENT_SELECT_STREAMS: A request to select one or more streams.
* @GST_EVENT_STREAM_START: Event to mark the start of a new stream. Sent before any
* other serialized event and only sent at the start of a new stream,
* not after flushing seeks.
......@@ -87,6 +88,7 @@ typedef enum {
* segment events contains information for clipping buffers and
* converting buffer timestamps to running-time and
* stream-time.
* @GST_EVENT_STREAM_COLLECTION: A new #GstStreamCollection is available.
* @GST_EVENT_TAG: A new set of metadata tags has been found in the stream.
* @GST_EVENT_BUFFERSIZE: Notification of buffering requirements. Currently not
* used yet.
......@@ -94,7 +96,8 @@ typedef enum {
* send messages that should be emitted in sync with
* rendering.
* @GST_EVENT_EOS: End-Of-Stream. No more data is to be expected to follow
* without a SEGMENT event.
* without either a STREAM_START event, or a FLUSH_STOP and a SEGMENT
* event.
* @GST_EVENT_SEGMENT_DONE: Marks the end of a segment playback.
* @GST_EVENT_GAP: Marks a gap in the datastream.
* @GST_EVENT_TOC: An event which indicates that a new table of contents (TOC)
......@@ -144,6 +147,7 @@ typedef enum {
GST_EVENT_STREAM_START = GST_EVENT_MAKE_TYPE (40, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_CAPS = GST_EVENT_MAKE_TYPE (50, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_SEGMENT = GST_EVENT_MAKE_TYPE (70, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_STREAM_COLLECTION = GST_EVENT_MAKE_TYPE (75, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)),
GST_EVENT_TAG = GST_EVENT_MAKE_TYPE (80, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)),
GST_EVENT_BUFFERSIZE = GST_EVENT_MAKE_TYPE (90, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (100, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)),
......@@ -163,6 +167,7 @@ typedef enum {
GST_EVENT_STEP = GST_EVENT_MAKE_TYPE (230, FLAG(UPSTREAM)),
GST_EVENT_RECONFIGURE = GST_EVENT_MAKE_TYPE (240, FLAG(UPSTREAM)),
GST_EVENT_TOC_SELECT = GST_EVENT_MAKE_TYPE (250, FLAG(UPSTREAM)),
GST_EVENT_SELECT_STREAMS = GST_EVENT_MAKE_TYPE (260, FLAG(UPSTREAM)),
/* custom events start here */
GST_EVENT_CUSTOM_UPSTREAM = GST_EVENT_MAKE_TYPE (270, FLAG(UPSTREAM)),
......@@ -174,6 +179,30 @@ typedef enum {
} GstEventType;
#undef FLAG
/**
* GstStreamFlags:
* @GST_STREAM_FLAG_NONE: This stream has no special attributes
* @GST_STREAM_FLAG_SPARSE: This stream is a sparse stream (e.g. a subtitle
* stream), data may flow only in irregular intervals with large gaps in
* between.
* @GST_STREAM_FLAG_SELECT: This stream should be selected by default. This
* flag may be used by demuxers to signal that a stream should be selected
* by default in a playback scenario.
* @GST_STREAM_FLAG_UNSELECT: This stream should not be selected by default.
* This flag may be used by demuxers to signal that a stream should not
* be selected by default in a playback scenario, but only if explicitly
* selected by the user (e.g. an audio track for the hard of hearing or
* a director's commentary track).
*
* Since: 1.2
*/
typedef enum {
GST_STREAM_FLAG_NONE,
GST_STREAM_FLAG_SPARSE = (1 << 0),
GST_STREAM_FLAG_SELECT = (1 << 1),
GST_STREAM_FLAG_UNSELECT = (1 << 2)
} GstStreamFlags;
#include <gst/gstminiobject.h>
#include <gst/gstformat.h>
#include <gst/gstobject.h>
......@@ -355,29 +384,6 @@ typedef enum {
GST_QOS_TYPE_THROTTLE = 2
} GstQOSType;
/**
* GstStreamFlags:
* @GST_STREAM_FLAG_NONE: This stream has no special attributes
* @GST_STREAM_FLAG_SPARSE: This stream is a sparse stream (e.g. a subtitle
* stream), data may flow only in irregular intervals with large gaps in
* between.
* @GST_STREAM_FLAG_SELECT: This stream should be selected by default. This
* flag may be used by demuxers to signal that a stream should be selected
* by default in a playback scenario.
* @GST_STREAM_FLAG_UNSELECT: This stream should not be selected by default.
* This flag may be used by demuxers to signal that a stream should not
* be selected by default in a playback scenario, but only if explicitly
* selected by the user (e.g. an audio track for the hard of hearing or
* a director's commentary track).
*
* Since: 1.2
*/
typedef enum {
GST_STREAM_FLAG_NONE,
GST_STREAM_FLAG_SPARSE = (1 << 0),
GST_STREAM_FLAG_SELECT = (1 << 1),
GST_STREAM_FLAG_UNSELECT = (1 << 2)
} GstStreamFlags;
/**
* GstEvent:
......@@ -467,6 +473,8 @@ void gst_event_set_running_time_offset (GstEvent *event, gint64 offse
/* Stream start event */
GstEvent * gst_event_new_stream_start (const gchar *stream_id) G_GNUC_MALLOC;
void gst_event_parse_stream_start (GstEvent *event, const gchar **stream_id);
void gst_event_set_stream (GstEvent *event, GstStream *stream);
void gst_event_parse_stream (GstEvent *event, GstStream **stream);
void gst_event_set_stream_flags (GstEvent *event, GstStreamFlags flags);
void gst_event_parse_stream_flags (GstEvent *event, GstStreamFlags *flags);
......@@ -480,6 +488,14 @@ GstEvent * gst_event_new_flush_start (void) G_GNUC_MALLOC;
GstEvent * gst_event_new_flush_stop (gboolean reset_time) G_GNUC_MALLOC;
void gst_event_parse_flush_stop (GstEvent *event, gboolean *reset_time);
/* Stream collection event */
GstEvent * gst_event_new_stream_collection (GstStreamCollection *collection) G_GNUC_MALLOC;
void gst_event_parse_stream_collection (GstEvent *event, GstStreamCollection **collection);
/* select streams event */
GstEvent * gst_event_new_select_streams (GList *streams);
void gst_event_parse_select_streams (GstEvent *event, GList **streams);
/* EOS event */
GstEvent * gst_event_new_eos (void) G_GNUC_MALLOC;
......
......@@ -52,6 +52,7 @@
#include "gsttaglist.h"
#include "gstutils.h"
#include "gstquark.h"
#include "gstvalue.h"
typedef struct
......@@ -106,6 +107,8 @@ static GstMessageQuarks message_quarks[] = {
{GST_MESSAGE_DEVICE_ADDED, "device-added", 0},
{GST_MESSAGE_DEVICE_REMOVED, "device-removed", 0},
{GST_MESSAGE_PROPERTY_NOTIFY, "property-notify", 0},
{GST_MESSAGE_STREAM_COLLECTION, "stream-collection", 0},
{GST_MESSAGE_STREAMS_SELECTED, "streams-selected", 0},
{0, NULL, 0}
};
......@@ -2522,3 +2525,198 @@ gst_message_parse_property_notify (GstMessage * message, GstObject ** object,
*property_value =
gst_structure_id_get_value (s, GST_QUARK (PROPERTY_VALUE));
}
/**
* gst_message_new_stream_collection:
* @src: The #GstObject that created the message
* @collection: (transfer none): The #GstStreamCollection
*
* Creates a new stream-collection message. The message is used to announce new
* #GstStreamCollection
*
* Returns: a newly allocated #GstMessage
*
* Since: 1.x
*/
GstMessage *
gst_message_new_stream_collection (GstObject * src,
GstStreamCollection * collection)
{
GstMessage *message;
GstStructure *structure;
g_return_val_if_fail (collection != NULL, NULL);
g_return_val_if_fail (GST_IS_STREAM_COLLECTION (collection), NULL);
structure =
gst_structure_new_id (GST_QUARK (MESSAGE_STREAM_COLLECTION),
GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
message =
gst_message_new_custom (GST_MESSAGE_STREAM_COLLECTION, src, structure);
return message;
}
/**
* gst_message_parse_stream_collection:
* @message: a #GstMessage of type %GST_MESSAGE_STREAM_COLLECTION
* @collection: (out) (allow-none) (transfer none): A location where to store a
* pointer to the #GstStreamCollection, or %NULL
*
* Parses a stream-collection message.
*
* Since: 1.x
*/
void
gst_message_parse_stream_collection (GstMessage * message,
GstStreamCollection ** collection)
{
g_return_if_fail (GST_IS_MESSAGE (message));
g_return_if_fail (GST_MESSAGE_TYPE (message) ==
GST_MESSAGE_STREAM_COLLECTION);
if (collection)
gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
}
/**
* gst_message_new_streams_selected:
* @src: The #GstObject that created the message
* @collection: (transfer none): The #GstStreamCollection
*
* Creates a new steams-selected message. The message is used to announce
* that an array of streams has been selected. This is generally in response
* to a #GST_EVENT_SELECT_STREAMS event, or when an element (such as decodebin3)
* makes an initial selection of streams.
*
* The message also contains the #GstStreamCollection to which the various streams
* belong to.
*
* Users of gst_message_new_streams_selected() can add the selected streams with
* gst_message_streams_selected_add().
*
* Returns: a newly allocated #GstMessage
*
* Since: 1.x
*/
GstMessage *
gst_message_new_streams_selected (GstObject * src,
GstStreamCollection * collection)
{
GstMessage *message;
GstStructure *structure;
GValue val = G_VALUE_INIT;
g_return_val_if_fail (collection != NULL, NULL);
g_return_val_if_fail (GST_IS_STREAM_COLLECTION (collection), NULL);
structure =
gst_structure_new_id (GST_QUARK (MESSAGE_STREAMS_SELECTED),
GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
g_value_init (&val, GST_TYPE_ARRAY);
gst_structure_id_take_value (structure, GST_QUARK (STREAMS), &val);
message =
gst_message_new_custom (GST_MESSAGE_STREAMS_SELECTED, src, structure);
return message;
}
/**
* gst_message_streams_selected_get_size:
* @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
*
* Returns the number of streams contained in the @message.
*
* Returns: The number of streams contained within.
*/
guint
gst_message_streams_selected_get_size (GstMessage * msg)
{
const GValue *val;
g_return_val_if_fail (GST_IS_MESSAGE (msg), 0);
g_return_val_if_fail (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAMS_SELECTED,
0);
val =
gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (msg),
GST_QUARK (STREAMS));
return gst_value_array_get_size (val);
}
/**
* gst_message_streams_selected_add:
* @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
* @stream: (transfer none): a #GstStream to add to @message
*
* Adds the @stream to the @message.
*/
void
gst_message_streams_selected_add (GstMessage * msg, GstStream * stream)
{
GValue *val;
GValue to_add = G_VALUE_INIT;
g_return_if_fail (GST_IS_MESSAGE (msg));
g_return_if_fail (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAMS_SELECTED);
g_return_if_fail (GST_IS_STREAM (stream));
val =
(GValue *) gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (msg),
GST_QUARK (STREAMS));
g_value_init (&to_add, GST_TYPE_STREAM);
g_value_set_object (&to_add, stream);
gst_value_array_append_and_take_value (val, &to_add);
}
/**
* gst_message_streams_selected_get_stream:
* @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
* @idx: Index of the stream to retrieve
*
* Retrieves the #GstStream with index @index from the @message.
*
* Returns: (transfer full): A #GstStream
*/
GstStream *
gst_message_streams_selected_get_stream (GstMessage * msg, guint idx)