diff options
author | Josep Torra <n770galaxy@gmail.com> | 2017-05-21 12:37:44 +0200 |
---|---|---|
committer | Josep Torra <n770galaxy@gmail.com> | 2017-05-22 18:31:54 +0200 |
commit | e812385691eecf3c694d6e1e43fe61a72f43ed4e (patch) | |
tree | 8e72c83e5a175ad78d1d5c50ac81936e87bc2a0c | |
parent | 16679b801b79fa0cd4d62582024c9c9c750ca76a (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.c | 32 |
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; |