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 "ges-track-object.h"
35 #include "ges-timeline-object.h"
37 static GQuark _start_quark;
38 static GQuark _inpoint_quark;
39 static GQuark _duration_quark;
40 static GQuark _priority_quark;
44 _start_quark = g_quark_from_static_string ("start"); \
45 _inpoint_quark = g_quark_from_static_string ("inpoint"); \
46 _duration_quark = g_quark_from_static_string ("duration"); \
47 _priority_quark = g_quark_from_static_string ("priority"); \
50 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GESTrackObject, ges_track_object,
51 G_TYPE_OBJECT, _do_init);
53 struct _GESTrackObjectPrivate
55 /* cache the base priority and offset */
56 guint32 base_priority;
57 guint32 priority_offset;
59 /* These fields are only used before the gnlobject is available */
60 guint64 pending_start;
61 guint64 pending_inpoint;
62 guint64 pending_duration;
63 guint32 pending_gnl_priority;
64 gboolean pending_active;
66 GstElement *gnlobject; /* The GnlObject */
67 GstElement *element; /* The element contained in the gnlobject (can be NULL) */
69 GESTimelineObject *timelineobj;
74 gboolean locked; /* If TRUE, then moves in sync with its controlling
75 * GESTimelineObject */
90 static GParamSpec *properties[PROP_LAST];
92 static GstElement *ges_track_object_create_gnl_object_func (GESTrackObject *
95 void gnlobject_start_cb (GstElement * gnlobject, GParamSpec * arg
96 G_GNUC_UNUSED, GESTrackObject * obj);
98 void gnlobject_media_start_cb (GstElement * gnlobject, GParamSpec * arg
99 G_GNUC_UNUSED, GESTrackObject * obj);
101 void gnlobject_priority_cb (GstElement * gnlobject, GParamSpec * arg
102 G_GNUC_UNUSED, GESTrackObject * obj);
104 void gnlobject_duration_cb (GstElement * gnlobject, GParamSpec * arg
105 G_GNUC_UNUSED, GESTrackObject * obj);
107 void gnlobject_active_cb (GstElement * gnlobject, GParamSpec * arg
108 G_GNUC_UNUSED, GESTrackObject * obj);
110 static inline gboolean
111 ges_track_object_set_start_internal (GESTrackObject * object, guint64 start);
112 static inline gboolean
113 ges_track_object_set_inpoint_internal (GESTrackObject * object,
115 static inline gboolean ges_track_object_set_duration_internal (GESTrackObject *
116 object, guint64 duration);
117 static inline gboolean ges_track_object_set_priority_internal (GESTrackObject *
118 object, guint32 priority);
119 static inline gboolean
120 ges_track_object_set_priority_offset_internal (GESTrackObject * object,
123 static gboolean ges_track_object_update_priority (GESTrackObject * object);
126 ges_track_object_get_property (GObject * object, guint property_id,
127 GValue * value, GParamSpec * pspec)
129 GESTrackObject *tobj = GES_TRACK_OBJECT (object);
131 switch (property_id) {
133 g_value_set_uint64 (value, tobj->start);
136 g_value_set_uint64 (value, tobj->inpoint);
139 g_value_set_uint64 (value, tobj->duration);
142 g_value_set_uint (value, tobj->priv->base_priority);
144 case PROP_PRIORITY_OFFSET:
145 g_value_set_uint (value, tobj->priv->priority_offset);
148 g_value_set_boolean (value, tobj->active);
151 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
156 ges_track_object_set_property (GObject * object, guint property_id,
157 const GValue * value, GParamSpec * pspec)
159 GESTrackObject *tobj = GES_TRACK_OBJECT (object);
161 switch (property_id) {
163 ges_track_object_set_start_internal (tobj, g_value_get_uint64 (value));
166 ges_track_object_set_inpoint_internal (tobj, g_value_get_uint64 (value));
169 ges_track_object_set_duration_internal (tobj, g_value_get_uint64 (value));
172 ges_track_object_set_priority_internal (tobj, g_value_get_uint (value));
174 case PROP_PRIORITY_OFFSET:
175 ges_track_object_set_priority_offset_internal (tobj, g_value_get_uint
179 ges_track_object_set_active (tobj, g_value_get_boolean (value));
182 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
187 ges_track_object_dispose (GObject * object)
189 G_OBJECT_CLASS (ges_track_object_parent_class)->dispose (object);
193 ges_track_object_finalize (GObject * object)
195 G_OBJECT_CLASS (ges_track_object_parent_class)->finalize (object);
199 ges_track_object_class_init (GESTrackObjectClass * klass)
201 GObjectClass *object_class = G_OBJECT_CLASS (klass);
203 g_type_class_add_private (klass, sizeof (GESTrackObjectPrivate));
205 object_class->get_property = ges_track_object_get_property;
206 object_class->set_property = ges_track_object_set_property;
207 object_class->dispose = ges_track_object_dispose;
208 object_class->finalize = ges_track_object_finalize;
211 * GESTrackObject:start
213 * The position of the object in the container #GESTrack (in nanoseconds).
215 properties[PROP_START] = g_param_spec_uint64 ("start", "Start",
216 "The position in the container", 0, G_MAXUINT64, 0, G_PARAM_READWRITE);
217 g_object_class_install_property (object_class, PROP_START,
218 properties[PROP_START]);
221 * GESTrackObject:in-point
223 * The in-point at which this #GESTrackObject will start outputting data
224 * from its contents (in nanoseconds).
226 * Ex : an in-point of 5 seconds means that the first outputted buffer will
227 * be the one located 5 seconds in the controlled resource.
229 properties[PROP_INPOINT] =
230 g_param_spec_uint64 ("in-point", "In-point", "The in-point", 0,
231 G_MAXUINT64, 0, G_PARAM_READWRITE);
232 g_object_class_install_property (object_class, PROP_INPOINT,
233 properties[PROP_INPOINT]);
236 * GESTrackObject:duration
238 * The duration (in nanoseconds) which will be used in the container #GESTrack
239 * starting from 'in-point'.
242 properties[PROP_DURATION] =
243 g_param_spec_uint64 ("duration", "Duration", "The duration to use", 0,
244 G_MAXUINT64, GST_SECOND, G_PARAM_READWRITE);
245 g_object_class_install_property (object_class, PROP_DURATION,
246 properties[PROP_DURATION]);
249 * GESTrackObject:priority
251 * The priority of the object within the containing #GESTrack.
252 * If two objects intersect over the same region of time, the @priority
253 * property is used to decide which one takes precedence.
255 * The highest priority (that supercedes everything) is 0, and then lowering
256 * priorities go in increasing numerical value (with #G_MAXUINT64 being the
259 properties[PROP_PRIORITY] = g_param_spec_uint ("priority", "Priority",
260 "The priority of the object", 0, G_MAXUINT, 0, G_PARAM_READWRITE);
261 g_object_class_install_property (object_class, PROP_PRIORITY,
262 properties[PROP_PRIORITY]);
265 * GESTrackObject:priority-offset
267 * The priority of the object relative to its parent #GESTimelineObject.
269 properties[PROP_PRIORITY_OFFSET] =
270 g_param_spec_uint ("priority-offset", "Priority Offset",
271 "An offset from the base priority", 0, G_MAXUINT, 0, G_PARAM_READWRITE);
272 g_object_class_install_property (object_class, PROP_PRIORITY_OFFSET,
273 properties[PROP_PRIORITY_OFFSET]);
276 * GESTrackObject:active
278 * Whether the object should be taken into account in the #GESTrack output.
279 * If #FALSE, then its contents will not be used in the resulting track.
281 properties[PROP_ACTIVE] =
282 g_param_spec_boolean ("active", "Active", "Use object in output", TRUE,
284 g_object_class_install_property (object_class, PROP_ACTIVE,
285 properties[PROP_ACTIVE]);
287 klass->create_gnl_object = ges_track_object_create_gnl_object_func;
291 ges_track_object_init (GESTrackObject * self)
293 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
294 GES_TYPE_TRACK_OBJECT, GESTrackObjectPrivate);
296 /* Sane default values */
297 self->priv->pending_start = 0;
298 self->priv->pending_inpoint = 0;
299 self->priv->pending_duration = GST_SECOND;
300 self->priv->pending_gnl_priority = 1;
301 self->priv->pending_active = TRUE;
302 self->priv->locked = TRUE;
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 g_object_notify_by_pspec (G_OBJECT (object), properties[PROP_START]);
335 static inline gboolean
336 ges_track_object_set_inpoint_internal (GESTrackObject * object, guint64 inpoint)
339 GST_DEBUG ("object:%p, inpoint:%" GST_TIME_FORMAT,
340 object, GST_TIME_ARGS (inpoint));
342 if (object->priv->gnlobject != NULL) {
343 if (G_UNLIKELY (inpoint == object->inpoint))
346 g_object_set (object->priv->gnlobject, "media-start", inpoint, NULL);
348 object->priv->pending_inpoint = inpoint;
354 * ges_track_object_set_inpoint:
355 * @object: a #GESTrackObject
356 * @inpoint: the in-point (in #GstClockTime)
358 * Set the offset within the contents of this #GESTrackObject
361 ges_track_object_set_inpoint (GESTrackObject * object, guint64 inpoint)
363 if (ges_track_object_set_inpoint_internal (object, inpoint))
364 g_object_notify_by_pspec (G_OBJECT (object), properties[PROP_INPOINT]);
367 static inline gboolean
368 ges_track_object_set_duration_internal (GESTrackObject * object,
371 GST_DEBUG ("object:%p, duration:%" GST_TIME_FORMAT,
372 object, GST_TIME_ARGS (duration));
374 if (object->priv->gnlobject != NULL) {
375 if (G_UNLIKELY (duration == object->duration))
378 g_object_set (object->priv->gnlobject, "duration", duration,
379 "media-duration", duration, NULL);
381 object->priv->pending_duration = duration;
386 * ges_track_object_set_duration:
387 * @object: a #GESTrackObject
388 * @duration: the duration (in #GstClockTime)
390 * Set the duration which will be used in the container #GESTrack
391 * starting from the 'in-point'
394 ges_track_object_set_duration (GESTrackObject * object, guint64 duration)
396 if (ges_track_object_set_duration_internal (object, duration))
397 g_object_notify_by_pspec (G_OBJECT (object), properties[PROP_DURATION]);
401 /* NOTE: we handle priority differently than other properties! the gnlpriority
402 * is object->base_priority + object->priority_offset! A change to either one
403 * will trigger an update to the gnonlin priority and a subsequent property
407 static inline gboolean
408 ges_track_object_set_priority_internal (GESTrackObject * object,
413 save = object->priv->base_priority;
414 GST_DEBUG ("object:%p, priority:%d", object, priority);
416 object->priv->base_priority = priority;
417 if (!ges_track_object_update_priority (object)) {
418 object->priv->base_priority = save;
425 * ges_track_object_set_priority:
426 * @object: a #GESTrackObject
427 * @priority: the priority
429 * Sets the priority of the object withing the containing #GESTrack.
430 * If two objects intersect over the same region of time, the priority
431 * property is used to decide which one takes precedence.
433 * The highest priority (that supercedes everything) is 0, and then
434 * lowering priorities go in increasing numerical value (with G_MAXUINT32
435 * being the lowest priority).
438 ges_track_object_set_priority (GESTrackObject * object, guint32 priority)
440 if (ges_track_object_set_priority_internal (object, priority))
441 g_object_notify_by_pspec (G_OBJECT (object), properties[PROP_PRIORITY]);
445 ges_track_object_set_priority_offset_internal (GESTrackObject * object,
446 guint32 priority_offset)
449 save = object->priv->priority_offset;
450 GST_DEBUG ("object:%p, offset:%d", object, priority_offset);
452 object->priv->priority_offset = priority_offset;
453 if (!ges_track_object_update_priority (object)) {
454 object->priv->base_priority = save;
461 ges_track_object_update_priority (GESTrackObject * object)
463 guint32 priority, offset, gnl;
465 priority = object->priv->base_priority;
466 offset = object->priv->priority_offset;
467 gnl = priority + offset;
468 GST_DEBUG ("object:%p, base:%d, offset:%d: gnl:%d", object, priority, offset,
471 if (object->priv->gnlobject != NULL) {
472 if (G_UNLIKELY (gnl == object->gnl_priority))
475 g_object_set (object->priv->gnlobject, "priority", gnl, NULL);
477 object->priv->pending_gnl_priority = gnl;
482 * ges_track_object_set_active:
483 * @object: a #GESTrackObject
484 * @active: visibility
486 * Sets the usage of the @object. If @active is %TRUE, the object will be used for
487 * playback and rendering, else it will be ignored.
489 * Returns: %TRUE if the property was toggled, else %FALSE
492 ges_track_object_set_active (GESTrackObject * object, gboolean active)
494 GST_DEBUG ("object:%p, active:%d", object, active);
496 if (object->priv->gnlobject != NULL) {
497 if (G_UNLIKELY (active == object->active))
500 g_object_set (object->priv->gnlobject, "active", active, NULL);
502 object->priv->pending_active = active;
506 /* Callbacks from the GNonLin object */
508 gnlobject_start_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
509 GESTrackObject * obj)
512 GESTrackObjectClass *klass;
514 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
516 g_object_get (gnlobject, "start", &start, NULL);
518 GST_DEBUG ("gnlobject start : %" GST_TIME_FORMAT " current : %"
519 GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (obj->start));
521 if (start != obj->start) {
523 if (klass->start_changed)
524 klass->start_changed (obj, start);
525 /* FIXME : emit changed */
529 /* Callbacks from the GNonLin object */
531 gnlobject_media_start_cb (GstElement * gnlobject,
532 GParamSpec * arg G_GNUC_UNUSED, GESTrackObject * obj)
535 GESTrackObjectClass *klass;
537 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
539 g_object_get (gnlobject, "media-start", &start, NULL);
541 GST_DEBUG ("gnlobject in-point : %" GST_TIME_FORMAT " current : %"
542 GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (obj->inpoint));
544 if (start != obj->inpoint) {
545 obj->inpoint = start;
546 if (klass->media_start_changed)
547 klass->media_start_changed (obj, start);
548 /* FIXME : emit changed */
553 gnlobject_priority_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
554 GESTrackObject * obj)
557 GESTrackObjectClass *klass;
559 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
561 g_object_get (gnlobject, "priority", &priority, NULL);
563 GST_DEBUG ("gnlobject priority : %d current : %d", priority,
566 if (priority != obj->gnl_priority) {
567 obj->gnl_priority = priority;
568 if (klass->gnl_priority_changed)
569 klass->gnl_priority_changed (obj, priority);
570 /* FIXME : emit changed */
575 gnlobject_duration_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
576 GESTrackObject * obj)
579 GESTrackObjectClass *klass;
581 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
583 g_object_get (gnlobject, "duration", &duration, NULL);
585 GST_DEBUG ("gnlobject duration : %" GST_TIME_FORMAT " current : %"
586 GST_TIME_FORMAT, GST_TIME_ARGS (duration), GST_TIME_ARGS (obj->duration));
588 if (duration != obj->duration) {
589 obj->duration = duration;
590 if (klass->duration_changed)
591 klass->duration_changed (obj, duration);
592 /* FIXME : emit changed */
597 gnlobject_active_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
598 GESTrackObject * obj)
601 GESTrackObjectClass *klass;
603 klass = GES_TRACK_OBJECT_GET_CLASS (obj);
605 g_object_get (gnlobject, "active", &active, NULL);
607 GST_DEBUG ("gnlobject active : %d current : %d", active, obj->active);
609 if (active != obj->active) {
610 obj->active = active;
611 if (klass->active_changed)
612 klass->active_changed (obj, active);
613 /* FIXME : emit changed */
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;
705 if (object->priv->gnlobject && object->priv->valid)
708 /* 1. Create the GnlObject */
709 GST_DEBUG ("Creating GnlObject");
711 class = GES_TRACK_OBJECT_GET_CLASS (object);
713 if (G_UNLIKELY (class->create_gnl_object == NULL)) {
714 GST_ERROR ("No 'create_gnl_object' implementation !");
718 GST_DEBUG ("Calling virtual method");
720 /* call the create_gnl_object virtual method */
721 gnlobject = class->create_gnl_object (object);
723 if (G_UNLIKELY (gnlobject == NULL)) {
725 ("'create_gnl_object' implementation returned TRUE but no GnlObject is available");
729 object->priv->gnlobject = gnlobject;
731 /* Connect to property notifications */
732 /* FIXME : remember the signalids so we can remove them later on !!! */
733 g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::start",
734 G_CALLBACK (gnlobject_start_cb), object);
735 g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::media-start",
736 G_CALLBACK (gnlobject_media_start_cb), object);
737 g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::duration",
738 G_CALLBACK (gnlobject_duration_cb), object);
739 g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::priority",
740 G_CALLBACK (gnlobject_priority_cb), object);
741 g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::active",
742 G_CALLBACK (gnlobject_active_cb), object);
744 /* 2. Fill in the GnlObject */
746 GST_DEBUG ("Got a valid GnlObject, now filling it in");
749 ges_timeline_object_fill_track_object (object->priv->timelineobj,
750 object, object->priv->gnlobject);
752 /* Set some properties on the GnlObject */
753 g_object_set (object->priv->gnlobject,
754 "caps", ges_track_get_caps (object->priv->track),
755 "duration", object->priv->pending_duration,
756 "media-duration", object->priv->pending_duration,
757 "start", object->priv->pending_start,
758 "media-start", object->priv->pending_inpoint,
759 "priority", object->priv->pending_gnl_priority,
760 "active", object->priv->pending_active, NULL);
765 object->priv->valid = res;
767 GST_DEBUG ("Returning res:%d", res);
774 ges_track_object_set_track (GESTrackObject * object, GESTrack * track)
776 GST_DEBUG ("object:%p, track:%p", object, track);
778 object->priv->track = track;
780 if (object->priv->track)
781 return ensure_gnl_object (object);
787 * ges_track_object_get_track:
788 * @object: a #GESTrackObject
790 * Returns: (transfer none): The #GESTrack to which this object belongs. Can be %NULL if it
791 * is not in any track
794 ges_track_object_get_track (GESTrackObject * object)
796 g_return_val_if_fail (GES_IS_TRACK_OBJECT (object), NULL);
798 return object->priv->track;
803 ges_track_object_set_timeline_object (GESTrackObject * object,
804 GESTimelineObject * tlobj)
806 GST_DEBUG ("object:%p, timeline-object:%p", object, tlobj);
808 object->priv->timelineobj = tlobj;
812 * ges_track_object_get_timeline_object:
813 * @object: a #GESTrackObject
815 * Returns: (transfer none): the #GESTimelineObject which is controlling
819 ges_track_object_get_timeline_object (GESTrackObject * object)
821 g_return_val_if_fail (GES_IS_TRACK_OBJECT (object), NULL);
823 return object->priv->timelineobj;
827 ges_track_object_get_priority_offset (GESTrackObject * object)
829 return object->priv->priority_offset;
833 * ges_track_object_get_gnlobject:
834 * @object: a #GESTrackObject
836 * Returns: (transfer none): the GNonLin object this object is controlling.
839 ges_track_object_get_gnlobject (GESTrackObject * object)
841 return object->priv->gnlobject;
845 * ges_track_object_get_element:
846 * @object: a #GESTrackObject
848 * Returns: (transfer none): the #GstElement this track object is controlling
852 ges_track_object_get_element (GESTrackObject * object)
854 return object->priv->element;
858 * ges_track_object_set_locked:
859 * @object: a #GESTrackObject
860 * @locked: whether the object is lock to its parent
862 * Set the locking status of the @object in relationship to its controlling
863 * #GESTimelineObject. If @locked is %TRUE, then this object will move synchronously
864 * with its controlling #GESTimelineObject.
867 ges_track_object_set_locked (GESTrackObject * object, gboolean locked)
869 object->priv->locked = locked;
873 * ges_track_object_is_locked:
874 * @object: a #GESTrackObject
876 * Returns: %TRUE if the object is moving synchronously to its controlling
877 * #GESTimelineObject, else %FALSE.
880 ges_track_object_is_locked (GESTrackObject * object)
882 return object->priv->locked;