mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 20:59:44 +00:00
stepping: do flushing steps correctly
Note in the docs that a flushing step in PLAYING brings the pipeline to the lost state and skips the data before prerolling again. Implement the flushing step correctly by invalidating the current step operation, which would activate the new step operation.
This commit is contained in:
parent
f0f9ed875f
commit
89c42f8506
2 changed files with 26 additions and 17 deletions
|
@ -123,9 +123,11 @@ events
|
||||||
When the pipeline was stepping while the event is sent, the current step
|
When the pipeline was stepping while the event is sent, the current step
|
||||||
operation is updated with the new amount and format. The sink will do a
|
operation is updated with the new amount and format. The sink will do a
|
||||||
best effort to comply with the new amount.
|
best effort to comply with the new amount.
|
||||||
- In the PLAYING state, the requested amount of data is skipped (not
|
- In the PLAYING state, the pipeline loses the PLAYING state, the
|
||||||
rendered) from the previous STEP request or from the position of the
|
requested amount of data is skipped (not rendered) from the previous STEP
|
||||||
last PAUSED if no previous STEP operation was performed.
|
request or from the position of the last PAUSED if no previous STEP
|
||||||
|
operation was performed. The pipeline goes back to the PLAYING state
|
||||||
|
when a non-intermediate step completes.
|
||||||
|
|
||||||
When flushing is FALSE, the step will be performed later.
|
When flushing is FALSE, the step will be performed later.
|
||||||
|
|
||||||
|
|
|
@ -1483,8 +1483,11 @@ start_stepping (GstBaseSink * sink, GstSegment * segment,
|
||||||
GstStepInfo * pending, GstStepInfo * current)
|
GstStepInfo * pending, GstStepInfo * current)
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (sink, "update pending step");
|
GST_DEBUG_OBJECT (sink, "update pending step");
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (sink);
|
||||||
memcpy (current, pending, sizeof (GstStepInfo));
|
memcpy (current, pending, sizeof (GstStepInfo));
|
||||||
pending->valid = FALSE;
|
pending->valid = FALSE;
|
||||||
|
GST_OBJECT_UNLOCK (sink);
|
||||||
|
|
||||||
/* get the running time of where we paused and remember it */
|
/* get the running time of where we paused and remember it */
|
||||||
current->start = gst_element_get_start_time (GST_ELEMENT_CAST (sink));
|
current->start = gst_element_get_start_time (GST_ELEMENT_CAST (sink));
|
||||||
|
@ -3439,19 +3442,22 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_step_info (GstBaseSink * sink, GstStepInfo * info, guint seqnum,
|
set_step_info (GstBaseSink * sink, GstStepInfo * current, GstStepInfo * pending,
|
||||||
GstFormat format, guint64 amount, gdouble rate, gboolean flush,
|
guint seqnum, GstFormat format, guint64 amount, gdouble rate,
|
||||||
gboolean intermediate)
|
gboolean flush, gboolean intermediate)
|
||||||
{
|
{
|
||||||
GST_OBJECT_LOCK (sink);
|
GST_OBJECT_LOCK (sink);
|
||||||
info->seqnum = seqnum;
|
pending->seqnum = seqnum;
|
||||||
info->format = format;
|
pending->format = format;
|
||||||
info->amount = amount;
|
pending->amount = amount;
|
||||||
info->position = 0;
|
pending->position = 0;
|
||||||
info->rate = rate;
|
pending->rate = rate;
|
||||||
info->flush = flush;
|
pending->flush = flush;
|
||||||
info->intermediate = intermediate;
|
pending->intermediate = intermediate;
|
||||||
info->valid = TRUE;
|
pending->valid = TRUE;
|
||||||
|
/* flush invalidates the current stepping segment */
|
||||||
|
if (flush)
|
||||||
|
current->valid = FALSE;
|
||||||
GST_OBJECT_UNLOCK (sink);
|
GST_OBJECT_UNLOCK (sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3465,7 +3471,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
guint64 amount;
|
guint64 amount;
|
||||||
guint seqnum;
|
guint seqnum;
|
||||||
GstStepInfo *pending;
|
GstStepInfo *pending, *current;
|
||||||
|
|
||||||
bclass = GST_BASE_SINK_GET_CLASS (sink);
|
bclass = GST_BASE_SINK_GET_CLASS (sink);
|
||||||
priv = sink->priv;
|
priv = sink->priv;
|
||||||
|
@ -3476,6 +3482,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
|
||||||
seqnum = gst_event_get_seqnum (event);
|
seqnum = gst_event_get_seqnum (event);
|
||||||
|
|
||||||
pending = &priv->pending_step;
|
pending = &priv->pending_step;
|
||||||
|
current = &priv->current_step;
|
||||||
|
|
||||||
if (flush) {
|
if (flush) {
|
||||||
/* we need to call ::unlock before locking PREROLL_LOCK
|
/* we need to call ::unlock before locking PREROLL_LOCK
|
||||||
|
@ -3489,7 +3496,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
|
||||||
bclass->unlock_stop (sink);
|
bclass->unlock_stop (sink);
|
||||||
|
|
||||||
/* update the stepinfo and make it valid */
|
/* update the stepinfo and make it valid */
|
||||||
set_step_info (sink, pending, seqnum, format, amount, rate, flush,
|
set_step_info (sink, current, pending, seqnum, format, amount, rate, flush,
|
||||||
intermediate);
|
intermediate);
|
||||||
|
|
||||||
if (sink->priv->async_enabled) {
|
if (sink->priv->async_enabled) {
|
||||||
|
@ -3522,7 +3529,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
|
||||||
GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
|
GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
|
||||||
} else {
|
} else {
|
||||||
/* update the stepinfo and make it valid */
|
/* update the stepinfo and make it valid */
|
||||||
set_step_info (sink, pending, seqnum, format, amount, rate, flush,
|
set_step_info (sink, current, pending, seqnum, format, amount, rate, flush,
|
||||||
intermediate);
|
intermediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue