diff options
author | Mathieu Duponchelle <mathieu@centricular.com> | 2021-04-12 14:02:46 +0200 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2021-04-14 11:14:38 +0100 |
commit | da03e3ad200f7df0762ad12130b17f41998267f1 (patch) | |
tree | 570133a751bde79efd8b1117bdfe9bdd89fbf684 | |
parent | bbc4d2cf305ed3ca9f2a78c0271afaccea876bf0 (diff) | |
download | gstreamer-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.c | 19 | ||||
-rw-r--r-- | gst/playback/gstplaybin3.c | 31 |
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); |