mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
GESTrackObject: Add a 'locked' property for position synchronization
And update all code using it
This commit is contained in:
parent
08fe90ab4e
commit
e6aeb97040
5 changed files with 146 additions and 50 deletions
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue