mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +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
|
GESTrackObject
|
||||||
GESTrackObjectClass
|
GESTrackObjectClass
|
||||||
ges_track_object_set_active
|
ges_track_object_set_active
|
||||||
|
ges_track_object_set_locked
|
||||||
|
ges_track_object_is_locked
|
||||||
ges_track_object_get_track
|
ges_track_object_get_track
|
||||||
ges_track_object_get_timeline_object
|
ges_track_object_get_timeline_object
|
||||||
ges_track_object_get_gnlobject
|
ges_track_object_get_gnlobject
|
||||||
|
|
|
@ -417,20 +417,20 @@ ges_timeline_object_fill_track_object_func (GESTimelineObject * object,
|
||||||
void
|
void
|
||||||
ges_timeline_object_set_start (GESTimelineObject * object, guint64 start)
|
ges_timeline_object_set_start (GESTimelineObject * object, guint64 start)
|
||||||
{
|
{
|
||||||
|
GList *tmp;
|
||||||
|
GESTrackObject *tr;
|
||||||
|
|
||||||
GST_DEBUG ("object:%p, start:%" GST_TIME_FORMAT,
|
GST_DEBUG ("object:%p, start:%" GST_TIME_FORMAT,
|
||||||
object, GST_TIME_ARGS (start));
|
object, GST_TIME_ARGS (start));
|
||||||
|
|
||||||
if (G_LIKELY (object->priv->trackobjects)) {
|
for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) {
|
||||||
GList *tmp;
|
tr = (GESTrackObject *) tmp->data;
|
||||||
|
if (ges_track_object_is_locked (tr))
|
||||||
for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp))
|
|
||||||
/* call set_start_internal on each trackobject */
|
/* 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;
|
object->start = start;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -444,22 +444,21 @@ ges_timeline_object_set_start (GESTimelineObject * object, guint64 start)
|
||||||
void
|
void
|
||||||
ges_timeline_object_set_inpoint (GESTimelineObject * object, guint64 inpoint)
|
ges_timeline_object_set_inpoint (GESTimelineObject * object, guint64 inpoint)
|
||||||
{
|
{
|
||||||
|
GList *tmp;
|
||||||
|
GESTrackObject *tr;
|
||||||
|
|
||||||
GST_DEBUG ("object:%p, inpoint:%" GST_TIME_FORMAT,
|
GST_DEBUG ("object:%p, inpoint:%" GST_TIME_FORMAT,
|
||||||
object, GST_TIME_ARGS (inpoint));
|
object, GST_TIME_ARGS (inpoint));
|
||||||
|
|
||||||
if (G_LIKELY (object->priv->trackobjects)) {
|
for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) {
|
||||||
GList *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 */
|
/* call set_inpoint_internal on each trackobject */
|
||||||
ges_track_object_set_inpoint_internal (GES_TRACK_OBJECT (tmp->data),
|
ges_track_object_set_inpoint_internal (tr, inpoint);
|
||||||
inpoint);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object->inpoint = inpoint;
|
object->inpoint = inpoint;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -472,22 +471,21 @@ ges_timeline_object_set_inpoint (GESTimelineObject * object, guint64 inpoint)
|
||||||
void
|
void
|
||||||
ges_timeline_object_set_duration (GESTimelineObject * object, guint64 duration)
|
ges_timeline_object_set_duration (GESTimelineObject * object, guint64 duration)
|
||||||
{
|
{
|
||||||
|
GList *tmp;
|
||||||
|
GESTrackObject *tr;
|
||||||
|
|
||||||
GST_DEBUG ("object:%p, duration:%" GST_TIME_FORMAT,
|
GST_DEBUG ("object:%p, duration:%" GST_TIME_FORMAT,
|
||||||
object, GST_TIME_ARGS (duration));
|
object, GST_TIME_ARGS (duration));
|
||||||
|
|
||||||
if (G_LIKELY (object->priv->trackobjects)) {
|
for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) {
|
||||||
GList *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 */
|
/* call set_duration_internal on each trackobject */
|
||||||
ges_track_object_set_duration_internal (GES_TRACK_OBJECT (tmp->data),
|
ges_track_object_set_duration_internal (tr, duration);
|
||||||
duration);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object->duration = duration;
|
object->duration = duration;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -500,20 +498,19 @@ ges_timeline_object_set_duration (GESTimelineObject * object, guint64 duration)
|
||||||
void
|
void
|
||||||
ges_timeline_object_set_priority (GESTimelineObject * object, guint priority)
|
ges_timeline_object_set_priority (GESTimelineObject * object, guint priority)
|
||||||
{
|
{
|
||||||
|
GList *tmp;
|
||||||
|
GESTrackObject *tr;
|
||||||
|
|
||||||
GST_DEBUG ("object:%p, priority:%d", object, priority);
|
GST_DEBUG ("object:%p, priority:%d", object, priority);
|
||||||
|
|
||||||
if (G_LIKELY (object->priv->trackobjects)) {
|
for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) {
|
||||||
GList *tmp;
|
tr = (GESTrackObject *) tmp->data;
|
||||||
|
if (ges_track_object_is_locked (tr))
|
||||||
for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp))
|
|
||||||
/* call set_priority_internal on each trackobject */
|
/* call set_priority_internal on each trackobject */
|
||||||
ges_track_object_set_priority_internal (GES_TRACK_OBJECT (tmp->data),
|
ges_track_object_set_priority_internal (tr, priority);
|
||||||
priority);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object->priority = priority;
|
object->priority = priority;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -537,23 +534,20 @@ ges_timeline_object_find_track_object (GESTimelineObject * object,
|
||||||
GESTrack * track, GType type)
|
GESTrack * track, GType type)
|
||||||
{
|
{
|
||||||
GESTrackObject *ret = NULL;
|
GESTrackObject *ret = NULL;
|
||||||
|
GList *tmp;
|
||||||
|
GESTrackObject *otmp;
|
||||||
|
|
||||||
if (G_LIKELY (object->priv->trackobjects)) {
|
for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) {
|
||||||
GList *tmp;
|
otmp = (GESTrackObject *) tmp->data;
|
||||||
GESTrackObject *otmp;
|
|
||||||
|
|
||||||
for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) {
|
if (ges_track_object_get_track (otmp) == track) {
|
||||||
otmp = (GESTrackObject *) tmp->data;
|
if ((type != G_TYPE_NONE) && !G_TYPE_CHECK_INSTANCE_TYPE (tmp->data,
|
||||||
|
type))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (ges_track_object_get_track (otmp) == track) {
|
ret = GES_TRACK_OBJECT (tmp->data);
|
||||||
if ((type != G_TYPE_NONE) && !G_TYPE_CHECK_INSTANCE_TYPE (tmp->data,
|
g_object_ref (ret);
|
||||||
type))
|
break;
|
||||||
continue;
|
|
||||||
|
|
||||||
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PROPERTY NOTIFICATIONS FROM TRACK OBJECTS
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
track_object_priority_offset_changed_cb (GESTrackObject * child,
|
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;
|
guint new, old;
|
||||||
|
|
||||||
/* all track objects have height 1 */
|
/* all track objects have height 1 */
|
||||||
new = ges_track_object_get_priority_offset (child) + 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) {
|
if (new > old) {
|
||||||
obj->height = new;
|
object->height = new;
|
||||||
GST_LOG ("emitting notify signal");
|
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 valid;
|
||||||
|
|
||||||
|
gboolean locked; /* If TRUE, then moves in sync with its controlling
|
||||||
|
* GESTimelineObject */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -273,6 +275,7 @@ ges_track_object_init (GESTrackObject * self)
|
||||||
self->priv->pending_duration = GST_SECOND;
|
self->priv->pending_duration = GST_SECOND;
|
||||||
self->priv->pending_gnl_priority = 1;
|
self->priv->pending_gnl_priority = 1;
|
||||||
self->priv->pending_active = TRUE;
|
self->priv->pending_active = TRUE;
|
||||||
|
self->priv->locked = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -760,3 +763,31 @@ ges_track_object_get_element (GESTrackObject * object)
|
||||||
{
|
{
|
||||||
return object->priv->element;
|
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_gnlobject (GESTrackObject * object);
|
||||||
GstElement * ges_track_object_get_element (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 */
|
/* Private methods for GESTimelineObject's usage only */
|
||||||
gboolean ges_track_object_set_start_internal (GESTrackObject * object, guint64 start);
|
gboolean ges_track_object_set_start_internal (GESTrackObject * object, guint64 start);
|
||||||
gboolean ges_track_object_set_inpoint_internal (GESTrackObject * object, guint64 inpoint);
|
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_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 *
|
static Suite *
|
||||||
ges_suite (void)
|
ges_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -122,6 +182,7 @@ ges_suite (void)
|
||||||
suite_add_tcase (s, tc_chain);
|
suite_add_tcase (s, tc_chain);
|
||||||
|
|
||||||
tcase_add_test (tc_chain, test_object_properties);
|
tcase_add_test (tc_chain, test_object_properties);
|
||||||
|
tcase_add_test (tc_chain, test_object_properties_unlocked);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue