pipeline: fix base_time selection when flush seeking live
When a live pipeline goes to PLAYING, its change_state method is called twice for PAUSED_TO_PLAYING: the first time is from GstElement, when NO_PREROLL is returned, the second is from GstBin, after all async_done messages have been collected. base_time selection is done only the first time, through comparisons with start_time. On the other hand, when this live pipeline gets flush seeked, even though start_time is reset by the sink upon reception of flush_stop(reset_time=TRUE), PAUSED_TO_PLAYING only occurs once, from GstBin, after all async_done messages have been collected. This causes the base_time to be off by <latency>. This commit addresses this by mimicing the behaviour of GstElement on NO_PREROLL, and calling the change_state method manually when the following conditions are met: * The pipeline is live * The target state is PLAYING
This commit is contained in:
parent
4679c2ed6f
commit
0566b0528a
@ -109,6 +109,7 @@ struct _GstPipelinePrivate
|
||||
{
|
||||
/* with LOCK */
|
||||
gboolean auto_flush_bus;
|
||||
gboolean is_live;
|
||||
|
||||
/* when we need to update stream_time or clock when going back to
|
||||
* PLAYING*/
|
||||
@ -228,6 +229,8 @@ gst_pipeline_init (GstPipeline * pipeline)
|
||||
pipeline->delay = DEFAULT_DELAY;
|
||||
pipeline->priv->latency = DEFAULT_LATENCY;
|
||||
|
||||
pipeline->priv->is_live = FALSE;
|
||||
|
||||
/* create and set a default bus */
|
||||
bus = gst_bus_new ();
|
||||
#if 0
|
||||
@ -512,6 +515,7 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
|
||||
break;
|
||||
}
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
pipeline->priv->is_live = FALSE;
|
||||
reset_start_time (pipeline, 0);
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
@ -520,6 +524,12 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
|
||||
|
||||
result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
|
||||
if (GST_STATE_TRANSITION_NEXT (transition) == GST_STATE_PAUSED) {
|
||||
pipeline->priv->is_live = result == GST_STATE_CHANGE_NO_PREROLL;
|
||||
GST_INFO_OBJECT (pipeline, "pipeline is%slive",
|
||||
pipeline->priv->is_live ? " " : " not ");
|
||||
}
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_NULL:
|
||||
break;
|
||||
@ -613,6 +623,14 @@ gst_pipeline_handle_message (GstBin * bin, GstMessage * message)
|
||||
/* reset our running time if we need to distribute a new base_time to the
|
||||
* children. */
|
||||
reset_start_time (pipeline, running_time);
|
||||
|
||||
/* If we are live, sample a new base_time immediately */
|
||||
if (pipeline->priv->is_live
|
||||
&& GST_STATE_TARGET (pipeline) == GST_STATE_PLAYING) {
|
||||
gst_pipeline_change_state (GST_ELEMENT (pipeline),
|
||||
GST_STATE_CHANGE_PAUSED_TO_PLAYING);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case GST_MESSAGE_CLOCK_LOST:
|
||||
|
Loading…
x
Reference in New Issue
Block a user