timeline-element: Add a "timeline" property
authorThibault Saunier <thibault.saunier@collabora.com>
Thu, 28 Feb 2013 18:12:15 +0000 (15:12 -0300)
committerThibault Saunier <thibault.saunier@collabora.com>
Thu, 14 Mar 2013 21:10:34 +0000 (18:10 -0300)
docs/libs/ges-sections.txt
ges/ges-timeline-element.c
ges/ges-timeline-element.h
ges/ges-timeline-layer.c
ges/ges-track.c

index cb99a34..19ac718 100644 (file)
@@ -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
index 007a4aa..e439b12 100644 (file)
@@ -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
index 20e712b..23a6dbf 100644 (file)
@@ -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);
index e35bc30..4d42268 100644 (file)
@@ -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);
index b1de6d4..492c32b 100644 (file)
@@ -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;
   }