+2005-06-30 Wim Taymans <wim@fluendo.com>
+
+ * 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 <wingo@pobox.com>
* gst/gstghostpad.c (gst_ghost_pad_do_activate_push): Proxy
-Subproject commit 2826306411790bf8aa9298922aa59b126897431f
+Subproject commit 4ca96aedcf2be0b3dcf31fce732aed1da21b8850
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 {
}
/* 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);
}
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 */
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. */
/*< 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;
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 {
}
/* 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);
}
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 */
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. */
/*< 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;