Commit 9fd2101b authored by Jan Schmidt's avatar Jan Schmidt

events: Implement the stream-group-done event

A new event which precedes EOS in situations where we
need downstream to unblock any pads waiting on a stream
before we can send EOS. E.g, decodebin draining a chain
so it can switch pads.

https://bugzilla.gnome.org/show_bug.cgi?id=768995
parent eead9cf8
...@@ -1183,6 +1183,9 @@ gst_event_parse_select_streams ...@@ -1183,6 +1183,9 @@ gst_event_parse_select_streams
gst_event_new_stream_collection gst_event_new_stream_collection
gst_event_parse_stream_collection gst_event_parse_stream_collection
gst_event_new_stream_group_done
gst_event_parse_stream_group_done
<SUBSECTION Standard> <SUBSECTION Standard>
GstEventClass GstEventClass
GST_EVENT GST_EVENT
......
...@@ -130,6 +130,7 @@ static GstEventQuarks event_quarks[] = { ...@@ -130,6 +130,7 @@ static GstEventQuarks event_quarks[] = {
{GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, "custom-downstream-sticky", 0}, {GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, "custom-downstream-sticky", 0},
{GST_EVENT_CUSTOM_BOTH, "custom-both", 0}, {GST_EVENT_CUSTOM_BOTH, "custom-both", 0},
{GST_EVENT_CUSTOM_BOTH_OOB, "custom-both-oob", 0}, {GST_EVENT_CUSTOM_BOTH_OOB, "custom-both-oob", 0},
{GST_EVENT_STREAM_GROUP_DONE, "stream-group-done", 0},
{0, NULL, 0} {0, NULL, 0}
}; };
...@@ -652,6 +653,57 @@ gst_event_parse_select_streams (GstEvent * event, GList ** streams) ...@@ -652,6 +653,57 @@ gst_event_parse_select_streams (GstEvent * event, GList ** streams)
} }
/**
* gst_event_new_stream_group_done:
* @group_id: the group id of the stream group which is ending
*
* Create a new Stream Group Done event. The stream-group-done event can
* only travel downstream synchronized with the buffer flow. Elements
* that receive the event on a pad should handle it mostly like EOS,
* and emit any data or pending buffers that would depend on more data
* arriving and unblock, since there won't be any more data.
*
* This event is followed by EOS at some point in the future, and is
* generally used when switching pads - to unblock downstream so that
* new pads can be exposed before sending EOS on the existing pads.
*
* Returns: (transfer full): the new stream-group-done event.
*
* Since: 1.10
*/
GstEvent *
gst_event_new_stream_group_done (guint group_id)
{
GstStructure *s;
s = gst_structure_new_id (GST_QUARK (EVENT_STREAM_GROUP_DONE),
GST_QUARK (GROUP_ID), G_TYPE_UINT, group_id, NULL);
return gst_event_new_custom (GST_EVENT_STREAM_GROUP_DONE, s);
}
/**
* gst_event_parse_stream_group_done:
* @event: a stream-group-done event.
* @group_id: (out): address of variable to store the group id into
*
* Parse a stream-group-done @event and store the result in the given
* @group_id location.
*
* Since: 1.10
*/
void
gst_event_parse_stream_group_done (GstEvent * event, guint * group_id)
{
g_return_if_fail (event != NULL);
g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_GROUP_DONE);
if (group_id) {
gst_structure_id_get (GST_EVENT_STRUCTURE (event),
GST_QUARK (GROUP_ID), G_TYPE_UINT, group_id, NULL);
}
}
/** /**
* gst_event_new_eos: * gst_event_new_eos:
* *
......
...@@ -95,6 +95,9 @@ typedef enum { ...@@ -95,6 +95,9 @@ typedef enum {
* @GST_EVENT_SINK_MESSAGE: An event that sinks turn into a message. Used to * @GST_EVENT_SINK_MESSAGE: An event that sinks turn into a message. Used to
* send messages that should be emitted in sync with * send messages that should be emitted in sync with
* rendering. * rendering.
* @GST_EVENT_STREAM_GROUP_DONE: Indicates that there is no more data for
* the stream group ID in the message. Sent before EOS
* in some instances and should be handled mostly the same. (Since 1.10)
* @GST_EVENT_EOS: End-Of-Stream. No more data is to be expected to follow * @GST_EVENT_EOS: End-Of-Stream. No more data is to be expected to follow
* without either a STREAM_START event, or a FLUSH_STOP and a SEGMENT * without either a STREAM_START event, or a FLUSH_STOP and a SEGMENT
* event. * event.
...@@ -151,6 +154,7 @@ typedef enum { ...@@ -151,6 +154,7 @@ typedef enum {
GST_EVENT_TAG = GST_EVENT_MAKE_TYPE (80, 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_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)), GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (100, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)),
GST_EVENT_STREAM_GROUP_DONE = GST_EVENT_MAKE_TYPE (105, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (110, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)), GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (110, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_TOC = GST_EVENT_MAKE_TYPE (120, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)), GST_EVENT_TOC = GST_EVENT_MAKE_TYPE (120, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)),
GST_EVENT_PROTECTION = GST_EVENT_MAKE_TYPE (130, FLAG (DOWNSTREAM) | FLAG (SERIALIZED) | FLAG (STICKY) | FLAG (STICKY_MULTI)), GST_EVENT_PROTECTION = GST_EVENT_MAKE_TYPE (130, FLAG (DOWNSTREAM) | FLAG (SERIALIZED) | FLAG (STICKY) | FLAG (STICKY_MULTI)),
...@@ -496,6 +500,10 @@ void gst_event_parse_stream_collection (GstEvent *event, GstStreamCol ...@@ -496,6 +500,10 @@ void gst_event_parse_stream_collection (GstEvent *event, GstStreamCol
GstEvent * gst_event_new_select_streams (GList *streams); GstEvent * gst_event_new_select_streams (GList *streams);
void gst_event_parse_select_streams (GstEvent *event, GList **streams); void gst_event_parse_select_streams (GstEvent *event, GList **streams);
/* stream-group-done event */
GstEvent * gst_event_new_stream_group_done (const guint group_id) G_GNUC_MALLOC;
void gst_event_parse_stream_group_done (GstEvent *event, guint *group_id);
/* EOS event */ /* EOS event */
GstEvent * gst_event_new_eos (void) G_GNUC_MALLOC; GstEvent * gst_event_new_eos (void) G_GNUC_MALLOC;
......
...@@ -5035,8 +5035,9 @@ store_sticky_event (GstPad * pad, GstEvent * event) ...@@ -5035,8 +5035,9 @@ store_sticky_event (GstPad * pad, GstEvent * event)
/* Unset the EOS flag when received STREAM_START event, so pad can /* Unset the EOS flag when received STREAM_START event, so pad can
* store sticky event and then push it later */ * store sticky event and then push it later */
if (type == GST_EVENT_STREAM_START) { if (type == GST_EVENT_STREAM_START) {
GST_LOG_OBJECT (pad, "Removing pending EOS events"); GST_LOG_OBJECT (pad, "Removing pending EOS and StreamGroupDone events");
remove_event_by_type (pad, GST_EVENT_EOS); remove_event_by_type (pad, GST_EVENT_EOS);
remove_event_by_type (pad, GST_EVENT_STREAM_GROUP_DONE);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS); GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
} }
...@@ -5202,6 +5203,7 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event, ...@@ -5202,6 +5203,7 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
/* Remove sticky EOS events */ /* Remove sticky EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS events"); GST_LOG_OBJECT (pad, "Removing pending EOS events");
remove_event_by_type (pad, GST_EVENT_EOS); remove_event_by_type (pad, GST_EVENT_EOS);
remove_event_by_type (pad, GST_EVENT_STREAM_GROUP_DONE);
remove_event_by_type (pad, GST_EVENT_SEGMENT); remove_event_by_type (pad, GST_EVENT_SEGMENT);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS); GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
pad->ABI.abi.last_flowret = GST_FLOW_OK; pad->ABI.abi.last_flowret = GST_FLOW_OK;
...@@ -5526,6 +5528,7 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event, ...@@ -5526,6 +5528,7 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
/* Remove pending EOS events */ /* Remove pending EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS and SEGMENT events"); GST_LOG_OBJECT (pad, "Removing pending EOS and SEGMENT events");
remove_event_by_type (pad, GST_EVENT_EOS); remove_event_by_type (pad, GST_EVENT_EOS);
remove_event_by_type (pad, GST_EVENT_STREAM_GROUP_DONE);
remove_event_by_type (pad, GST_EVENT_SEGMENT); remove_event_by_type (pad, GST_EVENT_SEGMENT);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS); GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
pad->ABI.abi.last_flowret = GST_FLOW_OK; pad->ABI.abi.last_flowret = GST_FLOW_OK;
...@@ -5553,6 +5556,7 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event, ...@@ -5553,6 +5556,7 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
/* Remove sticky EOS events */ /* Remove sticky EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS events"); GST_LOG_OBJECT (pad, "Removing pending EOS events");
remove_event_by_type (pad, GST_EVENT_EOS); remove_event_by_type (pad, GST_EVENT_EOS);
remove_event_by_type (pad, GST_EVENT_STREAM_GROUP_DONE);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS); GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
break; break;
default: default:
......
...@@ -74,7 +74,8 @@ static const gchar *_quark_strings[] = { ...@@ -74,7 +74,8 @@ static const gchar *_quark_strings[] = {
"property-value", "streams", "GstEventSelectStreams", "property-value", "streams", "GstEventSelectStreams",
"GstMessageStreamCollection", "collection", "stream", "stream-collection", "GstMessageStreamCollection", "collection", "stream", "stream-collection",
"GstMessageStreamsSelected", "GstMessageRedirect", "redirect-entry-locations", "GstMessageStreamsSelected", "GstMessageRedirect", "redirect-entry-locations",
"redirect-entry-taglists", "redirect-entry-structures" "redirect-entry-taglists", "redirect-entry-structures",
"GstEventStreamGroupDone"
}; };
GQuark _priv_gst_quark_table[GST_QUARK_MAX]; GQuark _priv_gst_quark_table[GST_QUARK_MAX];
......
...@@ -216,7 +216,8 @@ typedef enum _GstQuarkId ...@@ -216,7 +216,8 @@ typedef enum _GstQuarkId
GST_QUARK_REDIRECT_ENTRY_LOCATIONS = 185, GST_QUARK_REDIRECT_ENTRY_LOCATIONS = 185,
GST_QUARK_REDIRECT_ENTRY_TAGLISTS = 186, GST_QUARK_REDIRECT_ENTRY_TAGLISTS = 186,
GST_QUARK_REDIRECT_ENTRY_STRUCTURES = 187, GST_QUARK_REDIRECT_ENTRY_STRUCTURES = 187,
GST_QUARK_MAX = 188 GST_QUARK_EVENT_STREAM_GROUP_DONE = 188,
GST_QUARK_MAX = 189
} GstQuarkId; } GstQuarkId;
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
......
...@@ -52,6 +52,7 @@ GST_START_TEST (create_events) ...@@ -52,6 +52,7 @@ GST_START_TEST (create_events)
fail_unless (reset_time == TRUE); fail_unless (reset_time == TRUE);
gst_event_unref (event); gst_event_unref (event);
} }
/* SELECT_STREAMS */ /* SELECT_STREAMS */
{ {
GList *streams = NULL; GList *streams = NULL;
...@@ -77,6 +78,22 @@ GST_START_TEST (create_events) ...@@ -77,6 +78,22 @@ GST_START_TEST (create_events)
g_list_free (streams); g_list_free (streams);
g_list_free_full (res, g_free); g_list_free_full (res, g_free);
} }
/* STREAM_GROUP_DONE */
{
guint group_id = 0;
event = gst_event_new_stream_group_done (0x42);
fail_if (event == NULL);
fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_GROUP_DONE);
fail_if (GST_EVENT_IS_UPSTREAM (event));
fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
fail_unless (GST_EVENT_IS_SERIALIZED (event));
gst_event_parse_stream_group_done (event, &group_id);
fail_unless (group_id == 0x42);
gst_event_unref (event);
}
/* EOS */ /* EOS */
{ {
event = gst_event_new_eos (); event = gst_event_new_eos ();
......
...@@ -594,6 +594,7 @@ EXPORTS ...@@ -594,6 +594,7 @@ EXPORTS
gst_event_new_sink_message gst_event_new_sink_message
gst_event_new_step gst_event_new_step
gst_event_new_stream_collection gst_event_new_stream_collection
gst_event_new_stream_group_done
gst_event_new_stream_start gst_event_new_stream_start
gst_event_new_tag gst_event_new_tag
gst_event_new_toc gst_event_new_toc
...@@ -615,6 +616,7 @@ EXPORTS ...@@ -615,6 +616,7 @@ EXPORTS
gst_event_parse_stream gst_event_parse_stream
gst_event_parse_stream_collection gst_event_parse_stream_collection
gst_event_parse_stream_flags gst_event_parse_stream_flags
gst_event_parse_stream_group_done
gst_event_parse_stream_start gst_event_parse_stream_start
gst_event_parse_tag gst_event_parse_tag
gst_event_parse_toc gst_event_parse_toc
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment