diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index da733d62d0..1e7357fc43 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -2552,6 +2552,7 @@ gst_structure_get_type GstClockType GstSystemClock gst_system_clock_obtain +gst_system_clock_set_default GstSystemClockClass GstSystemClockPrivate diff --git a/gst/gstsystemclock.c b/gst/gstsystemclock.c index 5e7f6b1c7f..f71d420da9 100644 --- a/gst/gstsystemclock.c +++ b/gst/gstsystemclock.c @@ -112,6 +112,7 @@ enum /* the one instance of the systemclock */ static GstClock *_the_system_clock = NULL; +static gboolean _external_default_clock = FALSE; static void gst_system_clock_dispose (GObject * object); static void gst_system_clock_set_property (GObject * object, guint prop_id, @@ -280,6 +281,43 @@ gst_system_clock_get_property (GObject * object, guint prop_id, GValue * value, } } +/** + * gst_system_clock_set_default: + * @new_clock: a #GstClock + * + * Sets the default system clock that can be obtained with + * gst_system_clock_obtain. + * + * This is mostly used for testing and debugging purposes when you + * want to have control over the time reported by the default system + * clock. + * + * MT safe. + */ +void +gst_system_clock_set_default (GstClock * new_clock) +{ + GstClock *clock; + + g_mutex_lock (&_gst_sysclock_mutex); + clock = _the_system_clock; + + if (clock != NULL) + g_object_unref (clock); + + if (new_clock == NULL) { + GST_CAT_DEBUG (GST_CAT_CLOCK, "resetting default system clock"); + _external_default_clock = FALSE; + } else { + GST_CAT_DEBUG (GST_CAT_CLOCK, "setting new default system clock to %p", + new_clock); + _external_default_clock = TRUE; + g_object_ref (new_clock); + } + _the_system_clock = new_clock; + g_mutex_unlock (&_gst_sysclock_mutex); +} + /** * gst_system_clock_obtain: * @@ -301,6 +339,7 @@ gst_system_clock_obtain (void) if (clock == NULL) { GST_CAT_DEBUG (GST_CAT_CLOCK, "creating new static system clock"); + g_assert (_external_default_clock == FALSE); clock = g_object_new (GST_TYPE_SYSTEM_CLOCK, "name", "GstSystemClock", NULL); diff --git a/gst/gstsystemclock.h b/gst/gstsystemclock.h index aa9dc14186..fe5d009d29 100644 --- a/gst/gstsystemclock.h +++ b/gst/gstsystemclock.h @@ -81,6 +81,7 @@ struct _GstSystemClockClass { GType gst_system_clock_get_type (void); GstClock* gst_system_clock_obtain (void); +void gst_system_clock_set_default (GstClock *new_clock); G_END_DECLS diff --git a/tests/check/gst/gstsystemclock.c b/tests/check/gst/gstsystemclock.c index 7d5a146b4d..455de71f4e 100644 --- a/tests/check/gst/gstsystemclock.c +++ b/tests/check/gst/gstsystemclock.c @@ -117,6 +117,38 @@ notify_callback (GstClock * clock, GstClockTime time, return FALSE; } +GST_START_TEST (test_set_default) +{ + GstClock *clock, *static_clock; + + /* obtain the default system clock, which keeps a static ref and bumps the + * refcount before returning */ + static_clock = gst_system_clock_obtain (); + fail_unless (static_clock != NULL, "Could not create default system clock"); + g_assert_cmpint (GST_OBJECT_REFCOUNT (static_clock), ==, 2); + + /* set a new default clock to a different instance which should replace the + * static clock with this one, and unref the static clock */ + clock = g_object_new (GST_TYPE_SYSTEM_CLOCK, "name", "TestClock", NULL); + gst_system_clock_set_default (clock); + g_assert_cmpint (GST_OBJECT_REFCOUNT (static_clock), ==, 1); + static_clock = gst_system_clock_obtain (); + fail_unless (static_clock == clock); + g_assert_cmpint (GST_OBJECT_REFCOUNT (clock), ==, 3); + g_object_unref (static_clock); + + /* Reset the default clock to the static one */ + gst_system_clock_set_default (NULL); + static_clock = gst_system_clock_obtain (); + fail_unless (static_clock != clock); + g_assert_cmpint (GST_OBJECT_REFCOUNT (clock), ==, 1); + g_assert_cmpint (GST_OBJECT_REFCOUNT (static_clock), ==, 2); + g_object_unref (clock); + g_object_unref (static_clock); +} + +GST_END_TEST; + GST_START_TEST (test_single_shot) { GstClock *clock; @@ -654,6 +686,7 @@ gst_systemclock_suite (void) tcase_add_test (tc_chain, test_diff); tcase_add_test (tc_chain, test_mixed); tcase_add_test (tc_chain, test_async_full); + tcase_add_test (tc_chain, test_set_default); return s; } diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 6f8da1a40e..ce8893e64a 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -1127,6 +1127,7 @@ EXPORTS gst_structure_to_string gst_system_clock_get_type gst_system_clock_obtain + gst_system_clock_set_default gst_tag_exists gst_tag_flag_get_type gst_tag_get_description