From e6aeb9704032e533f944e6335c21c3b5012b4819 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 16 Dec 2010 16:27:26 +0100 Subject: [PATCH] GESTrackObject: Add a 'locked' property for position synchronization And update all code using it --- docs/libs/ges-sections.txt | 2 + ges/ges-timeline-object.c | 99 ++++++++++++++++---------------- ges/ges-track-object.c | 31 ++++++++++ ges/ges-track-object.h | 3 + tests/check/ges/timelineobject.c | 61 ++++++++++++++++++++ 5 files changed, 146 insertions(+), 50 deletions(-) diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index e0181e958e..a4fc9b0fa4 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -68,6 +68,8 @@ GES_TYPE_TRACK GESTrackObject GESTrackObjectClass ges_track_object_set_active +ges_track_object_set_locked +ges_track_object_is_locked ges_track_object_get_track ges_track_object_get_timeline_object ges_track_object_get_gnlobject diff --git a/ges/ges-timeline-object.c b/ges/ges-timeline-object.c index f35b01436c..58ed7ec5a6 100644 --- a/ges/ges-timeline-object.c +++ b/ges/ges-timeline-object.c @@ -417,20 +417,20 @@ ges_timeline_object_fill_track_object_func (GESTimelineObject * object, void ges_timeline_object_set_start (GESTimelineObject * object, guint64 start) { + GList *tmp; + GESTrackObject *tr; + GST_DEBUG ("object:%p, start:%" GST_TIME_FORMAT, object, GST_TIME_ARGS (start)); - if (G_LIKELY (object->priv->trackobjects)) { - GList *tmp; - - for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) + for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) { + tr = (GESTrackObject *) tmp->data; + if (ges_track_object_is_locked (tr)) /* call set_start_internal on each trackobject */ - ges_track_object_set_start_internal (GES_TRACK_OBJECT (tmp->data), start); - + ges_track_object_set_start_internal (tr, start); } object->start = start; - } /** @@ -444,22 +444,21 @@ ges_timeline_object_set_start (GESTimelineObject * object, guint64 start) void ges_timeline_object_set_inpoint (GESTimelineObject * object, guint64 inpoint) { + GList *tmp; + GESTrackObject *tr; + GST_DEBUG ("object:%p, inpoint:%" GST_TIME_FORMAT, object, GST_TIME_ARGS (inpoint)); - if (G_LIKELY (object->priv->trackobjects)) { - GList *tmp; + for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) { + tr = (GESTrackObject *) tmp->data; - for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) + if (ges_track_object_is_locked (tr)) /* call set_inpoint_internal on each trackobject */ - ges_track_object_set_inpoint_internal (GES_TRACK_OBJECT (tmp->data), - inpoint); - + ges_track_object_set_inpoint_internal (tr, inpoint); } object->inpoint = inpoint; - - } /** @@ -472,22 +471,21 @@ ges_timeline_object_set_inpoint (GESTimelineObject * object, guint64 inpoint) void ges_timeline_object_set_duration (GESTimelineObject * object, guint64 duration) { + GList *tmp; + GESTrackObject *tr; + GST_DEBUG ("object:%p, duration:%" GST_TIME_FORMAT, object, GST_TIME_ARGS (duration)); - if (G_LIKELY (object->priv->trackobjects)) { - GList *tmp; + for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) { + tr = (GESTrackObject *) tmp->data; - for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) + if (ges_track_object_is_locked (tr)) /* call set_duration_internal on each trackobject */ - ges_track_object_set_duration_internal (GES_TRACK_OBJECT (tmp->data), - duration); - + ges_track_object_set_duration_internal (tr, duration); } object->duration = duration; - - } /** @@ -500,20 +498,19 @@ ges_timeline_object_set_duration (GESTimelineObject * object, guint64 duration) void ges_timeline_object_set_priority (GESTimelineObject * object, guint priority) { + GList *tmp; + GESTrackObject *tr; + GST_DEBUG ("object:%p, priority:%d", object, priority); - if (G_LIKELY (object->priv->trackobjects)) { - GList *tmp; - - for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) + for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) { + tr = (GESTrackObject *) tmp->data; + if (ges_track_object_is_locked (tr)) /* call set_priority_internal on each trackobject */ - ges_track_object_set_priority_internal (GES_TRACK_OBJECT (tmp->data), - priority); - + ges_track_object_set_priority_internal (tr, priority); } object->priority = priority; - } /** @@ -537,23 +534,20 @@ ges_timeline_object_find_track_object (GESTimelineObject * object, GESTrack * track, GType type) { GESTrackObject *ret = NULL; + GList *tmp; + GESTrackObject *otmp; - if (G_LIKELY (object->priv->trackobjects)) { - GList *tmp; - GESTrackObject *otmp; + for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) { + otmp = (GESTrackObject *) tmp->data; - for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) { - otmp = (GESTrackObject *) tmp->data; + if (ges_track_object_get_track (otmp) == track) { + if ((type != G_TYPE_NONE) && !G_TYPE_CHECK_INSTANCE_TYPE (tmp->data, + type)) + continue; - if (ges_track_object_get_track (otmp) == track) { - if ((type != G_TYPE_NONE) && !G_TYPE_CHECK_INSTANCE_TYPE (tmp->data, - type)) - continue; - - ret = GES_TRACK_OBJECT (tmp->data); - g_object_ref (ret); - break; - } + ret = GES_TRACK_OBJECT (tmp->data); + g_object_ref (ret); + break; } } @@ -607,21 +601,26 @@ ges_timeline_object_get_track_objects (GESTimelineObject * object) return ret; } + +/* + * PROPERTY NOTIFICATIONS FROM TRACK OBJECTS + */ static void track_object_priority_offset_changed_cb (GESTrackObject * child, - GParamSpec * arg G_GNUC_UNUSED, GESTimelineObject * obj) + GParamSpec * arg G_GNUC_UNUSED, GESTimelineObject * object) { guint new, old; /* all track objects have height 1 */ new = ges_track_object_get_priority_offset (child) + 1; - old = GES_TIMELINE_OBJECT_HEIGHT (obj); + old = GES_TIMELINE_OBJECT_HEIGHT (object); - GST_LOG ("object %p, new=%d, old=%d", obj, new, old); + GST_LOG ("object %p, new=%d, old=%d", object, new, old); if (new > old) { - obj->height = new; + object->height = new; GST_LOG ("emitting notify signal"); - g_object_notify ((GObject *) obj, "height"); + /* FIXME : use g_object_notify_by_pspec */ + g_object_notify ((GObject *) object, "height"); } } diff --git a/ges/ges-track-object.c b/ges/ges-track-object.c index 0cf9181a30..30529551cb 100644 --- a/ges/ges-track-object.c +++ b/ges/ges-track-object.c @@ -71,6 +71,8 @@ struct _GESTrackObjectPrivate gboolean valid; + gboolean locked; /* If TRUE, then moves in sync with its controlling + * GESTimelineObject */ }; enum @@ -273,6 +275,7 @@ ges_track_object_init (GESTrackObject * self) self->priv->pending_duration = GST_SECOND; self->priv->pending_gnl_priority = 1; self->priv->pending_active = TRUE; + self->priv->locked = TRUE; } gboolean @@ -760,3 +763,31 @@ ges_track_object_get_element (GESTrackObject * object) { return object->priv->element; } + +/** + * ges_track_object_set_locked: + * @object: a #GESTrackObject + * @locked: whether the object is lock to its parent + * + * Set the locking status of the @object in relationship to its controlling + * #GESTimelineObject. If @locked is %TRUE, then this object will move synchronously + * with its controlling #GESTimelineObject. +*/ +void +ges_track_object_set_locked (GESTrackObject * object, gboolean locked) +{ + object->priv->locked = locked; +} + +/** + * ges_track_object_is_locked: + * @object: a #GESTrackObject + * + * Returns: %TRUE if the object is moving synchronously to its controlling + * #GESTimelineObject, else %FALSE. + */ +gboolean +ges_track_object_is_locked (GESTrackObject * object) +{ + return object->priv->locked; +} diff --git a/ges/ges-track-object.h b/ges/ges-track-object.h index c996c48708..2aa6f10e8a 100644 --- a/ges/ges-track-object.h +++ b/ges/ges-track-object.h @@ -151,6 +151,9 @@ GESTimelineObject * ges_track_object_get_timeline_object (GESTrackObject* object GstElement * ges_track_object_get_gnlobject (GESTrackObject * object); GstElement * ges_track_object_get_element (GESTrackObject * object); +void ges_track_object_set_locked (GESTrackObject * object, gboolean locked); +gboolean ges_track_object_is_locked (GESTrackObject * object); + /* Private methods for GESTimelineObject's usage only */ gboolean ges_track_object_set_start_internal (GESTrackObject * object, guint64 start); gboolean ges_track_object_set_inpoint_internal (GESTrackObject * object, guint64 inpoint); diff --git a/tests/check/ges/timelineobject.c b/tests/check/ges/timelineobject.c index 8bd98c7ab8..dacba20798 100644 --- a/tests/check/ges/timelineobject.c +++ b/tests/check/ges/timelineobject.c @@ -113,6 +113,66 @@ GST_START_TEST (test_object_properties) GST_END_TEST; +GST_START_TEST (test_object_properties_unlocked) +{ + GESTrack *track; + GESTrackObject *trackobject; + GESTimelineObject *object; + + ges_init (); + + track = ges_track_new (GES_TRACK_TYPE_CUSTOM, GST_CAPS_ANY); + fail_unless (track != NULL); + + object = + (GESTimelineObject *) ges_custom_timeline_source_new (my_fill_track_func, + NULL); + fail_unless (object != NULL); + + /* Set some properties */ + g_object_set (object, "start", (guint64) 42, "duration", (guint64) 51, + "in-point", (guint64) 12, NULL); + assert_equals_uint64 (GES_TIMELINE_OBJECT_START (object), 42); + assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 51); + assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 12); + + trackobject = ges_timeline_object_create_track_object (object, track); + fail_unless (trackobject != NULL); + fail_unless (ges_track_object_set_track (trackobject, track)); + + /* Check that trackobject has the same properties */ + assert_equals_uint64 (GES_TRACK_OBJECT_START (trackobject), 42); + assert_equals_uint64 (GES_TRACK_OBJECT_DURATION (trackobject), 51); + assert_equals_uint64 (GES_TRACK_OBJECT_INPOINT (trackobject), 12); + + /* And let's also check that it propagated correctly to GNonLin */ + gnl_object_check (ges_track_object_get_gnlobject (trackobject), 42, 51, 12, + 51, 0, TRUE); + + /* This time we unlock the trackobject and make sure it doesn't propagate */ + ges_track_object_set_locked (trackobject, FALSE); + + /* Change more properties, they will be set on the GESTimelineObject */ + g_object_set (object, "start", (guint64) 420, "duration", (guint64) 510, + "in-point", (guint64) 120, NULL); + assert_equals_uint64 (GES_TIMELINE_OBJECT_START (object), 420); + assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 510); + assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 120); + /* ... but not on the GESTrackObject since it was unlocked... */ + assert_equals_uint64 (GES_TRACK_OBJECT_START (trackobject), 42); + assert_equals_uint64 (GES_TRACK_OBJECT_DURATION (trackobject), 51); + assert_equals_uint64 (GES_TRACK_OBJECT_INPOINT (trackobject), 12); + /* ... and neither on the GNonLin object */ + gnl_object_check (ges_track_object_get_gnlobject (trackobject), 42, 51, 12, + 51, 0, TRUE); + + ges_timeline_object_release_track_object (object, trackobject); + + g_object_unref (object); + g_object_unref (track); +} + +GST_END_TEST; static Suite * ges_suite (void) { @@ -122,6 +182,7 @@ ges_suite (void) suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_object_properties); + tcase_add_test (tc_chain, test_object_properties_unlocked); return s; }