mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 16:02:00 +02:00
311 lines
10 KiB
Diff
311 lines
10 KiB
Diff
From bb4191a149108cda6d8a34814c1a3acdcfc74f56 Mon Sep 17 00:00:00 2001
|
|
From: Rafostar <40623528+Rafostar@users.noreply.github.com>
|
|
Date: Mon, 9 Nov 2020 11:22:32 +0100
|
|
Subject: [PATCH] player: set seek mode without stopping playback
|
|
|
|
Move seek mode setting outside of "config" object, so it can be changed without stopping playback.
|
|
---
|
|
gst-libs/gst/player/gstplayer.c | 117 ++++++++++++++++++++------------
|
|
gst-libs/gst/player/gstplayer.h | 30 ++++++--
|
|
2 files changed, 98 insertions(+), 49 deletions(-)
|
|
|
|
diff --git a/gst-libs/gst/player/gstplayer.c b/gst-libs/gst/player/gstplayer.c
|
|
index 45705c671..d13c0cc63 100644
|
|
--- a/gst-libs/gst/player/gstplayer.c
|
|
+++ b/gst-libs/gst/player/gstplayer.c
|
|
@@ -70,6 +70,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_player_debug);
|
|
#define DEFAULT_POSITION_UPDATE_INTERVAL_MS 100
|
|
#define DEFAULT_AUDIO_VIDEO_OFFSET 0
|
|
#define DEFAULT_SUBTITLE_VIDEO_OFFSET 0
|
|
+#define DEFAULT_SEEK_MODE GST_PLAYER_SEEK_MODE_DEFAULT
|
|
|
|
/**
|
|
* gst_player_error_quark:
|
|
@@ -87,7 +88,6 @@ typedef enum
|
|
{
|
|
CONFIG_QUARK_USER_AGENT = 0,
|
|
CONFIG_QUARK_POSITION_INTERVAL_UPDATE,
|
|
- CONFIG_QUARK_ACCURATE_SEEK,
|
|
|
|
CONFIG_QUARK_MAX
|
|
} ConfigQuarkId;
|
|
@@ -95,7 +95,6 @@ typedef enum
|
|
static const gchar *_config_quark_strings[] = {
|
|
"user-agent",
|
|
"position-interval-update",
|
|
- "accurate-seek",
|
|
};
|
|
|
|
GQuark _config_quark_table[CONFIG_QUARK_MAX];
|
|
@@ -123,6 +122,7 @@ enum
|
|
PROP_VIDEO_MULTIVIEW_FLAGS,
|
|
PROP_AUDIO_VIDEO_OFFSET,
|
|
PROP_SUBTITLE_VIDEO_OFFSET,
|
|
+ PROP_SEEK_MODE,
|
|
PROP_LAST
|
|
};
|
|
|
|
@@ -188,6 +188,8 @@ struct _GstPlayer
|
|
|
|
GstStructure *config;
|
|
|
|
+ GstPlayerSeekMode seek_mode;
|
|
+
|
|
/* Protected by lock */
|
|
gboolean seek_pending; /* Only set from main context */
|
|
GstClockTime last_seek_time; /* Only set from main context */
|
|
@@ -294,7 +296,6 @@ gst_player_init (GstPlayer * self)
|
|
/* *INDENT-OFF* */
|
|
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,
|
|
NULL);
|
|
/* *INDENT-ON* */
|
|
|
|
@@ -424,6 +425,12 @@ gst_player_class_init (GstPlayerClass * klass)
|
|
"The synchronisation offset between text and video in nanoseconds",
|
|
G_MININT64, G_MAXINT64, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
|
|
|
+ param_specs[PROP_SEEK_MODE] =
|
|
+ g_param_spec_enum ("seek-mode", "Player Seek Mode",
|
|
+ "Selected player seek mode to use when performing seeks",
|
|
+ GST_TYPE_PLAYER_SEEK_MODE, DEFAULT_SEEK_MODE,
|
|
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
|
+
|
|
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
|
|
|
signals[SIGNAL_URI_LOADED] =
|
|
@@ -747,6 +754,11 @@ gst_player_set_property (GObject * object, guint prop_id,
|
|
case PROP_SUBTITLE_VIDEO_OFFSET:
|
|
g_object_set_property (G_OBJECT (self->playbin), "text-offset", value);
|
|
break;
|
|
+ case PROP_SEEK_MODE:
|
|
+ g_mutex_lock (&self->lock);
|
|
+ self->seek_mode = g_value_get_enum (value);
|
|
+ g_mutex_unlock (&self->lock);
|
|
+ break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
@@ -847,6 +859,11 @@ gst_player_get_property (GObject * object, guint prop_id,
|
|
case PROP_SUBTITLE_VIDEO_OFFSET:
|
|
g_object_get_property (G_OBJECT (self->playbin), "text-offset", value);
|
|
break;
|
|
+ case PROP_SEEK_MODE:
|
|
+ g_mutex_lock (&self->lock);
|
|
+ g_value_set_enum (value, self->seek_mode);
|
|
+ g_mutex_unlock (&self->lock);
|
|
+ break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
@@ -2988,6 +3005,7 @@ gst_player_main (gpointer data)
|
|
self->is_eos = FALSE;
|
|
self->is_live = FALSE;
|
|
self->rate = 1.0;
|
|
+ self->seek_mode = DEFAULT_SEEK_MODE;
|
|
|
|
GST_TRACE_OBJECT (self, "Starting main loop");
|
|
g_main_loop_run (self->loop);
|
|
@@ -3316,8 +3334,8 @@ gst_player_seek_internal_locked (GstPlayer * self)
|
|
gdouble rate;
|
|
GstStateChangeReturn state_ret;
|
|
GstEvent *s_event;
|
|
+ GstPlayerSeekMode seek_mode;
|
|
GstSeekFlags flags = 0;
|
|
- gboolean accurate = FALSE;
|
|
|
|
remove_seek_source (self);
|
|
|
|
@@ -3330,8 +3348,6 @@ gst_player_seek_internal_locked (GstPlayer * self)
|
|
if (state_ret == GST_STATE_CHANGE_FAILURE) {
|
|
emit_error (self, g_error_new (GST_PLAYER_ERROR, GST_PLAYER_ERROR_FAILED,
|
|
"Failed to seek"));
|
|
- g_mutex_lock (&self->lock);
|
|
- return;
|
|
}
|
|
g_mutex_lock (&self->lock);
|
|
return;
|
|
@@ -3342,6 +3358,7 @@ gst_player_seek_internal_locked (GstPlayer * self)
|
|
self->seek_position = GST_CLOCK_TIME_NONE;
|
|
self->seek_pending = TRUE;
|
|
rate = self->rate;
|
|
+ seek_mode = self->seek_mode;
|
|
g_mutex_unlock (&self->lock);
|
|
|
|
remove_tick_source (self);
|
|
@@ -3349,12 +3366,15 @@ gst_player_seek_internal_locked (GstPlayer * self)
|
|
|
|
flags |= GST_SEEK_FLAG_FLUSH;
|
|
|
|
- accurate = gst_player_config_get_seek_accurate (self->config);
|
|
-
|
|
- if (accurate) {
|
|
- flags |= GST_SEEK_FLAG_ACCURATE;
|
|
- } else {
|
|
- flags &= ~GST_SEEK_FLAG_ACCURATE;
|
|
+ switch (seek_mode) {
|
|
+ case GST_PLAYER_SEEK_MODE_ACCURATE:
|
|
+ flags |= GST_SEEK_FLAG_ACCURATE;
|
|
+ break;
|
|
+ case GST_PLAYER_SEEK_MODE_FAST:
|
|
+ flags |= GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_SNAP_AFTER;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
}
|
|
|
|
if (rate != 1.0) {
|
|
@@ -4692,51 +4712,62 @@ gst_player_config_get_position_update_interval (const GstStructure * config)
|
|
return interval;
|
|
}
|
|
|
|
+GType
|
|
+gst_player_seek_mode_get_type (void)
|
|
+{
|
|
+ static gsize id = 0;
|
|
+ static const GEnumValue values[] = {
|
|
+ {C_ENUM (GST_PLAYER_SEEK_MODE_DEFAULT), "GST_PLAYER_SEEK_MODE_DEFAULT",
|
|
+ "default"},
|
|
+ {C_ENUM (GST_PLAYER_SEEK_MODE_ACCURATE), "GST_PLAYER_SEEK_MODE_ACCURATE",
|
|
+ "accurate"},
|
|
+ {C_ENUM (GST_PLAYER_SEEK_MODE_FAST), "GST_PLAYER_SEEK_MODE_FAST", "fast"},
|
|
+ {0, NULL, NULL}
|
|
+ };
|
|
+
|
|
+ if (g_once_init_enter (&id)) {
|
|
+ GType tmp = g_enum_register_static ("GstPlayerSeekMode", values);
|
|
+ g_once_init_leave (&id, tmp);
|
|
+ }
|
|
+
|
|
+ return (GType) id;
|
|
+}
|
|
+
|
|
/**
|
|
- * gst_player_config_set_seek_accurate:
|
|
- * @config: a #GstPlayer configuration
|
|
- * @accurate: accurate seek or not
|
|
- *
|
|
- * Enable or disable accurate seeking. When enabled, elements will try harder
|
|
- * to seek as accurately as possible to the requested seek position. Generally
|
|
- * 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.
|
|
+ * gst_player_get_seek_mode:
|
|
+ * @player: #GstPlayer instance
|
|
*
|
|
- * Accurate seeking is disabled by default.
|
|
+ * Returns: The currently used seek mode, Default: 0 "default"
|
|
*
|
|
- * Since: 1.12
|
|
+ * Since: 1.20
|
|
*/
|
|
-void
|
|
-gst_player_config_set_seek_accurate (GstStructure * config, gboolean accurate)
|
|
+GstPlayerSeekMode
|
|
+gst_player_get_seek_mode (GstPlayer * self)
|
|
{
|
|
- g_return_if_fail (config != NULL);
|
|
+ GstPlayerSeekMode mode;
|
|
|
|
- gst_structure_id_set (config,
|
|
- CONFIG_QUARK (ACCURATE_SEEK), G_TYPE_BOOLEAN, accurate, NULL);
|
|
+ g_return_val_if_fail (GST_IS_PLAYER (self), DEFAULT_SEEK_MODE);
|
|
+
|
|
+ g_object_get (self, "seek-mode", &mode, NULL);
|
|
+
|
|
+ return mode;
|
|
}
|
|
|
|
/**
|
|
- * gst_player_config_get_seek_accurate:
|
|
- * @config: a #GstPlayer configuration
|
|
+ * gst_player_set_seek_mode:
|
|
+ * @player: #GstPlayer instance
|
|
+ * @mode: #GstPlayerSeekMode
|
|
*
|
|
- * Returns: %TRUE if accurate seeking is enabled
|
|
+ * Changes currently used player seek mode to the one of @mode
|
|
*
|
|
- * Since: 1.12
|
|
+ * Since: 1.20
|
|
*/
|
|
-gboolean
|
|
-gst_player_config_get_seek_accurate (const GstStructure * config)
|
|
+void
|
|
+gst_player_set_seek_mode (GstPlayer * self, GstPlayerSeekMode mode)
|
|
{
|
|
- gboolean accurate = FALSE;
|
|
-
|
|
- g_return_val_if_fail (config != NULL, FALSE);
|
|
-
|
|
- gst_structure_id_get (config,
|
|
- CONFIG_QUARK (ACCURATE_SEEK), G_TYPE_BOOLEAN, &accurate, NULL);
|
|
+ g_return_if_fail (GST_IS_PLAYER (self));
|
|
|
|
- return accurate;
|
|
+ g_object_set (self, "seek-mode", mode, NULL);
|
|
}
|
|
|
|
/**
|
|
diff --git a/gst-libs/gst/player/gstplayer.h b/gst-libs/gst/player/gstplayer.h
|
|
index e853ed875..9c0ab5a60 100644
|
|
--- a/gst-libs/gst/player/gstplayer.h
|
|
+++ b/gst-libs/gst/player/gstplayer.h
|
|
@@ -96,6 +96,23 @@ typedef enum
|
|
GST_PLAYER_API
|
|
const gchar *gst_player_color_balance_type_get_name (GstPlayerColorBalanceType type);
|
|
|
|
+GST_PLAYER_API
|
|
+GType gst_player_seek_mode_get_type (void);
|
|
+#define GST_TYPE_PLAYER_SEEK_MODE (gst_player_seek_mode_get_type ())
|
|
+
|
|
+/**
|
|
+ * GstPlayerSeekMode:
|
|
+ * @GST_PLAYER_SEEK_MODE_DEFAULT: default seek method (flush only).
|
|
+ * @GST_PLAYER_SEEK_MODE_ACCURATE: accurate seek method.
|
|
+ * @GST_PLAYER_SEEK_MODE_FAST: fast seek method (next keyframe).
|
|
+ */
|
|
+typedef enum
|
|
+{
|
|
+ GST_PLAYER_SEEK_MODE_DEFAULT,
|
|
+ GST_PLAYER_SEEK_MODE_ACCURATE,
|
|
+ GST_PLAYER_SEEK_MODE_FAST,
|
|
+} GstPlayerSeekMode;
|
|
+
|
|
#define GST_TYPE_PLAYER (gst_player_get_type ())
|
|
#define GST_IS_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAYER))
|
|
#define GST_IS_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAYER))
|
|
@@ -127,6 +144,13 @@ GST_PLAYER_API
|
|
void gst_player_seek (GstPlayer * player,
|
|
GstClockTime position);
|
|
|
|
+GST_PLAYER_API
|
|
+GstPlayerSeekMode gst_player_get_seek_mode (GstPlayer * player);
|
|
+
|
|
+GST_PLAYER_API
|
|
+void gst_player_set_seek_mode (GstPlayer * player,
|
|
+ GstPlayerSeekMode mode);
|
|
+
|
|
GST_PLAYER_API
|
|
void gst_player_set_rate (GstPlayer * player,
|
|
gdouble rate);
|
|
@@ -282,12 +306,6 @@ 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_accurate (GstStructure * config, gboolean accurate);
|
|
-
|
|
-GST_PLAYER_API
|
|
-gboolean gst_player_config_get_seek_accurate (const GstStructure * config);
|
|
-
|
|
typedef enum
|
|
{
|
|
GST_PLAYER_THUMBNAIL_RAW_NATIVE = 0,
|
|
--
|
|
2.26.2
|
|
|