summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2021-04-12 14:02:46 +0200
committerTim-Philipp Müller <tim@centricular.com>2021-04-14 11:14:38 +0100
commitda03e3ad200f7df0762ad12130b17f41998267f1 (patch)
tree570133a751bde79efd8b1117bdfe9bdd89fbf684
parentbbc4d2cf305ed3ca9f2a78c0271afaccea876bf0 (diff)
downloadgstreamer-plugins-base-da03e3ad200f7df0762ad12130b17f41998267f1.tar.gz
playbin{2,3}: fix base_time selection when flush seeking live
This is a direct translation of <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/429>, as playbin{2,3} insulates its sub groups state changes from the pipeline base class, it needs to track whether the subgroup is live itself, and handle RESET_TIME the same way GstPipeline does. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1110>
-rw-r--r--gst/playback/gstplaybin2.c19
-rw-r--r--gst/playback/gstplaybin3.c31
2 files changed, 44 insertions, 6 deletions
diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c
index a8d719f22..9a1aa29ea 100644
--- a/gst/playback/gstplaybin2.c
+++ b/gst/playback/gstplaybin2.c
@@ -465,6 +465,8 @@ struct _GstPlayBin
guint64 ring_buffer_max_size; /* 0 means disabled */
GList *contexts;
+
+ gboolean is_live;
};
struct _GstPlayBinClass
@@ -1645,6 +1647,8 @@ gst_play_bin_finalize (GObject * object)
g_mutex_clear (&playbin->dyn_lock);
g_mutex_clear (&playbin->elements_lock);
+ playbin->is_live = FALSE;
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -2893,6 +2897,7 @@ gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
{
GstPlayBin *playbin = GST_PLAY_BIN (bin);
GstSourceGroup *group;
+ gboolean do_reset_time = FALSE;
if (gst_is_missing_plugin_message (msg)) {
gchar *detail;
@@ -3101,10 +3106,20 @@ gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
gst_message_parse_have_context (msg, &context);
gst_play_bin_update_context (playbin, context);
gst_context_unref (context);
+ } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_RESET_TIME) {
+ if (playbin->is_live && GST_STATE_TARGET (playbin) == GST_STATE_PLAYING) {
+ do_reset_time = TRUE;
+ }
}
if (msg)
GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
+
+ if (do_reset_time) {
+ /* If we are live, sample a new base_time immediately */
+ gst_element_change_state (GST_ELEMENT (playbin),
+ GST_STATE_CHANGE_PAUSED_TO_PLAYING);
+ }
}
static void
@@ -5864,6 +5879,7 @@ gst_play_bin_change_state (GstElement * element, GstStateChange transition)
/* FIXME Release audio device when we implement that */
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
+ playbin->is_live = FALSE;
save_current_group (playbin);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
@@ -5947,6 +5963,9 @@ gst_play_bin_change_state (GstElement * element, GstStateChange transition)
break;
}
+ if (GST_STATE_TRANSITION_NEXT (transition) == GST_STATE_PAUSED)
+ playbin->is_live = ret == GST_STATE_CHANGE_NO_PREROLL;
+
if (ret == GST_STATE_CHANGE_NO_PREROLL)
do_async_done (playbin);
diff --git a/gst/playback/gstplaybin3.c b/gst/playback/gstplaybin3.c
index 323dc1ffe..e0e422f12 100644
--- a/gst/playback/gstplaybin3.c
+++ b/gst/playback/gstplaybin3.c
@@ -516,6 +516,8 @@ struct _GstPlayBin3
GSequence *velements; /* a list of GstAVElements for video stream */
guint64 ring_buffer_max_size; /* 0 means disabled */
+
+ gboolean is_live; /* Whether our current group is live */
};
struct _GstPlayBin3Class
@@ -1386,6 +1388,8 @@ gst_play_bin3_init (GstPlayBin3 * playbin)
playbin->multiview_mode = GST_VIDEO_MULTIVIEW_FRAME_PACKING_NONE;
playbin->multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
+
+ playbin->is_live = FALSE;
}
static void
@@ -2314,8 +2318,8 @@ gst_play_bin3_send_event (GstElement * element, GstEvent * event)
group->selected_stream_types =
get_stream_type_for_event (group->collection, event);
playbin->selected_stream_types =
- playbin->groups[0].selected_stream_types | playbin->
- groups[1].selected_stream_types;
+ playbin->groups[0].selected_stream_types | playbin->groups[1].
+ selected_stream_types;
if (playbin->active_stream_types != playbin->selected_stream_types)
reconfigure_output (playbin);
}
@@ -2433,8 +2437,8 @@ do_stream_selection (GstPlayBin3 * playbin, GstSourceGroup * group)
group->selected_stream_types = chosen_stream_types;
/* Update global selected_stream_types */
playbin->selected_stream_types =
- playbin->groups[0].selected_stream_types | playbin->
- groups[1].selected_stream_types;
+ playbin->groups[0].selected_stream_types | playbin->groups[1].
+ selected_stream_types;
if (playbin->active_stream_types != playbin->selected_stream_types)
reconfigure_output (playbin);
}
@@ -2459,6 +2463,7 @@ static void
gst_play_bin3_handle_message (GstBin * bin, GstMessage * msg)
{
GstPlayBin3 *playbin = GST_PLAY_BIN3 (bin);
+ gboolean do_reset_time = FALSE;
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAM_START) {
GstSourceGroup *group = NULL, *other_group = NULL;
@@ -2559,11 +2564,21 @@ gst_play_bin3_handle_message (GstBin * bin, GstMessage * msg)
gst_object_unref (collection);
}
+ } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_RESET_TIME) {
+ if (playbin->is_live && GST_STATE_TARGET (playbin) == GST_STATE_PLAYING) {
+ do_reset_time = TRUE;
+ }
}
beach:
if (msg)
GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
+
+ if (do_reset_time) {
+ /* If we are live, sample a new base_time immediately */
+ gst_element_change_state (GST_ELEMENT (playbin),
+ GST_STATE_CHANGE_PAUSED_TO_PLAYING);
+ }
}
static void
@@ -4658,8 +4673,8 @@ deactivate_group (GstPlayBin3 * playbin, GstSourceGroup * group)
group->selected_stream_types = 0;
/* Update global selected_stream_types */
playbin->selected_stream_types =
- playbin->groups[0].selected_stream_types | playbin->
- groups[1].selected_stream_types;
+ playbin->groups[0].selected_stream_types | playbin->groups[1].
+ selected_stream_types;
if (playbin->active_stream_types != playbin->selected_stream_types)
reconfigure_output (playbin);
@@ -4973,6 +4988,7 @@ gst_play_bin3_change_state (GstElement * element, GstStateChange transition)
/* FIXME Release audio device when we implement that */
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
+ playbin->is_live = FALSE;
save_current_group (playbin);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
@@ -5022,6 +5038,9 @@ gst_play_bin3_change_state (GstElement * element, GstStateChange transition)
break;
}
+ if (GST_STATE_TRANSITION_NEXT (transition) == GST_STATE_PAUSED)
+ playbin->is_live = ret == GST_STATE_CHANGE_NO_PREROLL;
+
if (ret == GST_STATE_CHANGE_NO_PREROLL)
do_async_done (playbin);