diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2018-05-09 15:28:13 +0300 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2018-06-14 16:18:19 +0300 |
commit | 24a3ee6c535dcc3245a2ff8942a2cec48f69c6e5 (patch) | |
tree | 665fae7fa4890890d89293bb4ed905214ca01388 | |
parent | cba2c7dd89dc4cefebe6592b9b98e6e097bd840e (diff) |
event: Add new GST_EVENT_INSTANT_RATE_CHANGE and GST_SEEK_FLAGS_INSTANT_RATE_CHANGE
A seek with that flag set must be non-flushing, not change the playback
direction and start/stop position. A seek handler will then send the new
GST_EVENT_INSTANT_RATE_CHANGE event downstream for downstream elements
to immediately apply the new playback rate before the new in-band segment
event arrives.
-rw-r--r-- | docs/gst/gstreamer-sections.txt | 3 | ||||
-rw-r--r-- | gst/gstevent.c | 54 | ||||
-rw-r--r-- | gst/gstevent.h | 12 | ||||
-rw-r--r-- | gst/gstquark.c | 2 | ||||
-rw-r--r-- | gst/gstquark.h | 3 | ||||
-rw-r--r-- | gst/gstsegment.h | 11 | ||||
-rw-r--r-- | win32/common/libgstreamer.def | 2 |
7 files changed, 85 insertions, 2 deletions
diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 42c7c4c5f..357546832 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -1236,6 +1236,9 @@ gst_event_parse_stream_collection gst_event_new_stream_group_done gst_event_parse_stream_group_done + +gst_event_new_instant_rate_change +gst_event_parse_instant_rate_change <SUBSECTION Standard> GstEventClass GST_EVENT diff --git a/gst/gstevent.c b/gst/gstevent.c index cb2608872..fb21ea0ab 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -1264,6 +1264,10 @@ gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags, GstStructure *structure; g_return_val_if_fail (rate != 0.0, NULL); + g_return_val_if_fail ((flags & GST_SEEK_FLAG_INSTANT_RATE_CHANGE) == 0 + || (start_type == GST_SEEK_TYPE_NONE + && stop_type == GST_SEEK_TYPE_NONE + && (flags & GST_SEEK_FLAG_FLUSH) == 0), NULL); if (format == GST_FORMAT_TIME) { GST_CAT_INFO (GST_CAT_EVENT, @@ -2105,3 +2109,53 @@ gst_event_parse_segment_done (GstEvent * event, GstFormat * format, if (position != NULL) *position = g_value_get_int64 (val); } + +/** + * gst_event_new_instant_rate_change: + * @rate: the new playback rate to be applied + * + * Create a new instant-rate-change event. This event is sent by seek + * handlers (e.g. demuxers) when receiving a seek with the + * %GST_SEEK_FLAG_INSTANT_RATE_CHANGE and signals to downstream elements that + * the new playback rate should already be applied immediately instead of + * waiting for the following in-band segment event. + * + * Returns: (transfer full): the new instant-rate-change event. + * + * Since: 1.16 + */ +GstEvent * +gst_event_new_instant_rate_change (gdouble rate) +{ + GstEvent *event; + + g_return_val_if_fail (rate != 0.0, NULL); + + GST_CAT_TRACE (GST_CAT_EVENT, "creating instant-rate-change event %lf", rate); + + event = gst_event_new_custom (GST_EVENT_INSTANT_RATE_CHANGE, + gst_structure_new_id (GST_QUARK (EVENT_INSTANT_RATE_CHANGE), + GST_QUARK (RATE), G_TYPE_DOUBLE, rate, NULL)); + + return event; +} + +/** + * gst_event_parse_instant_rate_change: + * @event: a #GstEvent of type #GST_EVENT_INSTANT_RATE_CHANGE + * @rate: (out) (allow-none): location where to store the rate of + * the instant-rate-change event, or %NULL + * + * Extract rate from an instant-rate-change event. + */ +void +gst_event_parse_instant_rate_change (GstEvent * event, gdouble * rate) +{ + GstStructure *structure; + + g_return_if_fail (GST_IS_EVENT (event)); + g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_INSTANT_RATE_CHANGE); + + structure = GST_EVENT_STRUCTURE (event); + gst_structure_id_get (structure, GST_QUARK (RATE), G_TYPE_DOUBLE, rate, NULL); +} diff --git a/gst/gstevent.h b/gst/gstevent.h index 7a36f9a32..f707f68a3 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -163,6 +163,9 @@ typedef enum { GST_EVENT_SEGMENT_DONE = GST_EVENT_MAKE_TYPE (150, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_GAP = GST_EVENT_MAKE_TYPE (160, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), + /* non-sticky downstream non-serialized */ + GST_EVENT_INSTANT_RATE_CHANGE = GST_EVENT_MAKE_TYPE (180, FLAG(DOWNSTREAM)), + /* upstream events */ GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (190, FLAG(UPSTREAM)), GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (200, FLAG(UPSTREAM)), @@ -698,6 +701,15 @@ GstEvent* gst_event_new_segment_done (GstFormat format, gint64 positi GST_API void gst_event_parse_segment_done (GstEvent *event, GstFormat *format, gint64 *position); +/* instant-rate-change event */ + +GST_API +GstEvent * gst_event_new_instant_rate_change (gdouble rate) G_GNUC_MALLOC; + +GST_API +void gst_event_parse_instant_rate_change (GstEvent *event, + gdouble *rate); + #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstEvent, gst_event_unref) #endif diff --git a/gst/gstquark.c b/gst/gstquark.c index 4500cc63d..df06452a8 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -75,7 +75,7 @@ static const gchar *_quark_strings[] = { "GstMessageStreamCollection", "collection", "stream", "stream-collection", "GstMessageStreamsSelected", "GstMessageRedirect", "redirect-entry-locations", "redirect-entry-taglists", "redirect-entry-structures", - "GstEventStreamGroupDone" + "GstEventStreamGroupDone", "GstEventInstantRateChange" }; GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquark.h b/gst/gstquark.h index e41466bae..821b3f883 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -217,7 +217,8 @@ typedef enum _GstQuarkId GST_QUARK_REDIRECT_ENTRY_TAGLISTS = 186, GST_QUARK_REDIRECT_ENTRY_STRUCTURES = 187, GST_QUARK_EVENT_STREAM_GROUP_DONE = 188, - GST_QUARK_MAX = 189 + GST_QUARK_EVENT_INSTANT_RATE_CHANGE = 189, + GST_QUARK_MAX = 190 } GstQuarkId; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstsegment.h b/gst/gstsegment.h index b48d7e7a5..5acdccce7 100644 --- a/gst/gstsegment.h +++ b/gst/gstsegment.h @@ -76,6 +76,10 @@ typedef enum { * @GST_SEEK_FLAG_TRICKMODE_NO_AUDIO: when doing fast forward or fast reverse * playback, request that audio decoder elements skip * decoding and output only gap events or silence. (Since 1.6) + * @GST_SEEK_FLAG_INSTANT_RATE_CHANGE: Signals that a rate change should be + * applied immediately. Only valid if start/stop position + * are GST_CLOCK_TIME_NONE, the playback direction does not change + * and the seek is not flushing. (Since 1.16) * @GST_SEEK_FLAG_SKIP: Deprecated backward compatibility flag, replaced * by %GST_SEEK_FLAG_TRICKMODE * @@ -96,6 +100,12 @@ typedef enum { * continue playback. With this seek method it is possible to perform seamless * looping or simple linear editing. * + * When only changing the playback rate and not the direction, the + * %GST_SEEK_FLAG_INSTANT_RATE_CHANGE flag can be used for a non-flushing seek + * to signal that the rate change should be applied immediately. This requires + * special support in the seek handlers (e.g. demuxers) and any elements + * synchronizing to the clock. + * * When doing fast forward (rate > 1.0) or fast reverse (rate < -1.0) trickmode * playback, the %GST_SEEK_FLAG_TRICKMODE flag can be used to instruct decoders * and demuxers to adjust the playback rate by skipping frames. This can improve @@ -137,6 +147,7 @@ typedef enum { /* Careful to restart next flag with 1<<7 here */ GST_SEEK_FLAG_TRICKMODE_KEY_UNITS = (1 << 7), GST_SEEK_FLAG_TRICKMODE_NO_AUDIO = (1 << 8), + GST_SEEK_FLAG_INSTANT_RATE_CHANGE = (1 << 9), } GstSeekFlags; /** diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 4abfeec55..bee2b6c7b 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -609,6 +609,7 @@ EXPORTS gst_event_new_flush_start gst_event_new_flush_stop gst_event_new_gap + gst_event_new_instant_rate_change gst_event_new_latency gst_event_new_navigation gst_event_new_protection @@ -631,6 +632,7 @@ EXPORTS gst_event_parse_flush_stop gst_event_parse_gap gst_event_parse_group_id + gst_event_parse_instant_rate_change gst_event_parse_latency gst_event_parse_protection gst_event_parse_qos |