event: add reset_time boolean to flush_stop event

Add a boolean to the flush_stop event to make it possible to implement flushes
that don't reset_time.
Make basesink post async_done with the reset_time property from the flush stop
event.
Fix some unit tests
This commit is contained in:
Wim Taymans 2011-06-10 11:55:08 +02:00
parent ab0ab2fbca
commit bbfec45ecc
10 changed files with 72 additions and 24 deletions

View file

@ -481,6 +481,7 @@ gst_event_new_flush_start (void)
/**
* gst_event_new_flush_stop:
* @reset_time: if time should be reset
*
* Allocate a new flush stop event. The flush stop event can be sent
* upstream and downstream and travels serialized with the dataflow.
@ -496,9 +497,39 @@ gst_event_new_flush_start (void)
* Returns: (transfer full): a new flush stop event.
*/
GstEvent *
gst_event_new_flush_stop (void)
gst_event_new_flush_stop (gboolean reset_time)
{
return gst_event_new (GST_EVENT_FLUSH_STOP);
GstEvent *event;
GST_CAT_INFO (GST_CAT_EVENT, "creating flush stop %d", reset_time);
event = gst_event_new_custom (GST_EVENT_FLUSH_STOP,
gst_structure_id_new (GST_QUARK (EVENT_FLUSH_STOP),
GST_QUARK (RESET_TIME), G_TYPE_BOOLEAN, reset_time, NULL));
return event;
}
/**
* gst_event_parse_flush_stop:
* @event: The event to parse
* @reset_time: (out): if time should be reset
*
* Parse the FLUSH_STOP event and retrieve the @reset_time member.
*/
void
gst_event_parse_flush_stop (GstEvent * event, gboolean * reset_time)
{
GstStructure *structure;
g_return_if_fail (GST_IS_EVENT (event));
g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP);
structure = GST_EVENT_STRUCTURE (event);
if (G_LIKELY (reset_time))
*reset_time =
g_value_get_boolean (gst_structure_id_get_value (structure,
GST_QUARK (RESET_TIME)));
}
/**

View file

@ -428,7 +428,9 @@ void gst_event_set_seqnum (GstEvent *event, guint32 seqnum
/* flush events */
GstEvent * gst_event_new_flush_start (void);
GstEvent * gst_event_new_flush_stop (void);
GstEvent * gst_event_new_flush_stop (gboolean reset_time);
void gst_event_parse_flush_stop (GstEvent *event, gboolean *reset_time);
/* EOS event */
GstEvent * gst_event_new_eos (void);

View file

@ -54,7 +54,7 @@ static const gchar *_quark_strings[] = {
"min-buffers", "max-buffers", "prefix", "postfix", "align", "time",
"GstQueryAllocation", "need-pool", "meta", "pool", "GstEventCaps",
"GstEventReconfigure", "segment", "GstQueryScheduling", "pull-mode",
"random-access", "sequential", "allocator"
"random-access", "sequential", "allocator", "GstEventFlushStop"
};
GQuark _priv_gst_quark_table[GST_QUARK_MAX];

View file

@ -153,8 +153,9 @@ typedef enum _GstQuarkId
GST_QUARK_RANDOM_ACCESS = 124,
GST_QUARK_SEQUENTIAL = 125,
GST_QUARK_ALLOCATOR = 126,
GST_QUARK_EVENT_FLUSH_STOP = 127,
GST_QUARK_MAX = 127
GST_QUARK_MAX = 128
} GstQuarkId;
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];

View file

@ -3669,8 +3669,8 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
/* prepare for streaming again */
if (flush) {
GST_DEBUG_OBJECT (parse, "sending flush stop");
gst_pad_push_event (parse->srcpad, gst_event_new_flush_stop ());
gst_pad_push_event (parse->sinkpad, gst_event_new_flush_stop ());
gst_pad_push_event (parse->srcpad, gst_event_new_flush_stop (TRUE));
gst_pad_push_event (parse->sinkpad, gst_event_new_flush_stop (TRUE));
gst_base_parse_clear_queues (parse);
} else {
/* keep track of our position */

View file

@ -2066,8 +2066,8 @@ gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time,
/* FIXME: Casting to GstClockEntry only works because the types
* are the same */
if (G_LIKELY (sink->priv->cached_clock_id != NULL
&& GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->
priv->cached_clock_id) == clock)) {
&& GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv->
cached_clock_id) == clock)) {
if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id,
time)) {
gst_clock_id_unref (sink->priv->cached_clock_id);
@ -3260,7 +3260,6 @@ gst_base_sink_flush_start (GstBaseSink * basesink, GstPad * pad)
* prerolled buffer */
basesink->playing_async = TRUE;
if (basesink->priv->async_enabled) {
basesink->priv->reset_time = TRUE;
gst_element_lost_state (GST_ELEMENT_CAST (basesink));
} else {
basesink->priv->have_latency = TRUE;
@ -3270,7 +3269,8 @@ gst_base_sink_flush_start (GstBaseSink * basesink, GstPad * pad)
}
static void
gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad)
gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad,
gboolean reset_time)
{
/* unset flushing so we can accept new data, this also flushes out any EOS
* event. */
@ -3287,9 +3287,12 @@ gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad)
if (basesink->pad_mode == GST_ACTIVATE_PUSH) {
/* we need new segment info after the flush. */
basesink->have_newsegment = FALSE;
gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
gst_segment_init (&basesink->clip_segment, GST_FORMAT_UNDEFINED);
if (reset_time) {
gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
gst_segment_init (&basesink->clip_segment, GST_FORMAT_UNDEFINED);
}
}
basesink->priv->reset_time = reset_time;
GST_OBJECT_UNLOCK (basesink);
}
@ -3393,15 +3396,21 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
gst_event_unref (event);
break;
case GST_EVENT_FLUSH_STOP:
{
gboolean reset_time;
if (bclass->event)
bclass->event (basesink, event);
GST_DEBUG_OBJECT (basesink, "flush-stop %p", event);
gst_event_parse_flush_stop (event, &reset_time);
GST_DEBUG_OBJECT (basesink, "flush-stop %p, reset_time: %d", event,
reset_time);
gst_base_sink_flush_stop (basesink, pad);
gst_base_sink_flush_stop (basesink, pad, reset_time);
gst_event_unref (event);
break;
}
default:
/* other events are sent to queue or subclass depending on if they
* are serialized. */
@ -3824,8 +3833,8 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
if (flush) {
GST_DEBUG_OBJECT (sink, "stop flushing upstream");
gst_pad_push_event (pad, gst_event_new_flush_stop ());
gst_base_sink_flush_stop (sink, pad);
gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
gst_base_sink_flush_stop (sink, pad, TRUE);
} else if (res && sink->running) {
/* we are running the current segment and doing a non-flushing seek,
* close the segment first based on the position. */

View file

@ -1416,7 +1416,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
/* and prepare to continue streaming */
if (flush) {
tevent = gst_event_new_flush_stop ();
tevent = gst_event_new_flush_stop (TRUE);
gst_event_set_seqnum (tevent, seqnum);
/* send flush stop, peer will accept data and events again. We
* are not yet providing data as we still have the STREAM_LOCK. */

View file

@ -469,7 +469,7 @@ GST_START_TEST (test_eos)
fail_unless (eret == TRUE);
GST_DEBUG ("sending FLUSH_STOP");
event = gst_event_new_flush_stop ();
event = gst_event_new_flush_stop (TRUE);
eret = gst_pad_send_event (sinkpad, event);
fail_unless (eret == TRUE);
}
@ -714,7 +714,7 @@ GST_START_TEST (test_position)
/* stop flushing, timing is affected now */
{
GST_DEBUG ("sending flush_stop");
event = gst_event_new_flush_stop ();
event = gst_event_new_flush_stop (TRUE);
eret = gst_pad_send_event (sinkpad, event);
fail_if (eret == FALSE);
@ -802,7 +802,7 @@ GST_START_TEST (test_position)
{
GST_DEBUG ("sending flush_stop");
event = gst_event_new_flush_stop ();
event = gst_event_new_flush_stop (TRUE);
eret = gst_pad_send_event (sinkpad, event);
fail_if (eret == FALSE);

View file

@ -39,12 +39,17 @@ GST_START_TEST (create_events)
}
/* FLUSH_STOP */
{
event = gst_event_new_flush_stop ();
gboolean reset_time;
event = gst_event_new_flush_stop (TRUE);
fail_if (event == NULL);
fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP);
fail_unless (GST_EVENT_IS_UPSTREAM (event));
fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
fail_unless (GST_EVENT_IS_SERIALIZED (event));
gst_event_parse_flush_stop (event, &reset_time);
fail_unless (reset_time == TRUE);
gst_event_unref (event);
}
/* EOS */

View file

@ -828,7 +828,7 @@ GST_START_TEST (test_block_async_full_destroy)
/* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
*/
fail_unless (state == 1);
gst_pad_push_event (pad, gst_event_new_flush_stop ());
gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
/* unblock callback is called */
gst_pad_remove_probe (pad, id);
@ -856,7 +856,7 @@ GST_START_TEST (test_block_async_full_destroy_dispose)
/* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
*/
fail_unless_equals_int (state, 1);
gst_pad_push_event (pad, gst_event_new_flush_stop ());
gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
/* gst_BLOCK calls the destroy_notify function if necessary */
gst_object_unref (pad);