1 /* GStreamer Editing Services
2 * Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk>
3 * 2009 Nokia Corporation
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * SECTION:ges-track-object
23 * @short_description: Base Class for objects contained in a #GESTrack
25 * #GESTrackObject is the Base Class for any object that can be contained in a
28 * It contains the basic information as to the location of the object within
29 * its container, like the start position, the in-point, the duration and the
33 #include "ges-internal.h"
34 #include "gesmarshal.h"
35 #include "ges-track-object.h"
36 #include "ges-timeline-object.h"
38 G_DEFINE_ABSTRACT_TYPE (GESTrackObject, ges_track_object,
39 G_TYPE_INITIALLY_UNOWNED);
41 struct _GESTrackObjectPrivate
43 /* These fields are only used before the gnlobject is available */
44 guint64 pending_start;
45 guint64 pending_inpoint;
46 guint64 pending_duration;
47 guint32 pending_priority;
48 gboolean pending_active;
50 GstElement *gnlobject; /* The GnlObject */
51 GstElement *element; /* The element contained in the gnlobject (can be NULL) */
53 /* We keep a link between properties name and elements internally
54 * The hashtable should look like
55 * {'ClassName-propertyName' ---> element,}*/
56 GHashTable *properties_hashtable;
58 GESTimelineObject *timelineobj;
63 gboolean locked; /* If TRUE, then moves in sync with its controlling
64 * GESTimelineObject */
78 static GParamSpec *properties[PROP_LAST];
86 static guint ges_track_object_signals[LAST_SIGNAL] = { 0 };
88 static GstElement *ges_track_object_create_gnl_object_func (GESTrackObject *
91 static void gnlobject_start_cb (GstElement * gnlobject, GParamSpec * arg
92 G_GNUC_UNUSED, GESTrackObject * obj);
94 static void gnlobject_media_start_cb (GstElement * gnlobject, GParamSpec * arg
95 G_GNUC_UNUSED, GESTrackObject * obj);
97 static void gnlobject_priority_cb (GstElement * gnlobject, GParamSpec * arg
98 G_GNUC_UNUSED, GESTrackObject * obj);
100 static void gnlobject_duration_cb (GstElement * gnlobject, GParamSpec * arg
101 G_GNUC_UNUSED, GESTrackObject * obj);
103 static void gnlobject_active_cb (GstElement * gnlobject, GParamSpec * arg
104 G_GNUC_UNUSED, GESTrackObject * obj);
106 static void connect_properties_signals (GESTrackObject * object);
107 static void connect_signal (gpointer key, gpointer value, gpointer user_data);
108 static void gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg
109 G_GNUC_UNUSED, GESTrackObject * obj);
111 static inline gboolean
112 ges_track_object_set_start_internal (GESTrackObject * object, guint64 start);
113 static inline gboolean
114 ges_track_object_set_inpoint_internal (GESTrackObject * object,
116 static inline gboolean ges_track_object_set_duration_internal (GESTrackObject *
117 object, guint64 duration);
118 static inline gboolean ges_track_object_set_priority_internal (GESTrackObject *
119 object, guint32 priority);
122 ges_track_object_get_property (GObject * object, guint property_id,
123 GValue * value, GParamSpec * pspec)
125 GESTrackObject *tobj = GES_TRACK_OBJECT (object);
127 switch (property_id) {
129 g_value_set_uint64 (value, ges_track_object_get_start (tobj));
132 g_value_set_uint64 (value, ges_track_object_get_inpoint (tobj));
135 g_value_set_uint64 (value, ges_track_object_get_duration (tobj));
138 g_value_set_uint (value, ges_track_object_get_priority (tobj));
141 g_value_set_boolean (value, ges_track_object_is_active (tobj));
144 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
149 ges_track_object_set_property (GObject * object, guint property_id,
150 const GValue * value, GParamSpec * pspec)
152 GESTrackObject *tobj = GES_TRACK_OBJECT (object);
154 switch (property_id) {
156 ges_track_object_set_start_internal (tobj, g_value_get_uint64 (value));
159 ges_track_object_set_inpoint_internal (tobj, g_value_get_uint64 (value));
162 ges_track_object_set_duration_internal (tobj, g_value_get_uint64 (value));
165 ges_track_object_set_priority_internal (tobj, g_value_get_uint (value));
168 ges_track_object_set_active (tobj, g_value_get_boolean (value));
171 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
176 ges_track_object_dispose (GObject * object)
178 GESTrackObjectPrivate *priv = GES_TRACK_OBJECT (object)->priv;
179 if (priv->properties_hashtable)
180 g_hash_table_destroy (priv->properties_hashtable);
182 G_OBJECT_CLASS (ges_track_object_parent_class)->dispose (object);
186 ges_track_object_finalize (GObject * object)
188 G_OBJECT_CLASS (ges_track_object_parent_class)->finalize (object);
192 ges_track_object_class_init (GESTrackObjectClass * klass)
194 GObjectClass *object_class = G_OBJECT_CLASS (klass);
196 g_type_class_add_private (klass, sizeof (GESTrackObjectPrivate));
198 object_class->get_property = ges_track_object_get_property;
199 object_class->set_property = ges_track_object_set_property;
200 object_class->dispose = ges_track_object_dispose;
201 object_class->finalize = ges_track_object_finalize;
204 * GESTrackObject:start
206 * The position of the object in the container #GESTrack (in nanoseconds).
208 properties[PROP_START] = g_param_spec_uint64 ("start", "Start",
209 "The position in the container", 0, G_MAXUINT64, 0, G_PARAM_READWRITE);
210 g_object_class_install_property (object_class, PROP_START,
211 properties[PROP_START]);
214 * GESTrackObject:in-point
216 * The in-point at which this #GESTrackObject will start outputting data
217 * from its contents (in nanoseconds).
219 * Ex : an in-point of 5 seconds means that the first outputted buffer will
220 * be the one located 5 seconds in the controlled resource.
222 properties[PROP_INPOINT] =
223 g_param_spec_uint64 ("in-point", "In-point", "The in-point", 0,
224 G_MAXUINT64, 0, G_PARAM_READWRITE);
225 g_object_class_install_property (object_class, PROP_INPOINT,
226 properties[PROP_INPOINT]);
229 * GESTrackObject:duration
231 * The duration (in nanoseconds) which will be used in the container #GESTrack
232 * starting from 'in-point'.
235 properties[PROP_DURATION] =
236 g_param_spec_uint64 ("duration", "Duration", "The duration to use", 0,
237 G_MAXUINT64, GST_SECOND, G_PARAM_READWRITE);
238 g_object_class_install_property (object_class, PROP_DURATION,
239 properties[PROP_DURATION]);
242 * GESTrackObject:priority
244 * The priority of the object within the containing #GESTrack.
245 * If two objects intersect over the same region of time, the @priority
246 * property is used to decide which one takes precedence.
248 * The highest priority (that supercedes everything) is 0, and then lowering
249 * priorities go in increasing numerical value (with #G_MAXUINT64 being the
252 properties[PROP_PRIORITY] = g_param_spec_uint ("priority", "Priority",
253 "The priority of the object", 0, G_MAXUINT, 0, G_PARAM_READWRITE);
254 g_object_class_install_property (object_class, PROP_PRIORITY,
255 properties[PROP_PRIORITY]);
258 * GESTrackObject:active
260 * Whether the object should be taken into account in the #GESTrack output.
261 * If #FALSE, then its contents will not be used in the resulting track.
263 properties[PROP_ACTIVE] =
264 g_param_spec_boolean ("active", "Active", "Use object in output", TRUE,
266 g_object_class_install_property (object_class, PROP_ACTIVE,
267 properties[PROP_ACTIVE]);
270 * GESTrackObject::deep-notify:
271 * @track_object: a #GESTrackObject
272 * @prop_object: the object that originated the signal
273 * @prop: the property that changed
275 * The deep notify signal is used to be notified of property changes of all
276 * the childs of @track_object
278 ges_track_object_signals[DEEP_NOTIFY] =
279 g_signal_new ("deep-notify", G_TYPE_FROM_CLASS (klass),
280 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
281 G_SIGNAL_NO_HOOKS, 0, NULL, NULL, gst_marshal_VOID__OBJECT_PARAM,
282 G_TYPE_NONE, 2, GST_TYPE_ELEMENT, G_TYPE_PARAM);
284 klass->create_gnl_object = ges_track_object_create_gnl_object_func;
285 /* There is no 'get_props_hastable' default implementation */
286 klass->get_props_hastable = NULL;
290 ges_track_object_init (GESTrackObject * self)
292 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
293 GES_TYPE_TRACK_OBJECT, GESTrackObjectPrivate);
295 /* Sane default values */
296 self->priv->pending_start = 0;
297 self->priv->pending_inpoint = 0;
298 self->priv->pending_duration = GST_SECOND;
299 self->priv->pending_priority = 1;
300 self->priv->pending_active = TRUE;
301 self->priv->locked = TRUE;
302 self->priv->properties_hashtable = NULL;
305 static inline gboolean
306 ges_track_object_set_start_internal (GESTrackObject * object, guint64 start)
308 GST_DEBUG ("object:%p, start:%" GST_TIME_FORMAT,
309 object, GST_TIME_ARGS (start));
311 if (object->priv->gnlobject != NULL) {
312 if (G_UNLIKELY (start == object->start))
315 g_object_set (object->priv->gnlobject, "start", start, NULL);
317 object->priv->pending_start = start;
322 * ges_track_object_set_start:
323 * @object: a #GESTrackObject
324 * @start: the start position (in #GstClockTime)
326 * Sets the position of the object in the container #GESTrack.
329 ges_track_object_set_start (GESTrackObject * object, guint64 start)
331 if (ges_track_object_set_start_internal (object, start))
332 #if GLIB_CHECK_VERSION(2,26,0)
333 g_object_notify_by_pspec (G_OBJECT (object), properties[PROP_START]);
335 g_object_notify (G_OBJECT (object), "start");
339 static inline gboolean
340 ges_track_object_set_inpoint_internal (GESTrackObject * object, guint64 inpoint)
343 GST_DEBUG ("object:%p, inpoint:%" GST_TIME_FORMAT,
344 object, GST_TIME_ARGS (inpoint));
346 if (object->priv->gnlobject != NULL) {
347 if (G_UNLIKELY (inpoint == object->inpoint))
350 g_object_set (object->priv->gnlobject, "media-start", inpoint, NULL);
352 object->priv->pending_inpoint = inpoint;
358 * ges_track_object_set_inpoint:
359 * @object: a #GESTrackObject
360 * @inpoint: the in-point (in #GstClockTime)
362 * Set the offset within the contents of this #GESTrackObject
365 ges_track_object_set_inpoint (GESTrackObject * object, guint64 inpoint)
367 if (ges_track_object_set_inpoint_internal (object, inpoint))
368 #if GLIB_CHECK_VERSION(2,26,0)
369 g_object_notify_by_pspec (G_OBJECT (object), properties[PROP_INPOINT]);
371 g_object_notify (G_OBJECT (object), "in-point");
375 static inline gboolean
376 ges_track_object_set_duration_internal (GESTrackObject * object,
379 GST_DEBUG ("object:%p, duration:%" GST_TIME_FORMAT,
380 object, GST_TIME_ARGS (duration));
382 if (object->priv->gnlobject != NULL) {
383 if (G_UNLIKELY (duration == object->duration))
386 g_object_set (object->priv->gnlobject, "duration", duration,
387 "media-duration", duration, NULL);
389 object->priv->pending_duration = duration;
394 * ges_track_object_set_duration:
395 * @object: a #GESTrackObject
396 * @duration: the duration (in #GstClockTime)
398 * Set the duration which will be used in the container #GESTrack
399 * starting from the 'in-point'
402 ges_track_object_set_duration (GESTrackObject * object, guint64 duration)
404 if (ges_track_object_set_duration_internal (object, duration))
405 #if GLIB_CHECK_VERSION(2,26,0)
406 g_object_notify_by_pspec (G_OBJECT (object), properties[PROP_DURATION]);
408 g_object_notify (G_OBJECT (object), "duration");
412 static inline gboolean
413 ges_track_object_set_priority_internal (GESTrackObject * object,
416 GST_DEBUG ("object:%p, priority:%" G_GUINT32_FORMAT, object, priority);
418 if (object->priv->gnlobject != NULL) {
419 if (G_UNLIKELY (priority == object->priority))
422 g_object_set (object->priv->gnlobject, "priority", priority, NULL);
424 object->priv->pending_priority = priority;
429 * ges_track_object_set_priority:
430 * @object: a #GESTrackObject
431 * @priority: the priority
433 * Sets the priority of the object withing the containing #GESTrack.
434 * If two objects intersect over the same region of time, the priority
435 * property is used to decide which one takes precedence.
437 * The highest priority (that supercedes everything) is 0, and then
438 * lowering priorities go in increasing numerical value (with G_MAXUINT32
439 * being the lowest priority).
442 ges_track_object_set_priority (GESTrackObject * object, guint32 priority)
444 if (ges_track_object_set_priority_internal (object, priority))
445 #if GLIB_CHECK_VERSION(2,26,0)
446 g_object_notify_by_pspec (G_OBJECT (object), properties[PROP_PRIORITY]);
448 g_object_notify (G_OBJECT (object), "priority");
454 * ges_track_object_set_active:
455 * @object: a #GESTrackObject
456 * @active: visibility
458 * Sets the usage of the @object. If @active is %TRUE, the object will be used for
459 * playback and rendering, else it will be ignored.
461 * Returns: %TRUE if the property was toggled, else %FALSE
464 ges_track_object_set_active (GESTrackObject * object, gboolean active)
466 GST_DEBUG ("object:%p, active:%d", object, active);
468 if (object->priv->gnlobject != NULL) {
469 if (G_UNLIKELY (active == object->active))
472 g_object_set (object->priv->gnlobject, "active", active, NULL);
474 object->priv->pending_active = active;
478 /* Callbacks from the GNonLin object */
480 gnlobject_start_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
481 GESTrackObject * obj)
484 GESTrackObjectClass *klass;
486 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
488 g_object_get (gnlobject, "start", &start, NULL);
490 GST_DEBUG ("gnlobject start : %" GST_TIME_FORMAT " current : %"
491 GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (obj->start));
493 if (start != obj->start) {
495 if (klass->start_changed)
496 klass->start_changed (obj, start);
501 gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg
502 G_GNUC_UNUSED, GESTrackObject * obj)
504 g_signal_emit (obj, ges_track_object_signals[DEEP_NOTIFY], 0,
505 GST_ELEMENT (element), arg);
509 connect_signal (gpointer key, gpointer value, gpointer user_data)
511 gchar **name = g_strsplit ((char *) key, "-", 2);
512 gchar *signame = g_strconcat ("notify::", (gchar *) name[1], NULL);
515 g_signal_connect (G_OBJECT (value),
516 signame, G_CALLBACK (gst_element_prop_changed_cb),
517 GES_TRACK_OBJECT (user_data));
523 connect_properties_signals (GESTrackObject * object)
525 if (G_UNLIKELY (object->priv->properties_hashtable)) {
526 GST_WARNING ("The properties_hashtable hasn't been set");
529 g_hash_table_foreach (object->priv->properties_hashtable,
530 (GHFunc) connect_signal, object);
534 /* Callbacks from the GNonLin object */
536 gnlobject_media_start_cb (GstElement * gnlobject,
537 GParamSpec * arg G_GNUC_UNUSED, GESTrackObject * obj)
540 GESTrackObjectClass *klass;
542 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
544 g_object_get (gnlobject, "media-start", &start, NULL);
546 GST_DEBUG ("gnlobject in-point : %" GST_TIME_FORMAT " current : %"
547 GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (obj->inpoint));
549 if (start != obj->inpoint) {
550 obj->inpoint = start;
551 if (klass->media_start_changed)
552 klass->media_start_changed (obj, start);
557 gnlobject_priority_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
558 GESTrackObject * obj)
561 GESTrackObjectClass *klass;
563 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
565 g_object_get (gnlobject, "priority", &priority, NULL);
567 GST_DEBUG ("gnlobject priority : %d current : %d", priority, obj->priority);
569 if (priority != obj->priority) {
570 obj->priority = priority;
571 if (klass->gnl_priority_changed)
572 klass->gnl_priority_changed (obj, priority);
577 gnlobject_duration_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
578 GESTrackObject * obj)
581 GESTrackObjectClass *klass;
583 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
585 g_object_get (gnlobject, "duration", &duration, NULL);
587 GST_DEBUG ("gnlobject duration : %" GST_TIME_FORMAT " current : %"
588 GST_TIME_FORMAT, GST_TIME_ARGS (duration), GST_TIME_ARGS (obj->duration));
590 if (duration != obj->duration) {
591 obj->duration = duration;
592 if (klass->duration_changed)
593 klass->duration_changed (obj, duration);
598 gnlobject_active_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
599 GESTrackObject * obj)
602 GESTrackObjectClass *klass;
604 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
606 g_object_get (gnlobject, "active", &active, NULL);
608 GST_DEBUG ("gnlobject active : %d current : %d", active, obj->active);
610 if (active != obj->active) {
611 obj->active = active;
612 if (klass->active_changed)
613 klass->active_changed (obj, active);
618 /* default 'create_gnl_object' virtual method implementation */
620 ges_track_object_create_gnl_object_func (GESTrackObject * self)
622 GESTrackObjectClass *klass = NULL;
623 GstElement *child = NULL;
624 GstElement *gnlobject;
626 klass = GES_TRACK_OBJECT_GET_CLASS (self);
628 if (G_UNLIKELY (self->priv->gnlobject != NULL))
629 goto already_have_gnlobject;
631 if (G_UNLIKELY (klass->gnlobject_factorytype == NULL))
634 GST_DEBUG ("Creating a supporting gnlobject of type '%s'",
635 klass->gnlobject_factorytype);
637 gnlobject = gst_element_factory_make (klass->gnlobject_factorytype, NULL);
639 if (G_UNLIKELY (gnlobject == NULL))
642 if (klass->create_element) {
643 GST_DEBUG ("Calling subclass 'create_element' vmethod");
644 child = klass->create_element (self);
646 if (G_UNLIKELY (!child))
649 if (!gst_bin_add (GST_BIN (gnlobject), child))
652 GST_DEBUG ("Succesfully got the element to put in the gnlobject");
653 self->priv->element = child;
662 already_have_gnlobject:
664 GST_ERROR ("Already controlling a GnlObject %s",
665 GST_ELEMENT_NAME (self->priv->gnlobject));
671 GST_ERROR ("No GESTrackObject::gnlobject_factorytype implementation!");
677 GST_ERROR ("Error creating a gnlobject of type '%s'",
678 klass->gnlobject_factorytype);
684 GST_ERROR ("create_element returned NULL");
685 gst_object_unref (gnlobject);
691 GST_ERROR ("Error adding the contents to the gnlobject");
692 gst_object_unref (child);
693 gst_object_unref (gnlobject);
699 ensure_gnl_object (GESTrackObject * object)
701 GESTrackObjectClass *class;
702 GstElement *gnlobject;
703 GHashTable *props_hash;
704 gboolean res = FALSE;
706 if (object->priv->gnlobject && object->priv->valid)
709 /* 1. Create the GnlObject */
710 GST_DEBUG ("Creating GnlObject");
712 class = GES_TRACK_OBJECT_GET_CLASS (object);
714 if (G_UNLIKELY (class->create_gnl_object == NULL)) {
715 GST_ERROR ("No 'create_gnl_object' implementation !");
719 GST_DEBUG ("Calling virtual method");
721 /* call the create_gnl_object virtual method */
722 gnlobject = class->create_gnl_object (object);
724 if (G_UNLIKELY (gnlobject == NULL)) {
726 ("'create_gnl_object' implementation returned TRUE but no GnlObject is available");
730 object->priv->gnlobject = gnlobject;
732 /* 2. Fill in the GnlObject */
734 GST_DEBUG ("Got a valid GnlObject, now filling it in");
737 ges_timeline_object_fill_track_object (object->priv->timelineobj,
738 object, object->priv->gnlobject);
740 /* Connect to property notifications */
741 /* FIXME : remember the signalids so we can remove them later on !!! */
742 g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::start",
743 G_CALLBACK (gnlobject_start_cb), object);
744 g_signal_connect (G_OBJECT (object->priv->gnlobject),
745 "notify::media-start", G_CALLBACK (gnlobject_media_start_cb), object);
746 g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::duration",
747 G_CALLBACK (gnlobject_duration_cb), object);
748 g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::priority",
749 G_CALLBACK (gnlobject_priority_cb), object);
750 g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::active",
751 G_CALLBACK (gnlobject_active_cb), object);
753 /* Set some properties on the GnlObject */
754 g_object_set (object->priv->gnlobject,
755 "caps", ges_track_get_caps (object->priv->track),
756 "duration", object->priv->pending_duration,
757 "media-duration", object->priv->pending_duration,
758 "start", object->priv->pending_start,
759 "media-start", object->priv->pending_inpoint,
760 "priority", object->priv->pending_priority,
761 "active", object->priv->pending_active, NULL);
763 /* We feed up the props_hashtable if possible */
764 if (class->get_props_hastable) {
765 props_hash = class->get_props_hastable (object);
767 if (props_hash == NULL) {
768 GST_DEBUG ("'get_props_hastable' implementation returned TRUE but no\
769 properties_hashtable is available");
771 object->priv->properties_hashtable = props_hash;
772 connect_properties_signals (object);
779 object->priv->valid = res;
781 GST_DEBUG ("Returning res:%d", res);
788 ges_track_object_set_track (GESTrackObject * object, GESTrack * track)
790 GST_DEBUG ("object:%p, track:%p", object, track);
792 object->priv->track = track;
794 if (object->priv->track)
795 return ensure_gnl_object (object);
801 * ges_track_object_get_track:
802 * @object: a #GESTrackObject
804 * Get the #GESTrack to which this object belongs.
806 * Returns: (transfer none): The #GESTrack to which this object belongs. Can be %NULL if it
807 * is not in any track
810 ges_track_object_get_track (GESTrackObject * object)
812 g_return_val_if_fail (GES_IS_TRACK_OBJECT (object), NULL);
814 return object->priv->track;
819 ges_track_object_set_timeline_object (GESTrackObject * object,
820 GESTimelineObject * tlobj)
822 GST_DEBUG ("object:%p, timeline-object:%p", object, tlobj);
824 object->priv->timelineobj = tlobj;
828 * ges_track_object_get_timeline_object:
829 * @object: a #GESTrackObject
831 * Get the #GESTimelineObject which is controlling this track object
833 * Returns: (transfer none): the #GESTimelineObject which is controlling
837 ges_track_object_get_timeline_object (GESTrackObject * object)
839 g_return_val_if_fail (GES_IS_TRACK_OBJECT (object), NULL);
841 return object->priv->timelineobj;
845 * ges_track_object_get_gnlobject:
846 * @object: a #GESTrackObject
848 * Get the GNonLin object this object is controlling.
850 * Returns: (transfer none): the GNonLin object this object is controlling.
853 ges_track_object_get_gnlobject (GESTrackObject * object)
855 return object->priv->gnlobject;
859 * ges_track_object_get_element:
860 * @object: a #GESTrackObject
862 * Get the #GstElement this track object is controlling within GNonLin.
864 * Returns: (transfer none): the #GstElement this track object is controlling
868 ges_track_object_get_element (GESTrackObject * object)
870 return object->priv->element;
874 * ges_track_object_set_locked:
875 * @object: a #GESTrackObject
876 * @locked: whether the object is lock to its parent
878 * Set the locking status of the @object in relationship to its controlling
879 * #GESTimelineObject. If @locked is %TRUE, then this object will move synchronously
880 * with its controlling #GESTimelineObject.
883 ges_track_object_set_locked (GESTrackObject * object, gboolean locked)
885 object->priv->locked = locked;
889 * ges_track_object_is_locked:
890 * @object: a #GESTrackObject
892 * Let you know if object us locked or not (moving synchronously).
894 * Returns: %TRUE if the object is moving synchronously to its controlling
895 * #GESTimelineObject, else %FALSE.
898 ges_track_object_is_locked (GESTrackObject * object)
900 return object->priv->locked;
904 * ges_track_object_get_start:
905 * @object: a #GESTrackObject
907 * Get the position of the object in the container #GESTrack.
909 * Returns: the start position (in #GstClockTime)
912 ges_track_object_get_start (GESTrackObject * object)
914 if (G_UNLIKELY (object->priv->gnlobject == NULL))
915 return object->priv->pending_start;
917 return object->start;
921 * ges_track_object_get_inpoint:
922 * @object: a #GESTrackObject
924 * Get the offset within the contents of this #GESTrackObject
926 * Returns: the in-point (in #GstClockTime)
929 ges_track_object_get_inpoint (GESTrackObject * object)
931 if (G_UNLIKELY (object->priv->gnlobject == NULL))
932 return object->priv->pending_inpoint;
934 return object->inpoint;
938 * ges_track_object_get_duration:
939 * @object: a #GESTrackObject
941 * Get the duration which will be used in the container #GESTrack
942 * starting from the 'in-point'
944 * Returns: the duration (in #GstClockTime)
947 ges_track_object_get_duration (GESTrackObject * object)
949 if (G_UNLIKELY (object->priv->gnlobject == NULL))
950 return object->priv->pending_duration;
952 return object->duration;
956 * ges_track_object_get_priority:
957 * @object: a #GESTrackObject
959 * Get the priority of the object withing the containing #GESTrack.
961 * Returns: the priority of @object
964 ges_track_object_get_priority (GESTrackObject * object)
966 if (G_UNLIKELY (object->priv->gnlobject == NULL))
967 return object->priv->pending_priority;
969 return object->priority;
973 * ges_track_object_is_active:
974 * @object: a #GESTrackObject
976 * Lets you know if @object will be used for playback and rendering,
979 * Returns: %TRUE if @object is active, %FALSE otherwize
982 ges_track_object_is_active (GESTrackObject * object)
984 if (G_UNLIKELY (object->priv->gnlobject == NULL))
985 return object->priv->pending_active;
987 return object->active;
991 * ges_track_object_set_child_property:
992 * @object: a #GESTrackObject
993 * @property_name: The name of the property to set
996 * Sets a property of a child of @object. The property name
997 * should look like ClasseName-property-name
1000 ges_track_object_set_child_property (GESTrackObject * object,
1001 const gchar * property_name, GValue * value)
1003 GESTrackObjectPrivate *priv = object->priv;
1005 if (priv->properties_hashtable) {
1006 GstElement *element;
1009 element = g_hash_table_lookup (priv->properties_hashtable, property_name);
1011 prop_name = g_strsplit (property_name, "-", 2);
1012 g_object_set_property (G_OBJECT (element), prop_name[1], value);
1013 g_strfreev (prop_name);
1015 GST_ERROR ("The %s property doesn't exist", property_name);
1018 GST_DEBUG ("The child properties haven't been set on %p", object);
1023 * ges_track_object_get_child_property:
1024 * @object: The origin #GESTrackObject
1025 * @property_name: The name of the property
1026 * @value: return location for the property value
1028 * Gets a property of a child of @object.
1031 ges_track_object_get_child_property (GESTrackObject * object,
1032 const gchar * property_name, gpointer value)
1034 GESTrackObjectPrivate *priv = object->priv;
1036 if (priv->properties_hashtable) {
1037 GstElement *element;
1040 element = g_hash_table_lookup (priv->properties_hashtable, property_name);
1042 prop_name = g_strsplit (property_name, "-", 2);
1043 g_object_get (G_OBJECT (element), prop_name[1], value, NULL);
1044 g_strfreev (prop_name);
1046 GST_ERROR ("The %s property doesn't exist", property_name);
1049 GST_DEBUG ("The child properties haven't been set on %p", object);