From 1e82f617e4883d7b9a3ce2000d83d3b9d275e39d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 14 Jan 2004 00:46:48 +0000 Subject: [PATCH] gst/gstclock.*: deprecate old interface and disable functions that aren't in use anymore. Original commit message from CVS: 2004-01-13 Benjamin Otte * gst/gstclock.c: (gst_clock_class_init), (gst_clock_init), (gst_clock_set_speed), (gst_clock_set_active), (gst_clock_is_active), (gst_clock_reset), (gst_clock_handle_discont): * gst/gstclock.h: deprecate old interface and disable functions that aren't in use anymore. * gst/gstelement.h: * gst/gstelement.c: (gst_element_get_time), (gst_element_wait), (gst_element_set_time), (gst_element_adjust_time): add concept of "element time" and functions to get/set this time. * gst/gstelement.c: (gst_element_change_state): update element time correctly. * gst/gstelement.c: (gst_element_get_compatible_pad_filtered): This is a debug message, not a g_critical. * gst/gstpad.c: (gst_pad_event_default): handle discontinuous events right with element time. * gst/gstscheduler.c: (gst_scheduler_state_transition): update to clocking fixes. set clocks on elements in READY=>PAUSED. The old behaviour caused a wrong element time on the first element that started playing. * gst/schedulers/gstbasicscheduler.c: (gst_basic_scheduler_class_init): * gst/schedulers/gstoptimalscheduler.c: (gst_opt_scheduler_class_init): remove code that just implements the default behaviour. * gst/elements/gstfakesink.c: (gst_fakesink_chain): update to use new clocking functions * testsuite/clock/clock1.c: (gst_clock_debug), (main): * testsuite/clock/clock2.c: (gst_clock_debug), (main): update to test new element time. * gst/autoplug/gstspideridentity.c: (gst_spider_identity_getcaps): use _get_allowed_caps instead of _get_caps. This catches filtered caps correctly. * testsuite/debug/commandline.c: update for new GST_DEBUG syntax. * testsuite/threads/Makefile.am: disable a test that only works sometimes. --- ChangeLog | 41 ++++++ gst/autoplug/gstspideridentity.c | 6 +- gst/elements/gstfakesink.c | 7 +- gst/gstclock.c | 136 +++++++++---------- gst/gstclock.h | 24 +++- gst/gstelement.c | 170 +++++++++++++++++++++++- gst/gstelement.h | 8 +- gst/gstpad.c | 2 +- gst/gstscheduler.c | 28 +--- gst/schedulers/gstbasicscheduler.c | 11 +- gst/schedulers/gstoptimalscheduler.c | 11 +- plugins/elements/gstfakesink.c | 7 +- tests/old/testsuite/clock/clock1.c | 12 +- tests/old/testsuite/clock/clock2.c | 50 +++---- tests/old/testsuite/debug/commandline.c | 4 +- tests/old/testsuite/threads/Makefile.am | 4 +- testsuite/clock/clock1.c | 12 +- testsuite/clock/clock2.c | 50 +++---- testsuite/debug/commandline.c | 4 +- testsuite/threads/Makefile.am | 4 +- 20 files changed, 372 insertions(+), 219 deletions(-) diff --git a/ChangeLog b/ChangeLog index d159b275f2..142d6f0ff4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,44 @@ +2004-01-13 Benjamin Otte + + * gst/gstclock.c: (gst_clock_class_init), (gst_clock_init), + (gst_clock_set_speed), (gst_clock_set_active), + (gst_clock_is_active), (gst_clock_reset), + (gst_clock_handle_discont): + * gst/gstclock.h: + deprecate old interface and disable functions that aren't in use + anymore. + * gst/gstelement.h: + * gst/gstelement.c: (gst_element_get_time), (gst_element_wait), + (gst_element_set_time), (gst_element_adjust_time): + add concept of "element time" and functions to get/set this time. + * gst/gstelement.c: (gst_element_change_state): + update element time correctly. + * gst/gstelement.c: (gst_element_get_compatible_pad_filtered): + This is a debug message, not a g_critical. + * gst/gstpad.c: (gst_pad_event_default): + handle discontinuous events right with element time. + * gst/gstscheduler.c: (gst_scheduler_state_transition): + update to clocking fixes. + set clocks on elements in READY=>PAUSED. The old behaviour caused + a wrong element time on the first element that started playing. + * gst/schedulers/gstbasicscheduler.c: + (gst_basic_scheduler_class_init): + * gst/schedulers/gstoptimalscheduler.c: + (gst_opt_scheduler_class_init): + remove code that just implements the default behaviour. + * gst/elements/gstfakesink.c: (gst_fakesink_chain): + update to use new clocking functions + * testsuite/clock/clock1.c: (gst_clock_debug), (main): + * testsuite/clock/clock2.c: (gst_clock_debug), (main): + update to test new element time. + * gst/autoplug/gstspideridentity.c: (gst_spider_identity_getcaps): + use _get_allowed_caps instead of _get_caps. This catches filtered + caps correctly. + * testsuite/debug/commandline.c: + update for new GST_DEBUG syntax. + * testsuite/threads/Makefile.am: + disable a test that only works sometimes. + 2004-01-13 Julien MOUTTE * po/LINGUAS: Adding fr. diff --git a/gst/autoplug/gstspideridentity.c b/gst/autoplug/gstspideridentity.c index 3df2552ede..cbc5aaada7 100644 --- a/gst/autoplug/gstspideridentity.c +++ b/gst/autoplug/gstspideridentity.c @@ -251,10 +251,8 @@ gst_spider_identity_getcaps (GstPad *pad) otherpad = ident->src; if (otherpad != NULL) { - GstPad *peer = GST_PAD_PEER (otherpad); - - if (peer) { - GstCaps *ret = gst_pad_get_caps (peer); + if (GST_PAD_PEER (otherpad)) { + GstCaps *ret = gst_pad_get_allowed_caps (otherpad); if (ident->caps) { GstCaps *ret2 = gst_caps_intersect (ident->caps, ret); gst_caps_free (ret); diff --git a/gst/elements/gstfakesink.c b/gst/elements/gstfakesink.c index b402b9caa8..61621d9e73 100644 --- a/gst/elements/gstfakesink.c +++ b/gst/elements/gstfakesink.c @@ -312,7 +312,7 @@ gst_fakesink_chain (GstPad *pad, GstData *_data) case GST_EVENT_DISCONTINUOUS: if (fakesink->sync && fakesink->clock) { gint64 value = GST_EVENT_DISCONT_OFFSET (event, 0).value; - gst_clock_handle_discont (fakesink->clock, value); + gst_element_set_time (GST_ELEMENT (fakesink), value); } default: gst_pad_event_default (pad, event); @@ -322,10 +322,7 @@ gst_fakesink_chain (GstPad *pad, GstData *_data) } if (fakesink->sync && fakesink->clock) { - GstClockID id = gst_clock_new_single_shot_id (fakesink->clock, GST_BUFFER_TIMESTAMP (buf)); - - gst_element_clock_wait (GST_ELEMENT (fakesink), id, NULL); - gst_clock_id_free (id); + gst_element_wait (GST_ELEMENT (fakesink), GST_BUFFER_TIMESTAMP (buf)); } if (!fakesink->silent) { diff --git a/gst/gstclock.c b/gst/gstclock.c index 180c7526d3..3901262113 100644 --- a/gst/gstclock.c +++ b/gst/gstclock.c @@ -34,16 +34,21 @@ static GstAllocTrace *_gst_clock_entry_trace; #endif +#define DEFAULT_EVENT_DIFF (GST_SECOND / 10) #define DEFAULT_MAX_DIFF (2 * GST_SECOND) enum { ARG_0, ARG_STATS, - ARG_MAX_DIFF + ARG_MAX_DIFF, + ARG_EVENT_DIFF }; static GstMemChunk *_gst_clock_entries_chunk; +void gst_clock_id_unlock (GstClockID id); + + static void gst_clock_class_init (GstClockClass *klass); static void gst_clock_init (GstClock *clock); static void gst_clock_dispose (GObject *object); @@ -381,6 +386,10 @@ gst_clock_class_init (GstClockClass *klass) g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_DIFF, g_param_spec_int64 ("max-diff", "Max diff", "The maximum amount of time to wait in nanoseconds", 0, G_MAXINT64, DEFAULT_MAX_DIFF, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_DIFF, + g_param_spec_uint64 ("event-diff", "event diff", + "The amount of time that may elapse until 2 events are treated as happening at different times", + 0, G_MAXUINT64, DEFAULT_EVENT_DIFF, G_PARAM_READWRITE)); } static void @@ -389,7 +398,7 @@ gst_clock_init (GstClock *clock) clock->max_diff = DEFAULT_MAX_DIFF; clock->speed = 1.0; - clock->active = FALSE; + clock->active = TRUE; clock->start_time = 0; clock->last_time = 0; clock->entries = NULL; @@ -424,15 +433,9 @@ gst_clock_dispose (GObject *object) gdouble gst_clock_set_speed (GstClock *clock, gdouble speed) { - GstClockClass *cclass; - g_return_val_if_fail (GST_IS_CLOCK (clock), 0.0); - cclass = GST_CLOCK_GET_CLASS (clock); - - if (cclass->change_speed) - clock->speed = cclass->change_speed (clock, clock->speed, speed); - + GST_WARNING_OBJECT (clock, "called deprecated function"); return clock->speed; } @@ -449,6 +452,7 @@ gst_clock_get_speed (GstClock *clock) { g_return_val_if_fail (GST_IS_CLOCK (clock), 0.0); + GST_WARNING_OBJECT (clock, "called deprecated function"); return clock->speed; } @@ -511,34 +515,11 @@ gst_clock_get_resolution (GstClock *clock) void gst_clock_set_active (GstClock *clock, gboolean active) { - GstClockTime time = G_GINT64_CONSTANT (0); - GstClockClass *cclass; - g_return_if_fail (GST_IS_CLOCK (clock)); + + GST_ERROR_OBJECT (clock, "called deprecated function that does nothing now."); - clock->active = active; - - cclass = GST_CLOCK_GET_CLASS (clock); - - if (cclass->get_internal_time) { - time = cclass->get_internal_time (clock); - } - - GST_LOCK (clock); - if (active) { - clock->start_time = time - clock->last_time; - clock->accept_discont = TRUE; - } - else { - clock->last_time = time - clock->start_time; - clock->accept_discont = FALSE; - } - g_list_foreach (clock->entries, (GFunc) gst_clock_reschedule_func, NULL); - GST_UNLOCK (clock); - - g_mutex_lock (clock->active_mutex); - g_cond_broadcast (clock->active_cond); - g_mutex_unlock (clock->active_mutex); + return; } /** @@ -554,7 +535,9 @@ gst_clock_is_active (GstClock *clock) { g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE); - return clock->active; + GST_WARNING_OBJECT (clock, "called deprecated function."); + + return TRUE; } /** @@ -571,6 +554,8 @@ gst_clock_reset (GstClock *clock) g_return_if_fail (GST_IS_CLOCK (clock)); + GST_ERROR_OBJECT (clock, "called deprecated function."); + cclass = GST_CLOCK_GET_CLASS (clock); if (cclass->get_internal_time) { @@ -578,7 +563,7 @@ gst_clock_reset (GstClock *clock) } GST_LOCK (clock); - clock->active = FALSE; + //clock->active = FALSE; clock->start_time = time; clock->last_time = G_GINT64_CONSTANT (0); g_list_foreach (clock->entries, (GFunc) gst_clock_reschedule_func, NULL); @@ -599,35 +584,9 @@ gst_clock_reset (GstClock *clock) gboolean gst_clock_handle_discont (GstClock *clock, guint64 time) { - GstClockTime itime = G_GINT64_CONSTANT (0); - GstClockClass *cclass = GST_CLOCK_GET_CLASS (clock);; + GST_ERROR_OBJECT (clock, "called deprecated function."); - GST_CAT_DEBUG (GST_CAT_CLOCK, "clock discont %" G_GUINT64_FORMAT - " %" G_GUINT64_FORMAT " %d", - time, clock->start_time, clock->accept_discont); - - if (! GST_CLOCK_TIME_IS_VALID (time)) - return TRUE; - - GST_LOCK (clock); - if (cclass->get_internal_time) { - itime = cclass->get_internal_time (clock); - } - - clock->start_time = itime - time; - clock->last_time = time; - clock->accept_discont = FALSE; - g_list_foreach (clock->entries, (GFunc) gst_clock_reschedule_func, NULL); - GST_UNLOCK (clock); - - GST_CAT_DEBUG (GST_CAT_CLOCK, "new time %" G_GUINT64_FORMAT, - gst_clock_get_time (clock)); - - g_mutex_lock (clock->active_mutex); - g_cond_broadcast (clock->active_cond); - g_mutex_unlock (clock->active_mutex); - - return TRUE; + return FALSE; } /** @@ -646,11 +605,6 @@ gst_clock_get_time (GstClock *clock) g_return_val_if_fail (GST_IS_CLOCK (clock), G_GINT64_CONSTANT (0)); - if (!clock->active) { - /* clock is not active return previous time */ - ret = clock->last_time; - } - else { GstClockClass *cclass; cclass = GST_CLOCK_GET_CLASS (clock); @@ -665,11 +619,42 @@ gst_clock_get_time (GstClock *clock) else { clock->last_time = ret; } - } return ret; } +/** + * gst_clock_get_event_time: + * @clock: clock to query + * + * Gets the "event time" of a given clock. An event on the clock happens + * whenever this function is called. This ensures that multiple events that + * happen shortly after each other are treated as if they happened at the same + * time. GStreamer uses to keep state changes of multiple elements in sync. + * + * Returns: the time of the event + */ +GstClockTime +gst_clock_get_event_time (GstClock *clock) +{ + GstClockTime time; + + g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE); + + time = gst_clock_get_time (clock); + + if (clock->last_event + clock->max_event_diff >= time) { + GST_LOG_OBJECT (clock, "reporting last event time %"G_GUINT64_FORMAT, + clock->last_event); + } else { + GST_LOG_OBJECT (clock, "reporting new event time %"G_GUINT64_FORMAT, + clock->last_event); + clock->last_event = time; + } + + return clock->last_event; +} + /** * gst_clock_get_next_id * @clock: The clock to query @@ -709,9 +694,15 @@ gst_clock_set_property (GObject *object, guint prop_id, switch (prop_id) { case ARG_STATS: clock->stats = g_value_get_boolean (value); + g_object_notify (object, "stats"); break; case ARG_MAX_DIFF: clock->max_diff = g_value_get_int64 (value); + g_object_notify (object, "max-diff"); + break; + case ARG_EVENT_DIFF: + clock->max_event_diff = g_value_get_uint64 (value); + g_object_notify (object, "max-event-diff"); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -734,6 +725,9 @@ gst_clock_get_property (GObject *object, guint prop_id, case ARG_MAX_DIFF: g_value_set_int64 (value, clock->max_diff); break; + case ARG_EVENT_DIFF: + g_value_set_uint64 (value, clock->max_event_diff); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/gstclock.h b/gst/gstclock.h index 37d7e2871f..3df9249b94 100644 --- a/gst/gstclock.h +++ b/gst/gstclock.h @@ -128,16 +128,21 @@ struct _GstClock { gint64 max_diff; /* --- private --- */ - gboolean accept_discont; - gdouble speed; + gboolean accept_discont; /* FIXME: REMOVE! */ + gdouble speed; /* FIXME: REMOVE! */ guint64 resolution; - gboolean active; + gboolean active; /* FIXME: REMOVE! */ GList *entries; GMutex *active_mutex; GCond *active_cond; gboolean stats; - gpointer _gst_reserved[GST_PADDING]; + GstClockTime last_event; + GstClockTime max_event_diff; + + /* weird padding here */ + guint8 padding[sizeof(gpointer) * GST_PADDING - sizeof (GstClockTime) * 2]; + /*gpointer _gst_reserved[GST_PADDING];*/ }; struct _GstClockClass { @@ -158,25 +163,32 @@ struct _GstClockClass { GstClockEntryStatus (*wait_async) (GstClock *clock, GstClockEntry *entry); void (*unschedule) (GstClock *clock, GstClockEntry *entry); void (*unlock) (GstClock *clock, GstClockEntry *entry); - gpointer _gst_reserved[GST_PADDING]; }; GType gst_clock_get_type (void); +#ifndef GST_DISABLE_DEPRECATED gdouble gst_clock_set_speed (GstClock *clock, gdouble speed); gdouble gst_clock_get_speed (GstClock *clock); +#endif guint64 gst_clock_set_resolution (GstClock *clock, guint64 resolution); guint64 gst_clock_get_resolution (GstClock *clock); +#ifndef GST_DISABLE_DEPRECATED void gst_clock_set_active (GstClock *clock, gboolean active); gboolean gst_clock_is_active (GstClock *clock); void gst_clock_reset (GstClock *clock); gboolean gst_clock_handle_discont (GstClock *clock, guint64 time); +#endif GstClockTime gst_clock_get_time (GstClock *clock); +GstClockTime gst_clock_get_event_time (GstClock *clock); + +/* FIXME: deprecate? */ +#ifndef GST_DISABLE_DEPRECATED GstClockID gst_clock_get_next_id (GstClock *clock); /* creating IDs that can be used to get notifications */ @@ -196,6 +208,8 @@ GstClockReturn gst_clock_id_wait_async (GstClockID id, void gst_clock_id_unschedule (GstClockID id); void gst_clock_id_unlock (GstClockID id); void gst_clock_id_free (GstClockID id); +#endif + G_END_DECLS diff --git a/gst/gstelement.c b/gst/gstelement.c index 1f31996721..24f1b67465 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -792,13 +792,162 @@ gst_element_clock_wait (GstElement *element, GstClockID id, GstClockTimeDiff *ji return res; } +#undef GST_CAT_DEFAULT +#define GST_CAT_DEFAULT GST_CAT_CLOCK +/** + * gst_element_get_time: + * @element: element to query + * + * Query the element's time. The element must use + * + * Returns: the current time of the element or #GST_CLOCK_TIME_NONE when there + * is no time available. + */ +GstClockTime +gst_element_get_time (GstElement *element) +{ + g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE); + + if (element->clock == NULL) { + GST_WARNING_OBJECT (element, "element queries time but has no clock"); + return GST_CLOCK_TIME_NONE; + } + switch (element->current_state) { + case GST_STATE_NULL: + case GST_STATE_READY: + return GST_CLOCK_TIME_NONE; + case GST_STATE_PAUSED: + return element->base_time; + case GST_STATE_PLAYING: + return gst_clock_get_time (element->clock) - element->base_time; + default: + g_assert_not_reached (); + return GST_CLOCK_TIME_NONE; + } +} + +GstClockID gst_clock_new_single_shot_id (GstClock *clock, + GstClockTime time); +void gst_clock_id_free (GstClockID id); +/** + * gst_element_wait: + * @element: element that should wait + * @timestamp: wait until this time has arrived + * + * Waits until the given time has arrived. When this function returns successfully, + * the time specified in the timestamp has passed. + * This function can only be called on elements in #GST_STATE_PLAYING + * + * Returns: TRUE on success + */ +gboolean +gst_element_wait (GstElement *element, GstClockTime timestamp) +{ + GstClockID id; + GstClockReturn ret; + + g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); + g_return_val_if_fail (GST_IS_CLOCK (element->clock), FALSE); + g_return_val_if_fail (element->current_state == GST_STATE_PLAYING, FALSE); + g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); + + /* shortcut when we're already late... */ + if (gst_element_get_time (element) >= timestamp) { + GST_INFO_OBJECT (element, "called gst_element_wait and was late"); + return TRUE; + } + + id = gst_clock_new_single_shot_id (element->clock, element->base_time + timestamp); + ret = gst_element_clock_wait (element, id, NULL); + gst_clock_id_free (id); + + return ret == GST_CLOCK_STOPPED; +} + +/** + * gst_element_set_time: + * @element: element to set time on + * @time: time to set + * + * Sets the current time of the element. This function can be used when handling + * discont events. You can only call this function on an element with a clock in + * #GST_STATE_PAUSED or #GST_STATE_PLAYING. You might want to have a look at + * gst_element_adjust_time(), if you want to adjust by a difference as that is + * more accurate. + */ +void +gst_element_set_time (GstElement *element, GstClockTime time) +{ + g_return_if_fail (GST_IS_ELEMENT (element)); + g_return_if_fail (GST_IS_CLOCK (element->clock)); + g_return_if_fail (element->current_state >= GST_STATE_PAUSED); + + switch (element->current_state) { + case GST_STATE_PAUSED: + element->base_time = time; + break; + case GST_STATE_PLAYING: + element->base_time = gst_clock_get_time (element->clock) - time; + break; + default: + g_assert_not_reached (); + break; + } +} + +/** + * gst_element_adjust_time: + * @element: element to adjust time on + * @difference: difference to adjust + * + * Adjusts the current time of the element by the specified difference. This + * function can be used when handling discont events. You can only call this + * function on an element with a clock in #GST_STATE_PAUSED or + * #GST_STATE_PLAYING. It is more accurate than gst_element_set_time(). + */ +void +gst_element_adjust_time (GstElement *element, GstClockTimeDiff diff) +{ + GstClockTime time; + + g_return_if_fail (GST_IS_ELEMENT (element)); + g_return_if_fail (GST_IS_CLOCK (element->clock)); + g_return_if_fail (element->current_state >= GST_STATE_PAUSED); + + switch (element->current_state) { + case GST_STATE_PAUSED: + if (diff < 0 && element->base_time < abs (diff)) { + g_warning ("attempted to set the current time of element %s below 0", + GST_OBJECT_NAME (element)); + element->base_time = 0; + } else { + element->base_time += diff; + } + break; + case GST_STATE_PLAYING: + time = gst_clock_get_time (element->clock); + if (time < element->base_time - diff) { + g_warning ("attempted to set the current time of element %s below 0", + GST_OBJECT_NAME (element)); + element->base_time = time; + } else { + element->base_time -= diff; + } + break; + default: + g_assert_not_reached (); + break; + } +} + +#undef GST_CAT_DEFAULT #ifndef GST_DISABLE_INDEX /** * gst_element_is_indexable: * @element: a #GstElement. * - * Queries if the element can be indexed/ + * Queries if the element can be indexed. * * Returns: TRUE if the element can be indexed. */ @@ -1496,8 +1645,8 @@ gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad, if (foundpad) return foundpad; //} - g_critical("Could not find a compatible pad on element %s to link to %s:%s", - GST_ELEMENT_NAME (element), GST_DEBUG_PAD_NAME (pad)); + GST_DEBUG_OBJECT (element, "Could not find a compatible pad to link to %s:%s", + GST_DEBUG_PAD_NAME (pad)); return NULL; } @@ -2581,19 +2730,34 @@ gst_element_change_state (GstElement *element) switch (old_transition) { case GST_STATE_PLAYING_TO_PAUSED: + if (element->clock) { + GstClockTime time = gst_clock_get_event_time (element->clock); + g_assert (time >= element->base_time); + element->base_time = time - element->base_time; + GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %" + G_GINT64_FORMAT, element->base_time); + } gst_element_pads_activate (element, FALSE); break; case GST_STATE_PAUSED_TO_PLAYING: gst_element_pads_activate (element, TRUE); + if (element->clock) { + GstClockTime time = gst_clock_get_event_time (element->clock); + element->base_time = time - element->base_time; + GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %" + G_GINT64_FORMAT, element->base_time); + } break; /* if we are going to paused, we try to negotiate the pads */ case GST_STATE_READY_TO_PAUSED: + g_assert (element->base_time == 0); if (!gst_element_negotiate_pads (element)) goto failure; break; /* going to the READY state clears all pad caps */ /* FIXME: Why doesn't this happen on READY => NULL? -- Company */ case GST_STATE_PAUSED_TO_READY: + element->base_time = 0; gst_element_clear_pad_caps (element); break; default: diff --git a/gst/gstelement.h b/gst/gstelement.h index 3ae5fbd8a7..e8403249e9 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -159,7 +159,7 @@ struct _GstElement { /* allocated clock */ GstClock *clock; - GstClockTime base_time; + GstClockTimeDiff base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */ /* element pads */ guint16 numpads; @@ -275,8 +275,14 @@ gboolean gst_element_requires_clock (GstElement *element); gboolean gst_element_provides_clock (GstElement *element); GstClock* gst_element_get_clock (GstElement *element); void gst_element_set_clock (GstElement *element, GstClock *clock); +#ifndef GST_DEISABLE_DEPRECATED GstClockReturn gst_element_clock_wait (GstElement *element, GstClockID id, GstClockTimeDiff *jitter); +#endif +GstClockTime gst_element_get_time (GstElement *element); +gboolean gst_element_wait (GstElement *element, GstClockTime timestamp); +void gst_element_set_time (GstElement *element, GstClockTime time); +void gst_element_adjust_time (GstElement *element, GstClockTimeDiff diff); /* indexs */ gboolean gst_element_is_indexable (GstElement *element); diff --git a/gst/gstpad.c b/gst/gstpad.c index 9f2a8667c3..877d1ba332 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -3445,7 +3445,7 @@ gst_pad_event_default (GstPad *pad, GstEvent *event) if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)) { if (gst_element_requires_clock (element) && element->clock) { - gst_clock_handle_discont (element->clock, time); + gst_element_set_time (element, time); } } } diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c index d194b67cb8..9485ea7966 100644 --- a/gst/gstscheduler.c +++ b/gst/gstscheduler.c @@ -303,38 +303,12 @@ gst_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint t case GST_STATE_READY_TO_PAUSED: { GstClock *clock = gst_scheduler_get_clock (sched); - - if (clock) - gst_clock_reset (clock); - GST_CAT_DEBUG (GST_CAT_CLOCK, "scheduler READY to PAUSED clock is %p (%s)", clock, (clock ? GST_OBJECT_NAME (clock) : "nil")); - gst_object_replace ((GstObject **)&sched->current_clock, (GstObject *)clock); - break; - } - case GST_STATE_PAUSED_TO_PLAYING: - { - GstClock *clock = gst_scheduler_get_clock (sched); - - GST_CAT_DEBUG (GST_CAT_CLOCK, "scheduler PAUSED to PLAYING clock is %p (%s)", clock, - (clock ? GST_OBJECT_NAME (clock) : "nil")); - gst_scheduler_set_clock (sched, clock); - if (clock) { - GST_CAT_DEBUG (GST_CAT_CLOCK, "enabling clock %p (%s)", clock, - GST_OBJECT_NAME (clock)); - gst_clock_set_active (clock, TRUE); - } break; } - case GST_STATE_PLAYING_TO_PAUSED: - if (sched->current_clock) { - GST_CAT_DEBUG (GST_CAT_CLOCK, "disabling clock %p (%s)", sched->current_clock, - GST_OBJECT_NAME (sched->current_clock)); - gst_clock_set_active (sched->current_clock, FALSE); - } - break; } } @@ -678,6 +652,8 @@ gst_scheduler_auto_clock (GstScheduler *sched) GST_CAT_DEBUG (GST_CAT_CLOCK, "scheduler using automatic clock"); } +GstClockReturn gst_clock_id_wait (GstClockID id, + GstClockTimeDiff *jitter); /** * gst_scheduler_clock_wait: * @sched: the scheduler diff --git a/gst/schedulers/gstbasicscheduler.c b/gst/schedulers/gstbasicscheduler.c index 574c5ac02e..bf4337e3ca 100644 --- a/gst/schedulers/gstbasicscheduler.c +++ b/gst/schedulers/gstbasicscheduler.c @@ -131,8 +131,6 @@ static void gst_basic_scheduler_pad_link (GstScheduler *sched, GstPad *src static void gst_basic_scheduler_pad_unlink (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); static void gst_basic_scheduler_pad_select (GstScheduler *sched, GList *padlist); -static GstClockReturn gst_basic_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClockID id, GstClockTimeDiff *jitter); static GstSchedulerState gst_basic_scheduler_iterate (GstScheduler *sched); @@ -221,7 +219,7 @@ gst_basic_scheduler_class_init (GstBasicSchedulerClass * klass) gstscheduler_class->pad_link = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_link); gstscheduler_class->pad_unlink = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_unlink); gstscheduler_class->pad_select = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_select); - gstscheduler_class->clock_wait = GST_DEBUG_FUNCPTR (gst_basic_scheduler_clock_wait); + gstscheduler_class->clock_wait = NULL; gstscheduler_class->iterate = GST_DEBUG_FUNCPTR (gst_basic_scheduler_iterate); gstscheduler_class->show = GST_DEBUG_FUNCPTR (gst_basic_scheduler_show); @@ -1345,13 +1343,6 @@ gst_basic_scheduler_pad_select (GstScheduler * sched, GList * padlist) } } -static GstClockReturn -gst_basic_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClockID id, GstClockTimeDiff *jitter) -{ - return gst_clock_id_wait (id, jitter); -} - static GstSchedulerState gst_basic_scheduler_iterate (GstScheduler * sched) { diff --git a/gst/schedulers/gstoptimalscheduler.c b/gst/schedulers/gstoptimalscheduler.c index e54526da4a..374890a0a1 100644 --- a/gst/schedulers/gstoptimalscheduler.c +++ b/gst/schedulers/gstoptimalscheduler.c @@ -245,8 +245,6 @@ static void gst_opt_scheduler_error (GstScheduler *sched, GstElement *eleme static void gst_opt_scheduler_pad_link (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); static void gst_opt_scheduler_pad_unlink (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); static void gst_opt_scheduler_pad_select (GstScheduler *sched, GList *padlist); -static GstClockReturn gst_opt_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClockID id, GstClockTimeDiff *jitter); static GstSchedulerState gst_opt_scheduler_iterate (GstScheduler *sched); @@ -319,7 +317,7 @@ gst_opt_scheduler_class_init (GstOptSchedulerClass *klass) gstscheduler_class->pad_link = GST_DEBUG_FUNCPTR (gst_opt_scheduler_pad_link); gstscheduler_class->pad_unlink = GST_DEBUG_FUNCPTR (gst_opt_scheduler_pad_unlink); gstscheduler_class->pad_select = GST_DEBUG_FUNCPTR (gst_opt_scheduler_pad_select); - gstscheduler_class->clock_wait = GST_DEBUG_FUNCPTR (gst_opt_scheduler_clock_wait); + gstscheduler_class->clock_wait = NULL; gstscheduler_class->iterate = GST_DEBUG_FUNCPTR (gst_opt_scheduler_iterate); gstscheduler_class->show = GST_DEBUG_FUNCPTR (gst_opt_scheduler_show); @@ -2045,13 +2043,6 @@ gst_opt_scheduler_pad_select (GstScheduler *sched, GList *padlist) g_warning ("pad select, implement me"); } -static GstClockReturn -gst_opt_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClockID id, GstClockTimeDiff *jitter) -{ - return gst_clock_id_wait (id, jitter); -} - /* a scheduler iteration is done by looping and scheduling the active chains */ static GstSchedulerState gst_opt_scheduler_iterate (GstScheduler *sched) diff --git a/plugins/elements/gstfakesink.c b/plugins/elements/gstfakesink.c index b402b9caa8..61621d9e73 100644 --- a/plugins/elements/gstfakesink.c +++ b/plugins/elements/gstfakesink.c @@ -312,7 +312,7 @@ gst_fakesink_chain (GstPad *pad, GstData *_data) case GST_EVENT_DISCONTINUOUS: if (fakesink->sync && fakesink->clock) { gint64 value = GST_EVENT_DISCONT_OFFSET (event, 0).value; - gst_clock_handle_discont (fakesink->clock, value); + gst_element_set_time (GST_ELEMENT (fakesink), value); } default: gst_pad_event_default (pad, event); @@ -322,10 +322,7 @@ gst_fakesink_chain (GstPad *pad, GstData *_data) } if (fakesink->sync && fakesink->clock) { - GstClockID id = gst_clock_new_single_shot_id (fakesink->clock, GST_BUFFER_TIMESTAMP (buf)); - - gst_element_clock_wait (GST_ELEMENT (fakesink), id, NULL); - gst_clock_id_free (id); + gst_element_wait (GST_ELEMENT (fakesink), GST_BUFFER_TIMESTAMP (buf)); } if (!fakesink->silent) { diff --git a/tests/old/testsuite/clock/clock1.c b/tests/old/testsuite/clock/clock1.c index ebce7c85cd..f7865d8109 100644 --- a/tests/old/testsuite/clock/clock1.c +++ b/tests/old/testsuite/clock/clock1.c @@ -10,11 +10,8 @@ void gst_clock_debug (GstClock *clock) { - g_print ("Clock info: speed %f, active %s, time %d\n", - gst_clock_get_speed (clock), - gst_clock_is_active (clock) ? "yes" : "no", - (gint) gst_clock_get_time (clock) - ); + g_print ("Clock info: time %"G_GUINT64_FORMAT"\n", + gst_clock_get_time (clock)); } int @@ -53,12 +50,7 @@ main (int argc, char *argv[]) clock = gst_bin_get_clock (GST_BIN (pipeline)); g_assert (clock != NULL); gst_clock_debug (clock); - //gst_clock_set_active (clock, TRUE); gst_clock_debug (clock); - //clock = gst_clock_new ("clock"); - //gst_element_set_clock (src, clock); - //clock = gst_element_get_clock (src); - //g_assert (clock != NULL); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); gst_bin_iterate (GST_BIN (pipeline)); diff --git a/tests/old/testsuite/clock/clock2.c b/tests/old/testsuite/clock/clock2.c index 2a092b676e..be369103bf 100644 --- a/tests/old/testsuite/clock/clock2.c +++ b/tests/old/testsuite/clock/clock2.c @@ -8,46 +8,46 @@ #include void -gst_clock_debug (GstClock *clock) +gst_clock_debug (GstClock *clock, GstElement *fakesink) { - g_print ("Clock info: speed %f, active %s, time %d\n", - gst_clock_get_speed (clock), - gst_clock_is_active (clock) ? "yes" : "no", - (gint) gst_clock_get_time (clock) - ); + g_print ("Clock info: time %"G_GUINT64_FORMAT" - Element info: time %"G_GUINT64_FORMAT"\n", + gst_clock_get_time (clock), gst_element_get_time (fakesink)); } int main (int argc, char *argv[]) { GstClock *clock = NULL; - GstClockID id; + GstElement *pipeline, *fakesrc, *fakesink; gst_init (&argc, &argv); clock = gst_system_clock_obtain (); g_assert (clock != NULL); - gst_clock_debug (clock); - g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock); - gst_clock_set_active (clock, TRUE); - gst_clock_debug (clock); - g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock); - - id = gst_clock_new_single_shot_id (clock, GST_SECOND * 2); - gst_clock_id_wait (id, NULL); - gst_clock_debug (clock); + /* we check the time on an element */ + fakesrc = gst_element_factory_make ("fakesrc", NULL); + g_assert (fakesrc); + fakesink = gst_element_factory_make ("fakesink", NULL); + g_assert (fakesink); + pipeline = gst_element_factory_make ("pipeline", NULL); + g_assert (pipeline); + gst_bin_add_many (GST_BIN (pipeline), fakesink, fakesrc, NULL); + gst_element_link (fakesrc, fakesink); + gst_element_set_state (pipeline, GST_STATE_PLAYING); - id = gst_clock_new_single_shot_id (clock, GST_SECOND * 2); - gst_clock_id_wait (id, NULL); - gst_clock_debug (clock); - - gst_clock_set_active (clock, FALSE); - gst_clock_debug (clock); + gst_clock_debug (clock, fakesink); g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock); + gst_clock_debug (clock, fakesink); + + gst_element_wait (fakesink, 2 * GST_SECOND); + gst_clock_debug (clock, fakesink); + + gst_element_wait (fakesink, 5 * GST_SECOND); + gst_clock_debug (clock, fakesink); + + g_usleep (G_USEC_PER_SEC); + gst_clock_debug (clock, fakesink); /* success */ return 0; diff --git a/tests/old/testsuite/debug/commandline.c b/tests/old/testsuite/debug/commandline.c index b2e6c58d5e..7cb62bf488 100644 --- a/tests/old/testsuite/debug/commandline.c +++ b/tests/old/testsuite/debug/commandline.c @@ -30,8 +30,8 @@ static const gchar* lines[] = { "--gst-disable-debug", "--gst-debug-no-color", "--gst-debug-level=4", - "--gst-debug=cat=4:cat_*=3", - "--gst-debug-level=4 --gst-debug=cat_*=5" + "--gst-debug=cat:4,cat_*:3", + "--gst-debug-level=4 --gst-debug=cat_*:5" }; static void diff --git a/tests/old/testsuite/threads/Makefile.am b/tests/old/testsuite/threads/Makefile.am index fafa7dd7f5..927d287dd3 100644 --- a/tests/old/testsuite/threads/Makefile.am +++ b/tests/old/testsuite/threads/Makefile.am @@ -1,8 +1,8 @@ include ../Rules tests_pass = thread1 thread2 thread3 thread4 threadf -tests_fail = thread5 threadd threade queue -# tests which unexpectedly pass: threadb threadc +tests_fail = thread5 threadd queue +# tests which unexpectedly pass: threade threadb threadc queue_SOURCES = queue.c queue_CFLAGS = $(AM_CFLAGS) diff --git a/testsuite/clock/clock1.c b/testsuite/clock/clock1.c index ebce7c85cd..f7865d8109 100644 --- a/testsuite/clock/clock1.c +++ b/testsuite/clock/clock1.c @@ -10,11 +10,8 @@ void gst_clock_debug (GstClock *clock) { - g_print ("Clock info: speed %f, active %s, time %d\n", - gst_clock_get_speed (clock), - gst_clock_is_active (clock) ? "yes" : "no", - (gint) gst_clock_get_time (clock) - ); + g_print ("Clock info: time %"G_GUINT64_FORMAT"\n", + gst_clock_get_time (clock)); } int @@ -53,12 +50,7 @@ main (int argc, char *argv[]) clock = gst_bin_get_clock (GST_BIN (pipeline)); g_assert (clock != NULL); gst_clock_debug (clock); - //gst_clock_set_active (clock, TRUE); gst_clock_debug (clock); - //clock = gst_clock_new ("clock"); - //gst_element_set_clock (src, clock); - //clock = gst_element_get_clock (src); - //g_assert (clock != NULL); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); gst_bin_iterate (GST_BIN (pipeline)); diff --git a/testsuite/clock/clock2.c b/testsuite/clock/clock2.c index 2a092b676e..be369103bf 100644 --- a/testsuite/clock/clock2.c +++ b/testsuite/clock/clock2.c @@ -8,46 +8,46 @@ #include void -gst_clock_debug (GstClock *clock) +gst_clock_debug (GstClock *clock, GstElement *fakesink) { - g_print ("Clock info: speed %f, active %s, time %d\n", - gst_clock_get_speed (clock), - gst_clock_is_active (clock) ? "yes" : "no", - (gint) gst_clock_get_time (clock) - ); + g_print ("Clock info: time %"G_GUINT64_FORMAT" - Element info: time %"G_GUINT64_FORMAT"\n", + gst_clock_get_time (clock), gst_element_get_time (fakesink)); } int main (int argc, char *argv[]) { GstClock *clock = NULL; - GstClockID id; + GstElement *pipeline, *fakesrc, *fakesink; gst_init (&argc, &argv); clock = gst_system_clock_obtain (); g_assert (clock != NULL); - gst_clock_debug (clock); - g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock); - gst_clock_set_active (clock, TRUE); - gst_clock_debug (clock); - g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock); - - id = gst_clock_new_single_shot_id (clock, GST_SECOND * 2); - gst_clock_id_wait (id, NULL); - gst_clock_debug (clock); + /* we check the time on an element */ + fakesrc = gst_element_factory_make ("fakesrc", NULL); + g_assert (fakesrc); + fakesink = gst_element_factory_make ("fakesink", NULL); + g_assert (fakesink); + pipeline = gst_element_factory_make ("pipeline", NULL); + g_assert (pipeline); + gst_bin_add_many (GST_BIN (pipeline), fakesink, fakesrc, NULL); + gst_element_link (fakesrc, fakesink); + gst_element_set_state (pipeline, GST_STATE_PLAYING); - id = gst_clock_new_single_shot_id (clock, GST_SECOND * 2); - gst_clock_id_wait (id, NULL); - gst_clock_debug (clock); - - gst_clock_set_active (clock, FALSE); - gst_clock_debug (clock); + gst_clock_debug (clock, fakesink); g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock); + gst_clock_debug (clock, fakesink); + + gst_element_wait (fakesink, 2 * GST_SECOND); + gst_clock_debug (clock, fakesink); + + gst_element_wait (fakesink, 5 * GST_SECOND); + gst_clock_debug (clock, fakesink); + + g_usleep (G_USEC_PER_SEC); + gst_clock_debug (clock, fakesink); /* success */ return 0; diff --git a/testsuite/debug/commandline.c b/testsuite/debug/commandline.c index b2e6c58d5e..7cb62bf488 100644 --- a/testsuite/debug/commandline.c +++ b/testsuite/debug/commandline.c @@ -30,8 +30,8 @@ static const gchar* lines[] = { "--gst-disable-debug", "--gst-debug-no-color", "--gst-debug-level=4", - "--gst-debug=cat=4:cat_*=3", - "--gst-debug-level=4 --gst-debug=cat_*=5" + "--gst-debug=cat:4,cat_*:3", + "--gst-debug-level=4 --gst-debug=cat_*:5" }; static void diff --git a/testsuite/threads/Makefile.am b/testsuite/threads/Makefile.am index fafa7dd7f5..927d287dd3 100644 --- a/testsuite/threads/Makefile.am +++ b/testsuite/threads/Makefile.am @@ -1,8 +1,8 @@ include ../Rules tests_pass = thread1 thread2 thread3 thread4 threadf -tests_fail = thread5 threadd threade queue -# tests which unexpectedly pass: threadb threadc +tests_fail = thread5 threadd queue +# tests which unexpectedly pass: threade threadb threadc queue_SOURCES = queue.c queue_CFLAGS = $(AM_CFLAGS)