From 2ea32f3ab55edc7858c792a66748d0a2d328a0f5 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 5 Feb 2013 17:19:50 +0100 Subject: [PATCH] basesink: handle sync of EOS after item without duration After a buffer or GAP without duration, an EOS event should be rendered immediately instead of waiting for the end of the segment. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=692868 --- libs/gst/base/gstbasesink.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index febea91..c7101b2 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -1776,13 +1776,14 @@ handle_stepping (GstBaseSink * sink, GstSegment * segment, static gboolean gst_base_sink_get_sync_times (GstBaseSink * basesink, GstMiniObject * obj, GstClockTime * rsstart, GstClockTime * rsstop, - GstClockTime * rrstart, GstClockTime * rrstop, gboolean * do_sync, - gboolean * stepped, GstStepInfo * step, gboolean * step_end) + GstClockTime * rrstart, GstClockTime * rrstop, GstClockTime * rrnext, + gboolean * do_sync, gboolean * stepped, GstStepInfo * step, + gboolean * step_end) { GstBaseSinkClass *bclass; GstClockTime start, stop; /* raw start/stop timestamps */ guint64 cstart, cstop; /* clipped raw timestamps */ - guint64 rstart, rstop; /* clipped timestamps converted to running time */ + guint64 rstart, rstop, rnext; /* clipped timestamps converted to running time */ GstClockTime sstart, sstop; /* clipped timestamps converted to stream time */ GstFormat format; GstBaseSinkPrivate *priv; @@ -1822,7 +1823,7 @@ again: } } - rstart = rstop = priv->eos_rtime; + rstart = rstop = rnext = priv->eos_rtime; *do_sync = rstart != -1; GST_DEBUG_OBJECT (basesink, "sync times for EOS %" GST_TIME_FORMAT, GST_TIME_ARGS (rstart)); @@ -1912,6 +1913,11 @@ do_times: rstart = gst_segment_to_running_time (segment, format, cstart); rstop = gst_segment_to_running_time (segment, format, cstop); + if (GST_CLOCK_TIME_IS_VALID (stop)) + rnext = rstop; + else + rnext = rstart; + if (G_UNLIKELY (step->valid)) { if (!(*step_end = handle_stepping (basesink, segment, step, &cstart, &cstop, &rstart, &rstop))) { @@ -1944,6 +1950,7 @@ eos_done: *rsstop = sstop; *rrstart = rstart; *rrstop = rstop; + *rrnext = rnext; /* buffers and EOS always need syncing and preroll */ return TRUE; @@ -2047,8 +2054,8 @@ gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time, /* FIXME: Casting to GstClockEntry only works because the types * are the same */ if (G_LIKELY (sink->priv->cached_clock_id != NULL - && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv-> - cached_clock_id) == clock)) { + && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink-> + priv->cached_clock_id) == clock)) { if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id, time)) { gst_clock_id_unref (sink->priv->cached_clock_id); @@ -2348,7 +2355,7 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstClockTimeDiff jitter = 0; gboolean syncable; GstClockReturn status = GST_CLOCK_OK; - GstClockTime rstart, rstop, sstart, sstop, stime; + GstClockTime rstart, rstop, rnext, sstart, sstop, stime; gboolean do_sync; GstBaseSinkPrivate *priv; GstFlowReturn ret; @@ -2358,7 +2365,7 @@ gst_base_sink_do_sync (GstBaseSink * basesink, priv = basesink->priv; do_step: - sstart = sstop = rstart = rstop = GST_CLOCK_TIME_NONE; + sstart = sstop = rstart = rstop = rnext = GST_CLOCK_TIME_NONE; do_sync = TRUE; stepped = FALSE; @@ -2370,7 +2377,8 @@ do_step: /* get timing information for this object against the render segment */ syncable = gst_base_sink_get_sync_times (basesink, obj, - &sstart, &sstop, &rstart, &rstop, &do_sync, &stepped, current, step_end); + &sstart, &sstop, &rstart, &rstop, &rnext, &do_sync, &stepped, current, + step_end); if (G_UNLIKELY (stepped)) goto step_skipped; @@ -2385,7 +2393,7 @@ do_step: priv->current_rstop = (GST_CLOCK_TIME_IS_VALID (rstop) ? rstop : rstart); /* save sync time for eos when the previous object needed sync */ - priv->eos_rtime = (do_sync ? priv->current_rstop : GST_CLOCK_TIME_NONE); + priv->eos_rtime = (do_sync ? rnext : GST_CLOCK_TIME_NONE); /* calculate inter frame spacing */ if (G_UNLIKELY (priv->prev_rstart != -1 && priv->prev_rstart < rstart)) { @@ -3262,13 +3270,13 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad, if (bclass->prepare || bclass->prepare_list) { gboolean late = FALSE; gboolean do_sync = TRUE, stepped = FALSE, step_end = FALSE, syncable = TRUE; - GstClockTime sstart, sstop, rstart, rstop; + GstClockTime sstart, sstop, rstart, rstop, rnext; GstStepInfo *current; current = &priv->current_step; syncable = gst_base_sink_get_sync_times (basesink, obj, &sstart, &sstop, &rstart, - &rstop, &do_sync, &stepped, current, &step_end); + &rstop, &rnext, &do_sync, &stepped, current, &step_end); if (!stepped && syncable && do_sync) late = -- 2.7.4