GESTrackObject: Add a 'locked' property for position synchronization

And update all code using it
This commit is contained in:
Edward Hervey 2010-12-16 16:27:26 +01:00
parent 08fe90ab4e
commit e6aeb97040
5 changed files with 146 additions and 50 deletions

View file

@ -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

View file

@ -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");
}
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}