mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
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.
This commit is contained in:
parent
6da6bc4530
commit
6a6a717235
6 changed files with 175 additions and 91 deletions
|
@ -1,3 +1,11 @@
|
|||
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
|
||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit 2826306411790bf8aa9298922aa59b126897431f
|
||||
Subproject commit 4ca96aedcf2be0b3dcf31fce732aed1da21b8850
|
|
@ -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);
|
||||
|
||||
/* 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 !!");
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* and wait if needed */
|
||||
GST_PREROLL_LOCK (pad);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* and wait if needed */
|
||||
GST_PREROLL_LOCK (pad);
|
||||
|
||||
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_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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
/* 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 !!");
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* and wait if needed */
|
||||
GST_PREROLL_LOCK (pad);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* and wait if needed */
|
||||
GST_PREROLL_LOCK (pad);
|
||||
|
||||
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_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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue