summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosep Torra <n770galaxy@gmail.com>2017-05-21 12:37:44 +0200
committerJosep Torra <n770galaxy@gmail.com>2017-05-22 18:31:54 +0200
commite812385691eecf3c694d6e1e43fe61a72f43ed4e (patch)
tree8e72c83e5a175ad78d1d5c50ac81936e87bc2a0c
parent16679b801b79fa0cd4d62582024c9c9c750ca76a (diff)
basesink: do not require preroll when receiving a segment-done eventWIP
When performing a segment seek to just play a section of a stream the pipeline deadlocks if changing state from PLAYING to PAUSE after receiving the segment-done event. This change fixes this issue by do not require a prerolling buffer after receiving the segment-done event. https://bugzilla.gnome.org/show_bug.cgi?id=782960
-rw-r--r--libs/gst/base/gstbasesink.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c
index ee12a6bd4..e1e515e09 100644
--- a/libs/gst/base/gstbasesink.c
+++ b/libs/gst/base/gstbasesink.c
@@ -220,6 +220,9 @@ struct _GstBaseSinkPrivate
/* when we received EOS */
gboolean received_eos;
+ /* when we received segment-done event */
+ gboolean received_segment_done;
+
/* when we are prerolled and able to report latency */
gboolean have_latency;
@@ -3174,6 +3177,9 @@ gst_base_sink_default_event (GstBaseSink * basesink, GstEvent * event)
break;
}
case GST_EVENT_SEGMENT:
+ {
+ /* reset the segment-done flag */
+ basesink->priv->received_segment_done = FALSE;
/* configure the segment */
/* The segment is protected with both the STREAM_LOCK and the OBJECT_LOCK.
* We protect with the OBJECT_LOCK so that we can use the values to
@@ -3188,6 +3194,22 @@ gst_base_sink_default_event (GstBaseSink * basesink, GstEvent * event)
gst_base_sink_reset_qos (basesink);
GST_OBJECT_UNLOCK (basesink);
break;
+ }
+ case GST_EVENT_SEGMENT_DONE:
+ {
+ GST_DEBUG_OBJECT (basesink, "segment-done %p", event);
+ /* we set the received segment-done flag here so that we can use it
+ * when testing if we are prerolled. */
+ basesink->priv->received_segment_done = TRUE;
+
+ /* wait for segment-done */
+ if (G_UNLIKELY (gst_base_sink_wait_event (basesink,
+ event) != GST_FLOW_OK)) {
+ result = FALSE;
+ goto done;
+ }
+ break;
+ }
case GST_EVENT_GAP:
{
if (G_UNLIKELY (gst_base_sink_wait_event (basesink,
@@ -3333,11 +3355,13 @@ gst_base_sink_needs_preroll (GstBaseSink * basesink)
* 1) we are blocking in the PREROLL_LOCK and thus are prerolled.
* 2) we are syncing on the clock
*/
- is_prerolled = basesink->have_preroll || basesink->priv->received_eos;
+ is_prerolled = basesink->have_preroll || basesink->priv->received_eos ||
+ basesink->priv->received_segment_done;
res = !is_prerolled;
- GST_DEBUG_OBJECT (basesink, "have_preroll: %d, EOS: %d => needs preroll: %d",
- basesink->have_preroll, basesink->priv->received_eos, res);
+ GST_DEBUG_OBJECT (basesink, "have_preroll: %d, EOS: %d, SEGMENT DONE: %d "
+ "=> needs preroll: %d", basesink->have_preroll,
+ basesink->priv->received_eos, basesink->priv->received_segment_done, res);
return res;
}
@@ -4164,6 +4188,7 @@ gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
/* we can't have EOS anymore now */
basesink->eos = FALSE;
basesink->priv->received_eos = FALSE;
+ basesink->priv->received_segment_done = FALSE;
basesink->have_preroll = FALSE;
basesink->priv->step_unlock = FALSE;
/* can't report latency anymore until we preroll again */
@@ -5074,6 +5099,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
priv->latency = 0;
basesink->eos = FALSE;
priv->received_eos = FALSE;
+ priv->received_segment_done = FALSE;
gst_base_sink_reset_qos (basesink);
priv->rc_next = -1;
priv->commited = FALSE;