From: Wim Taymans Date: Fri, 14 Sep 2007 15:52:27 +0000 (+0000) Subject: libs/gst/base/gstbasesink.c: Latency query is allowed after we are prerolled. Introdu... X-Git-Tag: RELEASE-0_10_15~120 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4987f5a70f634582b1cb250683d0dc1d6523e10b;p=platform%2Fupstream%2Fgstreamer.git libs/gst/base/gstbasesink.c: Latency query is allowed after we are prerolled. Introduce a new flag for this and stop ... Original commit message from CVS: * libs/gst/base/gstbasesink.c: (gst_base_sink_init), (gst_base_sink_preroll_queue_flush), (gst_base_sink_commit_state), (gst_base_sink_wait_preroll), (gst_base_sink_needs_preroll), (gst_base_sink_set_flushing), (gst_base_sink_query), (gst_base_sink_change_state): Latency query is allowed after we are prerolled. Introduce a new flag for this and stop abusing other variables. --- diff --git a/ChangeLog b/ChangeLog index f5a6bcd..49a3e35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2007-09-14 Wim Taymans + + * libs/gst/base/gstbasesink.c: (gst_base_sink_init), + (gst_base_sink_preroll_queue_flush), (gst_base_sink_commit_state), + (gst_base_sink_wait_preroll), (gst_base_sink_needs_preroll), + (gst_base_sink_set_flushing), (gst_base_sink_query), + (gst_base_sink_change_state): + Latency query is allowed after we are prerolled. Introduce a new flag + for this and stop abusing other variables. + 2007-09-13 Wim Taymans * libs/gst/base/gstbasesrc.c: (gst_base_src_send_event): diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index bdfc025..84248fd 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -204,6 +204,9 @@ struct _GstBaseSinkPrivate /* when we received EOS */ gboolean received_eos; + + /* when we are prerolled and able to report latency */ + gboolean have_latency; }; #define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size)) @@ -522,6 +525,7 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class) basesink->pad_mode = GST_ACTIVATE_NONE; basesink->preroll_queue = g_queue_new (); basesink->abidata.ABI.clip_segment = gst_segment_new (); + priv->have_latency = FALSE; basesink->can_activate_push = DEFAULT_CAN_ACTIVATE_PUSH; basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL; @@ -983,14 +987,16 @@ gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad) gst_mini_object_unref (obj); } /* we can't have EOS anymore now */ - GST_OBJECT_LOCK (basesink); basesink->eos = FALSE; basesink->have_preroll = FALSE; - GST_OBJECT_UNLOCK (basesink); basesink->eos_queued = FALSE; basesink->preroll_queued = 0; basesink->buffers_queued = 0; basesink->events_queued = 0; + /* can't report latency anymore until we preroll again */ + GST_OBJECT_LOCK (basesink); + basesink->priv->have_latency = FALSE; + GST_OBJECT_UNLOCK (basesink); /* and signal any waiters now */ GST_PAD_PREROLL_SIGNAL (pad); } @@ -1104,6 +1110,9 @@ gst_base_sink_commit_state (GstBaseSink * basesink) break; } + /* we can report latency queries now */ + basesink->priv->have_latency = TRUE; + GST_STATE (basesink) = pending; GST_STATE_NEXT (basesink) = GST_STATE_VOID_PENDING; GST_STATE_PENDING (basesink) = GST_STATE_VOID_PENDING; @@ -1153,6 +1162,8 @@ nothing_pending: basesink->flushing = TRUE; break; } + /* we can report latency queries now */ + basesink->priv->have_latency = TRUE; GST_OBJECT_UNLOCK (basesink); return TRUE; } @@ -1401,22 +1412,11 @@ no_clock: GstFlowReturn gst_base_sink_wait_preroll (GstBaseSink * sink) { - /* have_preroll is also protected with the OBJECT lock */ - GST_OBJECT_LOCK (sink); sink->have_preroll = TRUE; - GST_OBJECT_UNLOCK (sink); - - GST_DEBUG_OBJECT (sink, "wait for preroll..."); - + GST_DEBUG_OBJECT (sink, "waiting in preroll for flush or PLAYING"); /* block until the state changes, or we get a flush, or something */ GST_PAD_PREROLL_WAIT (sink->sinkpad); - - GST_DEBUG_OBJECT (sink, "preroll done"); - - GST_OBJECT_LOCK (sink); sink->have_preroll = FALSE; - GST_OBJECT_UNLOCK (sink); - if (G_UNLIKELY (sink->flushing)) goto stopping; GST_DEBUG_OBJECT (sink, "continue after preroll"); @@ -2258,18 +2258,16 @@ gst_base_sink_get_times (GstBaseSink * basesink, GstBuffer * buffer, } } -/* no lock is needed */ +/* must be called with PREROLL_LOCK */ static gboolean gst_base_sink_needs_preroll (GstBaseSink * basesink) { gboolean is_prerolled, res; - GST_OBJECT_LOCK (basesink); is_prerolled = basesink->have_preroll || basesink->eos; res = !is_prerolled && basesink->pad_mode != GST_ACTIVATE_PULL; GST_DEBUG_OBJECT (basesink, "have_preroll: %d, EOS: %d => needs preroll: %d", basesink->have_preroll, basesink->eos, res); - GST_OBJECT_UNLOCK (basesink); return res; } @@ -2474,8 +2472,11 @@ gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad, if (bclass->unlock_stop) bclass->unlock_stop (basesink); - /* step 2, unblock clock sync (if any) or any other blocking thing */ + /* set need_preroll before we unblock the clock. If the clock is unblocked + * before timing out, we can reuse the buffer for preroll. */ basesink->need_preroll = TRUE; + + /* step 2, unblock clock sync (if any) or any other blocking thing */ if (basesink->clock_id) { gst_clock_id_unschedule (basesink->clock_id); } @@ -2943,10 +2944,15 @@ gst_base_sink_query (GstElement * element, GstQuery * query) break; case GST_QUERY_LATENCY: { - gboolean live, us_live; + gboolean live, us_live, have_latency; GstClockTime min, max; - if (gst_base_sink_needs_preroll (basesink)) { + /* we need to be negotiated before we can report caps */ + GST_OBJECT_LOCK (basesink); + have_latency = basesink->priv->have_latency; + GST_OBJECT_UNLOCK (basesink); + + if (!have_latency) { GST_DEBUG_OBJECT (basesink, "not prerolled yet, can't report latency"); res = FALSE; } else { @@ -2956,7 +2962,7 @@ gst_base_sink_query (GstElement * element, GstQuery * query) * compensation */ if (!live || !us_live) { GST_DEBUG_OBJECT (basesink, - "no latency compensation, we or upstream are not live"); + "no latency compensation, we %d, upstream %d", live, us_live); min = 0; max = -1; } @@ -3104,7 +3110,11 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition) if (bclass->unlock_stop) bclass->unlock_stop (basesink); + /* we need preroll again and we set the flag before unlocking the clockid + * because if the clockid is unlocked before a current buffer expired, we + * can use that buffer to preroll with */ basesink->need_preroll = TRUE; + if (basesink->clock_id) { gst_clock_id_unschedule (basesink->clock_id); }