From 75d9454bf41c6637ab84cf7d151d8807bb30a96e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 22 Jul 2013 11:41:35 +0200 Subject: [PATCH] gst: Add new group-id field to the stream-start event 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. --- docs/gst/gstreamer-sections.txt | 6 ++++ gst/gstevent.c | 51 ++++++++++++++++++++++++++++ gst/gstevent.h | 3 ++ gst/gstmessage.c | 73 ++++++++++++++++++++++++++++++++++++++++- gst/gstmessage.h | 3 ++ gst/gstquark.c | 3 +- gst/gstquark.h | 4 ++- gst/gstutils.c | 17 ++++++++++ gst/gstutils.h | 1 + win32/common/libgstreamer.def | 10 ++++-- 10 files changed, 166 insertions(+), 5 deletions(-) diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 7d9253c..9e9b5c6 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -1054,6 +1054,8 @@ gst_event_new_stream_start gst_event_parse_stream_start gst_event_set_stream_flags gst_event_parse_stream_flags +gst_event_set_group_id +gst_event_parse_group_id gst_event_new_segment gst_event_parse_segment @@ -1530,7 +1532,10 @@ gst_message_new_toc gst_message_parse_toc gst_message_new_reset_time gst_message_parse_reset_time + gst_message_new_stream_start +gst_message_set_group_id +gst_message_parse_group_id GstStructureChangeType gst_message_new_structure_change @@ -3061,6 +3066,7 @@ gst_util_fraction_add gst_util_fraction_compare gst_util_seqnum_next gst_util_seqnum_compare +gst_util_group_id_next gst_util_set_object_arg gst_util_set_value_from_string gst_util_get_timestamp diff --git a/gst/gstevent.c b/gst/gstevent.c index 0874471..f47c928 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -1474,6 +1474,57 @@ gst_event_parse_stream_flags (GstEvent * event, GstStreamFlags * flags) } /** + * 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_toc: * @toc: (transfer none): #GstToc structure. * @updated: whether @toc was updated or not. diff --git a/gst/gstevent.h b/gst/gstevent.h index 1c4104f..f4723ec 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -492,6 +492,9 @@ void gst_event_parse_stream_start (GstEvent *event, const gchar ** void gst_event_set_stream_flags (GstEvent *event, GstStreamFlags flags); void gst_event_parse_stream_flags (GstEvent *event, GstStreamFlags *flags); +void gst_event_set_group_id (GstEvent *event, guint group_id); +gboolean gst_event_parse_group_id (GstEvent *event, guint *group_id); + /* flush events */ GstEvent * gst_event_new_flush_start (void) G_GNUC_MALLOC; diff --git a/gst/gstmessage.c b/gst/gstmessage.c index bea9860..7ed646b 100644 --- a/gst/gstmessage.c +++ b/gst/gstmessage.c @@ -2146,12 +2146,83 @@ GstMessage * gst_message_new_stream_start (GstObject * src) { GstMessage *message; + GstStructure *s; - message = gst_message_new_custom (GST_MESSAGE_STREAM_START, src, NULL); + s = gst_structure_new_id_empty (GST_QUARK (MESSAGE_STREAM_START)); + message = gst_message_new_custom (GST_MESSAGE_STREAM_START, src, s); return message; } + +/** + * gst_message_set_group_id: + * @message: the message + * @group_id: the group id + * + * Sets the group id on the stream-start message. + * + * 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. + * + * MT safe. + * + * Since: 1.2 + */ +void +gst_message_set_group_id (GstMessage * message, guint group_id) +{ + GstStructure *structure; + + g_return_if_fail (GST_IS_MESSAGE (message)); + g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_START); + g_return_if_fail (gst_message_is_writable (message)); + + structure = GST_MESSAGE_STRUCTURE (message); + gst_structure_id_set (structure, GST_QUARK (GROUP_ID), G_TYPE_UINT, group_id, + NULL); +} + +/** + * gst_message_parse_group_id: + * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_START. + * @group_id: (out) (allow-none): Result location for the group id or + * NULL + * + * Extract the group from the STREAM_START message. + * + * Returns: %TRUE if the message had a group id set, %FALSE otherwise + * + * MT safe. + * + * Since: 1.2 + */ +gboolean +gst_message_parse_group_id (GstMessage * message, guint * group_id) +{ + GstStructure *structure; + const GValue *v; + + g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE); + g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_START, + FALSE); + + if (!group_id) + return TRUE; + + structure = GST_MESSAGE_STRUCTURE (message); + + v = gst_structure_id_get_value (structure, GST_QUARK (GROUP_ID)); + if (!v) + return FALSE; + + *group_id = g_value_get_uint (v); + return TRUE; +} + /** * gst_message_new_need_context: * @src: (transfer none): The object originating the message. diff --git a/gst/gstmessage.h b/gst/gstmessage.h index 66ad662..e359187 100644 --- a/gst/gstmessage.h +++ b/gst/gstmessage.h @@ -561,6 +561,9 @@ void gst_message_parse_reset_time (GstMessage *message, GstClockTi /* STREAM_START */ GstMessage * gst_message_new_stream_start (GstObject * src) G_GNUC_MALLOC; +void gst_message_set_group_id (GstMessage *message, guint group_id); +gboolean gst_message_parse_group_id (GstMessage *message, guint *group_id); + /* NEED_CONTEXT */ GstMessage * gst_message_new_need_context (GstObject * src) G_GNUC_MALLOC; void gst_message_add_context_type (GstMessage * message, const gchar * context_type); diff --git a/gst/gstquark.c b/gst/gstquark.c index 6343726..b3b6214 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -67,7 +67,8 @@ static const gchar *_quark_strings[] = { "GstMessageToc", "GstEventTocGlobal", "GstEventTocCurrent", "GstEventSegmentDone", "GstEventStreamStart", "stream-id", "GstEventContext", "GstQueryContext", - "GstMessageNeedContext", "GstMessageHaveContext", "context", "context-types" + "GstMessageNeedContext", "GstMessageHaveContext", "context", "context-types", + "GstMessageStreamStart", "group-id" }; GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquark.h b/gst/gstquark.h index 1abc2ee..cfa7e3f 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -194,7 +194,9 @@ typedef enum _GstQuarkId GST_QUARK_MESSAGE_HAVE_CONTEXT = 165, GST_QUARK_CONTEXT = 166, GST_QUARK_CONTEXT_TYPES = 167, - GST_QUARK_MAX = 168 + GST_QUARK_MESSAGE_STREAM_START = 168, + GST_QUARK_GROUP_ID = 169, + GST_QUARK_MAX = 170 } GstQuarkId; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstutils.c b/gst/gstutils.c index 454c7fa..ece5abe 100644 --- a/gst/gstutils.c +++ b/gst/gstutils.c @@ -3752,3 +3752,20 @@ gst_pad_get_stream_id (GstPad * pad) return ret; } + +/** + * gst_util_group_id_next: + * + * Return a constantly incrementing group id. + * + * This function is used to generate a new group-id for the + * stream-start event. + * + * Returns: A constantly incrementing unsigned integer, which might + * overflow back to 0 at some point. */ +guint +gst_util_group_id_next (void) +{ + static gint counter = 0; + return g_atomic_int_add (&counter, 1); +} diff --git a/gst/gstutils.h b/gst/gstutils.h index 54b7e45..1530807 100644 --- a/gst/gstutils.h +++ b/gst/gstutils.h @@ -75,6 +75,7 @@ guint64 gst_util_uint64_scale_int_ceil (guint64 val, gint num, gint den guint32 gst_util_seqnum_next (void); gint32 gst_util_seqnum_compare (guint32 s1, guint32 s2); +guint gst_util_group_id_next (void); /** * GST_CALL_PARENT: diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 6cdb907..55a3616 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -358,9 +358,11 @@ EXPORTS gst_debug_category_reset_threshold gst_debug_category_set_threshold gst_debug_color_flags_get_type + gst_debug_color_mode_get_type gst_debug_construct_term_color gst_debug_construct_win_color gst_debug_get_all_categories + gst_debug_get_color_mode gst_debug_get_default_threshold gst_debug_graph_details_get_type gst_debug_is_active @@ -375,10 +377,9 @@ EXPORTS gst_debug_remove_log_function gst_debug_remove_log_function_by_data gst_debug_set_active - gst_debug_set_colored gst_debug_set_color_mode - gst_debug_get_color_mode gst_debug_set_color_mode_from_string + gst_debug_set_colored gst_debug_set_default_threshold gst_debug_set_threshold_for_name gst_debug_set_threshold_from_string @@ -502,6 +503,7 @@ EXPORTS gst_event_parse_context gst_event_parse_flush_stop gst_event_parse_gap + gst_event_parse_group_id gst_event_parse_latency gst_event_parse_qos gst_event_parse_seek @@ -514,6 +516,7 @@ EXPORTS gst_event_parse_tag gst_event_parse_toc gst_event_parse_toc_select + gst_event_set_group_id gst_event_set_seqnum gst_event_set_stream_flags gst_event_type_flags_get_type @@ -632,6 +635,7 @@ EXPORTS gst_message_parse_clock_lost gst_message_parse_clock_provide gst_message_parse_error + gst_message_parse_group_id gst_message_parse_have_context gst_message_parse_info gst_message_parse_new_clock @@ -653,6 +657,7 @@ EXPORTS gst_message_parse_toc gst_message_parse_warning gst_message_set_buffering_stats + gst_message_set_group_id gst_message_set_qos_stats gst_message_set_qos_values gst_message_set_seqnum @@ -1290,6 +1295,7 @@ EXPORTS gst_util_get_timestamp gst_util_greatest_common_divisor gst_util_greatest_common_divisor_int64 + gst_util_group_id_next gst_util_guint64_to_gdouble gst_util_seqnum_compare gst_util_seqnum_next -- 2.7.4