Add fast seeking support as a patch

This commit is contained in:
Rafostar
2020-11-05 16:13:57 +01:00
parent 81bdcf6244
commit da21c2fafc
4 changed files with 170 additions and 10 deletions

View File

@@ -175,15 +175,7 @@ class ClapperPlayer extends PlayerBase
debug(`${this.seekingMode} seeking to position: ${position}`); debug(`${this.seekingMode} seeking to position: ${position}`);
if(this.seekingMode !== 'fast') super.seek(position);
return super.seek(position);
let pipeline = this.get_pipeline();
let flags = Gst.SeekFlags.FLUSH
| Gst.SeekFlags.KEY_UNIT
| Gst.SeekFlags.SNAP_AFTER;
pipeline.seek_simple(Gst.Format.TIME, flags, position);
} }
seek_seconds(position) seek_seconds(position)

View File

@@ -106,7 +106,10 @@ class ClapperPlayerBase extends GstPlayer.Player
let config = this.get_config(); let config = this.get_config();
setOption(config, value); setOption(config, value);
this.set_config(config); let success = this.set_config(config);
if(!success)
debug(`could not change option: ${option}`);
} }
/* FIXME: add in prefs and move to bind_settings() */ /* FIXME: add in prefs and move to bind_settings() */
@@ -160,10 +163,15 @@ class ClapperPlayerBase extends GstPlayer.Player
case 'seeking-mode': case 'seeking-mode':
this.seekingMode = settings.get_string('seeking-mode'); this.seekingMode = settings.get_string('seeking-mode');
switch(this.seekingMode) { switch(this.seekingMode) {
case 'fast':
this.set_config_option('seek_fast', true);
break;
case 'accurate': case 'accurate':
this.set_config_option('seek_fast', false);
this.set_config_option('seek_accurate', true); this.set_config_option('seek_accurate', true);
break; break;
default: default:
this.set_config_option('seek_fast', false);
this.set_config_option('seek_accurate', false); this.set_config_option('seek_accurate', false);
break; break;
} }

View File

@@ -0,0 +1,156 @@
From 35fcd972398c8efaf7ff389ab7b98f0428b02394 Mon Sep 17 00:00:00 2001
From: Rafostar <rafostar.github@gmail.com>
Date: Thu, 5 Nov 2020 15:34:45 +0100
Subject: [PATCH] player: add seek_fast config option
Add a `seek_fast` player config option as an alternative to currently available normal and accurate options.
The new `seek_fast` option restores playback from next keyframe from requested seek position and takes precedence over `seek_accurate` when both options are enabled.
Depending on how keyframes are distributed in the video, this can be even over 20x faster than standard seeking on some files (at the expense of being more inaccurate).
---
gst-libs/gst/player/gstplayer.c | 67 ++++++++++++++++++++++++++++-----
gst-libs/gst/player/gstplayer.h | 6 +++
2 files changed, 63 insertions(+), 10 deletions(-)
diff --git a/gst-libs/gst/player/gstplayer.c b/gst-libs/gst/player/gstplayer.c
index 45705c671..cfa9db11e 100644
--- a/gst-libs/gst/player/gstplayer.c
+++ b/gst-libs/gst/player/gstplayer.c
@@ -88,6 +88,7 @@ typedef enum
CONFIG_QUARK_USER_AGENT = 0,
CONFIG_QUARK_POSITION_INTERVAL_UPDATE,
CONFIG_QUARK_ACCURATE_SEEK,
+ CONFIG_QUARK_FAST_SEEK,
CONFIG_QUARK_MAX
} ConfigQuarkId;
@@ -96,6 +97,7 @@ static const gchar *_config_quark_strings[] = {
"user-agent",
"position-interval-update",
"accurate-seek",
+ "fast-seek",
};
GQuark _config_quark_table[CONFIG_QUARK_MAX];
@@ -295,6 +297,7 @@ gst_player_init (GstPlayer * self)
self->config = gst_structure_new_id (QUARK_CONFIG,
CONFIG_QUARK (POSITION_INTERVAL_UPDATE), G_TYPE_UINT, DEFAULT_POSITION_UPDATE_INTERVAL_MS,
CONFIG_QUARK (ACCURATE_SEEK), G_TYPE_BOOLEAN, FALSE,
+ CONFIG_QUARK (FAST_SEEK), G_TYPE_BOOLEAN, FALSE,
NULL);
/* *INDENT-ON* */
@@ -3317,7 +3320,6 @@ gst_player_seek_internal_locked (GstPlayer * self)
GstStateChangeReturn state_ret;
GstEvent *s_event;
GstSeekFlags flags = 0;
- gboolean accurate = FALSE;
remove_seek_source (self);
@@ -3349,12 +3351,10 @@ gst_player_seek_internal_locked (GstPlayer * self)
flags |= GST_SEEK_FLAG_FLUSH;
- accurate = gst_player_config_get_seek_accurate (self->config);
-
- if (accurate) {
+ if (gst_player_config_get_seek_fast (self->config)) {
+ flags |= GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_SNAP_AFTER;
+ } else if (gst_player_config_get_seek_accurate (self->config)) {
flags |= GST_SEEK_FLAG_ACCURATE;
- } else {
- flags &= ~GST_SEEK_FLAG_ACCURATE;
}
if (rate != 1.0) {
@@ -4692,6 +4692,53 @@ gst_player_config_get_position_update_interval (const GstStructure * config)
return interval;
}
+/**
+ * gst_player_config_set_seek_fast:
+ * @config: a #GstPlayer configuration
+ * @fast: fast seek or not
+ *
+ * Enable or disable fast seeking. When enabled, player will resume playback from
+ * next keyframe from requested seek position. Generally it will be much faster
+ * than default seeking behaviour, but the outcome position might differ greatly
+ * depending on how keyframes are distributed in video (usually up to few seconds).
+ *
+ * If fast and accurate seeking options are disabled, elements will seek as
+ * close as the request position without slowing down seeking too much.
+ *
+ * Fast seeking is disabled by default. This option takes precedence
+ * over accurate seeking option.
+ * Since: 1.20
+ */
+void
+gst_player_config_set_seek_fast (GstStructure * config, gboolean fast)
+{
+ g_return_if_fail (config != NULL);
+
+ gst_structure_id_set (config,
+ CONFIG_QUARK (FAST_SEEK), G_TYPE_BOOLEAN, fast, NULL);
+}
+
+/**
+ * gst_player_config_get_seek_fast:
+ * @config: a #GstPlayer configuration
+ *
+ * Returns: %TRUE if fast seeking is enabled
+ *
+ * Since: 1.20
+ */
+gboolean
+gst_player_config_get_seek_fast (const GstStructure * config)
+{
+ gboolean fast = FALSE;
+
+ g_return_val_if_fail (config != NULL, FALSE);
+
+ gst_structure_id_get (config,
+ CONFIG_QUARK (FAST_SEEK), G_TYPE_BOOLEAN, &fast, NULL);
+
+ return fast;
+}
+
/**
* gst_player_config_set_seek_accurate:
* @config: a #GstPlayer configuration
@@ -4702,11 +4749,11 @@ gst_player_config_get_position_update_interval (const GstStructure * config)
* it will be slower especially for formats that don't have any indexes or
* timestamp markers in the stream.
*
- * If accurate seeking is disabled, elements will seek as close as the request
- * position without slowing down seeking too much.
- *
- * Accurate seeking is disabled by default.
+ * If accurate and fast seeking options are disabled, elements will seek as
+ * close as the request position without slowing down seeking too much.
*
+ * Accurate seeking is disabled by default. This option is ignored when
+ * fast seeking is enabled.
* Since: 1.12
*/
void
diff --git a/gst-libs/gst/player/gstplayer.h b/gst-libs/gst/player/gstplayer.h
index e853ed875..4984126ac 100644
--- a/gst-libs/gst/player/gstplayer.h
+++ b/gst-libs/gst/player/gstplayer.h
@@ -282,6 +282,12 @@ void gst_player_config_set_position_update_interval (GstStructure * c
GST_PLAYER_API
guint gst_player_config_get_position_update_interval (const GstStructure * config);
+GST_PLAYER_API
+void gst_player_config_set_seek_fast (GstStructure * config, gboolean fast);
+
+GST_PLAYER_API
+gboolean gst_player_config_get_seek_fast (const GstStructure * config);
+
GST_PLAYER_API
void gst_player_config_set_seek_accurate (GstStructure * config, gboolean accurate);
--
2.26.2

View File

@@ -28,6 +28,10 @@
{ {
"type": "patch", "type": "patch",
"path": "gst-plugins-bad-gstplayer-ref-sink.patch" "path": "gst-plugins-bad-gstplayer-ref-sink.patch"
},
{
"type": "patch",
"path": "gst-plugins-bad-add-seek-fast-option.patch"
} }
] ]
} }