From 6a6a7172352b7000c02be05a38fc8cdfaf4cebb7 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 30 Jun 2005 12:14:47 +0000 Subject: [PATCH] gst/base/gstbasesink.*: Some tweaks, only EOS and a buffer complete a preroll. Original commit message from CVS: * gst/base/gstbasesink.c: (gst_base_sink_preroll_queue_empty), (gst_base_sink_preroll_queue_flush), (gst_base_sink_handle_object), (gst_base_sink_change_state): * gst/base/gstbasesink.h: Some tweaks, only EOS and a buffer complete a preroll. --- ChangeLog | 8 +++ common | 2 +- gst/base/gstbasesink.c | 117 ++++++++++++++++++++++++++++---------------- gst/base/gstbasesink.h | 3 ++ libs/gst/base/gstbasesink.c | 117 ++++++++++++++++++++++++++++---------------- libs/gst/base/gstbasesink.h | 3 ++ 6 files changed, 167 insertions(+), 83 deletions(-) diff --git a/ChangeLog b/ChangeLog index 900d034..6e7caa8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2005-06-30 Wim Taymans + + * gst/base/gstbasesink.c: (gst_base_sink_preroll_queue_empty), + (gst_base_sink_preroll_queue_flush), (gst_base_sink_handle_object), + (gst_base_sink_change_state): + * gst/base/gstbasesink.h: + Some tweaks, only EOS and a buffer complete a preroll. + 2005-06-30 Andy Wingo * gst/gstghostpad.c (gst_ghost_pad_do_activate_push): Proxy diff --git a/common b/common index 2826306..4ca96ae 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 2826306411790bf8aa9298922aa59b126897431f +Subproject commit 4ca96aedcf2be0b3dcf31fce732aed1da21b8850 diff --git a/gst/base/gstbasesink.c b/gst/base/gstbasesink.c index be4c2bb..f0aa9f8 100644 --- a/gst/base/gstbasesink.c +++ b/gst/base/gstbasesink.c @@ -380,12 +380,28 @@ gst_base_sink_preroll_queue_empty (GstBaseSink * basesink, GstPad * pad) if (q) { GST_DEBUG ("emptying queue"); while ((obj = g_queue_pop_head (q))) { + gboolean is_buffer; + + is_buffer = GST_IS_BUFFER (obj); + if (is_buffer) { + basesink->preroll_queued--; + basesink->buffers_queued--; + } else { + switch (GST_EVENT_TYPE (obj)) { + case GST_EVENT_EOS: + basesink->preroll_queued--; + break; + default: + break; + } + basesink->events_queued--; + } /* we release the preroll lock while pushing so that we * can still flush it while blocking on the clock or * inside the element. */ GST_PREROLL_UNLOCK (pad); - if (GST_IS_BUFFER (obj)) { + if (is_buffer) { GST_DEBUG ("poped buffer %p", obj); ret = gst_base_sink_handle_buffer (basesink, GST_BUFFER (obj)); } else { @@ -417,6 +433,9 @@ gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad) } /* we can't have EOS anymore now */ basesink->eos = FALSE; + basesink->preroll_queued = 0; + basesink->buffers_queued = 0; + basesink->events_queued = 0; /* and signal any waiters now */ GST_PREROLL_SIGNAL (pad); } @@ -432,22 +451,34 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad, GST_PREROLL_LOCK (pad); /* push object on the queue */ - GST_DEBUG ("push on queue %p %p", basesink, obj); + GST_DEBUG ("push on queue %p", basesink, obj); g_queue_push_tail (basesink->preroll_queue, obj); have_event = GST_IS_EVENT (obj); - - if (have_event && GST_EVENT_TYPE (obj) == GST_EVENT_EOS) { - basesink->eos = TRUE; + if (have_event) { + switch (GST_EVENT_TYPE (obj)) { + case GST_EVENT_EOS: + basesink->preroll_queued++; + basesink->eos = TRUE; + break; + default: + break; + } + basesink->events_queued++; + } else { + basesink->preroll_queued++; + basesink->buffers_queued++; } + GST_DEBUG ("now %d preroll, %d buffers, %d events on queue", + basesink->preroll_queued, + basesink->buffers_queued, basesink->events_queued); /* check if we are prerolling */ if (!basesink->need_preroll) goto no_preroll; - length = basesink->preroll_queue->length; - /* this is the first object we queued */ - if (length == 1) { + /* there is a buffer queued */ + if (basesink->buffers_queued == 1) { GST_DEBUG ("do preroll %p", obj); /* if it's a buffer, we need to call the preroll method */ @@ -459,46 +490,50 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad, bclass->preroll (basesink, GST_BUFFER (obj)); } } - /* we are prerolling */ - GST_DEBUG ("finish preroll %p >", basesink); - basesink->have_preroll = TRUE; - GST_PREROLL_UNLOCK (pad); + length = basesink->preroll_queued; + GST_DEBUG ("prerolled length %d", length); - /* have to release STREAM_LOCK as we cannot take the STATE_LOCK - * inside the STREAM_LOCK */ - t = GST_STREAM_UNLOCK_FULL (pad); - GST_DEBUG ("released stream lock %d times", t); - if (t == 0) { - GST_WARNING ("STREAM_LOCK should have been locked !!"); - g_warning ("STREAM_LOCK should have been locked !!"); - } + if (length == 1) { + basesink->have_preroll = TRUE; + /* we are prerolling */ + GST_PREROLL_UNLOCK (pad); - /* now we commit our state */ - GST_STATE_LOCK (basesink); - GST_DEBUG ("commit state %p >", basesink); - gst_element_commit_state (GST_ELEMENT (basesink)); - GST_STATE_UNLOCK (basesink); + /* have to release STREAM_LOCK as we cannot take the STATE_LOCK + * inside the STREAM_LOCK */ + t = GST_STREAM_UNLOCK_FULL (pad); + GST_DEBUG ("released stream lock %d times", t); + if (t == 0) { + GST_WARNING ("STREAM_LOCK should have been locked !!"); + g_warning ("STREAM_LOCK should have been locked !!"); + } - /* reacquire stream lock, pad could be flushing now */ - /* FIXME in glib, if t==0, the lock is still taken... hmmm */ - if (t > 0) - GST_STREAM_LOCK_FULL (pad, t); + /* now we commit our state */ + GST_STATE_LOCK (basesink); + GST_DEBUG ("commit state %p >", basesink); + gst_element_commit_state (GST_ELEMENT (basesink)); + GST_STATE_UNLOCK (basesink); - /* and wait if needed */ - GST_PREROLL_LOCK (pad); + /* reacquire stream lock, pad could be flushing now */ + /* FIXME in glib, if t==0, the lock is still taken... hmmm */ + if (t > 0) + GST_STREAM_LOCK_FULL (pad, t); - GST_LOCK (pad); - if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) - goto flushing; - GST_UNLOCK (pad); + /* and wait if needed */ + GST_PREROLL_LOCK (pad); - /* it is possible that the application set the state to PLAYING - * now in which case we don't need to block anymore. */ - if (!basesink->need_preroll) - goto no_preroll; + GST_LOCK (pad); + if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) + goto flushing; + GST_UNLOCK (pad); + + /* it is possible that the application set the state to PLAYING + * now in which case we don't need to block anymore. */ + if (!basesink->need_preroll) + goto no_preroll; + + length = basesink->preroll_queued; + } - length = basesink->preroll_queue->length; - GST_DEBUG ("prerolled length %d", length); /* see if we need to block now. We cannot block on events, only * on buffers, the reason is that events can be sent from the * application thread and we don't want to block there. */ diff --git a/gst/base/gstbasesink.h b/gst/base/gstbasesink.h index ceeb2ea..e0d0f8a 100644 --- a/gst/base/gstbasesink.h +++ b/gst/base/gstbasesink.h @@ -54,6 +54,9 @@ struct _GstBaseSink { /*< protected >*/ /* with PREROLL_LOCK */ GQueue *preroll_queue; gint preroll_queue_max_len; + gint preroll_queued; + gint buffers_queued; + gint events_queued; guint64 offset; gboolean has_loop; diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index be4c2bb..f0aa9f8 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -380,12 +380,28 @@ gst_base_sink_preroll_queue_empty (GstBaseSink * basesink, GstPad * pad) if (q) { GST_DEBUG ("emptying queue"); while ((obj = g_queue_pop_head (q))) { + gboolean is_buffer; + + is_buffer = GST_IS_BUFFER (obj); + if (is_buffer) { + basesink->preroll_queued--; + basesink->buffers_queued--; + } else { + switch (GST_EVENT_TYPE (obj)) { + case GST_EVENT_EOS: + basesink->preroll_queued--; + break; + default: + break; + } + basesink->events_queued--; + } /* we release the preroll lock while pushing so that we * can still flush it while blocking on the clock or * inside the element. */ GST_PREROLL_UNLOCK (pad); - if (GST_IS_BUFFER (obj)) { + if (is_buffer) { GST_DEBUG ("poped buffer %p", obj); ret = gst_base_sink_handle_buffer (basesink, GST_BUFFER (obj)); } else { @@ -417,6 +433,9 @@ gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad) } /* we can't have EOS anymore now */ basesink->eos = FALSE; + basesink->preroll_queued = 0; + basesink->buffers_queued = 0; + basesink->events_queued = 0; /* and signal any waiters now */ GST_PREROLL_SIGNAL (pad); } @@ -432,22 +451,34 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad, GST_PREROLL_LOCK (pad); /* push object on the queue */ - GST_DEBUG ("push on queue %p %p", basesink, obj); + GST_DEBUG ("push on queue %p", basesink, obj); g_queue_push_tail (basesink->preroll_queue, obj); have_event = GST_IS_EVENT (obj); - - if (have_event && GST_EVENT_TYPE (obj) == GST_EVENT_EOS) { - basesink->eos = TRUE; + if (have_event) { + switch (GST_EVENT_TYPE (obj)) { + case GST_EVENT_EOS: + basesink->preroll_queued++; + basesink->eos = TRUE; + break; + default: + break; + } + basesink->events_queued++; + } else { + basesink->preroll_queued++; + basesink->buffers_queued++; } + GST_DEBUG ("now %d preroll, %d buffers, %d events on queue", + basesink->preroll_queued, + basesink->buffers_queued, basesink->events_queued); /* check if we are prerolling */ if (!basesink->need_preroll) goto no_preroll; - length = basesink->preroll_queue->length; - /* this is the first object we queued */ - if (length == 1) { + /* there is a buffer queued */ + if (basesink->buffers_queued == 1) { GST_DEBUG ("do preroll %p", obj); /* if it's a buffer, we need to call the preroll method */ @@ -459,46 +490,50 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad, bclass->preroll (basesink, GST_BUFFER (obj)); } } - /* we are prerolling */ - GST_DEBUG ("finish preroll %p >", basesink); - basesink->have_preroll = TRUE; - GST_PREROLL_UNLOCK (pad); + length = basesink->preroll_queued; + GST_DEBUG ("prerolled length %d", length); - /* have to release STREAM_LOCK as we cannot take the STATE_LOCK - * inside the STREAM_LOCK */ - t = GST_STREAM_UNLOCK_FULL (pad); - GST_DEBUG ("released stream lock %d times", t); - if (t == 0) { - GST_WARNING ("STREAM_LOCK should have been locked !!"); - g_warning ("STREAM_LOCK should have been locked !!"); - } + if (length == 1) { + basesink->have_preroll = TRUE; + /* we are prerolling */ + GST_PREROLL_UNLOCK (pad); - /* now we commit our state */ - GST_STATE_LOCK (basesink); - GST_DEBUG ("commit state %p >", basesink); - gst_element_commit_state (GST_ELEMENT (basesink)); - GST_STATE_UNLOCK (basesink); + /* have to release STREAM_LOCK as we cannot take the STATE_LOCK + * inside the STREAM_LOCK */ + t = GST_STREAM_UNLOCK_FULL (pad); + GST_DEBUG ("released stream lock %d times", t); + if (t == 0) { + GST_WARNING ("STREAM_LOCK should have been locked !!"); + g_warning ("STREAM_LOCK should have been locked !!"); + } - /* reacquire stream lock, pad could be flushing now */ - /* FIXME in glib, if t==0, the lock is still taken... hmmm */ - if (t > 0) - GST_STREAM_LOCK_FULL (pad, t); + /* now we commit our state */ + GST_STATE_LOCK (basesink); + GST_DEBUG ("commit state %p >", basesink); + gst_element_commit_state (GST_ELEMENT (basesink)); + GST_STATE_UNLOCK (basesink); - /* and wait if needed */ - GST_PREROLL_LOCK (pad); + /* reacquire stream lock, pad could be flushing now */ + /* FIXME in glib, if t==0, the lock is still taken... hmmm */ + if (t > 0) + GST_STREAM_LOCK_FULL (pad, t); - GST_LOCK (pad); - if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) - goto flushing; - GST_UNLOCK (pad); + /* and wait if needed */ + GST_PREROLL_LOCK (pad); - /* it is possible that the application set the state to PLAYING - * now in which case we don't need to block anymore. */ - if (!basesink->need_preroll) - goto no_preroll; + GST_LOCK (pad); + if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) + goto flushing; + GST_UNLOCK (pad); + + /* it is possible that the application set the state to PLAYING + * now in which case we don't need to block anymore. */ + if (!basesink->need_preroll) + goto no_preroll; + + length = basesink->preroll_queued; + } - length = basesink->preroll_queue->length; - GST_DEBUG ("prerolled length %d", length); /* see if we need to block now. We cannot block on events, only * on buffers, the reason is that events can be sent from the * application thread and we don't want to block there. */ diff --git a/libs/gst/base/gstbasesink.h b/libs/gst/base/gstbasesink.h index ceeb2ea..e0d0f8a 100644 --- a/libs/gst/base/gstbasesink.h +++ b/libs/gst/base/gstbasesink.h @@ -54,6 +54,9 @@ struct _GstBaseSink { /*< protected >*/ /* with PREROLL_LOCK */ GQueue *preroll_queue; gint preroll_queue_max_len; + gint preroll_queued; + gint buffers_queued; + gint events_queued; guint64 offset; gboolean has_loop; -- 2.7.4