summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2018-05-09 15:28:13 +0300
committerSebastian Dröge <sebastian@centricular.com>2018-06-14 16:18:19 +0300
commit24a3ee6c535dcc3245a2ff8942a2cec48f69c6e5 (patch)
tree665fae7fa4890890d89293bb4ed905214ca01388
parentcba2c7dd89dc4cefebe6592b9b98e6e097bd840e (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.txt3
-rw-r--r--gst/gstevent.c54
-rw-r--r--gst/gstevent.h12
-rw-r--r--gst/gstquark.c2
-rw-r--r--gst/gstquark.h3
-rw-r--r--gst/gstsegment.h11
-rw-r--r--win32/common/libgstreamer.def2
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