diff options
author | Mathieu Duponchelle <mathieu@centricular.com> | 2019-04-01 18:34:07 +0200 |
---|---|---|
committer | Mathieu Duponchelle <mduponchelle1@gmail.com> | 2019-04-01 17:13:32 +0000 |
commit | 2fa15d53717c46619efb3011e7e61284483424a0 (patch) | |
tree | c705eed88a311f2d9c103e48c4459174df6b1ab2 | |
parent | 763d01f43755175410ca10f4c7b3af50c0cbc61e (diff) |
event: add new seek parameter, "trickmode-interval"
When performing a key unit trickmode seek, it may be useful to
specify a minimum interval between the output frames, either
in very high rate cases, or as a protection against streams
that may contain an overly large amount of key frames.
One use case is ONVIF Section 6.5.3:
<https://www.onvif.org/specs/stream/ONVIF-Streaming-Spec.pdf>
-rw-r--r-- | docs/gst/gstreamer-sections.txt | 2 | ||||
-rw-r--r-- | gst/gstevent.c | 45 | ||||
-rw-r--r-- | gst/gstevent.h | 6 | ||||
-rw-r--r-- | gst/gstquark.c | 2 | ||||
-rw-r--r-- | gst/gstquark.h | 3 | ||||
-rw-r--r-- | tests/check/gst/gstevent.c | 17 |
6 files changed, 72 insertions, 3 deletions
diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 9d172aed21..1af775aa72 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -1216,6 +1216,8 @@ GstSeekType GstSeekFlags gst_event_new_seek gst_event_parse_seek +gst_event_set_seek_trickmode_interval +gst_event_parse_seek_trickmode_interval gst_event_new_navigation diff --git a/gst/gstevent.c b/gst/gstevent.c index 0189f433b2..2bd06d7964 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -1306,7 +1306,8 @@ gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags, GST_QUARK (CUR_TYPE), GST_TYPE_SEEK_TYPE, start_type, GST_QUARK (CUR), G_TYPE_INT64, start, GST_QUARK (STOP_TYPE), GST_TYPE_SEEK_TYPE, stop_type, - GST_QUARK (STOP), G_TYPE_INT64, stop, NULL); + GST_QUARK (STOP), G_TYPE_INT64, stop, + GST_QUARK (TRICKMODE_INTERVAL), GST_TYPE_CLOCK_TIME, 0, NULL); event = gst_event_new_custom (GST_EVENT_SEEK, structure); return event; @@ -1367,6 +1368,48 @@ gst_event_parse_seek (GstEvent * event, gdouble * rate, } /** + * gst_event_set_seek_trickmode_interval: + * + * Sets a trickmode interval on a (writable) seek event. Elements + * that support TRICKMODE_KEY_UNITS seeks SHOULD use this as the minimal + * interval between each frame they may output. + * + * Since: 1.16 + */ +void +gst_event_set_seek_trickmode_interval (GstEvent * event, GstClockTime interval) +{ + g_return_if_fail (event != NULL); + g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEEK); + g_return_if_fail (gst_event_is_writable (event)); + g_return_if_fail (GST_CLOCK_TIME_IS_VALID (interval)); + + gst_structure_id_set (GST_EVENT_STRUCTURE (event), + GST_QUARK (TRICKMODE_INTERVAL), GST_TYPE_CLOCK_TIME, interval, NULL); +} + +/** + * gst_event_parse_seek_trickmode_interval: + * @interval: (out) + * + * Retrieve the trickmode interval that may have been set on a + * seek event with gst_event_set_seek_trickmode_interval(). + * + * Since: 1.16 + */ +void +gst_event_parse_seek_trickmode_interval (GstEvent * event, + GstClockTime * interval) +{ + g_return_if_fail (event != NULL); + g_return_if_fail (interval != NULL); + g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEEK); + + gst_structure_id_get (GST_EVENT_STRUCTURE (event), + GST_QUARK (TRICKMODE_INTERVAL), GST_TYPE_CLOCK_TIME, interval, NULL); +} + +/** * gst_event_new_navigation: * @structure: (transfer full): description of the event. The event will take * ownership of the structure. diff --git a/gst/gstevent.h b/gst/gstevent.h index 4033cac7bd..282acf271a 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -676,6 +676,12 @@ void gst_event_parse_seek (GstEvent *event, gdouble *rate, GstSeekType *start_type, gint64 *start, GstSeekType *stop_type, gint64 *stop); +GST_API +void gst_event_set_seek_trickmode_interval (GstEvent *event, GstClockTime interval); + +GST_API +void gst_event_parse_seek_trickmode_interval (GstEvent *event, GstClockTime *interval); + /* navigation event */ GST_API diff --git a/gst/gstquark.c b/gst/gstquark.c index 4614578ea1..e42e5d034a 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -76,7 +76,7 @@ static const gchar *_quark_strings[] = { "GstMessageStreamsSelected", "GstMessageRedirect", "redirect-entry-locations", "redirect-entry-taglists", "redirect-entry-structures", "GstEventStreamGroupDone", "GstQueryBitrate", "nominal-bitrate", - "GstMessageDeviceChanged", "device-changed" + "GstMessageDeviceChanged", "device-changed", "trickmode-interval", }; GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquark.h b/gst/gstquark.h index e93a61f7c0..84c40d7d39 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -221,7 +221,8 @@ typedef enum _GstQuarkId GST_QUARK_NOMINAL_BITRATE = 190, GST_QUARK_MESSAGE_DEVICE_CHANGED = 191, GST_QUARK_DEVICE_CHANGED = 192, - GST_QUARK_MAX = 193 + GST_QUARK_TRICKMODE_INTERVAL = 193, + GST_QUARK_MAX = 194 } GstQuarkId; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/tests/check/gst/gstevent.c b/tests/check/gst/gstevent.c index d124c91eb8..39b5f30b2c 100644 --- a/tests/check/gst/gstevent.c +++ b/tests/check/gst/gstevent.c @@ -218,6 +218,7 @@ GST_START_TEST (create_events) GstSeekFlags flags; GstSeekType start_type, stop_type; gint64 start, stop; + GstClockTime trickmode_interval; event = gst_event_new_seek (0.5, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, @@ -239,6 +240,22 @@ GST_START_TEST (create_events) fail_unless (stop_type == GST_SEEK_TYPE_NONE); fail_unless (stop == 0xdeadbeef); + gst_event_parse_seek_trickmode_interval (event, &trickmode_interval); + fail_unless_equals_uint64 (trickmode_interval, 0); + + gst_event_set_seek_trickmode_interval (event, GST_SECOND); + gst_event_parse_seek_trickmode_interval (event, &trickmode_interval); + fail_unless_equals_uint64 (trickmode_interval, GST_SECOND); + + gst_event_ref (event); + ASSERT_CRITICAL (gst_event_set_seek_trickmode_interval (event, + 2 * GST_SECOND)); + gst_event_unref (event); + + gst_event_unref (event); + + event = gst_event_new_flush_start (); + ASSERT_CRITICAL (gst_event_set_seek_trickmode_interval (event, GST_SECOND)); gst_event_unref (event); } |