mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
ges: Handle trimming in groups
This was broken, clips where moving all around, make it behave properly.
This commit is contained in:
parent
c74aee5fdc
commit
c4c26f8748
6 changed files with 109 additions and 23 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue