summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-06-08 17:39:47 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2009-06-08 17:41:56 +0200
commit89c42f8506ae8041573310b60fd27f8bf7010e0e (patch)
treec75798739ec112871667914079ef5fe5510225ae
parentf0f9ed875ff200015a31c279738c1fb611ff2f94 (diff)
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.
-rw-r--r--docs/design/draft-framestep.txt8
-rw-r--r--libs/gst/base/gstbasesink.c35
2 files changed, 26 insertions, 17 deletions
diff --git a/docs/design/draft-framestep.txt b/docs/design/draft-framestep.txt
index 8fe789e00..cdc064b72 100644
--- a/docs/design/draft-framestep.txt
+++ b/docs/design/draft-framestep.txt
@@ -123,9 +123,11 @@ events
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
best effort to comply with the new amount.
- - In the PLAYING state, the requested amount of data is skipped (not
- rendered) from the previous STEP request or from the position of the
- last PAUSED if no previous STEP operation was performed.
+ - In the PLAYING state, the pipeline loses the PLAYING state, the
+ requested amount of data is skipped (not rendered) from the previous STEP
+ 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.
diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c
index 77cf8d62e..cf9919f69 100644
--- a/libs/gst/base/gstbasesink.c
+++ b/libs/gst/base/gstbasesink.c
@@ -1483,8 +1483,11 @@ start_stepping (GstBaseSink * sink, GstSegment * segment,
GstStepInfo * pending, GstStepInfo * current)
{
GST_DEBUG_OBJECT (sink, "update pending step");
+
+ GST_OBJECT_LOCK (sink);
memcpy (current, pending, sizeof (GstStepInfo));
pending->valid = FALSE;
+ GST_OBJECT_UNLOCK (sink);
/* get the running time of where we paused and remember it */
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
-set_step_info (GstBaseSink * sink, GstStepInfo * info, guint seqnum,
- GstFormat format, guint64 amount, gdouble rate, gboolean flush,
- gboolean intermediate)
+set_step_info (GstBaseSink * sink, GstStepInfo * current, GstStepInfo * pending,
+ guint seqnum, GstFormat format, guint64 amount, gdouble rate,
+ gboolean flush, gboolean intermediate)
{
GST_OBJECT_LOCK (sink);
- info->seqnum = seqnum;
- info->format = format;
- info->amount = amount;
- info->position = 0;
- info->rate = rate;
- info->flush = flush;
- info->intermediate = intermediate;
- info->valid = TRUE;
+ pending->seqnum = seqnum;
+ pending->format = format;
+ pending->amount = amount;
+ pending->position = 0;
+ pending->rate = rate;
+ pending->flush = flush;
+ pending->intermediate = intermediate;
+ pending->valid = TRUE;
+ /* flush invalidates the current stepping segment */
+ if (flush)
+ current->valid = FALSE;
GST_OBJECT_UNLOCK (sink);
}
@@ -3465,7 +3471,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
GstFormat format;
guint64 amount;
guint seqnum;
- GstStepInfo *pending;
+ GstStepInfo *pending, *current;
bclass = GST_BASE_SINK_GET_CLASS (sink);
priv = sink->priv;
@@ -3476,6 +3482,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
seqnum = gst_event_get_seqnum (event);
pending = &priv->pending_step;
+ current = &priv->current_step;
if (flush) {
/* 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);
/* 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);
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);
} else {
/* 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);
}