X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstclock.c;h=279b1f8bc5a75bd55300d9c646971c6ba6ec96fa;hb=0c6f5b3e4c3dc55e684bca1e3fc9a2a9b74407b9;hp=35d5186209fabee05930bb99cbefb8c61bd15ec2;hpb=daa98fc02a7bece11709b485645320c00bcd6599;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstclock.c b/gst/gstclock.c index 35d5186..279b1f8 100644 --- a/gst/gstclock.c +++ b/gst/gstclock.c @@ -167,6 +167,14 @@ struct _GstClockPrivate gboolean synced; }; +typedef struct +{ + GstClockEntry entry; + GWeakRef clock; +} GstClockEntryImpl; + +#define GST_CLOCK_ENTRY_CLOCK_WEAK_REF(entry) (&((GstClockEntryImpl *)(entry))->clock) + /* seqlocks */ #define read_seqbegin(clock) \ g_atomic_int_get (&clock->priv->post_count); @@ -241,7 +249,7 @@ gst_clock_entry_new (GstClock * clock, GstClockTime time, { GstClockEntry *entry; - entry = g_slice_new (GstClockEntry); + entry = (GstClockEntry *) g_slice_new (GstClockEntryImpl); /* FIXME: add tracer hook for struct allocations such as clock entries */ @@ -249,7 +257,14 @@ gst_clock_entry_new (GstClock * clock, GstClockTime time, "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time)); entry->refcount = 1; +#ifndef GST_REMOVE_DEPRECATED +#ifndef GST_DISABLE_DEPRECATED entry->clock = clock; +#else + entry->_clock = clock; +#endif +#endif + g_weak_ref_init (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry), clock); entry->type = type; entry->time = time; entry->interval = interval; @@ -270,7 +285,8 @@ gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry, GstClockTime time, GstClockTime interval, GstClockEntryType type) { g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE); - g_return_val_if_fail (entry->clock == clock, FALSE); + g_return_val_if_fail (gst_clock_id_uses_clock ((GstClockID) entry, clock), + FALSE); entry->type = type; entry->time = time; @@ -354,9 +370,11 @@ _gst_clock_id_free (GstClockID id) if (entry->destroy_data) entry->destroy_data (entry->user_data); + g_weak_ref_clear (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + /* FIXME: add tracer hook for struct allocations such as clock entries */ - g_slice_free (GstClockEntry, id); + g_slice_free (GstClockEntryImpl, (GstClockEntryImpl *) id); } /** @@ -526,7 +544,9 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter) entry = (GstClockEntry *) id; requested = GST_CLOCK_ENTRY_TIME (entry); - clock = GST_CLOCK_ENTRY_CLOCK (entry); + clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + if (G_UNLIKELY (clock == NULL)) + goto invalid_entry; /* can't sync on invalid times */ if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested))) @@ -549,6 +569,7 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter) if (entry->type == GST_CLOCK_ENTRY_PERIODIC) entry->time = requested + entry->interval; + gst_object_unref (clock); return res; /* ERRORS */ @@ -556,13 +577,20 @@ invalid_time: { GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "invalid time requested, returning _BADTIME"); + gst_object_unref (clock); return GST_CLOCK_BADTIME; } not_supported: { GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported"); + gst_object_unref (clock); return GST_CLOCK_UNSUPPORTED; } +invalid_entry: + { + GST_CAT_DEBUG (GST_CAT_CLOCK, "clock entry %p lost its clock", id); + return GST_CLOCK_ERROR; + } } /** @@ -600,7 +628,9 @@ gst_clock_id_wait_async (GstClockID id, entry = (GstClockEntry *) id; requested = GST_CLOCK_ENTRY_TIME (entry); - clock = GST_CLOCK_ENTRY_CLOCK (entry); + clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + if (G_UNLIKELY (clock == NULL)) + goto invalid_entry; /* can't sync on invalid times */ if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested))) @@ -617,6 +647,7 @@ gst_clock_id_wait_async (GstClockID id, res = cclass->wait_async (clock, entry); + gst_object_unref (clock); return res; /* ERRORS */ @@ -625,13 +656,20 @@ invalid_time: (func) (clock, GST_CLOCK_TIME_NONE, id, user_data); GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "invalid time requested, returning _BADTIME"); + gst_object_unref (clock); return GST_CLOCK_BADTIME; } not_supported: { GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported"); + gst_object_unref (clock); return GST_CLOCK_UNSUPPORTED; } +invalid_entry: + { + GST_CAT_DEBUG (GST_CAT_CLOCK, "clock entry %p lost its clock", id); + return GST_CLOCK_ERROR; + } } /** @@ -655,12 +693,23 @@ gst_clock_id_unschedule (GstClockID id) g_return_if_fail (id != NULL); entry = (GstClockEntry *) id; - clock = entry->clock; + clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + if (G_UNLIKELY (clock == NULL)) + goto invalid_entry; cclass = GST_CLOCK_GET_CLASS (clock); if (G_LIKELY (cclass->unschedule)) cclass->unschedule (clock, entry); + + gst_object_unref (clock); + return; + +invalid_entry: + { + GST_CAT_DEBUG (GST_CAT_CLOCK, "clock entry %p lost its clock", id); + return; + } } @@ -668,7 +717,7 @@ gst_clock_id_unschedule (GstClockID id) * GstClock abstract base class implementation */ #define gst_clock_parent_class parent_class -G_DEFINE_ABSTRACT_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT); +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GstClock, gst_clock, GST_TYPE_OBJECT); static void gst_clock_class_init (GstClockClass * klass) @@ -713,8 +762,6 @@ gst_clock_class_init (GstClockClass * klass) g_signal_new ("synced", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - - g_type_class_add_private (klass, sizeof (GstClockPrivate)); } static void @@ -722,8 +769,7 @@ gst_clock_init (GstClock * clock) { GstClockPrivate *priv; - clock->priv = priv = - G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate); + clock->priv = priv = gst_clock_get_instance_private (clock); priv->last_time = 0; @@ -1342,6 +1388,68 @@ gst_clock_get_master (GstClock * clock) } /** + * gst_clock_id_get_clock: + * @id: a #GstClockID + * + * This function returns the underlying clock. + * + * Returns: (transfer full) (nullable): a #GstClock or %NULL when the + * underlying clock has been freed. Unref after usage. + * + * MT safe. + * + * Since: 1.16 + */ +GstClock * +gst_clock_id_get_clock (GstClockID id) +{ + GstClockEntry *entry; + + g_return_val_if_fail (id != NULL, NULL); + + entry = (GstClockEntry *) id; + return g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); +} + +/** + * gst_clock_id_uses_clock: + * @id: a #GstClockID to check + * @clock: a #GstClock to compare against + * + * This function returns whether @id uses @clock as the underlying clock. + * @clock can be NULL, in which case the return value indicates whether + * the underlying clock has been freed. If this is the case, the @id is + * no longer usable and should be freed. + * + * Returns: whether the clock @id uses the same underlying #GstClock @clock. + * + * MT safe. + * + * Since: 1.16 + */ +gboolean +gst_clock_id_uses_clock (GstClockID id, GstClock * clock) +{ + GstClockEntry *entry; + GstClock *entry_clock; + gboolean ret = FALSE; + + g_return_val_if_fail (id != NULL, FALSE); + g_return_val_if_fail (clock != NULL, FALSE); + + entry = (GstClockEntry *) id; + entry_clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + if (entry_clock == clock) + ret = TRUE; + + if (G_LIKELY (entry_clock != NULL)) + gst_object_unref (entry_clock); + + return ret; +} + + +/** * gst_clock_add_observation: * @clock: a #GstClock * @slave: a time on the slave