ges: Handle trimming in groups

This was broken, clips where moving all around, make it behave properly.
This commit is contained in:
Thibault Saunier 2013-09-07 02:11:23 -04:00
parent c74aee5fdc
commit c4c26f8748
6 changed files with 109 additions and 23 deletions

View file

@ -1395,6 +1395,8 @@ _trim (GESTimelineElement * element, GstClockTime start)
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);
}

View file

@ -315,26 +315,46 @@ _child_start_changed_cb (GESTimelineElement * child,
GParamSpec * arg G_GNUC_UNUSED, GESContainer * container)
{
ChildMapping *map;
GstClockTime start;
GESContainerPrivate *priv = container->priv;
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
if (container->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
return;
map = g_hash_table_lookup (priv->mappings, child);
g_assert (map);
if (container->children_control_mode == GES_CHILDREN_UPDATE_OFFSETS) {
map->start_offset = _START (container) - _START (child);
switch (container->children_control_mode) {
case GES_CHILDREN_IGNORE_NOTIFIES:
return;
case GES_CHILDREN_UPDATE_ALL_VALUES:
_ges_container_sort_children (container);
start = container->children ?
_START (container->children->data) : _START (container);
return;
if (start != _START (container)) {
_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)));
g_object_notify (G_OBJECT (container), "start");
}
/* Falltrough! */
case GES_CHILDREN_UPDATE_OFFSETS:
map->start_offset = _START (container) - _START (child);
break;
case GES_CHILDREN_UPDATE:
/* We update all the children calling our set_start method */
container->initiated_move = child;
_set_start0 (element, _START (child) + map->start_offset);
container->initiated_move = NULL;
break;
default:
break;
}
/* We update all the children calling our set_start method */
container->initiated_move = child;
_set_start0 (element, _START (child) + map->start_offset);
container->initiated_move = NULL;
}
static void
@ -370,6 +390,8 @@ _child_duration_changed_cb (GESTimelineElement * child,
{
ChildMapping *map;
GList *tmp;
GstClockTime end = 0;
GESContainerPrivate *priv = container->priv;
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
@ -379,16 +401,32 @@ _child_duration_changed_cb (GESTimelineElement * child,
map = g_hash_table_lookup (priv->mappings, child);
g_assert (map);
if (container->children_control_mode == GES_CHILDREN_UPDATE_OFFSETS) {
map->inpoint_offset = _START (container) - _START (child);
switch (container->children_control_mode) {
case GES_CHILDREN_IGNORE_NOTIFIES:
break;
case GES_CHILDREN_UPDATE_ALL_VALUES:
_ges_container_sort_children_by_end (container);
return;
for (tmp = container->children; tmp; tmp = tmp->next)
end = MAX (end, _END (tmp->data));
if (end != _END (container)) {
_DURATION (container) = end - _START (container);
g_object_notify (G_OBJECT (container), "duration");
}
/* Falltrough */
case GES_CHILDREN_UPDATE_OFFSETS:
map->inpoint_offset = _START (container) - _START (child);
break;
case GES_CHILDREN_UPDATE:
/* We update all the children calling our set_duration method */
container->initiated_move = child;
_set_duration0 (element, _DURATION (child) + map->duration_offset);
container->initiated_move = NULL;
break;
default:
break;
}
/* We update all the children calling our set_duration method */
container->initiated_move = child;
_set_duration0 (element, _DURATION (child) + map->duration_offset);
container->initiated_move = NULL;
}
/****************************************************

View file

@ -44,6 +44,7 @@ typedef enum
GES_CHILDREN_UPDATE,
GES_CHILDREN_IGNORE_NOTIFIES,
GES_CHILDREN_UPDATE_OFFSETS,
GES_CHILDREN_UPDATE_ALL_VALUES,
GES_CHILDREN_LAST
} GESChildrenControlMode;

View file

@ -185,7 +185,7 @@ static gboolean
_trim (GESTimelineElement * group, GstClockTime start)
{
GList *tmp;
GstClockTime last_child_end = 0;
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));
@ -201,10 +201,12 @@ _trim (GESTimelineElement * group, GstClockTime start)
GESTimelineElement *child = tmp->data;
if (expending) {
/* If the start if bigger, we do not touch it (in case we are expending)
*/
if (_START (child) > _START (group))
/* 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))

View file

@ -1363,6 +1363,28 @@ ges_timeline_trim_object_simple (GESTimeline * timeline,
switch (edge) {
case GES_EDGE_START:
{
GESTimelineElement *toplevel;
GESChildrenControlMode old_mode;
toplevel = ges_timeline_element_get_toplevel_parent (element);
if (position < _START (toplevel) && _START (toplevel) < _START (element)) {
GST_DEBUG_OBJECT (toplevel, "Not trimming %p as not at begining "
"of the container", element);
return FALSE;
}
old_mode = GES_CONTAINER (toplevel)->children_control_mode;
if (GES_IS_GROUP (toplevel) && old_mode == GES_CHILDREN_UPDATE) {
GST_DEBUG_OBJECT (toplevel, "Setting children udpate mode to"
" UPDDATE_ALL_VALUES so we can trim without moving the contained");
/* The container will update its values itself according to new
* values of the children */
GES_CONTAINER (toplevel)->children_control_mode =
GES_CHILDREN_UPDATE_ALL_VALUES;
}
inpoint = _INPOINT (track_element);
duration = _DURATION (track_element);
@ -1393,7 +1415,12 @@ ges_timeline_trim_object_simple (GESTimeline * timeline,
timeline->priv->needs_transitions_update = TRUE;
_set_duration0 (GES_TIMELINE_ELEMENT (track_element), duration);
if (GES_IS_GROUP (toplevel))
GES_CONTAINER (toplevel)->children_control_mode = old_mode;
gst_object_unref (toplevel);
break;
}
case GES_EDGE_END:
{
cur = g_hash_table_lookup (timeline->priv->by_end, track_element);

View file

@ -1150,6 +1150,22 @@ GST_START_TEST (test_groups)
check_layer (c4, 1);
check_layer (c5, 2);
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);
CHECK_OBJECT_PROPS (c1, 10, 0, 10);
CHECK_OBJECT_PROPS (c2, 20, 0, 20);
CHECK_OBJECT_PROPS (c3, 40, 10, 10);
CHECK_OBJECT_PROPS (c4, 40, 0, 20);
CHECK_OBJECT_PROPS (c5, 50, 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);
gst_object_unref (timeline);
gst_object_unref (asset);
}