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: * 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 * Allocate a new flush stop event. The flush stop event can be sent
* upstream and downstream and travels serialized with the dataflow. * 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. * Returns: (transfer full): a new flush stop event.
*/ */
GstEvent * 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 */ /* flush events */
GstEvent * gst_event_new_flush_start (void); 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 */ /* EOS event */
GstEvent * gst_event_new_eos (void); 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", "min-buffers", "max-buffers", "prefix", "postfix", "align", "time",
"GstQueryAllocation", "need-pool", "meta", "pool", "GstEventCaps", "GstQueryAllocation", "need-pool", "meta", "pool", "GstEventCaps",
"GstEventReconfigure", "segment", "GstQueryScheduling", "pull-mode", "GstEventReconfigure", "segment", "GstQueryScheduling", "pull-mode",
"random-access", "sequential", "allocator" "random-access", "sequential", "allocator", "GstEventFlushStop"
}; };
GQuark _priv_gst_quark_table[GST_QUARK_MAX]; GQuark _priv_gst_quark_table[GST_QUARK_MAX];

View file

@ -153,8 +153,9 @@ typedef enum _GstQuarkId
GST_QUARK_RANDOM_ACCESS = 124, GST_QUARK_RANDOM_ACCESS = 124,
GST_QUARK_SEQUENTIAL = 125, GST_QUARK_SEQUENTIAL = 125,
GST_QUARK_ALLOCATOR = 126, GST_QUARK_ALLOCATOR = 126,
GST_QUARK_EVENT_FLUSH_STOP = 127,
GST_QUARK_MAX = 127 GST_QUARK_MAX = 128
} GstQuarkId; } GstQuarkId;
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; 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 */ /* prepare for streaming again */
if (flush) { if (flush) {
GST_DEBUG_OBJECT (parse, "sending flush stop"); GST_DEBUG_OBJECT (parse, "sending flush stop");
gst_pad_push_event (parse->srcpad, 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 ()); gst_pad_push_event (parse->sinkpad, gst_event_new_flush_stop (TRUE));
gst_base_parse_clear_queues (parse); gst_base_parse_clear_queues (parse);
} else { } else {
/* keep track of our position */ /* 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 /* FIXME: Casting to GstClockEntry only works because the types
* are the same */ * are the same */
if (G_LIKELY (sink->priv->cached_clock_id != NULL if (G_LIKELY (sink->priv->cached_clock_id != NULL
&& GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink-> && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv->
priv->cached_clock_id) == clock)) { cached_clock_id) == clock)) {
if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id, if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id,
time)) { time)) {
gst_clock_id_unref (sink->priv->cached_clock_id); gst_clock_id_unref (sink->priv->cached_clock_id);
@ -3260,7 +3260,6 @@ gst_base_sink_flush_start (GstBaseSink * basesink, GstPad * pad)
* prerolled buffer */ * prerolled buffer */
basesink->playing_async = TRUE; basesink->playing_async = TRUE;
if (basesink->priv->async_enabled) { if (basesink->priv->async_enabled) {
basesink->priv->reset_time = TRUE;
gst_element_lost_state (GST_ELEMENT_CAST (basesink)); gst_element_lost_state (GST_ELEMENT_CAST (basesink));
} else { } else {
basesink->priv->have_latency = TRUE; basesink->priv->have_latency = TRUE;
@ -3270,7 +3269,8 @@ gst_base_sink_flush_start (GstBaseSink * basesink, GstPad * pad)
} }
static void 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 /* unset flushing so we can accept new data, this also flushes out any EOS
* event. */ * event. */
@ -3287,9 +3287,12 @@ gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad)
if (basesink->pad_mode == GST_ACTIVATE_PUSH) { if (basesink->pad_mode == GST_ACTIVATE_PUSH) {
/* we need new segment info after the flush. */ /* we need new segment info after the flush. */
basesink->have_newsegment = FALSE; basesink->have_newsegment = FALSE;
gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED); if (reset_time) {
gst_segment_init (&basesink->clip_segment, GST_FORMAT_UNDEFINED); 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); GST_OBJECT_UNLOCK (basesink);
} }
@ -3393,15 +3396,21 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
gst_event_unref (event); gst_event_unref (event);
break; break;
case GST_EVENT_FLUSH_STOP: case GST_EVENT_FLUSH_STOP:
{
gboolean reset_time;
if (bclass->event) if (bclass->event)
bclass->event (basesink, 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); gst_event_unref (event);
break; break;
}
default: default:
/* other events are sent to queue or subclass depending on if they /* other events are sent to queue or subclass depending on if they
* are serialized. */ * are serialized. */
@ -3824,8 +3833,8 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
if (flush) { if (flush) {
GST_DEBUG_OBJECT (sink, "stop flushing upstream"); GST_DEBUG_OBJECT (sink, "stop flushing upstream");
gst_pad_push_event (pad, gst_event_new_flush_stop ()); gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
gst_base_sink_flush_stop (sink, pad); gst_base_sink_flush_stop (sink, pad, TRUE);
} else if (res && sink->running) { } else if (res && sink->running) {
/* we are running the current segment and doing a non-flushing seek, /* we are running the current segment and doing a non-flushing seek,
* close the segment first based on the position. */ * 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 */ /* and prepare to continue streaming */
if (flush) { if (flush) {
tevent = gst_event_new_flush_stop (); tevent = gst_event_new_flush_stop (TRUE);
gst_event_set_seqnum (tevent, seqnum); gst_event_set_seqnum (tevent, seqnum);
/* send flush stop, peer will accept data and events again. We /* send flush stop, peer will accept data and events again. We
* are not yet providing data as we still have the STREAM_LOCK. */ * 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); fail_unless (eret == TRUE);
GST_DEBUG ("sending FLUSH_STOP"); 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); eret = gst_pad_send_event (sinkpad, event);
fail_unless (eret == TRUE); fail_unless (eret == TRUE);
} }
@ -714,7 +714,7 @@ GST_START_TEST (test_position)
/* stop flushing, timing is affected now */ /* stop flushing, timing is affected now */
{ {
GST_DEBUG ("sending flush_stop"); 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); eret = gst_pad_send_event (sinkpad, event);
fail_if (eret == FALSE); fail_if (eret == FALSE);
@ -802,7 +802,7 @@ GST_START_TEST (test_position)
{ {
GST_DEBUG ("sending flush_stop"); 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); eret = gst_pad_send_event (sinkpad, event);
fail_if (eret == FALSE); fail_if (eret == FALSE);

View file

@ -39,12 +39,17 @@ GST_START_TEST (create_events)
} }
/* FLUSH_STOP */ /* FLUSH_STOP */
{ {
event = gst_event_new_flush_stop (); gboolean reset_time;
event = gst_event_new_flush_stop (TRUE);
fail_if (event == NULL); fail_if (event == NULL);
fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP); fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP);
fail_unless (GST_EVENT_IS_UPSTREAM (event)); fail_unless (GST_EVENT_IS_UPSTREAM (event));
fail_unless (GST_EVENT_IS_DOWNSTREAM (event)); fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
fail_unless (GST_EVENT_IS_SERIALIZED (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); gst_event_unref (event);
} }
/* EOS */ /* 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 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
*/ */
fail_unless (state == 1); 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 */ /* unblock callback is called */
gst_pad_remove_probe (pad, id); 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 /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
*/ */
fail_unless_equals_int (state, 1); 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_BLOCK calls the destroy_notify function if necessary */
gst_object_unref (pad); gst_object_unref (pad);