mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
Reimplement the timeline editing API
This is implemented on top of a Tree that represents the whole timeline. SourceClips can not fully overlap anymore and the tests have been updated to take that into account. Some new tests were added to verify that behaviour in greater details
This commit is contained in:
parent
7261f714fc
commit
a46390ff56
27 changed files with 2814 additions and 2560 deletions
|
@ -46,6 +46,10 @@ neighbour_changed_cb (GESClip * clip, GParamSpec * arg G_GNUC_UNUSED,
|
|||
GESTimelineElement *parent =
|
||||
ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT (clip));
|
||||
|
||||
if (ELEMENT_FLAG_IS_SET (parent, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
GESTimelineElement *prev_topparent =
|
||||
ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT
|
||||
|
@ -54,6 +58,11 @@ neighbour_changed_cb (GESClip * clip, GParamSpec * arg G_GNUC_UNUSED,
|
|||
ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT
|
||||
(self->previous_source));
|
||||
|
||||
if (ELEMENT_FLAG_IS_SET (prev_topparent, GES_TIMELINE_ELEMENT_SET_SIMPLE) ||
|
||||
ELEMENT_FLAG_IS_SET (next_topparent, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent == prev_topparent && parent == next_topparent) {
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"Moving all inside the same group, nothing to do");
|
||||
|
@ -192,3 +201,11 @@ ges_auto_transition_new (GESTrackElement * transition,
|
|||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
ges_auto_transition_update (GESAutoTransition * self)
|
||||
{
|
||||
GST_INFO ("Updating info %s",
|
||||
GES_TIMELINE_ELEMENT_NAME (self->transition_clip));
|
||||
neighbour_changed_cb (self->previous_clip, NULL, self);
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ struct _GESAutoTransition
|
|||
|
||||
G_GNUC_INTERNAL GType ges_auto_transition_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_GNUC_INTERNAL void ges_auto_transition_update (GESAutoTransition *self);
|
||||
G_GNUC_INTERNAL GESAutoTransition * ges_auto_transition_new (GESTrackElement * transition,
|
||||
GESTrackElement * previous_source,
|
||||
GESTrackElement * next_source);
|
||||
|
|
229
ges/ges-clip.c
229
ges/ges-clip.c
|
@ -175,7 +175,6 @@ static gboolean
|
|||
_set_duration (GESTimelineElement * element, GstClockTime duration)
|
||||
{
|
||||
GList *tmp;
|
||||
GESTimeline *timeline;
|
||||
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
|
||||
|
@ -183,16 +182,8 @@ _set_duration (GESTimelineElement * element, GstClockTime duration)
|
|||
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
|
||||
if (child != container->initiated_move) {
|
||||
/* Make the snapping happen if in a timeline */
|
||||
timeline = GES_TIMELINE_ELEMENT_TIMELINE (child);
|
||||
if (timeline == NULL
|
||||
|| ELEMENT_FLAG_IS_SET (element, GES_CLIP_IS_SPLITTING)
|
||||
|| (ges_timeline_trim_object_simple (timeline, child, NULL,
|
||||
GES_EDGE_END, _START (child) + duration, TRUE) == FALSE)) {
|
||||
_set_duration0 (GES_TIMELINE_ELEMENT (child), duration);
|
||||
}
|
||||
}
|
||||
if (child != container->initiated_move)
|
||||
_set_duration0 (GES_TIMELINE_ELEMENT (child), duration);
|
||||
}
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
|
@ -628,9 +619,8 @@ static gboolean
|
|||
_edit (GESContainer * container, GList * layers,
|
||||
gint new_layer_priority, GESEditMode mode, GESEdge edge, guint64 position)
|
||||
{
|
||||
GList *tmp;
|
||||
gboolean ret = TRUE;
|
||||
GESLayer *layer;
|
||||
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (container);
|
||||
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
|
||||
|
||||
if (!G_UNLIKELY (GES_CONTAINER_CHILDREN (container))) {
|
||||
GST_WARNING_OBJECT (container, "Trying to edit, but not containing"
|
||||
|
@ -638,31 +628,35 @@ _edit (GESContainer * container, GList * layers,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
for (tmp = GES_CONTAINER_CHILDREN (container); tmp; tmp = g_list_next (tmp)) {
|
||||
if (GES_IS_SOURCE (tmp->data) || GES_IS_TRANSITION (tmp->data)) {
|
||||
ret &= ges_track_element_edit (tmp->data, layers, mode, edge, position);
|
||||
break;
|
||||
}
|
||||
if (!timeline) {
|
||||
GST_WARNING_OBJECT (container, "Trying to edit, but not in any"
|
||||
"timeline.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Moving to layer */
|
||||
if (new_layer_priority == -1) {
|
||||
GST_DEBUG_OBJECT (container, "Not moving new prio %d", new_layer_priority);
|
||||
} else {
|
||||
gint priority_offset;
|
||||
|
||||
layer = GES_CLIP (container)->priv->layer;
|
||||
if (layer == NULL) {
|
||||
GST_WARNING_OBJECT (container, "Not in any layer yet, not moving");
|
||||
|
||||
switch (mode) {
|
||||
case GES_EDIT_MODE_RIPPLE:
|
||||
return timeline_ripple_object (timeline, element,
|
||||
new_layer_priority <
|
||||
0 ? GES_TIMELINE_ELEMENT_LAYER_PRIORITY (container) :
|
||||
new_layer_priority, layers, edge, position);
|
||||
case GES_EDIT_MODE_TRIM:
|
||||
return timeline_trim_object (timeline, element,
|
||||
new_layer_priority <
|
||||
0 ? GES_TIMELINE_ELEMENT_LAYER_PRIORITY (container) :
|
||||
new_layer_priority, layers, edge, position);
|
||||
case GES_EDIT_MODE_NORMAL:
|
||||
return timeline_move_object (timeline, element,
|
||||
new_layer_priority <
|
||||
0 ? GES_TIMELINE_ELEMENT_LAYER_PRIORITY (container) :
|
||||
new_layer_priority, layers, edge, position);
|
||||
case GES_EDIT_MODE_ROLL:
|
||||
return timeline_roll_object (timeline, element, layers, edge, position);
|
||||
case GES_EDIT_MODE_SLIDE:
|
||||
GST_ERROR ("Sliding not implemented.");
|
||||
return FALSE;
|
||||
}
|
||||
priority_offset = new_layer_priority - ges_layer_get_priority (layer);
|
||||
|
||||
ret &= timeline_context_to_layer (layer->timeline, priority_offset);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1012,23 +1006,6 @@ ges_clip_set_layer (GESClip * clip, GESLayer * layer)
|
|||
g_object_notify_by_pspec (G_OBJECT (clip), properties[PROP_LAYER]);
|
||||
}
|
||||
|
||||
/**
|
||||
* ges_clip_get_layer_priority:
|
||||
* @clip: The clip to get the layer priority from
|
||||
*
|
||||
* Returns: The priority of the layer @clip is in, -1 if not in a layer.
|
||||
*/
|
||||
guint32
|
||||
ges_clip_get_layer_priority (GESClip * clip)
|
||||
{
|
||||
g_return_val_if_fail (GES_IS_CLIP (clip), -1);
|
||||
|
||||
if (clip->priv->layer == NULL)
|
||||
return -1;
|
||||
|
||||
return ges_layer_get_priority (clip->priv->layer);
|
||||
}
|
||||
|
||||
/**
|
||||
* ges_clip_set_moving_from_layer:
|
||||
* @clip: a #GESClip
|
||||
|
@ -1088,6 +1065,19 @@ ges_clip_move_to_layer (GESClip * clip, GESLayer * layer)
|
|||
g_return_val_if_fail (GES_IS_CLIP (clip), FALSE);
|
||||
g_return_val_if_fail (GES_IS_LAYER (layer), FALSE);
|
||||
|
||||
ELEMENT_SET_FLAG (clip, GES_CLIP_IS_MOVING);
|
||||
if (layer->timeline
|
||||
&& !timeline_tree_can_move_element (timeline_get_tree (layer->timeline),
|
||||
GES_TIMELINE_ELEMENT (clip),
|
||||
ges_layer_get_priority (layer),
|
||||
GES_TIMELINE_ELEMENT_START (clip),
|
||||
GES_TIMELINE_ELEMENT_DURATION (clip), NULL)) {
|
||||
GST_INFO_OBJECT (layer, "Clip %" GES_FORMAT " can't move to layer %d",
|
||||
GES_ARGS (clip), ges_layer_get_priority (layer));
|
||||
ELEMENT_UNSET_FLAG (clip, GES_CLIP_IS_MOVING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
current_layer = clip->priv->layer;
|
||||
|
||||
if (current_layer == NULL) {
|
||||
|
@ -1099,11 +1089,11 @@ ges_clip_move_to_layer (GESClip * clip, GESLayer * layer)
|
|||
GST_DEBUG_OBJECT (clip, "moving to layer %p, priority: %d", layer,
|
||||
ges_layer_get_priority (layer));
|
||||
|
||||
ELEMENT_SET_FLAG (clip, GES_CLIP_IS_MOVING);
|
||||
gst_object_ref (clip);
|
||||
ret = ges_layer_remove_clip (current_layer, clip);
|
||||
|
||||
if (!ret) {
|
||||
ELEMENT_UNSET_FLAG (clip, GES_CLIP_IS_MOVING);
|
||||
gst_object_unref (clip);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1418,16 +1408,9 @@ ges_clip_split (GESClip * clip, guint64 position)
|
|||
position - start + inpoint);
|
||||
}
|
||||
|
||||
ELEMENT_SET_FLAG (clip, GES_CLIP_IS_SPLITTING);
|
||||
ELEMENT_SET_FLAG (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE);
|
||||
_set_duration0 (GES_TIMELINE_ELEMENT (clip), old_duration);
|
||||
ELEMENT_UNSET_FLAG (clip, GES_CLIP_IS_SPLITTING);
|
||||
|
||||
if (GES_TIMELINE_ELEMENT_TIMELINE (clip)) {
|
||||
for (tmp = GES_CONTAINER_CHILDREN (new_object); tmp; tmp = tmp->next) {
|
||||
timeline_create_transitions (GES_TIMELINE_ELEMENT_TIMELINE (tmp->data),
|
||||
tmp->data);
|
||||
}
|
||||
}
|
||||
ELEMENT_UNSET_FLAG (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE);
|
||||
|
||||
return new_object;
|
||||
}
|
||||
|
@ -1466,134 +1449,40 @@ ges_clip_get_supported_formats (GESClip * clip)
|
|||
gboolean
|
||||
_ripple (GESTimelineElement * element, GstClockTime start)
|
||||
{
|
||||
gboolean ret = TRUE;
|
||||
GESTimeline *timeline;
|
||||
GESClip *clip = GES_CLIP (element);
|
||||
|
||||
timeline = ges_layer_get_timeline (clip->priv->layer);
|
||||
|
||||
if (timeline == NULL) {
|
||||
GST_DEBUG ("Not in a timeline yet");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (start > _END (element))
|
||||
start = _END (element);
|
||||
|
||||
if (GES_CONTAINER_CHILDREN (element)) {
|
||||
GESTrackElement *track_element =
|
||||
GES_TRACK_ELEMENT (GES_CONTAINER_CHILDREN (element)->data);
|
||||
|
||||
ret = timeline_ripple_object (timeline, track_element, NULL, GES_EDGE_NONE,
|
||||
start);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ges_container_edit (GES_CONTAINER (element), NULL,
|
||||
ges_timeline_element_get_layer_priority (element),
|
||||
GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, start);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_ripple_end (GESTimelineElement * element, GstClockTime end)
|
||||
{
|
||||
gboolean ret = TRUE;
|
||||
GESTimeline *timeline;
|
||||
GESClip *clip = GES_CLIP (element);
|
||||
|
||||
timeline = ges_layer_get_timeline (clip->priv->layer);
|
||||
|
||||
if (timeline == NULL) {
|
||||
GST_DEBUG ("Not in a timeline yet");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GES_CONTAINER_CHILDREN (element)) {
|
||||
GESTrackElement *track_element =
|
||||
GES_TRACK_ELEMENT (GES_CONTAINER_CHILDREN (element)->data);
|
||||
|
||||
ret = timeline_ripple_object (timeline, track_element, NULL, GES_EDGE_END,
|
||||
end);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ges_container_edit (GES_CONTAINER (element), NULL,
|
||||
ges_timeline_element_get_layer_priority (element),
|
||||
GES_EDIT_MODE_RIPPLE, GES_EDGE_END, end);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_roll_start (GESTimelineElement * element, GstClockTime start)
|
||||
{
|
||||
gboolean ret = TRUE;
|
||||
GESTimeline *timeline;
|
||||
|
||||
GESClip *clip = GES_CLIP (element);
|
||||
|
||||
timeline = ges_layer_get_timeline (clip->priv->layer);
|
||||
|
||||
if (timeline == NULL) {
|
||||
GST_DEBUG ("Not in a timeline yet");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GES_CONTAINER_CHILDREN (element)) {
|
||||
GESTrackElement *track_element =
|
||||
GES_TRACK_ELEMENT (GES_CONTAINER_CHILDREN (element)->data);
|
||||
|
||||
ret = timeline_roll_object (timeline, track_element, NULL, GES_EDGE_START,
|
||||
start);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ges_container_edit (GES_CONTAINER (element), NULL,
|
||||
ges_timeline_element_get_layer_priority (element),
|
||||
GES_EDIT_MODE_ROLL, GES_EDGE_START, start);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_roll_end (GESTimelineElement * element, GstClockTime end)
|
||||
{
|
||||
gboolean ret = TRUE;
|
||||
GESTimeline *timeline;
|
||||
|
||||
GESClip *clip = GES_CLIP (element);
|
||||
|
||||
timeline = ges_layer_get_timeline (clip->priv->layer);
|
||||
if (timeline == NULL) {
|
||||
GST_DEBUG ("Not in a timeline yet");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (GES_CONTAINER_CHILDREN (element)) {
|
||||
GESTrackElement *track_element =
|
||||
GES_TRACK_ELEMENT (GES_CONTAINER_CHILDREN (element)->data);
|
||||
|
||||
ret = timeline_roll_object (timeline, track_element,
|
||||
NULL, GES_EDGE_END, end);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ges_container_edit (GES_CONTAINER (element), NULL,
|
||||
ges_timeline_element_get_layer_priority (element),
|
||||
GES_EDIT_MODE_ROLL, GES_EDGE_END, end);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_trim (GESTimelineElement * element, GstClockTime start)
|
||||
{
|
||||
gboolean ret = TRUE;
|
||||
GESTimeline *timeline;
|
||||
|
||||
GESClip *clip = GES_CLIP (element);
|
||||
|
||||
timeline = ges_layer_get_timeline (clip->priv->layer);
|
||||
|
||||
if (timeline == NULL) {
|
||||
GST_DEBUG ("Not in a timeline yet");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GES_CONTAINER_CHILDREN (element)) {
|
||||
GESTrackElement *track_element =
|
||||
GES_TRACK_ELEMENT (GES_CONTAINER_CHILDREN (element)->data);
|
||||
|
||||
GST_DEBUG_OBJECT (element, "Trimming child: %" GST_PTR_FORMAT,
|
||||
track_element);
|
||||
ret = timeline_trim_object (timeline, track_element, NULL, GES_EDGE_START,
|
||||
start);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ges_container_edit (GES_CONTAINER (element), NULL, -1,
|
||||
GES_EDIT_MODE_TRIM, GES_EDGE_START, start);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -163,8 +163,6 @@ GES_API
|
|||
GESLayer* ges_clip_get_layer (GESClip *clip);
|
||||
GES_API
|
||||
gboolean ges_clip_move_to_layer (GESClip *clip, GESLayer *layer);
|
||||
GES_API
|
||||
guint32 ges_clip_get_layer_priority (GESClip * clip);
|
||||
|
||||
/****************************************************
|
||||
* Effects *
|
||||
|
|
|
@ -524,10 +524,14 @@ _child_start_changed_cb (GESTimelineElement * child,
|
|||
|
||||
GESContainerPrivate *priv = container->priv;
|
||||
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
|
||||
GESChildrenControlMode pmode = container->children_control_mode;
|
||||
|
||||
map = g_hash_table_lookup (priv->mappings, child);
|
||||
g_assert (map);
|
||||
|
||||
if (ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE))
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE_ALL_VALUES;
|
||||
|
||||
switch (container->children_control_mode) {
|
||||
case GES_CHILDREN_IGNORE_NOTIFIES:
|
||||
return;
|
||||
|
@ -540,8 +544,8 @@ _child_start_changed_cb (GESTimelineElement * child,
|
|||
_DURATION (container) = _END (container) - start;
|
||||
_START (container) = start;
|
||||
|
||||
GST_DEBUG_OBJECT (container, "Child move made us "
|
||||
"move to %" GST_TIME_FORMAT, GST_TIME_ARGS (_START (container)));
|
||||
GST_DEBUG_OBJECT (container, "Child move made us move %" GES_FORMAT,
|
||||
GES_ARGS (container));
|
||||
|
||||
g_object_notify (G_OBJECT (container), "start");
|
||||
}
|
||||
|
@ -560,6 +564,9 @@ _child_start_changed_cb (GESTimelineElement * child,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE))
|
||||
container->children_control_mode = pmode;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -577,7 +584,8 @@ _child_inpoint_changed_cb (GESTimelineElement * child,
|
|||
map = g_hash_table_lookup (priv->mappings, child);
|
||||
g_assert (map);
|
||||
|
||||
if (container->children_control_mode == GES_CHILDREN_UPDATE_OFFSETS) {
|
||||
if (container->children_control_mode == GES_CHILDREN_UPDATE_OFFSETS
|
||||
|| ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
|
||||
map->inpoint_offset = _START (container) - _START (child);
|
||||
|
||||
return;
|
||||
|
@ -599,10 +607,14 @@ _child_duration_changed_cb (GESTimelineElement * child,
|
|||
GstClockTime end = 0;
|
||||
GESContainerPrivate *priv = container->priv;
|
||||
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
|
||||
GESChildrenControlMode pmode = container->children_control_mode;
|
||||
|
||||
if (container->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
return;
|
||||
|
||||
if (ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE))
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE_ALL_VALUES;
|
||||
|
||||
map = g_hash_table_lookup (priv->mappings, child);
|
||||
g_assert (map);
|
||||
|
||||
|
@ -632,6 +644,9 @@ _child_duration_changed_cb (GESTimelineElement * child,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE))
|
||||
container->children_control_mode = pmode;
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
|
|
104
ges/ges-group.c
104
ges/ges-group.c
|
@ -255,11 +255,7 @@ _child_group_priority_changed (GESTimelineElement * child,
|
|||
static gboolean
|
||||
_trim (GESTimelineElement * group, GstClockTime start)
|
||||
{
|
||||
GList *tmp;
|
||||
GstClockTime last_child_end = 0, oldstart = _START (group);
|
||||
GESContainer *container = GES_CONTAINER (group);
|
||||
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (group);
|
||||
gboolean ret = TRUE, expending = (start < _START (group));
|
||||
|
||||
if (timeline == NULL) {
|
||||
GST_DEBUG ("Not in a timeline yet");
|
||||
|
@ -267,40 +263,9 @@ _trim (GESTimelineElement * group, GstClockTime start)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (group); tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *child = tmp->data;
|
||||
|
||||
if (expending) {
|
||||
/* If the start is bigger, we do not touch it (in case we are expending) */
|
||||
if (_START (child) > oldstart) {
|
||||
GST_DEBUG_OBJECT (child, "Skipping as not at begining of the group");
|
||||
continue;
|
||||
}
|
||||
|
||||
ret &= ges_timeline_element_trim (child, start);
|
||||
} else {
|
||||
if (start > _END (child))
|
||||
ret &= ges_timeline_element_trim (child, _END (child));
|
||||
else if (_START (child) < start && _DURATION (child))
|
||||
ret &= ges_timeline_element_trim (child, start);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (tmp = GES_CONTAINER_CHILDREN (group); tmp; tmp = tmp->next) {
|
||||
if (_DURATION (tmp->data))
|
||||
last_child_end =
|
||||
MAX (GES_TIMELINE_ELEMENT_END (tmp->data), last_child_end);
|
||||
}
|
||||
|
||||
GES_GROUP (group)->priv->setting_value = TRUE;
|
||||
_set_start0 (group, start);
|
||||
_set_duration0 (group, last_child_end - start);
|
||||
GES_GROUP (group)->priv->setting_value = FALSE;
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
return ret;
|
||||
return timeline_tree_trim (timeline_get_tree (timeline), group,
|
||||
0, GST_CLOCK_DIFF (start, _START (group)), GES_EDGE_START,
|
||||
ges_timeline_get_snapping_distance (timeline));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -309,38 +274,44 @@ _set_priority (GESTimelineElement * element, guint32 priority)
|
|||
GList *tmp, *layers;
|
||||
gint diff = priority - _PRIORITY (element);
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (element);
|
||||
|
||||
if (GES_GROUP (element)->priv->setting_value == TRUE)
|
||||
return TRUE;
|
||||
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
|
||||
layers = GES_TIMELINE_ELEMENT_TIMELINE (element) ?
|
||||
GES_TIMELINE_ELEMENT_TIMELINE (element)->layers : NULL;
|
||||
|
||||
if (layers == NULL) {
|
||||
GST_WARNING_OBJECT (element, "Not any layer in the timeline, not doing"
|
||||
"anything, timeline: %" GST_PTR_FORMAT,
|
||||
GES_TIMELINE_ELEMENT_TIMELINE (element));
|
||||
|
||||
return FALSE;
|
||||
} else if (priority + GES_CONTAINER_HEIGHT (container) - 1 >
|
||||
g_list_length (layers)) {
|
||||
GST_WARNING_OBJECT (container, "Trying to move to a layer outside of"
|
||||
"the timeline layers");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *child = tmp->data;
|
||||
|
||||
if (child != container->initiated_move) {
|
||||
if (child != container->initiated_move
|
||||
|| ELEMENT_FLAG_IS_SET (container, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
|
||||
if (GES_IS_CLIP (child)) {
|
||||
guint32 layer_prio = GES_TIMELINE_ELEMENT_LAYER_PRIORITY (child) + diff;
|
||||
GESLayer *layer =
|
||||
g_list_nth_data (GES_TIMELINE_GET_LAYERS (timeline), layer_prio);
|
||||
|
||||
GST_DEBUG_OBJECT (child, "moving from layer: %i to %i",
|
||||
GES_TIMELINE_ELEMENT_LAYER_PRIORITY (child), layer_prio);
|
||||
ges_clip_move_to_layer (GES_CLIP (child),
|
||||
g_list_nth_data (layers, layer_prio));
|
||||
if (layer == NULL) {
|
||||
do {
|
||||
layer = ges_timeline_append_layer (timeline);
|
||||
} while (ges_layer_get_priority (layer) < layer_prio);
|
||||
}
|
||||
|
||||
GST_DEBUG ("%" GES_FORMAT "moving from layer: %i to %i",
|
||||
GES_ARGS (child), GES_TIMELINE_ELEMENT_LAYER_PRIORITY (child),
|
||||
layer_prio);
|
||||
ges_clip_move_to_layer (GES_CLIP (child), g_list_nth_data (layers,
|
||||
layer_prio));
|
||||
} else if (GES_IS_GROUP (child)) {
|
||||
GST_DEBUG_OBJECT (child, "moving from %i to %i",
|
||||
_PRIORITY (child), diff + _PRIORITY (child));
|
||||
|
@ -358,24 +329,31 @@ _set_start (GESTimelineElement * element, GstClockTime start)
|
|||
{
|
||||
GList *tmp;
|
||||
gint64 diff = start - _START (element);
|
||||
GESTimeline *timeline;
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
GESTimelineElement *toplevel =
|
||||
ges_timeline_element_get_toplevel_parent (element);;
|
||||
|
||||
gst_object_unref (toplevel);
|
||||
if (GES_GROUP (element)->priv->setting_value == TRUE)
|
||||
/* Let GESContainer update itself */
|
||||
return GES_TIMELINE_ELEMENT_CLASS (parent_class)->set_start (element,
|
||||
start);
|
||||
|
||||
if (ELEMENT_FLAG_IS_SET (element, GES_TIMELINE_ELEMENT_SET_SIMPLE) ||
|
||||
ELEMENT_FLAG_IS_SET (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next)
|
||||
_set_start0 (tmp->data, _START (tmp->data) + diff);
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
|
||||
if (child != container->initiated_move &&
|
||||
(_END (child) > _START (element) || _END (child) > start)) {
|
||||
_set_start0 (child, _START (child) + diff);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
timeline = GES_TIMELINE_ELEMENT_TIMELINE (element);
|
||||
if (timeline)
|
||||
return ges_timeline_move_object_simple (timeline, element, NULL,
|
||||
GES_EDGE_NONE, start);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -399,6 +377,12 @@ _set_duration (GESTimelineElement * element, GstClockTime duration)
|
|||
return GES_TIMELINE_ELEMENT_CLASS (parent_class)->set_duration (element,
|
||||
duration);
|
||||
|
||||
if (element->timeline
|
||||
&& !timeline_tree_can_move_element (timeline_get_tree (element->timeline),
|
||||
element, _PRIORITY (element), element->start, duration, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (container->initiated_move == NULL) {
|
||||
gboolean expending = (_DURATION (element) < duration);
|
||||
|
||||
|
@ -471,6 +455,7 @@ _child_added (GESContainer * group, GESTimelineElement * child)
|
|||
}
|
||||
|
||||
priv->setting_value = TRUE;
|
||||
ELEMENT_SET_FLAG (group, GES_TIMELINE_ELEMENT_SET_SIMPLE);
|
||||
if (first_child_start != GES_TIMELINE_ELEMENT_START (group)) {
|
||||
group->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
_set_start0 (GES_TIMELINE_ELEMENT (group), first_child_start);
|
||||
|
@ -480,6 +465,7 @@ _child_added (GESContainer * group, GESTimelineElement * child)
|
|||
_set_duration0 (GES_TIMELINE_ELEMENT (group),
|
||||
last_child_end - first_child_start);
|
||||
}
|
||||
ELEMENT_UNSET_FLAG (group, GES_TIMELINE_ELEMENT_SET_SIMPLE);
|
||||
priv->setting_value = FALSE;
|
||||
|
||||
group->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
@ -561,12 +547,14 @@ _child_removed (GESContainer * group, GESTimelineElement * child)
|
|||
}
|
||||
|
||||
priv->setting_value = TRUE;
|
||||
ELEMENT_SET_FLAG (group, GES_TIMELINE_ELEMENT_SET_SIMPLE);
|
||||
first_child_start = GES_TIMELINE_ELEMENT_START (children->data);
|
||||
if (first_child_start > GES_TIMELINE_ELEMENT_START (group)) {
|
||||
group->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
_set_start0 (GES_TIMELINE_ELEMENT (group), first_child_start);
|
||||
group->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
}
|
||||
ELEMENT_UNSET_FLAG (group, GES_TIMELINE_ELEMENT_SET_SIMPLE);
|
||||
priv->setting_value = FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "ges-asset.h"
|
||||
#include "ges-base-xml-formatter.h"
|
||||
#include "ges-timeline-tree.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -50,7 +51,9 @@ GST_DEBUG_CATEGORY_EXTERN (_ges_debug);
|
|||
#define _DURATION(obj) GES_TIMELINE_ELEMENT_DURATION (obj)
|
||||
#define _MAXDURATION(obj) GES_TIMELINE_ELEMENT_MAX_DURATION (obj)
|
||||
#define _PRIORITY(obj) GES_TIMELINE_ELEMENT_PRIORITY (obj)
|
||||
#ifndef _END
|
||||
#define _END(obj) (_START (obj) + _DURATION (obj))
|
||||
#endif
|
||||
#define _set_start0 ges_timeline_element_set_start
|
||||
#define _set_inpoint0 ges_timeline_element_set_inpoint
|
||||
#define _set_duration0 ges_timeline_element_set_duration
|
||||
|
@ -60,44 +63,50 @@ GST_DEBUG_CATEGORY_EXTERN (_ges_debug);
|
|||
"s<%p>" \
|
||||
" [ %" GST_TIME_FORMAT \
|
||||
" (%" GST_TIME_FORMAT \
|
||||
") - %" GST_TIME_FORMAT "]"
|
||||
") - %" GST_TIME_FORMAT "(%" GST_TIME_FORMAT") layer: %" G_GINT32_FORMAT "] "
|
||||
|
||||
#define GES_TIMELINE_ELEMENT_ARGS(element) \
|
||||
GES_TIMELINE_ELEMENT_NAME(element), element, \
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_START(element)), \
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_INPOINT(element)), \
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_DURATION(element))
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_DURATION(element)), \
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_MAX_DURATION(element)), \
|
||||
GES_TIMELINE_ELEMENT_LAYER_PRIORITY(element)
|
||||
|
||||
#define GES_FORMAT GES_TIMELINE_ELEMENT_FORMAT
|
||||
#define GES_ARGS GES_TIMELINE_ELEMENT_ARGS
|
||||
|
||||
G_GNUC_INTERNAL gboolean
|
||||
timeline_ripple_object (GESTimeline *timeline, GESTrackElement *obj,
|
||||
GList * layers, GESEdge edge,
|
||||
guint64 position);
|
||||
timeline_ripple_object (GESTimeline *timeline, GESTimelineElement *obj,
|
||||
gint new_layer_priority,
|
||||
GList * layers, GESEdge edge,
|
||||
guint64 position);
|
||||
|
||||
G_GNUC_INTERNAL gboolean
|
||||
timeline_slide_object (GESTimeline *timeline, GESTrackElement *obj,
|
||||
GList * layers, GESEdge edge, guint64 position);
|
||||
|
||||
G_GNUC_INTERNAL gboolean
|
||||
timeline_roll_object (GESTimeline *timeline, GESTrackElement *obj,
|
||||
GList * layers, GESEdge edge, guint64 position);
|
||||
timeline_roll_object (GESTimeline *timeline, GESTimelineElement *obj,
|
||||
GList * layers, GESEdge edge, guint64 position);
|
||||
|
||||
G_GNUC_INTERNAL gboolean
|
||||
timeline_trim_object (GESTimeline *timeline, GESTrackElement * object,
|
||||
GList * layers, GESEdge edge, guint64 position);
|
||||
timeline_trim_object (GESTimeline *timeline, GESTimelineElement * object,
|
||||
guint32 new_layer_priority, GList * layers, GESEdge edge,
|
||||
guint64 position);
|
||||
G_GNUC_INTERNAL gboolean
|
||||
ges_timeline_trim_object_simple (GESTimeline * timeline, GESTimelineElement * obj,
|
||||
GList * layers, GESEdge edge, guint64 position, gboolean snapping);
|
||||
guint32 new_layer_priority, GList * layers, GESEdge edge,
|
||||
guint64 position, gboolean snapping);
|
||||
|
||||
G_GNUC_INTERNAL gboolean
|
||||
ges_timeline_move_object_simple (GESTimeline * timeline, GESTimelineElement * object,
|
||||
GList * layers, GESEdge edge, guint64 position);
|
||||
|
||||
G_GNUC_INTERNAL gboolean
|
||||
timeline_move_object (GESTimeline *timeline, GESTrackElement * object,
|
||||
GList * layers, GESEdge edge, guint64 position);
|
||||
|
||||
G_GNUC_INTERNAL gboolean
|
||||
timeline_context_to_layer (GESTimeline *timeline, gint offset);
|
||||
timeline_move_object (GESTimeline *timeline, GESTimelineElement * object,
|
||||
guint32 new_layer_priority, GList * layers, GESEdge edge,
|
||||
guint64 position);
|
||||
|
||||
G_GNUC_INTERNAL void
|
||||
timeline_add_group (GESTimeline *timeline,
|
||||
|
@ -121,6 +130,14 @@ gboolean
|
|||
timeline_remove_element (GESTimeline *timeline,
|
||||
GESTimelineElement *element);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GNode *
|
||||
timeline_get_tree (GESTimeline *timeline);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
timeline_update_transition (GESTimeline *timeline);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
timeline_fill_gaps (GESTimeline *timeline);
|
||||
|
@ -396,9 +413,8 @@ G_GNUC_INTERNAL GESVideoTestSource * ges_video_test_source_new (void);
|
|||
****************************************************/
|
||||
typedef enum
|
||||
{
|
||||
GES_CLIP_IS_SPLITTING = (1 << 0),
|
||||
GES_CLIP_IS_MOVING = (1 << 1),
|
||||
GES_TIMELINE_ELEMENT_SET_SIMPLE = (1 << 2),
|
||||
GES_CLIP_IS_MOVING = (1 << 0),
|
||||
GES_TIMELINE_ELEMENT_SET_SIMPLE = (1 << 1),
|
||||
} GESTimelineElementFlags;
|
||||
|
||||
G_GNUC_INTERNAL gdouble ges_timeline_element_get_media_duration_factor(GESTimelineElement *self);
|
||||
|
@ -406,9 +422,6 @@ G_GNUC_INTERNAL GESTimelineElement * ges_timeline_element_get_copied_from (GESTi
|
|||
G_GNUC_INTERNAL GESTimelineElementFlags ges_timeline_element_flags (GESTimelineElement *self);
|
||||
G_GNUC_INTERNAL void ges_timeline_element_set_flags (GESTimelineElement *self, GESTimelineElementFlags flags);
|
||||
|
||||
/* FIXME: Provide a clean way to get layer prio generically */
|
||||
G_GNUC_INTERNAL gint32 _layer_priority (GESTimelineElement * element);
|
||||
|
||||
#define ELEMENT_FLAGS(obj) (ges_timeline_element_flags (GES_TIMELINE_ELEMENT(obj)))
|
||||
#define ELEMENT_SET_FLAG(obj,flag) (ges_timeline_element_set_flags(GES_TIMELINE_ELEMENT(obj), (ELEMENT_FLAGS(obj) | (flag))))
|
||||
#define ELEMENT_UNSET_FLAG(obj,flag) (ges_timeline_element_set_flags(GES_TIMELINE_ELEMENT(obj), (ELEMENT_FLAGS(obj) & ~(flag))))
|
||||
|
|
|
@ -666,6 +666,17 @@ ges_layer_add_clip (GESLayer * layer, GESClip * clip)
|
|||
/* emit 'clip-added' */
|
||||
g_signal_emit (layer, ges_layer_signals[OBJECT_ADDED], 0, clip);
|
||||
|
||||
if (!ELEMENT_FLAG_IS_SET (clip, GES_CLIP_IS_MOVING) && layer->timeline
|
||||
&& !timeline_tree_can_move_element (timeline_get_tree (layer->timeline),
|
||||
GES_TIMELINE_ELEMENT (clip),
|
||||
GES_TIMELINE_ELEMENT_LAYER_PRIORITY (clip),
|
||||
GES_TIMELINE_ELEMENT_START (clip),
|
||||
GES_TIMELINE_ELEMENT_DURATION (clip), NULL)) {
|
||||
GST_INFO_OBJECT (layer, "Clip %" GES_FORMAT, GES_ARGS (clip));
|
||||
ges_layer_remove_clip_internal (layer, clip, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,43 +49,41 @@ G_DEFINE_TYPE_WITH_PRIVATE (GESSourceClip, ges_source_clip, GES_TYPE_CLIP);
|
|||
static gboolean
|
||||
_set_start (GESTimelineElement * element, GstClockTime start)
|
||||
{
|
||||
GList *tmp;
|
||||
GESTimeline *timeline;
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
GstClockTime rollback_start = GES_TIMELINE_ELEMENT_START (element);
|
||||
GESTimelineElement *toplevel =
|
||||
ges_timeline_element_get_toplevel_parent (element);
|
||||
|
||||
GST_DEBUG_OBJECT (element, "Setting children start, (initiated_move: %"
|
||||
GST_PTR_FORMAT ")", container->initiated_move);
|
||||
|
||||
element->start = start;
|
||||
g_object_notify (G_OBJECT (element), "start");
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
|
||||
if (child != container->initiated_move) {
|
||||
/* Make the snapping happen if in a timeline */
|
||||
timeline = GES_TIMELINE_ELEMENT_TIMELINE (child);
|
||||
if (timeline && !container->initiated_move) {
|
||||
if (!ges_timeline_move_object_simple (timeline, child, NULL,
|
||||
GES_EDGE_NONE, start)) {
|
||||
for (tmp = container->children; tmp; tmp = g_list_next (tmp))
|
||||
ges_timeline_element_set_start (tmp->data, rollback_start);
|
||||
|
||||
element->start = rollback_start;
|
||||
g_object_notify (G_OBJECT (element), "start");
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
_set_start0 (GES_TIMELINE_ELEMENT (child), start);
|
||||
}
|
||||
gst_object_unref (toplevel);
|
||||
if (element->timeline
|
||||
&& !ELEMENT_FLAG_IS_SET (element, GES_TIMELINE_ELEMENT_SET_SIMPLE)
|
||||
&& !ELEMENT_FLAG_IS_SET (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
|
||||
ges_timeline_move_object_simple (element->timeline, element, NULL,
|
||||
GES_EDGE_NONE, start);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
return
|
||||
GES_TIMELINE_ELEMENT_CLASS (ges_source_clip_parent_class)->set_start
|
||||
(element, start);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
static gboolean
|
||||
_set_duration (GESTimelineElement * element, GstClockTime duration)
|
||||
{
|
||||
GESTimelineElement *toplevel =
|
||||
ges_timeline_element_get_toplevel_parent (element);
|
||||
|
||||
gst_object_unref (toplevel);
|
||||
if (element->timeline
|
||||
&& !ELEMENT_FLAG_IS_SET (element, GES_TIMELINE_ELEMENT_SET_SIMPLE)
|
||||
&& !ELEMENT_FLAG_IS_SET (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
|
||||
return !timeline_trim_object (element->timeline, element,
|
||||
GES_TIMELINE_ELEMENT_LAYER_PRIORITY (element), NULL, GES_EDGE_END,
|
||||
element->start + duration);
|
||||
}
|
||||
|
||||
return
|
||||
GES_TIMELINE_ELEMENT_CLASS (ges_source_clip_parent_class)->set_duration
|
||||
(element, duration);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -125,6 +123,7 @@ ges_source_clip_class_init (GESSourceClipClass * klass)
|
|||
object_class->finalize = ges_source_clip_finalize;
|
||||
|
||||
element_class->set_start = _set_start;
|
||||
element_class->set_duration = _set_duration;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -694,6 +694,9 @@ ges_timeline_element_set_start (GESTimelineElement * self, GstClockTime start)
|
|||
|
||||
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);
|
||||
|
||||
if (self->start == start)
|
||||
return TRUE;
|
||||
|
||||
klass = GES_TIMELINE_ELEMENT_GET_CLASS (self);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "current start: %" GST_TIME_FORMAT
|
||||
|
|
1256
ges/ges-timeline-tree.c
Normal file
1256
ges/ges-timeline-tree.c
Normal file
File diff suppressed because it is too large
Load diff
79
ges/ges-timeline-tree.h
Normal file
79
ges/ges-timeline-tree.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
#ifndef __GES_TIMELINE_TREE__
|
||||
#define __GES_TIMELINE_TREE__
|
||||
|
||||
#include <ges/ges.h>
|
||||
#include "ges-auto-transition.h"
|
||||
|
||||
void timeline_tree_track_element (GNode *root,
|
||||
GESTimelineElement *element);
|
||||
|
||||
void timeline_tree_stop_tracking_element (GNode *root,
|
||||
GESTimelineElement *element);
|
||||
|
||||
gboolean timeline_tree_can_move_element (GNode *root,
|
||||
GESTimelineElement *element,
|
||||
guint32 priority,
|
||||
GstClockTime start,
|
||||
GstClockTime duration,
|
||||
GList *moving_track_elements);
|
||||
|
||||
gboolean timeline_tree_ripple (GNode *root,
|
||||
gint64 layer_priority_offset,
|
||||
GstClockTimeDiff offset,
|
||||
GESTimelineElement *rippled_element,
|
||||
GESEdge moving_edge,
|
||||
GstClockTime snapping_distance);
|
||||
|
||||
void ges_timeline_emit_snapping (GESTimeline * timeline,
|
||||
GESTimelineElement * elem1,
|
||||
GESTimelineElement * elem2,
|
||||
GstClockTime snap_time);
|
||||
|
||||
gboolean timeline_tree_trim (GNode *root,
|
||||
GESTimelineElement *element,
|
||||
gint64 layer_priority_offset,
|
||||
GstClockTimeDiff offset,
|
||||
GESEdge edge,
|
||||
GstClockTime snapping_distance);
|
||||
|
||||
|
||||
gboolean timeline_tree_move (GNode *root,
|
||||
GESTimelineElement *element,
|
||||
gint64 layer_priority_offset,
|
||||
GstClockTimeDiff offset,
|
||||
GESEdge edge,
|
||||
GstClockTime snapping_distance);
|
||||
|
||||
gboolean timeline_tree_roll (GNode * root,
|
||||
GESTimelineElement * element,
|
||||
GstClockTimeDiff offset,
|
||||
GESEdge edge,
|
||||
GstClockTime snapping_distance);
|
||||
|
||||
typedef GESAutoTransition *
|
||||
(*GESTreeGetAutoTransitionFunc) (GESTimeline * timeline,
|
||||
GESTrackElement * previous,
|
||||
GESTrackElement * next,
|
||||
GstClockTime transition_duration);
|
||||
|
||||
void timeline_tree_create_transitions (GNode *root,
|
||||
GESTreeGetAutoTransitionFunc get_auto_transition);
|
||||
|
||||
GstClockTime timeline_tree_get_duration (GNode *root);
|
||||
|
||||
void timeline_tree_debug (GNode * root);
|
||||
|
||||
GESAutoTransition *
|
||||
ges_timeline_create_transition (GESTimeline * timeline, GESTrackElement * previous,
|
||||
GESTrackElement * next, GESClip * transition,
|
||||
GESLayer * layer, guint64 start, guint64 duration);
|
||||
GESAutoTransition *
|
||||
ges_timeline_find_auto_transition (GESTimeline * timeline, GESTrackElement * prev,
|
||||
GESTrackElement * next, GstClockTime transition_duration);
|
||||
|
||||
void
|
||||
timeline_update_duration (GESTimeline * timeline);
|
||||
|
||||
void timeline_tree_init_debug (void);
|
||||
|
||||
#endif // __GES_TIMELINE_TREE__
|
1718
ges/ges-timeline.c
1718
ges/ges-timeline.c
File diff suppressed because it is too large
Load diff
|
@ -1364,16 +1364,21 @@ ges_track_element_edit (GESTrackElement * object,
|
|||
|
||||
switch (mode) {
|
||||
case GES_EDIT_MODE_NORMAL:
|
||||
return timeline_move_object (timeline, object, layers, edge, position);
|
||||
return timeline_move_object (timeline, GES_TIMELINE_ELEMENT (object), -1,
|
||||
layers, edge, position);
|
||||
break;
|
||||
case GES_EDIT_MODE_TRIM:
|
||||
return timeline_trim_object (timeline, object, layers, edge, position);
|
||||
return timeline_trim_object (timeline, GES_TIMELINE_ELEMENT (object), -1,
|
||||
layers, edge, position);
|
||||
break;
|
||||
case GES_EDIT_MODE_RIPPLE:
|
||||
return timeline_ripple_object (timeline, object, layers, edge, position);
|
||||
return timeline_ripple_object (timeline, GES_TIMELINE_ELEMENT (object),
|
||||
GES_TIMELINE_ELEMENT_PRIORITY (object) / LAYER_HEIGHT,
|
||||
layers, edge, position);
|
||||
break;
|
||||
case GES_EDIT_MODE_ROLL:
|
||||
return timeline_roll_object (timeline, object, layers, edge, position);
|
||||
return timeline_roll_object (timeline, GES_TIMELINE_ELEMENT (object),
|
||||
layers, edge, position);
|
||||
break;
|
||||
case GES_EDIT_MODE_SLIDE:
|
||||
return timeline_slide_object (timeline, object, layers, edge, position);
|
||||
|
|
|
@ -276,6 +276,24 @@ extractable_set_asset (GESExtractable * self, GESAsset * asset)
|
|||
g_return_val_if_fail (GES_IS_URI_CLIP_ASSET (asset), FALSE);
|
||||
|
||||
uri_clip_asset = GES_URI_CLIP_ASSET (asset);
|
||||
if (GST_CLOCK_TIME_IS_VALID (GES_TIMELINE_ELEMENT_DURATION (self)) &&
|
||||
ges_uri_clip_asset_get_duration (uri_clip_asset) <
|
||||
GES_TIMELINE_ELEMENT_INPOINT (self) +
|
||||
GES_TIMELINE_ELEMENT_DURATION (self)) {
|
||||
GST_INFO_OBJECT (self,
|
||||
"Can not set asset to %p as its duration is %" GST_TIME_FORMAT
|
||||
" < to inpoint %" GST_TIME_FORMAT " + %" GST_TIME_FORMAT " = %"
|
||||
GST_TIME_FORMAT, asset,
|
||||
GST_TIME_ARGS (ges_uri_clip_asset_get_duration (uri_clip_asset)),
|
||||
GST_TIME_ARGS (GES_TIMELINE_ELEMENT_INPOINT (self)),
|
||||
GST_TIME_ARGS (GES_TIMELINE_ELEMENT_DURATION (self)),
|
||||
GST_TIME_ARGS (GES_TIMELINE_ELEMENT_INPOINT (self) +
|
||||
GES_TIMELINE_ELEMENT_DURATION (self)));
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (GES_TIMELINE_ELEMENT_DURATION (clip)) == FALSE)
|
||||
_set_duration0 (GES_TIMELINE_ELEMENT (uriclip),
|
||||
ges_uri_clip_asset_get_duration (uri_clip_asset));
|
||||
|
|
|
@ -51,6 +51,7 @@ ges_sources = [
|
|||
'ges-command-line-formatter.c',
|
||||
'ges-auto-transition.c',
|
||||
'ges-timeline-element.c',
|
||||
'ges-timeline-tree.c',
|
||||
'ges-container.c',
|
||||
'ges-effect-asset.c',
|
||||
'ges-smart-adder.c',
|
||||
|
|
|
@ -227,6 +227,9 @@ GST_START_TEST (test_uri_clip_change_asset)
|
|||
asset1 = GES_ASSET (ges_uri_clip_asset_request_sync (uri1, NULL));
|
||||
fail_unless_equals_int (g_list_length (GES_CONTAINER_CHILDREN (extractable)),
|
||||
2);
|
||||
fail_if (ges_extractable_set_asset (extractable, asset1));
|
||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (extractable),
|
||||
ges_uri_clip_asset_get_duration (GES_URI_CLIP_ASSET (asset1)));
|
||||
fail_unless (ges_extractable_set_asset (extractable, asset1));
|
||||
fail_unless_equals_int (g_list_length (GES_CONTAINER_CHILDREN (extractable)),
|
||||
1);
|
||||
|
|
|
@ -94,13 +94,13 @@ GST_START_TEST (test_ges_scenario)
|
|||
/* There are 3 references:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3);
|
||||
/* There are 3 references:
|
||||
* 1 by the clip
|
||||
* 2 by the timeline
|
||||
* 3 by the timeline
|
||||
* 1 by the track */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3);
|
||||
|
||||
GST_DEBUG ("Remove the Clip from the layer");
|
||||
|
||||
|
@ -225,13 +225,13 @@ GST_START_TEST (test_ges_timeline_add_layer)
|
|||
/* There are 3 references:
|
||||
* 1 by the clip
|
||||
* 1 by the trackelement
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3);
|
||||
/* There are 3 references:
|
||||
* 1 by the clip
|
||||
* 1 by the timeline
|
||||
* 2 by the trackelement */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4);
|
||||
* 1 by the trackelement */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3);
|
||||
|
||||
trackelements = GES_CONTAINER_CHILDREN (s2);
|
||||
trackelement = GES_TRACK_ELEMENT (trackelements->data);
|
||||
|
@ -240,8 +240,8 @@ GST_START_TEST (test_ges_timeline_add_layer)
|
|||
/* There are 3 references:
|
||||
* 1 by the clip
|
||||
* 1 by the timeline
|
||||
* 2 by the trackelement */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (trackelement), "trackelement", 4);
|
||||
* 1 by the trackelement */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (trackelement), "trackelement", 3);
|
||||
|
||||
trackelements = GES_CONTAINER_CHILDREN (s3);
|
||||
trackelement = GES_TRACK_ELEMENT (trackelements->data);
|
||||
|
@ -251,7 +251,7 @@ GST_START_TEST (test_ges_timeline_add_layer)
|
|||
* 1 by the clip
|
||||
* 1 by the timeline
|
||||
* 2 by the trackelement */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3);
|
||||
|
||||
/* theoretically this is all we need to do to ensure cleanup */
|
||||
gst_object_unref (timeline);
|
||||
|
@ -334,8 +334,8 @@ GST_START_TEST (test_ges_timeline_add_layer_first)
|
|||
/* Each object has 3 references:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3);
|
||||
}
|
||||
|
||||
trackelements = GES_CONTAINER_CHILDREN (s2);
|
||||
|
@ -344,8 +344,8 @@ GST_START_TEST (test_ges_timeline_add_layer_first)
|
|||
/* Each object has 3 references:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3);
|
||||
}
|
||||
|
||||
trackelements = GES_CONTAINER_CHILDREN (s3);
|
||||
|
@ -354,8 +354,8 @@ GST_START_TEST (test_ges_timeline_add_layer_first)
|
|||
/* Each object has 3 references:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3);
|
||||
}
|
||||
|
||||
/* theoretically this is all we need to do to ensure cleanup */
|
||||
|
@ -444,14 +444,14 @@ GST_START_TEST (test_ges_timeline_remove_track)
|
|||
/* There are 3 references held:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3);
|
||||
}
|
||||
/* There are 3 references held:
|
||||
* 1 by the container
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 3);
|
||||
|
||||
trackelements = GES_CONTAINER_CHILDREN (s2);
|
||||
fail_unless (trackelements != NULL);
|
||||
|
@ -460,14 +460,14 @@ GST_START_TEST (test_ges_timeline_remove_track)
|
|||
/* There are 3 references held:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3);
|
||||
}
|
||||
/* There are 3 references held:
|
||||
* 1 by the container
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (t2, "t2", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (t2, "t2", 3);
|
||||
|
||||
trackelements = GES_CONTAINER_CHILDREN (s3);
|
||||
fail_unless (trackelements != NULL);
|
||||
|
@ -476,21 +476,21 @@ GST_START_TEST (test_ges_timeline_remove_track)
|
|||
/* There are 3 references held:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3);
|
||||
}
|
||||
/* There are 3 references held:
|
||||
* 1 by the container
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (t3, "t3", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (t3, "t3", 3);
|
||||
|
||||
/* remove the track and check that the track elements have been released */
|
||||
fail_unless (ges_timeline_remove_track (timeline, track));
|
||||
|
||||
ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 2);
|
||||
ASSERT_OBJECT_REFCOUNT (t2, "trackelement", 2);
|
||||
ASSERT_OBJECT_REFCOUNT (t3, "trackelement", 2);
|
||||
ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 1);
|
||||
ASSERT_OBJECT_REFCOUNT (t2, "trackelement", 1);
|
||||
ASSERT_OBJECT_REFCOUNT (t3, "trackelement", 1);
|
||||
ASSERT_OBJECT_REFCOUNT (layer, "1 for the timeline", 1);
|
||||
ASSERT_OBJECT_REFCOUNT (timeline, "1 for the us", 1);
|
||||
tmp = ges_layer_get_clips (layer);
|
||||
|
@ -614,17 +614,17 @@ GST_START_TEST (test_ges_timeline_multiple_tracks)
|
|||
/* There are 3 references held:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3);
|
||||
fail_unless (ges_track_element_get_track (tmp->data) == track1);
|
||||
}
|
||||
gst_object_ref (t1);
|
||||
/* There are 3 references held:
|
||||
* 1 by the container
|
||||
* 1 by the track
|
||||
* 2 by the timeline
|
||||
* 1 by the timeline
|
||||
* 1 added by ourselves above (gst_object_ref (t1)) */
|
||||
ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 5);
|
||||
ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 4);
|
||||
|
||||
trackelements = GES_CONTAINER_CHILDREN (s2);
|
||||
fail_unless (trackelements != NULL);
|
||||
|
@ -633,17 +633,17 @@ GST_START_TEST (test_ges_timeline_multiple_tracks)
|
|||
/* There are 3 references held:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3);
|
||||
fail_unless (ges_track_element_get_track (tmp->data) == track2);
|
||||
}
|
||||
gst_object_ref (t2);
|
||||
/* There are 3 references held:
|
||||
* 1 by the container
|
||||
* 1 by the track
|
||||
* 2 by the timeline
|
||||
* 1 by the timeline
|
||||
* 1 added by ourselves above (gst_object_ref (t2)) */
|
||||
ASSERT_OBJECT_REFCOUNT (t2, "t2", 5);
|
||||
ASSERT_OBJECT_REFCOUNT (t2, "t2", 4);
|
||||
|
||||
trackelements = GES_CONTAINER_CHILDREN (s3);
|
||||
fail_unless (trackelements != NULL);
|
||||
|
@ -652,17 +652,17 @@ GST_START_TEST (test_ges_timeline_multiple_tracks)
|
|||
/* There are 3 references held:
|
||||
* 1 by the clip
|
||||
* 1 by the track
|
||||
* 2 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4);
|
||||
* 1 by the timeline */
|
||||
ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3);
|
||||
fail_unless (ges_track_element_get_track (tmp->data) == track1);
|
||||
}
|
||||
gst_object_ref (t3);
|
||||
/* There are 3 references held:
|
||||
* 1 by the container
|
||||
* 1 by the track
|
||||
* 2 by the timeline
|
||||
* 1 by the timeline
|
||||
* 1 added by ourselves above (gst_object_ref (t3)) */
|
||||
ASSERT_OBJECT_REFCOUNT (t3, "t3", 5);
|
||||
ASSERT_OBJECT_REFCOUNT (t3, "t3", 4);
|
||||
|
||||
gst_object_unref (t1);
|
||||
gst_object_unref (t2);
|
||||
|
|
|
@ -365,7 +365,7 @@ GST_START_TEST (test_split_object)
|
|||
/* 1 ref for the Clip, 1 ref for the Track and 2 ref for the timeline
|
||||
* (1 for the "all_element" hashtable, another for the sequence of TrackElement*/
|
||||
ASSERT_OBJECT_REFCOUNT (splittrackelement,
|
||||
"1 ref for the Clip, 1 ref for the Track and 2 ref for the timeline", 4);
|
||||
"1 ref for the Clip, 1 ref for the Track and 1 ref for the timeline", 3);
|
||||
|
||||
check_destroyed (G_OBJECT (timeline), G_OBJECT (splitclip), clip,
|
||||
splittrackelement, NULL);
|
||||
|
@ -429,7 +429,7 @@ GST_START_TEST (test_clip_group_ungroup)
|
|||
tmp = ges_track_get_elements (audio_track);
|
||||
assert_equals_int (g_list_length (tmp), 1);
|
||||
ASSERT_OBJECT_REFCOUNT (tmp->data, "1 for the track + 1 for the container "
|
||||
"+ 2 for the timeline + 1 in tmp list", 5);
|
||||
"+ 1 for the timeline + 1 in tmp list", 4);
|
||||
assert_equals_int (ges_track_element_get_track_type (tmp->data),
|
||||
GES_TRACK_TYPE_AUDIO);
|
||||
assert_equals_int (ges_clip_get_supported_formats (GES_CLIP
|
||||
|
@ -438,7 +438,7 @@ GST_START_TEST (test_clip_group_ungroup)
|
|||
tmp = ges_track_get_elements (video_track);
|
||||
assert_equals_int (g_list_length (tmp), 1);
|
||||
ASSERT_OBJECT_REFCOUNT (tmp->data, "1 for the track + 1 for the container "
|
||||
"+ 2 for the timeline + 1 in tmp list", 5);
|
||||
"+ 1 for the timeline + 1 in tmp list", 4);
|
||||
assert_equals_int (ges_track_element_get_track_type (tmp->data),
|
||||
GES_TRACK_TYPE_VIDEO);
|
||||
assert_equals_int (ges_clip_get_supported_formats (GES_CLIP
|
||||
|
@ -489,7 +489,7 @@ GST_START_TEST (test_clip_group_ungroup)
|
|||
tmp = ges_track_get_elements (video_track);
|
||||
assert_equals_int (g_list_length (tmp), 1);
|
||||
ASSERT_OBJECT_REFCOUNT (tmp->data, "1 for the track + 1 for the container "
|
||||
"+ 2 for the timeline + 1 in tmp list", 5);
|
||||
"+ 1 for the timeline + 1 in tmp list", 4);
|
||||
assert_equals_int (ges_track_element_get_track_type (tmp->data),
|
||||
GES_TRACK_TYPE_VIDEO);
|
||||
fail_unless (GES_CONTAINER (ges_timeline_element_get_parent (tmp->data)) ==
|
||||
|
|
|
@ -165,147 +165,69 @@ GST_START_TEST (test_move_group)
|
|||
CHECK_OBJECT_PROPS (clip2, 60, 0, 50);
|
||||
CHECK_OBJECT_PROPS (group, 10, 0, 100);
|
||||
ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2);
|
||||
|
||||
/*
|
||||
* 0 20---Group1---------------110
|
||||
* | |
|
||||
* layer: | |
|
||||
* | |
|
||||
* |--------------------------|
|
||||
* 5--------- 0------------|
|
||||
* layer1: | clip1 | | clip2 |
|
||||
* 20--------30 60----------|
|
||||
* |--------------------------|
|
||||
*/
|
||||
ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 20);
|
||||
CHECK_OBJECT_PROPS (clip, 15, 5, 0);
|
||||
fail_if (ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 20));
|
||||
CHECK_OBJECT_PROPS (clip, 10, 0, 5);
|
||||
CHECK_OBJECT_PROPS (clip1, 20, 5, 10);
|
||||
CHECK_OBJECT_PROPS (clip2, 60, 0, 50);
|
||||
CHECK_OBJECT_PROPS (group, 20, 0, 90);
|
||||
|
||||
/*
|
||||
* 0 25---Group1---------------110
|
||||
* | |
|
||||
* layer: | |
|
||||
* | |
|
||||
* |--------------------------|
|
||||
* 10------ 0------------|
|
||||
* layer1: | clip1 | | clip2 |
|
||||
* 25------30 60----------|
|
||||
* |--------------------------|
|
||||
*/
|
||||
ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 25);
|
||||
CHECK_OBJECT_PROPS (clip, 15, 5, 0);
|
||||
CHECK_OBJECT_PROPS (clip1, 25, 10, 5);
|
||||
CHECK_OBJECT_PROPS (clip2, 60, 0, 50);
|
||||
CHECK_OBJECT_PROPS (group, 25, 0, 85);
|
||||
CHECK_OBJECT_PROPS (group, 10, 0, 100);
|
||||
ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2);
|
||||
|
||||
/*
|
||||
* 0 10------------Group1------------------110
|
||||
* |------ |
|
||||
* layer: |clip | |
|
||||
* |-----15 |
|
||||
* |-------------------------------------|
|
||||
* | 10------ 0------------|
|
||||
* layer1: | | clip1 | | clip2 |
|
||||
* | 25------30 60----------|
|
||||
* | |--------------------------|
|
||||
* |-------------------------------------|
|
||||
*/
|
||||
fail_if (ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 25));
|
||||
CHECK_OBJECT_PROPS (clip, 10, 0, 5);
|
||||
CHECK_OBJECT_PROPS (clip1, 20, 5, 10);
|
||||
CHECK_OBJECT_PROPS (clip2, 60, 0, 50);
|
||||
CHECK_OBJECT_PROPS (group, 10, 0, 100);
|
||||
ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2);
|
||||
|
||||
/* Same thing in the end... */
|
||||
ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 10);
|
||||
CHECK_OBJECT_PROPS (clip, 10, 0, 5);
|
||||
CHECK_OBJECT_PROPS (clip1, 25, 10, 5);
|
||||
CHECK_OBJECT_PROPS (clip1, 20, 5, 10);
|
||||
CHECK_OBJECT_PROPS (clip2, 60, 0, 50);
|
||||
CHECK_OBJECT_PROPS (group, 10, 0, 100);
|
||||
ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2);
|
||||
|
||||
/*
|
||||
* 0 25---Group1---------------110
|
||||
* | |
|
||||
* layer: 15 | |
|
||||
* |clip | |
|
||||
* - |--------------------------|
|
||||
* 10------ 0------------|
|
||||
* layer1: | clip1 | | clip2 |
|
||||
* 25------30 60----------|
|
||||
* |--------------------------|
|
||||
* 0 12------------Group1---------------110
|
||||
* 2------ |
|
||||
* layer: |clip | |
|
||||
* |-----15 |
|
||||
* |----------------------------------|
|
||||
* | 7--------- 2----------|
|
||||
* layer1: | | clip1 | | clip2 |
|
||||
* | 22--------30 62----------|
|
||||
* |----------------------------------|
|
||||
*/
|
||||
ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 25);
|
||||
CHECK_OBJECT_PROPS (clip, 15, 5, 0);
|
||||
CHECK_OBJECT_PROPS (clip1, 25, 10, 5);
|
||||
CHECK_OBJECT_PROPS (clip2, 60, 0, 50);
|
||||
CHECK_OBJECT_PROPS (group, 25, 0, 85);
|
||||
ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 12);
|
||||
CHECK_OBJECT_PROPS (clip, 12, 2, 3);
|
||||
CHECK_OBJECT_PROPS (clip1, 22, 7, 8);
|
||||
CHECK_OBJECT_PROPS (clip2, 62, 2, 48);
|
||||
CHECK_OBJECT_PROPS (group, 12, 0, 98);
|
||||
ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2);
|
||||
|
||||
/*
|
||||
* 0 25---Group1--30
|
||||
* | |
|
||||
* layer: 15 | |
|
||||
* |clip | |
|
||||
* - |------------
|
||||
* 15-----------| 60
|
||||
* layer1: | clip1 | |clip2
|
||||
* 25------------| -
|
||||
* |------------|
|
||||
*/
|
||||
/* Setting the duration would lead to overlaps */
|
||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (group), 10);
|
||||
CHECK_OBJECT_PROPS (clip, 15, 5, 0);
|
||||
CHECK_OBJECT_PROPS (clip1, 25, 10, 5);
|
||||
CHECK_OBJECT_PROPS (clip2, 60, 0, 0);
|
||||
CHECK_OBJECT_PROPS (group, 25, 0, 5);
|
||||
|
||||
/*
|
||||
* 0 25---Group1---------------125
|
||||
* | |
|
||||
* layer: 15 | |
|
||||
* |clip | |
|
||||
* - |--------------------------|
|
||||
* 10-------------------------|
|
||||
* layer1: | clip1 | clip2 |
|
||||
* 25--------------60----------|
|
||||
* |--------------------------|
|
||||
*/
|
||||
CHECK_OBJECT_PROPS (clip, 12, 2, 3);
|
||||
CHECK_OBJECT_PROPS (clip1, 22, 7, 8);
|
||||
CHECK_OBJECT_PROPS (clip2, 62, 2, 48);
|
||||
CHECK_OBJECT_PROPS (group, 12, 0, 98);
|
||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (group), 100);
|
||||
CHECK_OBJECT_PROPS (clip, 15, 5, 0);
|
||||
CHECK_OBJECT_PROPS (clip1, 25, 10, 100);
|
||||
CHECK_OBJECT_PROPS (clip2, 60, 0, 65);
|
||||
CHECK_OBJECT_PROPS (group, 25, 0, 100);
|
||||
ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2);
|
||||
CHECK_OBJECT_PROPS (clip, 12, 2, 3);
|
||||
CHECK_OBJECT_PROPS (clip1, 22, 7, 8);
|
||||
CHECK_OBJECT_PROPS (clip2, 62, 2, 50);
|
||||
CHECK_OBJECT_PROPS (group, 12, 0, 100);
|
||||
|
||||
/*
|
||||
* 0 20---Group1---------------120
|
||||
* | |
|
||||
* layer: 15 | |
|
||||
* |clip| |
|
||||
* - |--------------------------|
|
||||
* 10-------------------------|
|
||||
* layer1: | clip1 | clip2 |
|
||||
* 20-------------55----------|
|
||||
* |--------------------------|
|
||||
*/
|
||||
ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (group), 20);
|
||||
CHECK_OBJECT_PROPS (clip, 15, 5, 0);
|
||||
CHECK_OBJECT_PROPS (clip1, 20, 10, 100);
|
||||
CHECK_OBJECT_PROPS (clip2, 55, 0, 65);
|
||||
CHECK_OBJECT_PROPS (clip, 20, 2, 3);
|
||||
CHECK_OBJECT_PROPS (clip1, 30, 7, 8);
|
||||
CHECK_OBJECT_PROPS (clip2, 70, 2, 50);
|
||||
CHECK_OBJECT_PROPS (group, 20, 0, 100);
|
||||
|
||||
/*
|
||||
* 0 10---Group1---------------120
|
||||
* |-----15 |
|
||||
* layer: | clip| |
|
||||
* |------ |
|
||||
* |--------------------------|
|
||||
* 5--------------------------|
|
||||
* layer1: | clip1 | clip2 |
|
||||
* 10-------------55----------|
|
||||
* |--------------------------|
|
||||
*/
|
||||
ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 10);
|
||||
CHECK_OBJECT_PROPS (clip, 10, 0, 5);
|
||||
CHECK_OBJECT_PROPS (clip1, 10, 0, 110);
|
||||
CHECK_OBJECT_PROPS (clip2, 55, 0, 65);
|
||||
CHECK_OBJECT_PROPS (group, 10, 0, 110);
|
||||
fail_if (ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 10));
|
||||
CHECK_OBJECT_PROPS (clip, 20, 2, 3);
|
||||
CHECK_OBJECT_PROPS (clip1, 30, 7, 8);
|
||||
CHECK_OBJECT_PROPS (clip2, 70, 2, 50);
|
||||
CHECK_OBJECT_PROPS (group, 20, 0, 100);
|
||||
|
||||
ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2);
|
||||
check_destroyed (G_OBJECT (timeline), G_OBJECT (group), NULL);
|
||||
|
|
|
@ -308,7 +308,7 @@ GST_START_TEST (test_single_layer_automatic_transition)
|
|||
{
|
||||
GESAsset *asset;
|
||||
GESTimeline *timeline;
|
||||
GList *objects, *current;
|
||||
GList *objects;
|
||||
GESClip *transition;
|
||||
GESLayer *layer;
|
||||
GESTimelineElement *src, *src1, *src2;
|
||||
|
@ -379,24 +379,19 @@ GST_START_TEST (test_single_layer_automatic_transition)
|
|||
ges_timeline_element_set_start (src, 250);
|
||||
|
||||
/*
|
||||
* 500_____transition____1250
|
||||
* 250___________src_________1250
|
||||
* 600_____transition______1500
|
||||
* 600___________src_________1600
|
||||
* 500___________src1_________1500
|
||||
*/
|
||||
GST_DEBUG ("Checking src timing values");
|
||||
assert_equals_uint64 (_START (src), 250);
|
||||
assert_equals_uint64 (_DURATION (src), 1250 - 250);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1500 - 500);
|
||||
CHECK_OBJECT_PROPS (src, 250, 0, 1000);
|
||||
CHECK_OBJECT_PROPS (src1, 500, 0, 1000);
|
||||
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 4);
|
||||
assert_is_type (objects->data, GES_TYPE_TEST_CLIP);
|
||||
|
||||
transition = objects->next->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
assert_equals_uint64 (_START (transition), 500);
|
||||
assert_equals_uint64 (_DURATION (transition), 750);
|
||||
CHECK_OBJECT_PROPS (transition, 500, 0, 750);
|
||||
|
||||
transition = objects->next->next->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
|
@ -404,295 +399,65 @@ GST_START_TEST (test_single_layer_automatic_transition)
|
|||
assert_equals_uint64 (_DURATION (transition), 750);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG ("Moving second source to 250, the transitions should be removed");
|
||||
ges_timeline_element_set_start (src1, 250);
|
||||
fail_if (ges_timeline_element_set_start (src1, 250));
|
||||
|
||||
/* The transition should be removed
|
||||
* 250___________src_________1250
|
||||
* 250___________src1________1250
|
||||
fail_if (ges_container_edit (GES_CONTAINER (src), NULL, -1,
|
||||
GES_EDIT_MODE_TRIM, GES_EDGE_START, 500));
|
||||
CHECK_OBJECT_PROPS (src, 250, 0, 1000);
|
||||
CHECK_OBJECT_PROPS (src1, 500, 0, 1000);
|
||||
fail_if (ges_timeline_element_trim (src, 500));
|
||||
CHECK_OBJECT_PROPS (src, 250, 0, 1000);
|
||||
CHECK_OBJECT_PROPS (src1, 500, 0, 1000);
|
||||
fail_if (ges_timeline_element_trim (src, 750));
|
||||
CHECK_OBJECT_PROPS (src, 250, 0, 1000);
|
||||
CHECK_OBJECT_PROPS (src1, 500, 0, 1000);
|
||||
fail_if (ges_timeline_element_set_start (src, 500));
|
||||
CHECK_OBJECT_PROPS (src, 250, 0, 1000);
|
||||
CHECK_OBJECT_PROPS (src1, 500, 0, 1000);
|
||||
|
||||
/*
|
||||
* 600_____transition______1500
|
||||
* 600___________src_________1600
|
||||
* 500___________src1_________1500
|
||||
*/
|
||||
GST_DEBUG ("Checking src timing values");
|
||||
assert_equals_uint64 (_START (src), 250);
|
||||
assert_equals_uint64 (_DURATION (src), 1250 - 250);
|
||||
assert_equals_uint64 (_START (src1), 250);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 250);
|
||||
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG ("Trimming second source to 500 no transition should be created "
|
||||
"as they have the same end");
|
||||
ges_container_edit (GES_CONTAINER (src1), NULL, -1,
|
||||
GES_EDIT_MODE_TRIM, GES_EDGE_START, 500);
|
||||
|
||||
/* 250___________src_________1250
|
||||
* 500______src1_______1250
|
||||
*/
|
||||
GST_DEBUG ("Checking src timing values");
|
||||
assert_equals_uint64 (_START (src), 250);
|
||||
assert_equals_uint64 (_DURATION (src), 1250 - 250);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG ("Trimming second source to 500, no transition should be created");
|
||||
ges_timeline_element_trim (src, 500);
|
||||
|
||||
/* 500___________src_________1250
|
||||
* 500___________src1________1250
|
||||
*/
|
||||
GST_DEBUG ("Checking src timing values");
|
||||
assert_equals_uint64 (_START (src), 500);
|
||||
assert_equals_uint64 (_DURATION (src), 1250 - 500);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
|
||||
GST_DEBUG ("Trimming first source to 750, no transition should be created");
|
||||
ges_timeline_element_trim (src, 750);
|
||||
|
||||
/* 750_______src_______1250
|
||||
* 500___________src1________1250
|
||||
*/
|
||||
GST_DEBUG ("Checking src timing values");
|
||||
assert_equals_uint64 (_START (src), 750);
|
||||
assert_equals_uint64 (_DURATION (src), 1250 - 750);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG ("Moving first source to 500, no transition should be created");
|
||||
ges_timeline_element_set_start (src, 500);
|
||||
|
||||
/* 500________src______1000
|
||||
* 500___________src1________1250
|
||||
*/
|
||||
GST_DEBUG ("Checking src timing values");
|
||||
assert_equals_uint64 (_START (src), 500);
|
||||
assert_equals_uint64 (_DURATION (src), 1000 - 500);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG ("Moving first source to 600, no transition should be created");
|
||||
ges_timeline_element_set_start (src, 600);
|
||||
/* 600____src___1100
|
||||
* 500___________src1________1250
|
||||
*/
|
||||
GST_DEBUG ("Checking src timing values");
|
||||
assert_equals_uint64 (_START (src), 600);
|
||||
assert_equals_uint64 (_DURATION (src), 1100 - 600);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
|
||||
CHECK_OBJECT_PROPS (src, 600, 0, 1000);
|
||||
CHECK_OBJECT_PROPS (src1, 500, 0, 1000);
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
assert_equals_int (g_list_length (objects), 4);
|
||||
transition = objects->next->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
CHECK_OBJECT_PROPS (transition, 600, 0, 900);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG ("Adding asset to first layer");
|
||||
GST_DEBUG ("Adding clip from 1250 -- 1000 to first layer");
|
||||
src2 =
|
||||
GES_TIMELINE_ELEMENT (ges_layer_add_asset (layer, asset, 1250, 0,
|
||||
fail_if (ges_layer_add_asset (layer, asset, 1250, 0,
|
||||
1000, GES_TRACK_TYPE_UNKNOWN));
|
||||
|
||||
/*
|
||||
* 1500___________src2________2000
|
||||
* 1500_trans_1600
|
||||
* 600______________src________________1600
|
||||
* 600_____transition______1500
|
||||
* 500___________src1_________1500
|
||||
*/
|
||||
src2 = GES_TIMELINE_ELEMENT (ges_layer_add_asset (layer, asset, 1500, 0,
|
||||
500, GES_TRACK_TYPE_UNKNOWN));
|
||||
assert_is_type (src2, GES_TYPE_TEST_CLIP);
|
||||
|
||||
/* 600____src___1100
|
||||
* 500___________src1________1250
|
||||
* 1250___________src2________2250
|
||||
*/
|
||||
assert_equals_uint64 (_START (src), 600);
|
||||
assert_equals_uint64 (_DURATION (src), 1100 - 600);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
assert_equals_uint64 (_START (src2), 1250);
|
||||
assert_equals_uint64 (_DURATION (src2), 1000);
|
||||
|
||||
CHECK_OBJECT_PROPS (src, 600, 0, 1000);
|
||||
CHECK_OBJECT_PROPS (src1, 500, 0, 1000);
|
||||
CHECK_OBJECT_PROPS (src2, 1500, 0, 500);
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 3);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG
|
||||
("Changig first source duration to 800 2 transitions should be created");
|
||||
ges_timeline_element_set_duration (src, 800);
|
||||
ges_timeline_commit (timeline);
|
||||
/* 600__________________src_____________1400
|
||||
* 500___________src1________1250
|
||||
* 1250___________src2________2250
|
||||
* 600_____trans1_______1250
|
||||
* 1250___trans2___1400
|
||||
*/
|
||||
GST_DEBUG ("Checking src timing values");
|
||||
assert_equals_uint64 (_START (src), 600);
|
||||
assert_equals_uint64 (_DURATION (src), 1400 - 600);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
|
||||
current = objects = ges_layer_get_clips (layer);
|
||||
transition = objects->next->next->data;
|
||||
assert_equals_int (g_list_length (objects), 7);
|
||||
assert_is_type (objects->data, GES_TYPE_TEST_CLIP);
|
||||
fail_unless (objects->data == src1);
|
||||
|
||||
current = current->next;
|
||||
transition = current->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
assert_equals_uint64 (_START (transition), 600);
|
||||
assert_equals_uint64 (_DURATION (transition), 1250 - 600);
|
||||
ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline + ourself", 3);
|
||||
|
||||
current = current->next;
|
||||
transition = current->data;
|
||||
CHECK_OBJECT_PROPS (transition, 600, 0, 900);
|
||||
transition = objects->next->next->next->next->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
assert_equals_uint64 (_START (transition), 600);
|
||||
assert_equals_uint64 (_DURATION (transition), 1250 - 600);
|
||||
ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline + ourself", 3);
|
||||
CHECK_OBJECT_PROPS (transition, 1500, 0, 100);
|
||||
|
||||
current = current->next;
|
||||
fail_unless (current->data == src);
|
||||
|
||||
current = current->next;
|
||||
transition = current->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
assert_equals_uint64 (_START (transition), 1250);
|
||||
assert_equals_uint64 (_DURATION (transition), 1400 - 1250);
|
||||
ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline + ourself", 3);
|
||||
|
||||
current = current->next;
|
||||
transition = current->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
assert_equals_uint64 (_START (transition), 1250);
|
||||
assert_equals_uint64 (_DURATION (transition), 1400 - 1250);
|
||||
ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline + ourself", 3);
|
||||
|
||||
current = current->next;
|
||||
fail_unless (current->data == src2);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG ("Back to previous state");
|
||||
/* Make sure to keep 1 ref so we can check_destroyed afterward */
|
||||
gst_object_ref (transition);
|
||||
ges_timeline_element_set_duration (src, 1100 - 600);
|
||||
/* 600____src___1100
|
||||
* 500___________src1________1250
|
||||
* 1250___________src2________2250
|
||||
*/
|
||||
assert_equals_uint64 (_START (src), 600);
|
||||
assert_equals_uint64 (_DURATION (src), 1100 - 600);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
assert_equals_uint64 (_START (src2), 1250);
|
||||
assert_equals_uint64 (_DURATION (src2), 1000);
|
||||
|
||||
/* We check that the transition as actually been freed */
|
||||
check_destroyed (G_OBJECT (transition), NULL, NULL);
|
||||
|
||||
objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 3);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG
|
||||
("Set third clip start to 1100, 1 new transition should be created");
|
||||
ges_timeline_element_set_start (src2, 1100);
|
||||
ges_timeline_commit (timeline);
|
||||
/* 600____src___1100
|
||||
* 500___________src1________1250
|
||||
* 1100___________src2________2100
|
||||
* ^__trans___^
|
||||
*/
|
||||
assert_equals_uint64 (_START (src), 600);
|
||||
assert_equals_uint64 (_DURATION (src), 1100 - 600);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
assert_equals_uint64 (_START (src2), 1100);
|
||||
assert_equals_uint64 (_DURATION (src2), 1000);
|
||||
|
||||
current = objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 5);
|
||||
assert_is_type (objects->data, GES_TYPE_TEST_CLIP);
|
||||
fail_unless (current->data == src1);
|
||||
|
||||
current = current->next;
|
||||
fail_unless (current->data == src);
|
||||
|
||||
current = current->next;
|
||||
transition = current->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
assert_equals_uint64 (_START (transition), 1100);
|
||||
assert_equals_uint64 (_DURATION (transition), 1250 - 1100);
|
||||
|
||||
current = current->next;
|
||||
transition = current->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
assert_equals_uint64 (_START (transition), 1100);
|
||||
assert_equals_uint64 (_DURATION (transition), 1250 - 1100);
|
||||
|
||||
current = current->next;
|
||||
fail_unless (current->data == src2);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
GST_DEBUG ("Check that we can not create 2 transitions at the same place");
|
||||
fail_if (ges_container_edit (GES_CONTAINER (src2), NULL, -1,
|
||||
GES_EDIT_MODE_NORMAL, GES_EDGE_START, 1000));
|
||||
|
||||
/*
|
||||
* 500___________src1________1250
|
||||
* 1000___________src2________2000
|
||||
* ^____trans____^
|
||||
*/
|
||||
ges_layer_remove_clip (layer, GES_CLIP (src));
|
||||
fail_unless (ges_container_edit (GES_CONTAINER (src2), NULL, -1,
|
||||
GES_EDIT_MODE_NORMAL, GES_EDGE_START, 1000));
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
assert_equals_uint64 (_START (src2), 1000);
|
||||
assert_equals_uint64 (_DURATION (src2), 1000);
|
||||
|
||||
current = objects = ges_layer_get_clips (layer);
|
||||
current = objects;
|
||||
assert_equals_int (g_list_length (objects), 4);
|
||||
assert_is_type (objects->data, GES_TYPE_TEST_CLIP);
|
||||
transition = objects->next->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
fail_unless (current->data == src1);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
/*
|
||||
* 500___________src1________1250
|
||||
* ^____trans____^
|
||||
* 1100___________src2________2000
|
||||
*/
|
||||
ges_container_edit (GES_CONTAINER (transition),
|
||||
NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_START, 1100);
|
||||
assert_equals_uint64 (_START (src1), 500);
|
||||
assert_equals_uint64 (_DURATION (src1), 1250 - 500);
|
||||
assert_equals_uint64 (_START (src2), 1100);
|
||||
assert_equals_uint64 (_DURATION (src2), 2000 - 1100);
|
||||
|
||||
current = objects = ges_layer_get_clips (layer);
|
||||
current = objects;
|
||||
assert_equals_int (g_list_length (objects), 4);
|
||||
assert_is_type (objects->data, GES_TYPE_TEST_CLIP);
|
||||
fail_unless (current->data == src1);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
|
||||
gst_object_unref (timeline);
|
||||
|
@ -1006,7 +771,7 @@ GST_START_TEST (test_multi_layer_automatic_transition)
|
|||
|
||||
GST_DEBUG
|
||||
("Moving src to second layer, should remove first transition on first layer");
|
||||
ges_clip_move_to_layer (GES_CLIP (src), layer1);
|
||||
fail_if (ges_clip_move_to_layer (GES_CLIP (src), layer1));
|
||||
|
||||
/* 500___________src1_________1500
|
||||
* 1000___________src3_________2000 Layer
|
||||
|
@ -1027,31 +792,8 @@ GST_START_TEST (test_multi_layer_automatic_transition)
|
|||
|
||||
GST_DEBUG ("Checking transitions on first layer");
|
||||
current = objects = ges_layer_get_clips (layer);
|
||||
assert_equals_int (g_list_length (objects), 4);
|
||||
fail_unless (current->data == src1);
|
||||
assert_equals_int (g_list_length (objects), 7);
|
||||
|
||||
current = current->next;
|
||||
transition = current->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
assert_equals_uint64 (_START (transition), 1000);
|
||||
assert_equals_uint64 (_DURATION (transition), 500);
|
||||
|
||||
current = current->next;
|
||||
transition = current->data;
|
||||
assert_is_type (transition, GES_TYPE_TRANSITION_CLIP);
|
||||
assert_equals_uint64 (_START (transition), 1000);
|
||||
assert_equals_uint64 (_DURATION (transition), 500);
|
||||
|
||||
current = current->next;
|
||||
fail_unless (current->data == src3);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2);
|
||||
|
||||
GST_DEBUG ("Checking second layer");
|
||||
current = objects = ges_layer_get_clips (layer1);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
assert_is_type (current->data, GES_TYPE_TEST_CLIP);
|
||||
assert_is_type (current->next->data, GES_TYPE_TEST_CLIP);
|
||||
g_list_free_full (objects, gst_object_unref);
|
||||
ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2);
|
||||
|
||||
|
|
|
@ -83,30 +83,37 @@ G_STMT_START { \
|
|||
#define _DURATION(obj) GES_TIMELINE_ELEMENT_DURATION (obj)
|
||||
#define _INPOINT(obj) GES_TIMELINE_ELEMENT_INPOINT (obj)
|
||||
#define _PRIORITY(obj) GES_TIMELINE_ELEMENT_PRIORITY (obj)
|
||||
#ifndef _END
|
||||
#define _END(obj) (_START(obj) + _DURATION(obj))
|
||||
#endif
|
||||
|
||||
#define CHECK_OBJECT_PROPS(obj, start, inpoint, duration) {\
|
||||
assert_equals_uint64 (_START (obj), start);\
|
||||
assert_equals_uint64 (_INPOINT (obj), inpoint);\
|
||||
assert_equals_uint64 (_DURATION (obj), duration);\
|
||||
fail_unless (_START (obj) == start, "%s start is %" GST_TIME_FORMAT " != %" GST_TIME_FORMAT, GES_TIMELINE_ELEMENT_NAME(obj), GST_TIME_ARGS (_START(obj)), GST_TIME_ARGS (start));\
|
||||
fail_unless (_INPOINT (obj) == inpoint, "%s inpoint is %" GST_TIME_FORMAT " != %" GST_TIME_FORMAT, GES_TIMELINE_ELEMENT_NAME(obj), GST_TIME_ARGS (_INPOINT(obj)), GST_TIME_ARGS (inpoint));\
|
||||
fail_unless (_DURATION (obj) == duration, "%s duration is %" GST_TIME_FORMAT " != %" GST_TIME_FORMAT, GES_TIMELINE_ELEMENT_NAME(obj), GST_TIME_ARGS (_DURATION(obj)), GST_TIME_ARGS (duration));\
|
||||
}
|
||||
|
||||
#define check_layer(clip, layer_prio) { \
|
||||
GESLayer *tmplayer = ges_clip_get_layer ((clip)); \
|
||||
assert_equals_int (ges_layer_get_priority (tmplayer), (layer_prio)); \
|
||||
gst_object_unref (tmplayer); \
|
||||
#define check_layer(clip, layer_prio) { \
|
||||
fail_unless (GES_TIMELINE_ELEMENT_LAYER_PRIORITY (clip) == (layer_prio), \
|
||||
"%s in layer %d instead of %d", GES_TIMELINE_ELEMENT_NAME (clip), \
|
||||
GES_TIMELINE_ELEMENT_LAYER_PRIORITY (clip), layer_prio); \
|
||||
}
|
||||
|
||||
#define GES_TIMELINE_ELEMENT_FORMAT \
|
||||
"s<%p>" \
|
||||
" [ %" GST_TIME_FORMAT \
|
||||
" (%" GST_TIME_FORMAT \
|
||||
") - %" GST_TIME_FORMAT "]"
|
||||
") - %" GST_TIME_FORMAT "(%" GST_TIME_FORMAT") layer: %" G_GINT32_FORMAT "] "
|
||||
|
||||
#define GES_TIMELINE_ELEMENT_ARGS(element) \
|
||||
GES_TIMELINE_ELEMENT_NAME(element), element, \
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_START(element)), \
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_INPOINT(element)), \
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_DURATION(element))
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_DURATION(element)), \
|
||||
GST_TIME_ARGS(GES_TIMELINE_ELEMENT_MAX_DURATION(element)), \
|
||||
GES_TIMELINE_ELEMENT_LAYER_PRIORITY(element)
|
||||
#define GES_ARGS GES_TIMELINE_ELEMENT_ARGS
|
||||
#define GES_FORMAT GES_TIMELINE_ELEMENT_FORMAT
|
||||
|
||||
void print_timeline(GESTimeline *timeline);
|
||||
|
||||
|
|
|
@ -25,19 +25,21 @@
|
|||
#define DEEP_CHECK(element, start, inpoint, duration) \
|
||||
{ \
|
||||
GList *track_elements, *tmp; \
|
||||
\
|
||||
assert_equals_uint64 (_START (element), start); \
|
||||
assert_equals_uint64 (_INPOINT (element), inpoint); \
|
||||
assert_equals_uint64 (_DURATION (element), duration); \
|
||||
CHECK_OBJECT_PROPS (element, start, inpoint, duration) \
|
||||
\
|
||||
track_elements = GES_CONTAINER_CHILDREN (element); \
|
||||
for (tmp = track_elements; tmp; tmp = tmp->next) { \
|
||||
assert_equals_uint64 (_START (tmp->data), start); \
|
||||
assert_equals_uint64 (_INPOINT (tmp->data), inpoint); \
|
||||
assert_equals_uint64 (_DURATION (tmp->data), duration); \
|
||||
CHECK_OBJECT_PROPS (tmp->data, start, inpoint, duration) \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECK_CLIP(element, start, inpoint, duration, layer_prio) \
|
||||
{ \
|
||||
DEEP_CHECK(element, start, inpoint, duration);\
|
||||
check_layer (element, layer_prio); \
|
||||
}\
|
||||
|
||||
|
||||
GST_START_TEST (test_basic_timeline_edition)
|
||||
{
|
||||
GESAsset *asset;
|
||||
|
@ -288,7 +290,7 @@ GST_START_TEST (test_snapping)
|
|||
fail_unless (ges_track_element_get_track (trackelement) == track);
|
||||
assert_equals_uint64 (_DURATION (trackelement), 37);
|
||||
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "track + timeline + clip", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "track + timeline + clip", 3);
|
||||
ASSERT_OBJECT_REFCOUNT (clip, "layer + timeline", 2);
|
||||
|
||||
fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip1)));
|
||||
|
@ -299,7 +301,7 @@ GST_START_TEST (test_snapping)
|
|||
assert_equals_uint64 (_DURATION (trackelement1), 15);
|
||||
|
||||
/* Same ref logic */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement1, "First trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement1, "First trackelement", 3);
|
||||
ASSERT_OBJECT_REFCOUNT (clip1, "First clip", 2);
|
||||
|
||||
fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip2)));
|
||||
|
@ -310,7 +312,7 @@ GST_START_TEST (test_snapping)
|
|||
assert_equals_uint64 (_DURATION (trackelement2), 60);
|
||||
|
||||
/* Same ref logic */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement2, "First trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement2, "First trackelement", 3);
|
||||
ASSERT_OBJECT_REFCOUNT (clip2, "First clip", 2);
|
||||
|
||||
/* Snaping to edge, so no move */
|
||||
|
@ -322,8 +324,7 @@ GST_START_TEST (test_snapping)
|
|||
CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
|
||||
|
||||
/* Snaping to edge, so no move */
|
||||
fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM,
|
||||
GES_EDGE_END, 27));
|
||||
ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_END, 27);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
|
||||
|
@ -338,144 +339,78 @@ GST_START_TEST (test_snapping)
|
|||
*/
|
||||
g_object_set (timeline, "snapping-distance", (guint64) 0, NULL);
|
||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (clip1), 10);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
|
||||
DEEP_CHECK (clip, 25, 0, 37);
|
||||
DEEP_CHECK (clip1, 20, 0, 10);
|
||||
DEEP_CHECK (clip2, 62, 0, 60);
|
||||
|
||||
/**
|
||||
* New timeline(the "layers" are just to help reading diagram, nothing else):
|
||||
* ------------
|
||||
* 0----------
|
||||
* | clip |
|
||||
* 25---------62
|
||||
* inpoints 0----------------------- 10--------
|
||||
* | clip1 || clip2 |
|
||||
* time 20---------------------- 72 --------122
|
||||
*/
|
||||
/* Rolling involves only neighbour that are currently snapping */
|
||||
fail_unless (ges_timeline_element_roll_end (GES_TIMELINE_ELEMENT (clip1),
|
||||
62));
|
||||
fail_unless (ges_timeline_element_roll_end (GES_TIMELINE_ELEMENT (clip1),
|
||||
/* clip and clip1 would fully overlap ... forbiden */
|
||||
fail_if (ges_timeline_element_roll_end (GES_TIMELINE_ELEMENT (clip1), 62));
|
||||
DEEP_CHECK (clip, 25, 0, 37);
|
||||
DEEP_CHECK (clip1, 20, 0, 10);
|
||||
DEEP_CHECK (clip2, 62, 0, 60);
|
||||
fail_if (ges_timeline_element_roll_end (GES_TIMELINE_ELEMENT (clip1),
|
||||
72) == TRUE);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 20, 0, 52);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50);
|
||||
DEEP_CHECK (clip, 25, 0, 37);
|
||||
DEEP_CHECK (clip1, 20, 0, 10);
|
||||
DEEP_CHECK (clip2, 62, 0, 60);
|
||||
|
||||
/**
|
||||
* 0----------
|
||||
* | clip |
|
||||
* 25---------62
|
||||
* inpoints 5--------------- 10--------
|
||||
* | clip1 || clip2 |
|
||||
* time 25------------- 72 --------122
|
||||
* 30-------+0-------------+
|
||||
* inpoints 0-----------5 clip || clip2 |
|
||||
* | clip1 |------- 62 -----------122
|
||||
* time 20----------30
|
||||
*/
|
||||
g_object_set (timeline, "snapping-distance", (guint64) 4, NULL);
|
||||
fail_unless (ges_timeline_element_trim (GES_TIMELINE_ELEMENT (clip1),
|
||||
fail_unless (ges_timeline_element_trim (GES_TIMELINE_ELEMENT (clip),
|
||||
28) == TRUE);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 25, 5, 47);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50);
|
||||
DEEP_CHECK (clip, 30, 5, 32);
|
||||
DEEP_CHECK (clip1, 20, 0, 10);
|
||||
DEEP_CHECK (clip2, 62, 0, 60);
|
||||
|
||||
/**
|
||||
* 0----------
|
||||
* | clip |
|
||||
* 25---------62
|
||||
* inpoints 5---------- 0---------
|
||||
* | clip1 || clip2 |
|
||||
* time 25-------- 62 --------122
|
||||
* 30-------+0-------------+
|
||||
* inpoints 0-----------5 clip || clip2 |
|
||||
* | clip1 |------- 62 -----------122
|
||||
* time 20----------30
|
||||
*/
|
||||
fail_unless (ges_timeline_element_set_inpoint (GES_TIMELINE_ELEMENT (clip2),
|
||||
5));
|
||||
fail_unless (ges_timeline_element_roll_start (GES_TIMELINE_ELEMENT (clip2),
|
||||
59) == TRUE);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 25, 5, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
|
||||
60));
|
||||
DEEP_CHECK (clip, 30, 5, 32);
|
||||
DEEP_CHECK (clip1, 20, 0, 10);
|
||||
DEEP_CHECK (clip2, 62, 5, 60);
|
||||
|
||||
/**
|
||||
* 0----------
|
||||
* | clip |
|
||||
* 25--------62
|
||||
* inpoints 5-----------------------+
|
||||
* | clip1 || clip2 |
|
||||
* time 30------------]--------122
|
||||
* 67
|
||||
* 30-------+0-------------+
|
||||
* inpoints 0-----------5 clip || clip2 |
|
||||
* | clip1 |------- 62 -----------122
|
||||
* time 20----------30
|
||||
*/
|
||||
ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 30);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 30, 5, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
|
||||
/* Moving clip1 to 26 would lead to snapping to 30, and clip1 and clip
|
||||
* would fully overlap */
|
||||
fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL,
|
||||
GES_EDGE_NONE, 26) == TRUE);
|
||||
DEEP_CHECK (clip, 30, 5, 32);
|
||||
DEEP_CHECK (clip1, 20, 0, 10);
|
||||
DEEP_CHECK (clip2, 62, 5, 60);
|
||||
|
||||
/**
|
||||
* inpoints 0----------5--------------
|
||||
* | clip || clip1 |
|
||||
* time 25----------62----------99
|
||||
* 0-----------
|
||||
* | clip2 |
|
||||
* 98--------168
|
||||
* Check that clip1 snaps with the end of clip */
|
||||
fail_unless (ges_timeline_element_ripple (GES_TIMELINE_ELEMENT (clip1),
|
||||
58) == TRUE);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 94, 0, 60);
|
||||
|
||||
/**
|
||||
* inpoints 0----------- 5------------ 0-----------
|
||||
* | clip || clip1 | | clip2 |
|
||||
* time 25----------62----------99 110--------170
|
||||
*/
|
||||
ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE,
|
||||
110);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
|
||||
|
||||
/**
|
||||
* inpoints 0----------5 5 --------- 0----------
|
||||
* | clip | | clip1 || clip2 |
|
||||
* time 25---------62 73---------110--------170
|
||||
*/
|
||||
* 30-------+0-------------+
|
||||
* inpoints 5 clip || clip2 |-------------+
|
||||
* +------- 62 -----------122 clip1 |
|
||||
* time +------------132
|
||||
* Check that clip1 snaps with the end of clip2 */
|
||||
fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL,
|
||||
GES_EDGE_NONE, 72) == TRUE);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 73, 5, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
|
||||
|
||||
/**
|
||||
* inpoints 0----------5---------- 0----------
|
||||
* | clip || clip1 | | clip2 |
|
||||
* time 25---------62-------- 99 110--------170
|
||||
*/
|
||||
fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL,
|
||||
GES_EDGE_NONE, 58) == TRUE);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
|
||||
|
||||
|
||||
/**
|
||||
* inpoints 0----------5---------- 0----------
|
||||
* | clip || clip1 || clip2 |
|
||||
* time 25---------62--------110--------170
|
||||
*/
|
||||
g_object_set (clip1, "duration", (guint64) 46, NULL);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 62, 5, 48);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
|
||||
|
||||
/**
|
||||
* inpoints 5----------- 0--------- 0----------
|
||||
* | clip1 || clip2 || clip |
|
||||
* time 62---------110--------170--------207
|
||||
*/
|
||||
ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 168);
|
||||
CHECK_OBJECT_PROPS (trackelement, 170, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 62, 5, 48);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
|
||||
GES_EDGE_NONE, 125) == TRUE);
|
||||
DEEP_CHECK (clip, 30, 5, 32);
|
||||
DEEP_CHECK (clip1, 122, 0, 10);
|
||||
DEEP_CHECK (clip2, 62, 5, 60);
|
||||
|
||||
/* Check we didn't lose/screwed any references */
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 3);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 3);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 3);
|
||||
ASSERT_OBJECT_REFCOUNT (clip, "First clip", 2);
|
||||
ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 2);
|
||||
ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 2);
|
||||
|
@ -782,6 +717,15 @@ GST_START_TEST (test_timeline_edition_mode)
|
|||
assert_equals_int (ges_layer_get_priority (layer), 2);
|
||||
gst_object_unref (layer);
|
||||
|
||||
/* Roll end clip back to 35 */
|
||||
/* Can not move to the first layer as clip2 should move to a layer with priority < 0 */
|
||||
fail_if (ges_container_edit (clip, NULL, 0, GES_EDIT_MODE_RIPPLE,
|
||||
GES_EDGE_END, 52));
|
||||
CHECK_OBJECT_PROPS (trackelement, 32, 5, 3);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60);
|
||||
assert_equals_int (GES_TIMELINE_ELEMENT_LAYER_PRIORITY (clip), 2);
|
||||
|
||||
/* Ripple clip end to 52
|
||||
* New timeline:
|
||||
* ------------
|
||||
|
@ -795,8 +739,7 @@ GST_START_TEST (test_timeline_edition_mode)
|
|||
* 32------52
|
||||
*
|
||||
*/
|
||||
/* Can not move to the first layer as clip2 should move to a layer with priority < 0 */
|
||||
fail_unless (ges_container_edit (clip, NULL, 0, GES_EDIT_MODE_RIPPLE,
|
||||
fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_RIPPLE,
|
||||
GES_EDGE_END, 52) == TRUE);
|
||||
CHECK_OBJECT_PROPS (trackelement, 32, 5, 20);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
|
||||
|
@ -817,9 +760,9 @@ GST_START_TEST (test_timeline_edition_mode)
|
|||
/* We have 3 references:
|
||||
* track + timeline + clip
|
||||
*/
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 4);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 3);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 3);
|
||||
ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 3);
|
||||
ASSERT_OBJECT_REFCOUNT (clip, "First clip", 2);
|
||||
ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 2);
|
||||
ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 2);
|
||||
|
@ -904,16 +847,13 @@ GST_START_TEST (test_timeline_edition_mode)
|
|||
|
||||
/* Snaping to edge, so no move */
|
||||
g_object_set (timeline, "snapping-distance", (guint64) 3, NULL);
|
||||
fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM,
|
||||
GES_EDGE_END, 27));
|
||||
ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_END, 27);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
|
||||
|
||||
/* Snaping to edge, so no move */
|
||||
fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM,
|
||||
GES_EDGE_END, 27));
|
||||
|
||||
ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_END, 27);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
|
||||
|
@ -939,13 +879,13 @@ GST_START_TEST (test_timeline_edition_mode)
|
|||
* 0----------
|
||||
* | clip |
|
||||
* 25---------62
|
||||
* -------------------------------------------------
|
||||
* inpoints 0----------------------- 10--------
|
||||
* | clip1 || clip2 |
|
||||
* time 20---------------------- 72 --------122
|
||||
*/
|
||||
/* Rolling involves only neighbours that are currently snapping */
|
||||
fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL,
|
||||
GES_EDGE_END, 62) == TRUE);
|
||||
ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, 62);
|
||||
fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL,
|
||||
GES_EDGE_END, 72) == TRUE);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
|
@ -968,19 +908,8 @@ GST_START_TEST (test_timeline_edition_mode)
|
|||
CHECK_OBJECT_PROPS (trackelement1, 25, 5, 47);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50);
|
||||
|
||||
/**
|
||||
* 0----------
|
||||
* | clip |
|
||||
* 25---------62
|
||||
* inpoints 5---------- 0---------
|
||||
* | clip1 || clip2 |
|
||||
* time 25-------- 62 --------122
|
||||
*/
|
||||
fail_unless (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_ROLL,
|
||||
GES_EDGE_START, 59) == TRUE);
|
||||
CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement1, 25, 5, 37);
|
||||
CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
|
||||
fail_if (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_ROLL,
|
||||
GES_EDGE_START, 59));
|
||||
|
||||
ges_deinit ();
|
||||
}
|
||||
|
@ -1040,131 +969,70 @@ GST_START_TEST (test_groups)
|
|||
g_list_free (clips);
|
||||
|
||||
fail_unless (GES_IS_GROUP (group));
|
||||
DEEP_CHECK (c, 0, 0, 10);
|
||||
DEEP_CHECK (c1, 10, 0, 10);
|
||||
DEEP_CHECK (c2, 20, 0, 10);
|
||||
CHECK_CLIP (c, 0, 0, 10, 0);
|
||||
CHECK_CLIP (c1, 10, 0, 10, 1);
|
||||
CHECK_CLIP (c2, 20, 0, 10, 1);
|
||||
CHECK_OBJECT_PROPS (group, 0, 0, 30);
|
||||
|
||||
c3 = ges_layer_add_asset (layer, asset, 30, 0, 20, GES_TRACK_TYPE_UNKNOWN);
|
||||
c4 = ges_layer_add_asset (layer1, asset, 40, 0, 20, GES_TRACK_TYPE_UNKNOWN);
|
||||
c5 = ges_layer_add_asset (layer2, asset, 50, 0, 20, GES_TRACK_TYPE_UNKNOWN);
|
||||
|
||||
DEEP_CHECK (c3, 30, 0, 20);
|
||||
DEEP_CHECK (c4, 40, 0, 20);
|
||||
DEEP_CHECK (c5, 50, 0, 20);
|
||||
CHECK_CLIP (c3, 30, 0, 20, 0);
|
||||
CHECK_CLIP (c4, 40, 0, 20, 1);
|
||||
CHECK_CLIP (c5, 50, 0, 20, 2);
|
||||
check_layer (c, 0);
|
||||
check_layer (c1, 1);
|
||||
check_layer (c2, 1);
|
||||
check_layer (c3, 0);
|
||||
check_layer (c4, 1);
|
||||
check_layer (c5, 2);
|
||||
|
||||
fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, -1,
|
||||
GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE);
|
||||
|
||||
DEEP_CHECK (c, 10, 0, 10);
|
||||
DEEP_CHECK (c1, 10, 0, 10);
|
||||
DEEP_CHECK (c2, 30, 0, 10);
|
||||
DEEP_CHECK (c3, 40, 0, 20);
|
||||
DEEP_CHECK (c4, 50, 0, 20);
|
||||
DEEP_CHECK (c5, 60, 0, 20);
|
||||
check_layer (c, 0);
|
||||
check_layer (c1, 1);
|
||||
check_layer (c2, 1);
|
||||
check_layer (c3, 0);
|
||||
check_layer (c4, 1);
|
||||
check_layer (c5, 2);
|
||||
CHECK_CLIP (c, 10, 0, 10, 0);
|
||||
CHECK_CLIP (c1, 20, 0, 10, 1);
|
||||
CHECK_CLIP (c2, 30, 0, 10, 1);
|
||||
CHECK_CLIP (c3, 40, 0, 20, 0);
|
||||
CHECK_CLIP (c4, 50, 0, 20, 1);
|
||||
CHECK_CLIP (c5, 60, 0, 20, 2);
|
||||
|
||||
fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 1,
|
||||
GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE);
|
||||
DEEP_CHECK (c, 10, 0, 10);
|
||||
DEEP_CHECK (c1, 10, 0, 10);
|
||||
DEEP_CHECK (c2, 30, 0, 10);
|
||||
DEEP_CHECK (c3, 40, 0, 20);
|
||||
DEEP_CHECK (c4, 50, 0, 20);
|
||||
DEEP_CHECK (c5, 60, 0, 20);
|
||||
check_layer (c, 1);
|
||||
check_layer (c1, 2);
|
||||
check_layer (c2, 2);
|
||||
check_layer (c3, 1);
|
||||
check_layer (c4, 2);
|
||||
check_layer (c5, 3);
|
||||
CHECK_CLIP (c, 10, 0, 10, 1);
|
||||
CHECK_CLIP (c1, 20, 0, 10, 2);
|
||||
CHECK_CLIP (c2, 30, 0, 10, 2);
|
||||
CHECK_CLIP (c3, 40, 0, 20, 1);
|
||||
CHECK_CLIP (c4, 50, 0, 20, 2);
|
||||
CHECK_CLIP (c5, 60, 0, 20, 3);
|
||||
|
||||
fail_unless (ges_container_edit (GES_CONTAINER (c1), NULL, 2,
|
||||
fail_if (ges_container_edit (GES_CONTAINER (c1), NULL, 2,
|
||||
GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 40) == TRUE);
|
||||
DEEP_CHECK (c, 10, 0, 10);
|
||||
DEEP_CHECK (c1, 10, 0, 30);
|
||||
DEEP_CHECK (c2, 50, 0, 10);
|
||||
DEEP_CHECK (c3, 60, 0, 20);
|
||||
DEEP_CHECK (c4, 70, 0, 20);
|
||||
DEEP_CHECK (c5, 80, 0, 20);
|
||||
check_layer (c, 1);
|
||||
check_layer (c1, 2);
|
||||
check_layer (c2, 2);
|
||||
check_layer (c3, 1);
|
||||
check_layer (c4, 2);
|
||||
check_layer (c5, 3);
|
||||
|
||||
fail_unless (ges_container_edit (GES_CONTAINER (c1), NULL, 2,
|
||||
fail_if (ges_container_edit (GES_CONTAINER (c1), NULL, 2,
|
||||
GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 30) == TRUE);
|
||||
DEEP_CHECK (c, 10, 0, 10);
|
||||
DEEP_CHECK (c1, 10, 0, 20);
|
||||
DEEP_CHECK (c2, 40, 0, 10);
|
||||
DEEP_CHECK (c3, 50, 0, 20);
|
||||
DEEP_CHECK (c4, 60, 0, 20);
|
||||
DEEP_CHECK (c5, 70, 0, 20);
|
||||
check_layer (c, 1);
|
||||
check_layer (c1, 2);
|
||||
check_layer (c2, 2);
|
||||
check_layer (c3, 1);
|
||||
check_layer (c4, 2);
|
||||
check_layer (c5, 3);
|
||||
|
||||
CHECK_CLIP (c, 10, 0, 10, 1);
|
||||
CHECK_CLIP (c1, 20, 0, 10, 2);
|
||||
CHECK_CLIP (c2, 30, 0, 10, 2);
|
||||
CHECK_CLIP (c3, 40, 0, 20, 1);
|
||||
CHECK_CLIP (c4, 50, 0, 20, 2);
|
||||
CHECK_CLIP (c5, 60, 0, 20, 3);
|
||||
fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 0,
|
||||
GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 0) == TRUE);
|
||||
DEEP_CHECK (c, 0, 0, 10);
|
||||
DEEP_CHECK (c1, 10, 0, 20);
|
||||
DEEP_CHECK (c2, 30, 0, 10);
|
||||
DEEP_CHECK (c3, 40, 0, 20);
|
||||
DEEP_CHECK (c4, 50, 0, 20);
|
||||
DEEP_CHECK (c5, 60, 0, 20);
|
||||
check_layer (c, 0);
|
||||
check_layer (c1, 1);
|
||||
check_layer (c2, 1);
|
||||
check_layer (c3, 0);
|
||||
check_layer (c4, 1);
|
||||
check_layer (c5, 2);
|
||||
|
||||
fail_if (ges_container_edit (GES_CONTAINER (c2), NULL, -1,
|
||||
GES_EDIT_MODE_ROLL, GES_EDGE_END, 40) == TRUE);
|
||||
DEEP_CHECK (c, 0, 0, 10);
|
||||
DEEP_CHECK (c1, 10, 0, 20);
|
||||
DEEP_CHECK (c2, 30, 0, 10);
|
||||
DEEP_CHECK (c3, 40, 0, 20);
|
||||
DEEP_CHECK (c4, 50, 0, 20);
|
||||
DEEP_CHECK (c5, 60, 0, 20);
|
||||
check_layer (c, 0);
|
||||
check_layer (c1, 1);
|
||||
check_layer (c2, 1);
|
||||
check_layer (c3, 0);
|
||||
check_layer (c4, 1);
|
||||
check_layer (c5, 2);
|
||||
CHECK_CLIP (c, 0, 0, 10, 0);
|
||||
CHECK_CLIP (c1, 10, 0, 10, 1);
|
||||
CHECK_CLIP (c2, 20, 0, 10, 1);
|
||||
CHECK_CLIP (c3, 30, 0, 20, 0);
|
||||
CHECK_CLIP (c4, 40, 0, 20, 1);
|
||||
CHECK_CLIP (c5, 50, 0, 20, 2);
|
||||
CHECK_OBJECT_PROPS (group, 0, 0, 30);
|
||||
|
||||
fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 0,
|
||||
GES_EDIT_MODE_TRIM, GES_EDGE_START, 5) == TRUE);
|
||||
CHECK_OBJECT_PROPS (c, 5, 5, 5);
|
||||
DEEP_CHECK (c1, 10, 0, 20);
|
||||
DEEP_CHECK (c2, 30, 0, 10);
|
||||
DEEP_CHECK (c3, 40, 0, 20);
|
||||
DEEP_CHECK (c4, 50, 0, 20);
|
||||
DEEP_CHECK (c5, 60, 0, 20);
|
||||
CHECK_OBJECT_PROPS (group, 5, 0, 35);
|
||||
check_layer (c, 0);
|
||||
check_layer (c1, 1);
|
||||
check_layer (c2, 1);
|
||||
check_layer (c3, 0);
|
||||
check_layer (c4, 1);
|
||||
check_layer (c5, 2);
|
||||
CHECK_CLIP (c, 5, 5, 5, 0);
|
||||
CHECK_CLIP (c1, 10, 0, 10, 1);
|
||||
CHECK_CLIP (c2, 20, 0, 10, 1);
|
||||
CHECK_CLIP (c3, 30, 0, 20, 0);
|
||||
CHECK_CLIP (c4, 40, 0, 20, 1);
|
||||
CHECK_CLIP (c5, 50, 0, 20, 2);
|
||||
CHECK_OBJECT_PROPS (group, 5, 0, 25);
|
||||
|
||||
gst_object_unref (timeline);
|
||||
gst_object_unref (asset);
|
||||
|
|
|
@ -263,7 +263,7 @@ GST_START_TEST (test_filesource_images)
|
|||
fail_unless (GES_IS_IMAGE_SOURCE (track_element));
|
||||
|
||||
ASSERT_OBJECT_REFCOUNT (track_element, "1 in track, 1 in clip 2 in timeline",
|
||||
4);
|
||||
3);
|
||||
|
||||
gst_object_unref (asset);
|
||||
gst_object_unref (timeline);
|
||||
|
|
|
@ -194,7 +194,16 @@ class GESSimpleTimelineTest(GESTest):
|
|||
|
||||
return clip
|
||||
|
||||
def assertTimelineTopology(self, topology):
|
||||
def append_clip(self, layer=0):
|
||||
layer = self.timeline.get_layers()[layer]
|
||||
clip = GES.TestClip()
|
||||
clip.props.start = layer.get_duration()
|
||||
clip.props.duration = 10
|
||||
self.assertTrue(layer.add_clip(clip))
|
||||
|
||||
return clip
|
||||
|
||||
def assertTimelineTopology(self, topology, groups=[]):
|
||||
res = []
|
||||
for layer in self.timeline.get_layers():
|
||||
layer_timings = []
|
||||
|
@ -203,6 +212,14 @@ class GESSimpleTimelineTest(GESTest):
|
|||
(type(clip), clip.props.start, clip.props.duration))
|
||||
|
||||
res.append(layer_timings)
|
||||
if topology != res:
|
||||
Gst.error(self.timeline_as_str())
|
||||
self.assertEqual(topology, res)
|
||||
|
||||
self.assertEqual(topology, res)
|
||||
return res
|
||||
timeline_groups = self.timeline.get_groups()
|
||||
if groups and timeline_groups:
|
||||
for i, group in enumerate(groups):
|
||||
self.assertEqual(set(group), set(timeline_groups[i].get_children(False)))
|
||||
self.assertEqual(len(timeline_groups), i + 1)
|
||||
|
||||
return res
|
||||
|
|
|
@ -251,6 +251,8 @@ class TestGroup(common.GESSimpleTimelineTest):
|
|||
self.assertEqual(audio_transition.props.duration, 10)
|
||||
|
||||
def test_moving_group_snapping_from_the_middle(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
snapped_positions = []
|
||||
def snapping_started_cb(timeline, first_element, second_element,
|
||||
position, snapped_positions):
|
||||
|
@ -272,10 +274,88 @@ class TestGroup(common.GESSimpleTimelineTest):
|
|||
group = GES.Container.group(clips[1:3])
|
||||
self.assertIsNotNone(group)
|
||||
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 5),
|
||||
(GES.TestClip, 5, 5),
|
||||
(GES.TestClip, 10, 5),
|
||||
(GES.TestClip, 15, 5),
|
||||
],
|
||||
], groups=[clips[1:3]])
|
||||
|
||||
self.assertEqual(clips[1].props.start, 5)
|
||||
self.assertEqual(clips[2].props.start, 10)
|
||||
clips[2].edit([], 0, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 11)
|
||||
|
||||
self.assertEqual(snapped_positions[0], clips[2].start + clips[2].duration)
|
||||
self.assertEqual(clips[1].props.start, 5)
|
||||
self.assertEqual(clips[2].props.start, 10)
|
||||
self.assertEqual(snapped_positions[0], 5)
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 5),
|
||||
(GES.TestClip, 5, 5),
|
||||
(GES.TestClip, 10, 5),
|
||||
(GES.TestClip, 15, 5),
|
||||
],
|
||||
], groups=[clips[1:3]])
|
||||
|
||||
def test_rippling_with_group(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
for _ in range(4):
|
||||
self.append_clip()
|
||||
|
||||
snapped_positions = []
|
||||
def snapping_started_cb(timeline, first_element, second_element,
|
||||
position, snapped_positions):
|
||||
snapped_positions.append(position)
|
||||
|
||||
self.timeline.props.snapping_distance = 5
|
||||
self.timeline.connect("snapping-started", snapping_started_cb,
|
||||
snapped_positions)
|
||||
|
||||
clips = self.layer.get_clips()
|
||||
self.assertEqual(len(clips), 4)
|
||||
|
||||
group_clips = clips[1:3]
|
||||
GES.Container.group(group_clips)
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
],
|
||||
], groups=[group_clips])
|
||||
|
||||
self.assertFalse(clips[2].edit([], 0, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, 5))
|
||||
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
],
|
||||
], groups=[group_clips])
|
||||
|
||||
# Negative start...
|
||||
self.assertFalse(clips[2].edit([], 1, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, 1))
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
],
|
||||
], groups=[group_clips])
|
||||
|
||||
self.assertTrue(clips[2].edit([], 1, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, 20))
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
],
|
||||
[
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
],
|
||||
], groups=[group_clips])
|
|
@ -35,7 +35,7 @@ Gst.init(None)
|
|||
GES.init()
|
||||
|
||||
|
||||
class TestTimeline(unittest.TestCase):
|
||||
class TestTimeline(common.GESSimpleTimelineTest):
|
||||
|
||||
def test_signals_not_emitted_when_loading(self):
|
||||
mainloop = common.create_main_loop()
|
||||
|
@ -63,13 +63,31 @@ class TestTimeline(unittest.TestCase):
|
|||
self.assertTrue(loaded_called)
|
||||
handle.assert_not_called()
|
||||
|
||||
def test_timeline_duration(self):
|
||||
self.append_clip()
|
||||
self.append_clip()
|
||||
clips = self.layer.get_clips()
|
||||
|
||||
class TestSplitting(common.GESSimpleTimelineTest):
|
||||
def setUp(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super(TestSplitting, self).setUp()
|
||||
self.assertEqual(self.timeline.props.duration, 20)
|
||||
self.layer.remove_clip(clips[1])
|
||||
self.assertEqual(self.timeline.props.duration, 10)
|
||||
|
||||
self.append_clip()
|
||||
self.append_clip()
|
||||
clips = self.layer.get_clips()
|
||||
self.assertEqual(self.timeline.props.duration, 30)
|
||||
|
||||
group = GES.Container.group(clips[1:])
|
||||
self.assertEqual(self.timeline.props.duration, 30)
|
||||
|
||||
group1 = GES.Container.group([])
|
||||
group1.add(group)
|
||||
self.assertEqual(self.timeline.props.duration, 30)
|
||||
|
||||
def test_spliting_with_auto_transition_on_the_left(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
|
||||
self.timeline.props.auto_transition = True
|
||||
clip1 = self.add_clip(0, 0, 100)
|
||||
clip2 = self.add_clip(50, 0, 100)
|
||||
|
@ -117,6 +135,102 @@ class TestEditing(common.GESSimpleTimelineTest):
|
|||
self.assertEqual(len(self.layer.get_clips()), 1)
|
||||
self.assertEqual(len(layer2.get_clips()), 1)
|
||||
|
||||
def activate_snapping(self):
|
||||
self.timeline.set_snapping_distance(5)
|
||||
self.snapped_at = []
|
||||
|
||||
def _snapped_cb(timeline, elem1, elem2, position):
|
||||
self.snapped_at.append(position)
|
||||
Gst.error('%s' % position)
|
||||
|
||||
def _snapped_end_cb(timeline, elem1, elem2, position):
|
||||
if self.snapped_at: # Ignoring first snap end.
|
||||
self.snapped_at.append(Gst.CLOCK_TIME_NONE)
|
||||
Gst.error('%s' % position)
|
||||
|
||||
self.timeline.connect("snapping-started", _snapped_cb)
|
||||
self.timeline.connect("snapping-ended", _snapped_end_cb)
|
||||
|
||||
def test_snap_start_snap_end(self):
|
||||
clip = self.append_clip()
|
||||
self.append_clip()
|
||||
|
||||
self.activate_snapping()
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
|
||||
clip.props.start = 18
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
]
|
||||
])
|
||||
self.assertEqual(self.snapped_at, [20])
|
||||
|
||||
clip.props.start = 30
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
]
|
||||
])
|
||||
self.assertEqual(self.snapped_at, [20, Gst.CLOCK_TIME_NONE])
|
||||
|
||||
clip.props.start = 18
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
]
|
||||
])
|
||||
self.assertEqual(self.snapped_at, [20, Gst.CLOCK_TIME_NONE,
|
||||
Gst.CLOCK_TIME_NONE, 20])
|
||||
clip.props.start = 19
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
]
|
||||
])
|
||||
self.assertEqual(self.snapped_at, [20, Gst.CLOCK_TIME_NONE,
|
||||
Gst.CLOCK_TIME_NONE, 20])
|
||||
|
||||
def test_rippling_snaps(self):
|
||||
self.timeline.props.auto_transition = True
|
||||
self.append_clip()
|
||||
clip = self.append_clip()
|
||||
|
||||
self.activate_snapping()
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
|
||||
clip.edit([], 0, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, 15)
|
||||
self.assertEqual(self.snapped_at, [10])
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
|
||||
clip.edit([], 0, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, 20)
|
||||
self.assertEqual(self.snapped_at, [10, Gst.CLOCK_TIME_NONE])
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
]
|
||||
])
|
||||
|
||||
def test_transition_moves_when_rippling_to_another_layer(self):
|
||||
self.timeline.props.auto_transition = True
|
||||
clip1 = self.add_clip(0, 0, 100)
|
||||
|
@ -160,6 +274,451 @@ class TestEditing(common.GESSimpleTimelineTest):
|
|||
GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, 35 * Gst.SECOND)
|
||||
self.assertEqual(len(self.layer.get_clips()), 4)
|
||||
|
||||
def test_trim_transition(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
|
||||
self.timeline.props.auto_transition = True
|
||||
self.add_clip(0, 0, 10)
|
||||
self.add_clip(5, 0, 10)
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TransitionClip, 5, 5),
|
||||
(GES.TestClip, 5, 10),
|
||||
]
|
||||
])
|
||||
transition = self.layer.get_clips()[1]
|
||||
self.assertTrue(transition.edit([], -1, GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, 7))
|
||||
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TransitionClip, 7, 3),
|
||||
(GES.TestClip, 7, 8),
|
||||
]
|
||||
])
|
||||
|
||||
def test_trim_start(self):
|
||||
clip = self.append_clip()
|
||||
self.assertTrue(clip.edit([], -1, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 10))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
|
||||
self.assertFalse(clip.edit([], -1, GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_NONE, 0))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
|
||||
def test_ripple_end(self):
|
||||
clip = self.append_clip()
|
||||
clip.set_max_duration(20)
|
||||
self.append_clip().set_max_duration(10)
|
||||
self.append_clip().set_max_duration(10)
|
||||
self.print_timeline()
|
||||
self.assertTrue(clip.edit([], -1, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_END, 20))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 20),
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
]
|
||||
])
|
||||
|
||||
self.assertTrue(clip.edit([], -1, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_END, 15))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 15),
|
||||
(GES.TestClip, 15, 10),
|
||||
(GES.TestClip, 25, 10),
|
||||
]
|
||||
])
|
||||
|
||||
def test_move_group_full_overlap(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
|
||||
for _ in range(4):
|
||||
self.append_clip()
|
||||
clips = self.layer.get_clips()
|
||||
|
||||
self.assertTrue(clips[0].ripple(20))
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
(GES.TestClip, 40, 10),
|
||||
(GES.TestClip, 50, 10),
|
||||
]
|
||||
])
|
||||
group = GES.Container.group(clips[1:])
|
||||
self.print_timeline()
|
||||
self.assertFalse(group.edit([], -1, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 0))
|
||||
self.print_timeline()
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
(GES.TestClip, 40, 10),
|
||||
(GES.TestClip, 50, 10),
|
||||
]
|
||||
])
|
||||
|
||||
self.assertFalse(clips[1].edit([], -1, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 0))
|
||||
self.print_timeline()
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
(GES.TestClip, 40, 10),
|
||||
(GES.TestClip, 50, 10),
|
||||
]
|
||||
])
|
||||
|
||||
def test_trim_inside_group(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
|
||||
for _ in range(2):
|
||||
self.append_clip()
|
||||
clips = self.layer.get_clips()
|
||||
group = GES.Container.group(clips)
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
self.assertEqual(group.props.start, 0)
|
||||
self.assertEqual(group.props.duration, 20)
|
||||
|
||||
clips[0].trim(5)
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 5, 5),
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
self.assertEqual(group.props.start, 5)
|
||||
self.assertEqual(group.props.duration, 15)
|
||||
|
||||
def test_trim_end_past_max_duration(self):
|
||||
clip = self.append_clip()
|
||||
max_duration = clip.props.duration
|
||||
clip.set_max_duration(max_duration)
|
||||
self.assertTrue(clip.edit([], -1, GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, 5))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 5, 5),
|
||||
]
|
||||
])
|
||||
|
||||
self.assertFalse(clip.edit([], -1, GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_END, 15))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 5, 5),
|
||||
]
|
||||
])
|
||||
|
||||
|
||||
class TestInvalidOverlaps(common.GESSimpleTimelineTest):
|
||||
|
||||
def test_adding_or_moving(self):
|
||||
clip1 = self.add_clip(start=10, in_point=0, duration=3)
|
||||
self.assertIsNotNone(clip1)
|
||||
|
||||
def check_add_move_clip(start, duration):
|
||||
self.timeline.props.auto_transition = True
|
||||
self.layer.props.auto_transition = True
|
||||
clip2 = GES.TestClip()
|
||||
clip2.props.start = start
|
||||
clip2.props.duration = duration
|
||||
self.assertFalse(self.layer.add_clip(clip2))
|
||||
self.assertEqual(len(self.layer.get_clips()), 1)
|
||||
|
||||
# Add the clip at a different position.
|
||||
clip2.props.start = 25
|
||||
self.assertTrue(self.layer.add_clip(clip2))
|
||||
self.assertEqual(clip2.props.start, 25)
|
||||
|
||||
# Try to move the second clip by editing it.
|
||||
self.assertFalse(clip2.edit([], -1, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, start))
|
||||
self.assertEqual(clip2.props.start, 25)
|
||||
|
||||
# Try to put it in a group and move the group.
|
||||
clip3 = GES.TestClip()
|
||||
clip3.props.start = 20
|
||||
clip3.props.duration = 1
|
||||
self.assertTrue(self.layer.add_clip(clip3))
|
||||
group = GES.Container.group([clip3, clip2])
|
||||
self.assertTrue(group.props.start, 20)
|
||||
self.assertFalse(group.edit([], -1, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, start - 5))
|
||||
self.assertEqual(group.props.start, 20)
|
||||
self.assertEqual(clip3.props.start, 20)
|
||||
self.assertEqual(clip2.props.start, 25)
|
||||
|
||||
for clip in group.ungroup(False):
|
||||
self.assertTrue(self.layer.remove_clip(clip))
|
||||
|
||||
# clip1 contains...
|
||||
check_add_move_clip(start=10, duration=1)
|
||||
check_add_move_clip(start=11, duration=1)
|
||||
check_add_move_clip(start=12, duration=1)
|
||||
|
||||
def test_splitting(self):
|
||||
clip1 = self.add_clip(start=9, in_point=0, duration=3)
|
||||
clip2 = self.add_clip(start=10, in_point=0, duration=4)
|
||||
clip3 = self.add_clip(start=12, in_point=0, duration=3)
|
||||
|
||||
self.assertIsNone(clip1.split(13))
|
||||
self.assertIsNone(clip1.split(8))
|
||||
|
||||
self.assertIsNone(clip3.split(12))
|
||||
self.assertIsNone(clip3.split(15))
|
||||
|
||||
def test_changing_duration(self):
|
||||
clip1 = self.add_clip(start=9, in_point=0, duration=2)
|
||||
clip2 = self.add_clip(start=10, in_point=0, duration=2)
|
||||
|
||||
self.assertFalse(clip1.set_start(10))
|
||||
self.assertFalse(clip1.edit([], -1, GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_END, clip2.props.start + clip2.props.duration))
|
||||
self.assertFalse(clip1.ripple_end(clip2.props.start + clip2.props.duration))
|
||||
self.assertFalse(clip1.roll_end(clip2.props.start + clip2.props.duration))
|
||||
|
||||
# clip2's end edge to the left, to decrease its duration.
|
||||
self.assertFalse(clip2.edit([], -1, GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_END, clip1.props.start + clip1.props.duration))
|
||||
self.assertFalse(clip2.ripple_end(clip1.props.start + clip1.props.duration))
|
||||
self.assertFalse(clip2.roll_end(clip1.props.start + clip1.props.duration))
|
||||
|
||||
# clip2's start edge to the left, to increase its duration.
|
||||
self.assertFalse(clip2.edit([], -1, GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, clip1.props.start))
|
||||
self.assertFalse(clip2.trim(clip1.props.start))
|
||||
|
||||
# clip1's start edge to the right, to decrease its duration.
|
||||
self.assertFalse(clip1.edit([], -1, GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, clip2.props.start))
|
||||
self.assertFalse(clip1.trim(clip2.props.start))
|
||||
|
||||
def test_rippling_backward(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
self.maxDiff = None
|
||||
for i in range(4):
|
||||
self.append_clip()
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
]
|
||||
])
|
||||
|
||||
clip = self.layer.get_clips()[2]
|
||||
self.assertFalse(clip.edit([], -1, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, clip.props.start - 20))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
]
|
||||
])
|
||||
self.assertTrue(clip.edit([], -1, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, clip.props.start + 10))
|
||||
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
(GES.TestClip, 40, 10),
|
||||
]
|
||||
])
|
||||
|
||||
self.assertFalse(clip.edit([], -1, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, clip.props.start -20))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
(GES.TestClip, 40, 10),
|
||||
]
|
||||
])
|
||||
|
||||
def test_rolling(self):
|
||||
clip1 = self.add_clip(start=9, in_point=0, duration=2)
|
||||
clip2 = self.add_clip(start=10, in_point=0, duration=2)
|
||||
clip3 = self.add_clip(start=11, in_point=0, duration=2)
|
||||
|
||||
# Rolling clip1's end -1 would lead to clip3 to overlap 100% with clip2.
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 9, 2),
|
||||
(GES.TestClip, 10, 2),
|
||||
(GES.TestClip, 11, 2)
|
||||
]
|
||||
])
|
||||
self.assertFalse(clip1.edit([], -1, GES.EditMode.EDIT_ROLL, GES.Edge.EDGE_END, clip1.props.start + clip1.props.duration - 1))
|
||||
self.assertFalse(clip1.roll_end(13))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 9, 2),
|
||||
(GES.TestClip, 10, 2),
|
||||
(GES.TestClip, 11, 2)
|
||||
]
|
||||
])
|
||||
|
||||
# Rolling clip3's start +1 would lead to clip1 to overlap 100% with clip2.
|
||||
self.assertFalse(clip3.edit([], -1, GES.EditMode.EDIT_ROLL, GES.Edge.EDGE_START, 12))
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 9, 2),
|
||||
(GES.TestClip, 10, 2),
|
||||
(GES.TestClip, 11, 2)
|
||||
]
|
||||
])
|
||||
|
||||
def test_layers(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
self.maxDiff = None
|
||||
self.timeline.append_layer()
|
||||
|
||||
for i in range(2):
|
||||
self.append_clip()
|
||||
self.append_clip(1)
|
||||
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
],
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
|
||||
clip = self.layer.get_clips()[0]
|
||||
self.assertFalse(clip.edit([], 1, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 0))
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
],
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
|
||||
def test_rippling(self):
|
||||
self.timeline.remove_track(self.timeline.get_tracks()[0])
|
||||
clip1 = self.add_clip(start=9, in_point=0, duration=2)
|
||||
clip2 = self.add_clip(start=10, in_point=0, duration=2)
|
||||
clip3 = self.add_clip(start=11, in_point=0, duration=2)
|
||||
|
||||
# Rippling clip2's start -2 would bring clip3 exactly on top of clip1.
|
||||
self.assertFalse(clip2.edit([], -1, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_NONE, 8))
|
||||
self.assertFalse(clip2.ripple(8))
|
||||
|
||||
# Rippling clip1's end -1 would bring clip3 exactly on top of clip2.
|
||||
self.assertFalse(clip1.edit([], -1, GES.EditMode.EDIT_RIPPLE, GES.Edge.EDGE_END, 8))
|
||||
self.assertFalse(clip1.ripple_end(8))
|
||||
|
||||
def test_move_group_to_layer(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
self.append_clip()
|
||||
self.append_clip()
|
||||
self.append_clip()
|
||||
|
||||
clips = self.layer.get_clips()
|
||||
|
||||
clips[1].props.start += 2
|
||||
group = GES.Container.group(clips[1:])
|
||||
self.assertTrue(clips[1].edit([], 1, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE,
|
||||
group.props.start))
|
||||
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
],
|
||||
[
|
||||
(GES.TestClip, 12, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
]
|
||||
])
|
||||
|
||||
clips[0].props.start = 15
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 15, 10),
|
||||
],
|
||||
[
|
||||
(GES.TestClip, 12, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
]
|
||||
])
|
||||
|
||||
self.assertFalse(clips[1].edit([], 0, GES.EditMode.EDIT_NORMAL,
|
||||
GES.Edge.EDGE_NONE, group.props.start))
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 15, 10),
|
||||
],
|
||||
[
|
||||
(GES.TestClip, 12, 10),
|
||||
(GES.TestClip, 20, 10),
|
||||
]
|
||||
])
|
||||
|
||||
def test_move_group_with_overlaping_clips(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
self.append_clip()
|
||||
self.append_clip()
|
||||
self.append_clip()
|
||||
|
||||
self.timeline.props.auto_transition = True
|
||||
clips = self.layer.get_clips()
|
||||
|
||||
clips[1].props.start += 5
|
||||
group = GES.Container.group(clips[1:])
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 15, 10),
|
||||
(GES.TransitionClip, 20, 5),
|
||||
(GES.TestClip, 20, 10),
|
||||
]
|
||||
])
|
||||
|
||||
clips[0].props.start = 30
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 15, 10),
|
||||
(GES.TransitionClip, 20, 5),
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
]
|
||||
])
|
||||
|
||||
# the 3 clips would overlap
|
||||
self.assertFalse(clips[1].edit([], 0, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 25))
|
||||
self.assertTimelineTopology([
|
||||
[
|
||||
(GES.TestClip, 15, 10),
|
||||
(GES.TransitionClip, 20, 5),
|
||||
(GES.TestClip, 20, 10),
|
||||
(GES.TestClip, 30, 10),
|
||||
]
|
||||
])
|
||||
|
||||
|
||||
class TestSnapping(common.GESSimpleTimelineTest):
|
||||
|
||||
|
@ -180,14 +739,77 @@ class TestSnapping(common.GESSimpleTimelineTest):
|
|||
clip2.props.start - 1)
|
||||
self.assertEqual(clip2.props.start, split_position)
|
||||
|
||||
def test_trim_snapps_inside_group(self):
|
||||
self.track_types = [GES.TrackType.AUDIO]
|
||||
super().setUp()
|
||||
|
||||
self.timeline.props.auto_transition = True
|
||||
self.timeline.set_snapping_distance(5)
|
||||
|
||||
snaps = []
|
||||
def snapping_started_cb(timeline, element1, element2, dist, self):
|
||||
snaps.append(set([element1, element2]))
|
||||
|
||||
self.timeline.connect('snapping-started', snapping_started_cb, self)
|
||||
clip = self.append_clip()
|
||||
clip1 = self.append_clip()
|
||||
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
|
||||
clip1.edit([], self.layer.get_priority(), GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, 15)
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 10, 10),
|
||||
]
|
||||
])
|
||||
self.assertEqual(snaps[0], set([clip.get_children(False)[0], clip1.get_children(False)[0]]))
|
||||
|
||||
clip1.edit([], self.layer.get_priority(), GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, 16)
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 0, 10),
|
||||
(GES.TestClip, 16, 4),
|
||||
]
|
||||
])
|
||||
|
||||
def test_trim_no_snapping_on_same_clip(self):
|
||||
self.timeline.props.auto_transition = True
|
||||
self.timeline.set_snapping_distance(1)
|
||||
|
||||
not_called = []
|
||||
def snapping_started_cb(timeline, element1, element2, dist, self):
|
||||
not_called.append("No snapping should happen")
|
||||
|
||||
self.timeline.connect('snapping-started', snapping_started_cb, self)
|
||||
clip = self.append_clip()
|
||||
clip.edit([], self.layer.get_priority(), GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, 5)
|
||||
self.assertEqual(not_called, [])
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 5, 5),
|
||||
]
|
||||
])
|
||||
|
||||
clip.edit([], self.layer.get_priority(), GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, 4)
|
||||
self.assertEqual(not_called, [])
|
||||
self.assertTimelineTopology([
|
||||
[ # Unique layer
|
||||
(GES.TestClip, 4, 6),
|
||||
]
|
||||
])
|
||||
|
||||
def test_no_snapping_on_split(self):
|
||||
self.timeline.props.auto_transition = True
|
||||
self.timeline.set_snapping_distance(1)
|
||||
|
||||
not_called = []
|
||||
def snapping_started_cb(timeline, element1, element2, dist, self):
|
||||
Gst.error("Here %s %s" % (Gst.TIME_ARGS(element1.props.start + element1.props.duration),
|
||||
Gst.TIME_ARGS(element2.props.start)))
|
||||
not_called.append("No snapping should happen")
|
||||
|
||||
self.timeline.connect('snapping-started', snapping_started_cb, self)
|
||||
|
@ -296,9 +918,9 @@ class TestTransitions(common.GESSimpleTimelineTest):
|
|||
self.assertLess(clip1.props.start + clip1.props.duration, clip2.props.start + clip2.props.duration)
|
||||
self.assertEqual(len(clips), 3)
|
||||
|
||||
# Even though 3 clips overlap 1 transition will be created
|
||||
# 3 clips would be overlapping, 1 of them wasn't added!
|
||||
clips = layers[1].get_clips()
|
||||
self.assertEqual(len(clips), 4)
|
||||
self.assertEqual(len(clips), 3)
|
||||
|
||||
|
||||
class TestPriorities(common.GESSimpleTimelineTest):
|
||||
|
|
Loading…
Reference in a new issue