diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index 6741cd25a2..fa6cc949b6 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -125,9 +125,12 @@ struct _MoveContext /* Max priority of the objects currently in toplevel_containers */ guint max_layer_prio; - /* Never trim so duration would becomes < 0 */ + /* Never trim so duration would become < 0 */ guint64 max_trim_pos; + /* Never trim so inpoint + duration would change */ + guint64 min_trim_pos; + /* fields to force/avoid new context */ /* Set to %TRUE when the track is doing updates of track element * properties so we don't end up always needing new move context */ @@ -1328,6 +1331,7 @@ ges_move_context_set_objects (GESTimeline * timeline, GESTrackElement * obj, case GES_EDGE_START: /* set it properly in the context of "trimming" */ mv_ctx->max_trim_pos = 0; + mv_ctx->min_trim_pos = 0; start = _START (obj); if (g_sequence_iter_is_begin (trackelement_iter)) @@ -1344,10 +1348,13 @@ ges_move_context_set_objects (GESTimeline * timeline, GESTrackElement * obj, if (tmpend <= start) { mv_ctx->max_trim_pos = MAX (mv_ctx->max_trim_pos, _START (tmptrackelement)); + mv_ctx->min_trim_pos = MAX (mv_ctx->min_trim_pos, + _START (tmptrackelement) - _INPOINT (tmptrackelement)); mv_ctx->moving_trackelements = g_list_prepend (mv_ctx->moving_trackelements, tmptrackelement); } + if (g_sequence_iter_is_begin (iter)) break; } @@ -1547,8 +1554,15 @@ ges_timeline_trim_object_simple (GESTimeline * timeline, /* Calculate new values */ position = MIN (position, start + duration); - inpoint = inpoint + position > start ? inpoint + position - start : 0; + if (inpoint + position < start) { + GST_INFO_OBJECT (timeline, "Track element %s inpoint would be negative," + " not trimming", GES_TIMELINE_ELEMENT_NAME (track_element)); + gst_object_unref (toplevel); + return FALSE; + } + + inpoint = inpoint + position - start; real_dur = _END (element) - position; duration = CLAMP (real_dur, 0, max_duration > inpoint ? max_duration - inpoint : G_MAXUINT64); @@ -1772,7 +1786,8 @@ timeline_roll_object (GESTimeline * timeline, GESTrackElement * obj, case GES_EDGE_START: /* Avoid negative durations */ - if (position < mv_ctx->max_trim_pos || position > end) + if (position < mv_ctx->max_trim_pos || position > end || + position < mv_ctx->min_trim_pos) goto error; cur = g_hash_table_lookup (timeline->priv->by_start, obj); @@ -1783,6 +1798,14 @@ timeline_roll_object (GESTimeline * timeline, GESTrackElement * obj, ret &= ges_timeline_trim_object_simple (timeline, GES_TIMELINE_ELEMENT (obj), layers, GES_EDGE_START, position, FALSE); + if (!ret) { + GST_INFO_OBJECT (timeline, "Could not trim %s", + GES_TIMELINE_ELEMENT_NAME (obj)); + + return FALSE; + } + + /* In the case we reached max_duration we just make sure to roll * everything to the real new position */ position = _START (obj); diff --git a/tests/check/ges/group.c b/tests/check/ges/group.c index a31ed365b1..3526d024b6 100644 --- a/tests/check/ges/group.c +++ b/tests/check/ges/group.c @@ -64,6 +64,7 @@ GST_START_TEST (test_move_group) clips = g_list_prepend (clips, clip2); group = GES_GROUP (ges_container_group (clips)); g_list_free (clips); + ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2); fail_unless (GES_IS_GROUP (group)); ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2); @@ -111,6 +112,7 @@ GST_START_TEST (test_move_group) CHECK_OBJECT_PROPS (clip1, 20, 0, 10); CHECK_OBJECT_PROPS (clip2, 60, 0, 60); CHECK_OBJECT_PROPS (group, 10, 0, 110); + ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2); /* * 0 10------------Group1---------------110 @@ -162,6 +164,7 @@ GST_START_TEST (test_move_group) 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 20---Group1---------------110 @@ -196,23 +199,26 @@ GST_START_TEST (test_move_group) CHECK_OBJECT_PROPS (clip1, 25, 10, 5); CHECK_OBJECT_PROPS (clip2, 60, 0, 50); CHECK_OBJECT_PROPS (group, 25, 0, 85); + ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2); /* - * 0 10------------Group1---------------110 - * |------ | - * layer: |clip | | - * |-----15 | - * |----------------------------------| - * 0----------------- 0-----------| - * layer1: | clip1 | | clip2 | - * |-----------------30 60----------| - * |----------------------------------| + * 0 10------------Group1------------------110 + * |------ | + * layer: |clip | | + * |-----15 | + * |-------------------------------------| + * | 10------ 0------------| + * layer1: | | clip1 | | clip2 | + * | 25------30 60----------| + * | |--------------------------| + * |-------------------------------------| */ ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 10); CHECK_OBJECT_PROPS (clip, 10, 0, 5); - CHECK_OBJECT_PROPS (clip1, 10, 0, 20); + CHECK_OBJECT_PROPS (clip1, 25, 10, 5); 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 @@ -220,16 +226,17 @@ GST_START_TEST (test_move_group) * layer: 15 | | * |clip | | * - |--------------------------| - * 15------ 0------------| + * 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, 15, 5); + CHECK_OBJECT_PROPS (clip1, 25, 10, 5); CHECK_OBJECT_PROPS (clip2, 60, 0, 50); CHECK_OBJECT_PROPS (group, 25, 0, 85); + ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2); /* * 0 25---Group1--30 @@ -244,7 +251,7 @@ GST_START_TEST (test_move_group) */ ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (group), 10); CHECK_OBJECT_PROPS (clip, 15, 5, 0); - CHECK_OBJECT_PROPS (clip1, 25, 15, 5); + CHECK_OBJECT_PROPS (clip1, 25, 10, 5); CHECK_OBJECT_PROPS (clip2, 60, 0, 0); CHECK_OBJECT_PROPS (group, 25, 0, 5); @@ -254,16 +261,17 @@ GST_START_TEST (test_move_group) * layer: 15 | | * |clip | | * - |--------------------------| - * 15-------------------------| + * 10-------------------------| * layer1: | clip1 | clip2 | * 25--------------60----------| * |--------------------------| */ ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (group), 100); CHECK_OBJECT_PROPS (clip, 15, 5, 0); - CHECK_OBJECT_PROPS (clip1, 25, 15, 100); + 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); /* * 0 20---Group1---------------120 @@ -271,14 +279,14 @@ GST_START_TEST (test_move_group) * layer: 15 | | * |clip| | * - |--------------------------| - * 15-------------------------| + * 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, 15, 100); + CHECK_OBJECT_PROPS (clip1, 20, 10, 100); CHECK_OBJECT_PROPS (clip2, 55, 0, 65); CHECK_OBJECT_PROPS (group, 20, 0, 100); @@ -295,7 +303,7 @@ GST_START_TEST (test_move_group) */ ges_timeline_element_trim (GES_TIMELINE_ELEMENT (group), 10); CHECK_OBJECT_PROPS (clip, 10, 0, 5); - CHECK_OBJECT_PROPS (clip1, 10, 5, 110); + CHECK_OBJECT_PROPS (clip1, 10, 0, 110); CHECK_OBJECT_PROPS (clip2, 55, 0, 65); CHECK_OBJECT_PROPS (group, 10, 0, 110); diff --git a/tests/check/ges/timelineedition.c b/tests/check/ges/timelineedition.c index e2ff0ab715..8d74bb268e 100644 --- a/tests/check/ges/timelineedition.c +++ b/tests/check/ges/timelineedition.c @@ -216,19 +216,17 @@ GST_START_TEST (test_basic_timeline_edition) * | clip1 || clip || clip2 | * time 20------ 25 ------ 62 ---------122 */ - fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM, - GES_EDGE_START, 40) == TRUE); - fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_ROLL, - GES_EDGE_START, 25) == TRUE); - CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); - CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); + fail_if (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_ROLL, + GES_EDGE_START, 25)); + CHECK_OBJECT_PROPS (trackelement, 40, 3, 22); + CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /* Make sure that not doing anything when not able to roll */ fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, 65) == TRUE, 0); - CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); - CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); + CHECK_OBJECT_PROPS (trackelement, 40, 3, 22); + CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); gst_object_unref (timeline); @@ -859,6 +857,7 @@ GST_START_TEST (test_timeline_edition_mode) * 25------62 * */ + ges_timeline_element_set_inpoint (GES_TIMELINE_ELEMENT (clip), 15); fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, 25) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); @@ -868,6 +867,8 @@ GST_START_TEST (test_timeline_edition_mode) /* Make sure that not doing anything when not able to roll */ fail_if (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_START, 65)); + fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL, + GES_EDGE_END, 65)); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);