diff --git a/gst/gstevent.c b/gst/gstevent.c index 31f43e0d2e..821ea7b768 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -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))); } /** diff --git a/gst/gstevent.h b/gst/gstevent.h index 88670b042b..1402967a0b 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -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); diff --git a/gst/gstquark.c b/gst/gstquark.c index 68e8f974bd..07bfa9a071 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -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]; diff --git a/gst/gstquark.h b/gst/gstquark.h index 81b6776d0a..6af2a8f4a3 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -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]; diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c index 416ea8c8ea..0e3f39b16b 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -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 */ diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index c3617b2884..5a74fe7442 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -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. */ diff --git a/libs/gst/base/gstbasesrc.c b/libs/gst/base/gstbasesrc.c index 867b95b6b3..08175f7697 100644 --- a/libs/gst/base/gstbasesrc.c +++ b/libs/gst/base/gstbasesrc.c @@ -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. */ diff --git a/tests/check/elements/fakesink.c b/tests/check/elements/fakesink.c index f7f3bd936c..10756f1249 100644 --- a/tests/check/elements/fakesink.c +++ b/tests/check/elements/fakesink.c @@ -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); diff --git a/tests/check/gst/gstevent.c b/tests/check/gst/gstevent.c index c11fbfc25f..1c608c2a07 100644 --- a/tests/check/gst/gstevent.c +++ b/tests/check/gst/gstevent.c @@ -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 */ diff --git a/tests/check/gst/gstpad.c b/tests/check/gst/gstpad.c index fdfe959c1d..4a763e1de8 100644 --- a/tests/check/gst/gstpad.c +++ b/tests/check/gst/gstpad.c @@ -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);