From 0cb8c671eaa0f0f6b8c4c6ac6a03710dd2599f4a Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Thu, 28 Feb 2013 15:12:15 -0300 Subject: [PATCH] timeline-element: Add a "timeline" property --- docs/libs/ges-sections.txt | 3 ++ ges/ges-timeline-element.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-- ges/ges-timeline-element.h | 11 +++++++ ges/ges-timeline-layer.c | 4 +++ ges/ges-track.c | 4 +++ 5 files changed, 100 insertions(+), 2 deletions(-) diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index cb99a34..19ac718 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -324,6 +324,8 @@ GESTimelineElement GESTimelineElementClass ges_timeline_element_set_parent ges_timeline_element_get_parent +ges_timeline_element_set_timeline +ges_timeline_element_get_timeline ges_timeline_element_set_start ges_timeline_element_set_inpoint ges_timeline_element_set_duration @@ -340,6 +342,7 @@ ges_timeline_element_roll_start ges_timeline_element_roll_end ges_timeline_element_trim GES_TIMELINE_ELEMENT_PARENT +GES_TIMELINE_ELEMENT_TIMELINE GES_TIMELINE_ELEMENT_START GES_TIMELINE_ELEMENT_INPOINT GES_TIMELINE_ELEMENT_DURATION diff --git a/ges/ges-timeline-element.c b/ges/ges-timeline-element.c index 007a4aa..e439b12 100644 --- a/ges/ges-timeline-element.c +++ b/ges/ges-timeline-element.c @@ -41,6 +41,7 @@ enum { PROP_0, PROP_PARENT, + PROP_TIMELINE, PROP_START, PROP_INPOINT, PROP_DURATION, @@ -65,6 +66,10 @@ _get_property (GObject * object, guint property_id, switch (property_id) { case PROP_PARENT: g_value_set_object (value, self->parent); + break; + case PROP_TIMELINE: + g_value_set_object (value, self->timeline); + break; case PROP_START: g_value_set_uint64 (value, self->start); break; @@ -95,6 +100,9 @@ _set_property (GObject * object, guint property_id, case PROP_PARENT: ges_timeline_element_set_parent (self, g_value_get_object (value)); break; + case PROP_TIMELINE: + ges_timeline_element_set_timeline (self, g_value_get_object (value)); + break; case PROP_START: ges_timeline_element_set_start (self, g_value_get_uint64 (value)); break; @@ -146,6 +154,15 @@ ges_timeline_element_class_init (GESTimelineElementClass * klass) G_PARAM_READWRITE); /** + * GESTimelineElement:timeline: + * + * The timeline in which the object is in + */ + properties[PROP_TIMELINE] = + g_param_spec_object ("timeline", "Timeline", + "The timeline the object is in", GES_TYPE_TIMELINE, G_PARAM_READWRITE); + + /** * GESTimelineElement:start: * * The position of the object in its container (in nanoseconds). @@ -241,7 +258,6 @@ ges_timeline_element_set_parent (GESTimelineElement * self, goto had_parent; self->parent = parent; - g_object_ref_sink (self); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PARENT]); return TRUE; @@ -259,7 +275,7 @@ had_parent: * @self: a #GESTimelineElement * * Returns the parent of @self. This function increases the refcount - * of the parent self so you should gst_object_unref() it after usage. + * of the parent object so you should gst_object_unref() it after usage. * * Returns: (transfer full): parent of @self, this can be %NULL if @self * has no parent. unref after usage. @@ -279,6 +295,66 @@ ges_timeline_element_get_parent (GESTimelineElement * self) } /** + * ges_timeline_element_set_timeline: + * @self: a #GESTimelineElement + * @timeline: The #GESTimeline @self is in + * + * Sets the timeline of @self to @timeline. + * + * Returns: %TRUE if @timeline could be set or %FALSE when @timeline + * already had a timeline. + */ +gboolean +ges_timeline_element_set_timeline (GESTimelineElement * self, + GESTimeline * timeline) +{ + g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE); + g_return_val_if_fail (timeline == NULL || GES_IS_TIMELINE (timeline), FALSE); + + GST_DEBUG_OBJECT (self, "set timeline to %" GST_PTR_FORMAT, timeline); + + if (G_UNLIKELY (self->timeline != NULL)) + goto had_timeline; + + self->timeline = timeline; + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TIMELINE]); + return TRUE; + + /* ERROR handling */ +had_timeline: + { + GST_DEBUG_OBJECT (self, "set timeline failed, object already had a " + "timeline"); + return FALSE; + } +} + +/** + * ges_timeline_element_get_timeline: + * @self: a #GESTimelineElement + * + * Returns the timeline of @self. This function increases the refcount + * of the timeline so you should gst_object_unref() it after usage. + * + * Returns: (transfer full): timeline of @self, this can be %NULL if @self + * has no timeline. unref after usage. + */ +GESTimeline * +ges_timeline_element_get_timeline (GESTimelineElement * self) +{ + GESTimeline *result = NULL; + + g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), NULL); + + result = self->timeline; + if (G_LIKELY (result)) + gst_object_ref (result); + + return result; +} + +/** * ges_timeline_element_set_start: * @self: a #GESTimelineElement * @start: the position in #GstClockTime diff --git a/ges/ges-timeline-element.h b/ges/ges-timeline-element.h index 20e712b..23a6dbf 100644 --- a/ges/ges-timeline-element.h +++ b/ges/ges-timeline-element.h @@ -85,6 +85,14 @@ typedef struct _GESTimelineElementPrivate GESTimelineElementPrivate; #define GES_TIMELINE_ELEMENT_PARENT(obj) (((GESTimelineElement*)obj)->parent) /** + * GES_TIMELINE_ELEMENT_TIMELINE: + * @obj: a #GESTimelineElement + * + * The timeline in which the object is. + */ +#define GES_TIMELINE_ELEMENT_TIMELINE(obj) (((GESTimelineElement*)obj)->timeline) + +/** * GESTimelineElementClass: * @set_start: method to set the start of a #GESTimelineElement * @set_duration: method to set the duration of a #GESTimelineElement @@ -147,6 +155,7 @@ struct _GESTimelineElement GstClockTime duration; GstClockTime maxduration; guint32 priority; + GESTimeline *timeline; /*< private >*/ GESTimelineElementPrivate *priv; @@ -159,6 +168,7 @@ GType ges_timeline_element_get_type (void) G_GNUC_CONST; GESTimelineElement * ges_timeline_element_get_parent (GESTimelineElement * self); gboolean ges_timeline_element_set_parent (GESTimelineElement *self, GESTimelineElement *parent); +gboolean ges_timeline_element_set_timeline (GESTimelineElement *self, GESTimeline *timeline); void ges_timeline_element_set_start (GESTimelineElement *self, GstClockTime start); void ges_timeline_element_set_inpoint (GESTimelineElement *self, GstClockTime inpoint); void ges_timeline_element_set_duration (GESTimelineElement *self, GstClockTime duration); @@ -169,6 +179,7 @@ GstClockTime ges_timeline_element_get_start (GESTimelineElement *self); GstClockTime ges_timeline_element_get_inpoint (GESTimelineElement *self); GstClockTime ges_timeline_element_get_duration (GESTimelineElement *self); GstClockTime ges_timeline_element_get_max_duration (GESTimelineElement *self); +GESTimeline * ges_timeline_element_get_timeline (GESTimelineElement *self); guint32 ges_timeline_element_get_priority (GESTimelineElement *self); gboolean ges_timeline_element_ripple (GESTimelineElement *self, GstClockTime start); diff --git a/ges/ges-timeline-layer.c b/ges/ges-timeline-layer.c index e35bc30..4d42268 100644 --- a/ges/ges-timeline-layer.c +++ b/ges/ges-timeline-layer.c @@ -315,6 +315,8 @@ ges_timeline_layer_remove_clip (GESTimelineLayer * layer, GESClip * clip) /* inform the clip it's no longer in a layer */ ges_clip_set_layer (clip, NULL); + /* so neither in a timeline */ + ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (clip), NULL); /* Remove it from our list of controlled objects */ layer->priv->clips_start = g_list_remove (layer->priv->clips_start, clip); @@ -552,6 +554,8 @@ ges_timeline_layer_add_clip (GESTimelineLayer * layer, GESClip * clip) /* If the clip has an acceptable priority, we just let it with its current * priority */ ges_timeline_layer_resync_priorities (layer); + ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (clip), + layer->timeline); /* emit 'clip-added' */ g_signal_emit (layer, ges_timeline_layer_signals[OBJECT_ADDED], 0, clip); diff --git a/ges/ges-track.c b/ges/ges-track.c index b1de6d4..492c32b 100644 --- a/ges/ges-track.c +++ b/ges/ges-track.c @@ -367,6 +367,7 @@ remove_object_internal (GESTrack * track, GESTrackElement * object) g_signal_handlers_disconnect_by_func (object, sort_track_elements_cb, NULL); ges_track_element_set_track (object, NULL); + ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (object), NULL); g_signal_emit (track, ges_track_signals[TRACK_ELEMENT_REMOVED], 0, GES_TRACK_ELEMENT (object)); @@ -752,6 +753,8 @@ ges_track_add_element (GESTrack * track, GESTrackElement * object) g_sequence_insert_sorted (track->priv->trackelements_by_start, object, (GCompareDataFunc) element_start_compare, NULL)); + ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (object), + track->priv->timeline); g_signal_emit (track, ges_track_signals[TRACK_ELEMENT_ADDED], 0, GES_TRACK_ELEMENT (object)); @@ -821,6 +824,7 @@ ges_track_remove_element (GESTrack * track, GESTrackElement * object) g_sequence_remove (it); resort_and_fill_gaps (track); + ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (object), NULL); return TRUE; } -- 2.7.4