gst/base/gstbasesink.*: Repost EOS message while going to PLAYING if still EOS.

Original commit message from CVS:
* gst/base/gstbasesink.c: (gst_base_sink_preroll_queue_flush),
(gst_base_sink_handle_object), (gst_base_sink_event),
(gst_base_sink_wait), (gst_base_sink_handle_event),
(gst_base_sink_change_state):
* gst/base/gstbasesink.h:
Repost EOS message while going to PLAYING if still EOS.
Make sure that when receiving a FLUSH_START we don't attempt
to sync on the clock anymore.
This commit is contained in:
Wim Taymans 2005-10-08 09:58:30 +00:00
parent c2691f6c80
commit d80f874fc8
5 changed files with 103 additions and 26 deletions

View file

@ -1,3 +1,14 @@
2005-10-08 Wim Taymans <wim@fluendo.com>
* gst/base/gstbasesink.c: (gst_base_sink_preroll_queue_flush),
(gst_base_sink_handle_object), (gst_base_sink_event),
(gst_base_sink_wait), (gst_base_sink_handle_event),
(gst_base_sink_change_state):
* gst/base/gstbasesink.h:
Repost EOS message while going to PLAYING if still EOS.
Make sure that when receiving a FLUSH_START we don't attempt
to sync on the clock anymore.
2005-10-08 Wim Taymans <wim@fluendo.com>
* tools/gst-launch.c: (event_loop):

View file

@ -432,6 +432,7 @@ gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad)
}
/* we can't have EOS anymore now */
basesink->eos = FALSE;
basesink->eos_queued = FALSE;
basesink->preroll_queued = 0;
basesink->buffers_queued = 0;
basesink->events_queued = 0;
@ -461,6 +462,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
case GST_EVENT_EOS:
basesink->preroll_queued++;
basesink->eos = TRUE;
basesink->eos_queued = TRUE;
break;
case GST_EVENT_NEWSEGMENT:
{
@ -475,6 +477,14 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
basesink->have_newsegment = TRUE;
/* any other format with 0 also gives time 0, the other values are
* invalid as time though. */
if (format != GST_FORMAT_TIME && segment_start == 0) {
format = GST_FORMAT_TIME;
segment_stop = -1;
basesink->segment_base = -1;
}
if (format != GST_FORMAT_TIME) {
GST_DEBUG_OBJECT (basesink,
"received non time %d NEW_SEGMENT %" G_GINT64_FORMAT
@ -633,7 +643,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
GST_STATE_UNLOCK (basesink);
/* reacquire stream lock, pad could be flushing now */
/* FIXME in glib, if t==0, the lock is still taken... hmmm */
/* FIXME in glib, if t==0, the lock is still taken... hmmm.. bug #317802 */
if (t > 0)
GST_STREAM_LOCK_FULL (pad, t);
@ -812,18 +822,19 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
if (bclass->event)
bclass->event (basesink, event);
GST_LOCK (basesink);
basesink->flushing = TRUE;
if (basesink->clock_id) {
gst_clock_id_unschedule (basesink->clock_id);
}
GST_UNLOCK (basesink);
GST_PREROLL_LOCK (pad);
/* we need preroll after the flush */
GST_DEBUG_OBJECT (basesink, "flushing, need preroll after flush");
basesink->need_preroll = TRUE;
/* unlock from a possible state change/preroll */
gst_base_sink_preroll_queue_flush (basesink, pad);
GST_LOCK (basesink);
if (basesink->clock_id) {
gst_clock_id_unschedule (basesink->clock_id);
}
GST_UNLOCK (basesink);
GST_PREROLL_UNLOCK (pad);
/* and we need to commit our state again on the next
@ -843,6 +854,9 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
/* now we are completely unblocked and the _chain method
* will return */
GST_STREAM_LOCK (pad);
GST_LOCK (basesink);
basesink->flushing = FALSE;
GST_UNLOCK (basesink);
/* we need new segment info after the flush. */
basesink->segment_start = -1;
basesink->segment_stop = -1;
@ -891,19 +905,27 @@ static GstClockReturn
gst_base_sink_wait (GstBaseSink * basesink, GstClockTime time)
{
GstClockReturn ret;
GstClockID id;
/* no need to attempt a clock wait if we are flushing */
if (basesink->flushing) {
return GST_CLOCK_UNSCHEDULED;
}
/* clock_id should be NULL outside of this function */
g_assert (basesink->clock_id == NULL);
g_assert (GST_CLOCK_TIME_IS_VALID (time));
basesink->clock_id = gst_clock_new_single_shot_id (basesink->clock, time);
id = gst_clock_new_single_shot_id (basesink->clock, time);
basesink->clock_id = id;
/* release the object lock while waiting */
GST_UNLOCK (basesink);
ret = gst_clock_id_wait (basesink->clock_id, NULL);
GST_LOCK (basesink);
gst_clock_id_unref (basesink->clock_id);
ret = gst_clock_id_wait (id, NULL);
GST_LOCK (basesink);
gst_clock_id_unref (id);
basesink->clock_id = NULL;
return ret;
@ -1056,6 +1078,7 @@ gst_base_sink_handle_event (GstBaseSink * basesink, GstEvent * event)
GST_DEBUG_OBJECT (basesink, "Now posting EOS");
gst_element_post_message (GST_ELEMENT (basesink),
gst_message_new_eos (GST_OBJECT (basesink)));
basesink->eos_queued = FALSE;
}
GST_PREROLL_UNLOCK (basesink->sinkpad);
break;
@ -1413,7 +1436,6 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
ret = GST_STATE_CHANGE_ASYNC;
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
{
GST_PREROLL_LOCK (basesink->sinkpad);
/* if we have EOS, we should empty the queue now as there will
* be no more data received in the chain function.
@ -1421,7 +1443,17 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
* we are pushing and syncing the buffers, better start a new
* thread to do this. */
if (basesink->eos) {
gboolean do_eos = !basesink->eos_queued;
gst_base_sink_preroll_queue_empty (basesink, basesink->sinkpad);
/* need to post EOS message here if it was not in the preroll queue we
* just emptied. */
if (do_eos) {
GST_DEBUG_OBJECT (basesink, "Now posting EOS");
gst_element_post_message (GST_ELEMENT (basesink),
gst_message_new_eos (GST_OBJECT (basesink)));
}
} else if (!basesink->have_preroll) {
/* don't need preroll, but do queue a commit_state */
GST_DEBUG_OBJECT (basesink,
@ -1440,7 +1472,6 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
}
GST_PREROLL_UNLOCK (basesink->sinkpad);
break;
}
default:
break;
}

View file

@ -72,6 +72,7 @@ struct _GstBaseSink {
gint buffers_queued;
gint events_queued;
gboolean eos;
gboolean eos_queued;
gboolean need_preroll;
gboolean have_preroll;
gboolean playing_async;
@ -93,6 +94,7 @@ struct _GstBaseSink {
GstClockID clock_id;
GstClockTime end_time;
gboolean sync;
gboolean flushing;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];

View file

@ -432,6 +432,7 @@ gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad)
}
/* we can't have EOS anymore now */
basesink->eos = FALSE;
basesink->eos_queued = FALSE;
basesink->preroll_queued = 0;
basesink->buffers_queued = 0;
basesink->events_queued = 0;
@ -461,6 +462,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
case GST_EVENT_EOS:
basesink->preroll_queued++;
basesink->eos = TRUE;
basesink->eos_queued = TRUE;
break;
case GST_EVENT_NEWSEGMENT:
{
@ -475,6 +477,14 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
basesink->have_newsegment = TRUE;
/* any other format with 0 also gives time 0, the other values are
* invalid as time though. */
if (format != GST_FORMAT_TIME && segment_start == 0) {
format = GST_FORMAT_TIME;
segment_stop = -1;
basesink->segment_base = -1;
}
if (format != GST_FORMAT_TIME) {
GST_DEBUG_OBJECT (basesink,
"received non time %d NEW_SEGMENT %" G_GINT64_FORMAT
@ -633,7 +643,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
GST_STATE_UNLOCK (basesink);
/* reacquire stream lock, pad could be flushing now */
/* FIXME in glib, if t==0, the lock is still taken... hmmm */
/* FIXME in glib, if t==0, the lock is still taken... hmmm.. bug #317802 */
if (t > 0)
GST_STREAM_LOCK_FULL (pad, t);
@ -812,18 +822,19 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
if (bclass->event)
bclass->event (basesink, event);
GST_LOCK (basesink);
basesink->flushing = TRUE;
if (basesink->clock_id) {
gst_clock_id_unschedule (basesink->clock_id);
}
GST_UNLOCK (basesink);
GST_PREROLL_LOCK (pad);
/* we need preroll after the flush */
GST_DEBUG_OBJECT (basesink, "flushing, need preroll after flush");
basesink->need_preroll = TRUE;
/* unlock from a possible state change/preroll */
gst_base_sink_preroll_queue_flush (basesink, pad);
GST_LOCK (basesink);
if (basesink->clock_id) {
gst_clock_id_unschedule (basesink->clock_id);
}
GST_UNLOCK (basesink);
GST_PREROLL_UNLOCK (pad);
/* and we need to commit our state again on the next
@ -843,6 +854,9 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
/* now we are completely unblocked and the _chain method
* will return */
GST_STREAM_LOCK (pad);
GST_LOCK (basesink);
basesink->flushing = FALSE;
GST_UNLOCK (basesink);
/* we need new segment info after the flush. */
basesink->segment_start = -1;
basesink->segment_stop = -1;
@ -891,19 +905,27 @@ static GstClockReturn
gst_base_sink_wait (GstBaseSink * basesink, GstClockTime time)
{
GstClockReturn ret;
GstClockID id;
/* no need to attempt a clock wait if we are flushing */
if (basesink->flushing) {
return GST_CLOCK_UNSCHEDULED;
}
/* clock_id should be NULL outside of this function */
g_assert (basesink->clock_id == NULL);
g_assert (GST_CLOCK_TIME_IS_VALID (time));
basesink->clock_id = gst_clock_new_single_shot_id (basesink->clock, time);
id = gst_clock_new_single_shot_id (basesink->clock, time);
basesink->clock_id = id;
/* release the object lock while waiting */
GST_UNLOCK (basesink);
ret = gst_clock_id_wait (basesink->clock_id, NULL);
GST_LOCK (basesink);
gst_clock_id_unref (basesink->clock_id);
ret = gst_clock_id_wait (id, NULL);
GST_LOCK (basesink);
gst_clock_id_unref (id);
basesink->clock_id = NULL;
return ret;
@ -1056,6 +1078,7 @@ gst_base_sink_handle_event (GstBaseSink * basesink, GstEvent * event)
GST_DEBUG_OBJECT (basesink, "Now posting EOS");
gst_element_post_message (GST_ELEMENT (basesink),
gst_message_new_eos (GST_OBJECT (basesink)));
basesink->eos_queued = FALSE;
}
GST_PREROLL_UNLOCK (basesink->sinkpad);
break;
@ -1413,7 +1436,6 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
ret = GST_STATE_CHANGE_ASYNC;
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
{
GST_PREROLL_LOCK (basesink->sinkpad);
/* if we have EOS, we should empty the queue now as there will
* be no more data received in the chain function.
@ -1421,7 +1443,17 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
* we are pushing and syncing the buffers, better start a new
* thread to do this. */
if (basesink->eos) {
gboolean do_eos = !basesink->eos_queued;
gst_base_sink_preroll_queue_empty (basesink, basesink->sinkpad);
/* need to post EOS message here if it was not in the preroll queue we
* just emptied. */
if (do_eos) {
GST_DEBUG_OBJECT (basesink, "Now posting EOS");
gst_element_post_message (GST_ELEMENT (basesink),
gst_message_new_eos (GST_OBJECT (basesink)));
}
} else if (!basesink->have_preroll) {
/* don't need preroll, but do queue a commit_state */
GST_DEBUG_OBJECT (basesink,
@ -1440,7 +1472,6 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
}
GST_PREROLL_UNLOCK (basesink->sinkpad);
break;
}
default:
break;
}

View file

@ -72,6 +72,7 @@ struct _GstBaseSink {
gint buffers_queued;
gint events_queued;
gboolean eos;
gboolean eos_queued;
gboolean need_preroll;
gboolean have_preroll;
gboolean playing_async;
@ -93,6 +94,7 @@ struct _GstBaseSink {
GstClockID clock_id;
GstClockTime end_time;
gboolean sync;
gboolean flushing;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];