gstreamer/subprojects/gst-editing-services/ges/ges-timeline-tree.c

2585 lines
79 KiB
C
Raw Normal View History

/* GStreamer Editing Services
* Copyright (C) 2019 Igalia S.L
* Author: 2019 Thibault Saunier <tsaunier@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ges-timeline-tree.h"
#include "ges-internal.h"
#include "ges-marker-list.h"
GST_DEBUG_CATEGORY_STATIC (tree_debug);
#undef GST_CAT_DEFAULT
#define GST_CAT_DEFAULT tree_debug
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
#define ELEMENT_EDGE_VALUE(e, edge) ((edge == GES_EDGE_END) ? _END (e) : _START (e))
typedef struct _SnappedPosition
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* the element that was being snapped */
GESTrackElement *element;
/* the position of element, and whether it is a negative position */
gboolean negative;
GstClockTime position;
/* the element that was snapped to */
GESTrackElement *snapped_to;
/* the snapped positioned */
GstClockTime snapped;
/* the distance below which two elements can snap */
GstClockTime distance;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
} SnappedPosition;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
typedef enum
{
EDIT_MOVE,
EDIT_TRIM_START,
EDIT_TRIM_END,
EDIT_TRIM_INPOINT_ONLY,
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
} ElementEditMode;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
typedef struct _EditData
{
/* offsets to use */
GstClockTime offset;
gint64 layer_offset;
/* actual values */
GstClockTime duration;
GstClockTime start;
GstClockTime inpoint;
guint32 layer_priority;
/* mode */
ElementEditMode mode;
} EditData;
typedef struct _PositionData
{
guint32 layer_priority;
GstClockTime start;
GstClockTime end;
} PositionData;
/* *INDENT-OFF* */
struct _TreeIterationData
{
GNode *root;
gboolean res;
/* an error to set */
GError **error;
/* The element we are visiting */
GESTimelineElement *element;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* the position data of the visited element */
PositionData *pos_data;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* All the TrackElement currently moving: owned by data */
GHashTable *moving;
/* Elements overlaping on the start/end of @element */
GESTimelineElement *overlaping_on_start;
GESTimelineElement *overlaping_on_end;
GstClockTime overlap_start_final_time;
GstClockTime overlap_end_first_time;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
SnappedPosition *snap;
GList *sources;
GstClockTime position;
GstClockTime negative;
GESEdge edge;
GList *neighbours;
} tree_iteration_data_init = {
.root = NULL,
.res = TRUE,
.element = NULL,
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
.pos_data = NULL,
.moving = NULL,
.overlaping_on_start = NULL,
.overlaping_on_end = NULL,
.overlap_start_final_time = GST_CLOCK_TIME_NONE,
.overlap_end_first_time = GST_CLOCK_TIME_NONE,
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
.snap = NULL,
.sources = NULL,
.position = GST_CLOCK_TIME_NONE,
.negative = FALSE,
.edge = GES_EDGE_NONE,
.neighbours = NULL,
};
/* *INDENT-ON* */
typedef struct _TreeIterationData TreeIterationData;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
static EditData *
new_edit_data (ElementEditMode mode, GstClockTimeDiff offset,
gint64 layer_offset)
{
EditData *data = g_new (EditData, 1);
data->start = GST_CLOCK_TIME_NONE;
data->duration = GST_CLOCK_TIME_NONE;
data->inpoint = GST_CLOCK_TIME_NONE;
data->layer_priority = GES_TIMELINE_ELEMENT_NO_LAYER_PRIORITY;
data->mode = mode;
data->offset = offset;
data->layer_offset = layer_offset;
return data;
}
static SnappedPosition *
new_snapped_position (GstClockTime distance)
{
SnappedPosition *snap;
if (distance == 0)
return NULL;
snap = g_new0 (SnappedPosition, 1);
snap->position = GST_CLOCK_TIME_NONE;
snap->snapped = GST_CLOCK_TIME_NONE;
snap->distance = distance;
return snap;
}
static GHashTable *
new_edit_table ()
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return g_hash_table_new_full (NULL, NULL, NULL, g_free);
}
static GHashTable *
new_position_table ()
{
return g_hash_table_new_full (NULL, NULL, NULL, g_free);
}
void
timeline_tree_init_debug (void)
{
GST_DEBUG_CATEGORY_INIT (tree_debug, "gestree",
GST_DEBUG_FG_YELLOW, "timeline tree");
}
static gboolean
print_node (GNode * node, gpointer unused_data)
{
if (G_NODE_IS_ROOT (node)) {
gst_print ("Timeline: %p\n", node->data);
return FALSE;
}
gst_print ("%*c- %" GES_FORMAT " - layer %" G_GINT32_FORMAT "\n",
2 * g_node_depth (node), ' ', GES_ARGS (node->data),
ges_timeline_element_get_layer_priority (node->data));
return FALSE;
}
void
timeline_tree_debug (GNode * root)
{
g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
(GNodeTraverseFunc) print_node, NULL);
}
static GNode *
find_node (GNode * root, gpointer element)
{
return g_node_find (root, G_IN_ORDER, G_TRAVERSE_ALL, element);
}
static void
timeline_element_parent_cb (GESTimelineElement * child, GParamSpec * arg
G_GNUC_UNUSED, GNode * root)
{
GNode *new_parent_node = NULL, *node = find_node (root, child);
if (child->parent)
new_parent_node = find_node (root, child->parent);
if (!new_parent_node)
new_parent_node = root;
g_node_unlink (node);
g_node_prepend (new_parent_node, node);
}
void
timeline_tree_track_element (GNode * root, GESTimelineElement * element)
{
GNode *node;
GNode *parent;
GESTimelineElement *toplevel;
if (find_node (root, element)) {
return;
}
g_signal_connect (element, "notify::parent",
G_CALLBACK (timeline_element_parent_cb), root);
toplevel = ges_timeline_element_peak_toplevel (element);
if (toplevel == element) {
GST_DEBUG ("Tracking toplevel element %" GES_FORMAT, GES_ARGS (element));
node = g_node_prepend_data (root, element);
} else {
parent = find_node (root, element->parent);
GST_LOG ("%" GES_FORMAT "parent is %" GES_FORMAT, GES_ARGS (element),
GES_ARGS (element->parent));
g_assert (parent);
node = g_node_prepend_data (parent, element);
}
if (GES_IS_CONTAINER (element)) {
GList *tmp;
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
GNode *child_node = find_node (root, tmp->data);
if (child_node) {
g_node_unlink (child_node);
g_node_prepend (node, child_node);
} else {
timeline_tree_track_element (root, tmp->data);
}
}
}
timeline_update_duration (root->data);
}
void
timeline_tree_stop_tracking_element (GNode * root, GESTimelineElement * element)
{
GNode *node = find_node (root, element);
node = find_node (root, element);
/* Move children to the parent */
while (node->children) {
GNode *tmp = node->children;
g_node_unlink (tmp);
g_node_prepend (node->parent, tmp);
}
g_assert (node);
GST_DEBUG ("Stop tracking %" GES_FORMAT, GES_ARGS (element));
g_signal_handlers_disconnect_by_func (element, timeline_element_parent_cb,
root);
g_node_destroy (node);
timeline_update_duration (root->data);
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/****************************************************
* GstClockTime with over/underflow checking *
****************************************************/
static GstClockTime
_clock_time_plus (GstClockTime time, GstClockTime add)
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!GST_CLOCK_TIME_IS_VALID (time) || !GST_CLOCK_TIME_IS_VALID (add))
return GST_CLOCK_TIME_NONE;
if (time >= (G_MAXUINT64 - add)) {
GST_ERROR ("The time %" G_GUINT64_FORMAT " would overflow when "
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
"adding %" G_GUINT64_FORMAT, time, add);
return GST_CLOCK_TIME_NONE;
}
return time + add;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
static GstClockTime
_clock_time_minus (GstClockTime time, GstClockTime minus, gboolean * negative)
{
if (negative)
*negative = FALSE;
if (!GST_CLOCK_TIME_IS_VALID (time) || !GST_CLOCK_TIME_IS_VALID (minus))
return GST_CLOCK_TIME_NONE;
if (time < minus) {
if (negative) {
*negative = TRUE;
return minus - time;
}
/* otherwise don't allow negative */
GST_INFO ("The time %" G_GUINT64_FORMAT " would underflow when "
"subtracting %" G_GUINT64_FORMAT, time, minus);
return GST_CLOCK_TIME_NONE;
}
return time - minus;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
static GstClockTime
_clock_time_minus_diff (GstClockTime time, GstClockTimeDiff diff,
gboolean * negative)
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (negative)
*negative = FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!GST_CLOCK_TIME_IS_VALID (time))
return GST_CLOCK_TIME_NONE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (diff < 0)
return _clock_time_plus (time, -diff);
else
return _clock_time_minus (time, diff, negative);
}
static GstClockTime
_abs_clock_time_distance (GstClockTime time1, GstClockTime time2)
{
if (!GST_CLOCK_TIME_IS_VALID (time1) || !GST_CLOCK_TIME_IS_VALID (time2))
return GST_CLOCK_TIME_NONE;
if (time1 > time2)
return time1 - time2;
else
return time2 - time1;
}
static void
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
get_start_end_from_offset (GESTimelineElement * element, ElementEditMode mode,
GstClockTimeDiff offset, GstClockTime * start, gboolean * negative_start,
GstClockTime * end, gboolean * negative_end)
{
GstClockTime current_end =
_clock_time_plus (element->start, element->duration);
GstClockTime new_start = GST_CLOCK_TIME_NONE, new_end = GST_CLOCK_TIME_NONE;
switch (mode) {
case EDIT_MOVE:
new_start =
_clock_time_minus_diff (element->start, offset, negative_start);
new_end = _clock_time_minus_diff (current_end, offset, negative_end);
break;
case EDIT_TRIM_START:
new_start =
_clock_time_minus_diff (element->start, offset, negative_start);
new_end = current_end;
if (negative_end)
*negative_end = FALSE;
break;
case EDIT_TRIM_END:
new_start = element->start;
if (negative_start)
*negative_start = FALSE;
new_end = _clock_time_minus_diff (current_end, offset, negative_end);
break;
case EDIT_TRIM_INPOINT_ONLY:
GST_ERROR_OBJECT (element, "Trim in-point only not handled");
break;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
}
if (start)
*start = new_start;
if (end)
*end = new_end;
}
/****************************************************
* Snapping *
****************************************************/
static void
snap_to_marker (GESTrackElement * element, GstClockTime position,
gboolean negative, GstClockTime marker_timestamp,
GESTrackElement * marker_parent, SnappedPosition * snap)
{
GstClockTime distance;
if (negative)
distance = _clock_time_plus (position, marker_timestamp);
else
distance = _abs_clock_time_distance (position, marker_timestamp);
if (GST_CLOCK_TIME_IS_VALID (distance) && distance <= snap->distance) {
snap->negative = negative;
snap->position = position;
snap->distance = distance;
snap->snapped = marker_timestamp;
snap->element = element;
snap->snapped_to = marker_parent;
}
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
static void
snap_to_edge (GESTrackElement * element, GstClockTime position,
gboolean negative, GESTrackElement * snap_to, GESEdge edge,
SnappedPosition * snap)
{
GstClockTime edge_pos = ELEMENT_EDGE_VALUE (snap_to, edge);
GstClockTime distance;
if (negative)
distance = _clock_time_plus (position, edge_pos);
else
distance = _abs_clock_time_distance (position, edge_pos);
if (GST_CLOCK_TIME_IS_VALID (distance) && distance <= snap->distance) {
GESTimelineElement *parent = GES_TIMELINE_ELEMENT_PARENT (element);
GESTimelineElement *snap_parent = GES_TIMELINE_ELEMENT_PARENT (snap_to);
GST_LOG_OBJECT (element, "%s (under %s) snapped with %" GES_FORMAT
"(under %s) from position %s%" GST_TIME_FORMAT " to %"
GST_TIME_FORMAT, GES_TIMELINE_ELEMENT_NAME (element),
parent ? parent->name : NULL, GES_ARGS (snap_to),
snap_parent ? snap_parent->name : NULL, negative ? "-" : "",
GST_TIME_ARGS (position), GST_TIME_ARGS (edge_pos));
snap->negative = negative;
snap->position = position;
snap->distance = distance;
snap->snapped = edge_pos;
snap->element = element;
snap->snapped_to = snap_to;
}
}
static void
find_marker_snap (const GESMetaContainer * container, const gchar * key,
const GValue * value, TreeIterationData * data)
{
GESTrackElement *marker_parent, *moving;
GESClip *parent_clip;
GstClockTime timestamp;
GESMarkerList *marker_list;
GESMarker *marker;
GESMarkerFlags flags;
GObject *obj;
if (!G_VALUE_HOLDS_OBJECT (value))
return;
obj = g_value_get_object (value);
if (!GES_IS_MARKER_LIST (obj))
return;
marker_list = GES_MARKER_LIST (obj);
g_object_get (marker_list, "flags", &flags, NULL);
if (!(flags & GES_MARKER_FLAG_SNAPPABLE))
return;
marker_parent = GES_TRACK_ELEMENT ((gpointer) container);
moving = GES_TRACK_ELEMENT (data->element);
parent_clip = (GESClip *) GES_TIMELINE_ELEMENT_PARENT (marker_parent);
/* Translate current position into the target clip's time domain */
timestamp =
ges_clip_get_internal_time_from_timeline_time (parent_clip, marker_parent,
data->position, NULL);
marker = ges_marker_list_get_closest (marker_list, timestamp);
if (marker == NULL)
return;
/* Make timestamp timeline-relative again */
g_object_get (marker, "position", &timestamp, NULL);
timestamp =
ges_clip_get_timeline_time_from_internal_time (parent_clip, marker_parent,
timestamp, NULL);
snap_to_marker (moving, data->position, data->negative, timestamp,
marker_parent, data->snap);
g_object_unref (marker);
}
static gboolean
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
find_snap (GNode * node, TreeIterationData * data)
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GESTimelineElement *element = node->data;
GESTrackElement *track_el, *moving;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* Only snap to sources */
/* Maybe we should allow snapping to anything that isn't an
* auto-transition? */
if (!GES_IS_SOURCE (element))
return FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* don't snap to anything we are moving */
if (g_hash_table_contains (data->moving, element))
return FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
track_el = GES_TRACK_ELEMENT (element);
moving = GES_TRACK_ELEMENT (data->element);
snap_to_edge (moving, data->position, data->negative, track_el,
GES_EDGE_END, data->snap);
snap_to_edge (moving, data->position, data->negative, track_el,
GES_EDGE_START, data->snap);
ges_meta_container_foreach (GES_META_CONTAINER (element),
(GESMetaForeachFunc) find_marker_snap, data);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
static void
find_snap_for_element (GESTrackElement * element, GstClockTime position,
gboolean negative, TreeIterationData * data)
{
data->element = GES_TIMELINE_ELEMENT (element);
data->position = position;
data->negative = negative;
g_node_traverse (data->root, G_IN_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) find_snap, data);
}
/* find up to one source at the edge */
static gboolean
find_source_at_edge (GNode * node, TreeIterationData * data)
{
GESEdge edge = data->edge;
GESTimelineElement *element = node->data;
GESTimelineElement *ancestor = data->element;
if (!GES_IS_SOURCE (element))
return FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (ELEMENT_EDGE_VALUE (element, edge) == ELEMENT_EDGE_VALUE (ancestor, edge)) {
data->sources = g_list_append (data->sources, element);
return TRUE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
static gboolean
find_sources (GNode * node, TreeIterationData * data)
{
GESTimelineElement *element = node->data;
if (GES_IS_SOURCE (element))
data->sources = g_list_append (data->sources, element);
return FALSE;
}
/* Tries to find a new snap to the start or end edge of one of the
* descendant sources of @element, depending on @mode, and updates @offset
* by the size of the jump.
* Any elements in @moving are not snapped to.
*/
static gboolean
timeline_tree_snap (GNode * root, GESTimelineElement * element,
ElementEditMode mode, GstClockTimeDiff * offset, GHashTable * moving,
SnappedPosition * snap)
{
gboolean ret = FALSE;
TreeIterationData data = tree_iteration_data_init;
GList *tmp;
GNode *node;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!snap)
return TRUE;
/* get the sources we can snap to */
data.root = root;
data.moving = moving;
data.sources = NULL;
data.snap = snap;
data.element = element;
node = find_node (root, element);
if (!node) {
GST_ERROR_OBJECT (element, "Not being tracked");
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
switch (mode) {
case EDIT_MOVE:
/* can snap with any source below the element, if any */
g_node_traverse (node, G_IN_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) find_sources, &data);
break;
case EDIT_TRIM_START:
/* can only snap with sources at the start of the element.
* only need one such source since all will share the same start.
* if there is no source at the start edge, then snapping is not
* possible */
data.edge = GES_EDGE_START;
g_node_traverse (node, G_IN_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) find_source_at_edge, &data);
break;
case EDIT_TRIM_END:
/* can only snap with sources at the end of the element.
* only need one such source since all will share the same end.
* if there is no source at the end edge, then snapping is not
* possible */
data.edge = GES_EDGE_END;
g_node_traverse (node, G_IN_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) find_source_at_edge, &data);
break;
case EDIT_TRIM_INPOINT_ONLY:
GST_ERROR_OBJECT (element, "Trim in-point only not handled");
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
for (tmp = data.sources; tmp; tmp = tmp->next) {
GESTrackElement *source = tmp->data;
GstClockTime end, start;
gboolean negative_end, negative_start;
/* Allow negative start/end positions in case a snap makes them valid!
* But we can still only snap to an existing edge in the timeline,
* which should be a valid time */
get_start_end_from_offset (GES_TIMELINE_ELEMENT (source), mode, *offset,
&start, &negative_start, &end, &negative_end);
if (!GST_CLOCK_TIME_IS_VALID (start)) {
GST_INFO_OBJECT (element, "Cannot edit element %" GES_FORMAT
" with offset %" G_GINT64_FORMAT " because it would result in "
"an invalid start", GES_ARGS (element), *offset);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto done;
}
if (!GST_CLOCK_TIME_IS_VALID (end)) {
GST_INFO_OBJECT (element, "Cannot edit element %" GES_FORMAT
" with offset %" G_GINT64_FORMAT " because it would result in "
"an invalid end", GES_ARGS (element), *offset);
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
switch (mode) {
case EDIT_MOVE:
/* try snap start and end */
find_snap_for_element (source, end, negative_end, &data);
find_snap_for_element (source, start, negative_start, &data);
break;
case EDIT_TRIM_START:
/* only snap the start of the source */
find_snap_for_element (source, start, negative_start, &data);
break;
case EDIT_TRIM_END:
/* only snap the start of the source */
find_snap_for_element (source, end, negative_end, &data);
break;
case EDIT_TRIM_INPOINT_ONLY:
GST_ERROR_OBJECT (element, "Trim in-point only not handled");
goto done;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
}
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (GST_CLOCK_TIME_IS_VALID (snap->snapped)) {
if (snap->negative)
*offset -= (snap->position + snap->snapped);
else
*offset += (snap->position - snap->snapped);
GST_INFO_OBJECT (element, "Element %s under %s snapped with %" GES_FORMAT
" from %s%" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
GES_TIMELINE_ELEMENT_NAME (snap->element), element->name,
GES_ARGS (snap->snapped_to), snap->negative ? "-" : "",
GST_TIME_ARGS (snap->position), GST_TIME_ARGS (snap->snapped));
} else {
GST_INFO_OBJECT (element, "Nothing within snapping distance of %s",
element->name);
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
ret = TRUE;
done:
g_list_free (data.sources);
return ret;
}
/****************************************************
* Check Overlaps *
****************************************************/
#define _SOURCE_FORMAT "\"%s\"%s%s%s"
#define _SOURCE_ARGS(element) \
element->name, element->parent ? " (parent: \"" : "", \
element->parent ? element->parent->name : "", \
element->parent ? "\")" : ""
static void
set_full_overlap_error (GError ** error, GESTimelineElement * super,
GESTimelineElement * sub, GESTrack * track)
{
if (error) {
gchar *track_name = gst_object_get_name (GST_OBJECT (track));
g_set_error (error, GES_ERROR, GES_ERROR_INVALID_OVERLAP_IN_TRACK,
"The source " _SOURCE_FORMAT " would totally overlap the "
"source " _SOURCE_FORMAT " in the track \"%s\"", _SOURCE_ARGS (super),
_SOURCE_ARGS (sub), track_name);
g_free (track_name);
}
}
static void
set_triple_overlap_error (GError ** error, GESTimelineElement * first,
GESTimelineElement * second, GESTimelineElement * third, GESTrack * track)
{
if (error) {
gchar *track_name = gst_object_get_name (GST_OBJECT (track));
g_set_error (error, GES_ERROR, GES_ERROR_INVALID_OVERLAP_IN_TRACK,
"The sources " _SOURCE_FORMAT ", " _SOURCE_FORMAT " and "
_SOURCE_FORMAT " would all overlap at the same point in the "
"track \"%s\"", _SOURCE_ARGS (first), _SOURCE_ARGS (second),
_SOURCE_ARGS (third), track_name);
g_free (track_name);
}
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
#define _ELEMENT_FORMAT \
"%s (under %s) [%" GST_TIME_FORMAT " - %" GST_TIME_FORMAT "] " \
"(layer: %" G_GUINT32_FORMAT ") (track :%" GST_PTR_FORMAT ")"
#define _E_ARGS e->name, e->parent ? e->parent->name : NULL, \
GST_TIME_ARGS (start), GST_TIME_ARGS (end), layer_prio, track
#define _CMP_ARGS cmp->name, cmp->parent ? cmp->parent->name : NULL, \
GST_TIME_ARGS (cmp_start), GST_TIME_ARGS (cmp_end), cmp_layer_prio, \
cmp_track
static gboolean
check_overlap_with_element (GNode * node, TreeIterationData * data)
{
GESTimelineElement *e = node->data, *cmp = data->element;
GstClockTime start, end, cmp_start, cmp_end;
guint32 layer_prio, cmp_layer_prio;
GESTrack *track, *cmp_track;
PositionData *pos_data;
if (e == cmp)
return FALSE;
if (!GES_IS_SOURCE (e) || !GES_IS_SOURCE (cmp))
return FALSE;
/* get position of compared element */
pos_data = data->pos_data;
if (pos_data) {
cmp_start = pos_data->start;
cmp_end = pos_data->end;
cmp_layer_prio = pos_data->layer_priority;
} else {
cmp_start = cmp->start;
cmp_end = cmp_start + cmp->duration;
cmp_layer_prio = ges_timeline_element_get_layer_priority (cmp);
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* get position of the node */
if (data->moving)
pos_data = g_hash_table_lookup (data->moving, e);
else
pos_data = NULL;
if (pos_data) {
start = pos_data->start;
end = pos_data->end;
layer_prio = pos_data->layer_priority;
} else {
start = e->start;
end = start + e->duration;
layer_prio = ges_timeline_element_get_layer_priority (e);
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
track = ges_track_element_get_track (GES_TRACK_ELEMENT (e));
cmp_track = ges_track_element_get_track (GES_TRACK_ELEMENT (cmp));
GST_LOG ("Checking overlap between " _ELEMENT_FORMAT " and "
_ELEMENT_FORMAT, _CMP_ARGS, _E_ARGS);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (track != cmp_track || track == NULL || cmp_track == NULL) {
GST_LOG (_ELEMENT_FORMAT " and " _ELEMENT_FORMAT " are not in the "
"same track", _CMP_ARGS, _E_ARGS);
return FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (layer_prio != cmp_layer_prio) {
GST_LOG (_ELEMENT_FORMAT " and " _ELEMENT_FORMAT " are not in the "
"same layer", _CMP_ARGS, _E_ARGS);
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (start >= cmp_end || cmp_start >= end) {
/* They do not overlap at all */
GST_LOG (_ELEMENT_FORMAT " and " _ELEMENT_FORMAT " do not overlap",
_CMP_ARGS, _E_ARGS);
return FALSE;
}
if (cmp_start <= start && cmp_end >= end) {
/* cmp fully overlaps e */
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO (_ELEMENT_FORMAT " and " _ELEMENT_FORMAT " fully overlap",
_CMP_ARGS, _E_ARGS);
set_full_overlap_error (data->error, cmp, e, track);
goto error;
}
if (cmp_start >= start && cmp_end <= end) {
/* e fully overlaps cmp */
GST_INFO (_ELEMENT_FORMAT " and " _ELEMENT_FORMAT " fully overlap",
_CMP_ARGS, _E_ARGS);
set_full_overlap_error (data->error, e, cmp, track);
goto error;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (cmp_start < end && cmp_start > start) {
/* cmp_start is between the start and end of the node */
GST_LOG (_ELEMENT_FORMAT " is overlapped at its start by "
_ELEMENT_FORMAT ". Overlap ends at %" GST_TIME_FORMAT,
_CMP_ARGS, _E_ARGS, GST_TIME_ARGS (end));
if (data->overlaping_on_start) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO (_ELEMENT_FORMAT " is overlapped by %s and %s on its start",
_CMP_ARGS, data->overlaping_on_start->name, e->name);
set_triple_overlap_error (data->error, cmp, e, data->overlaping_on_start,
track);
goto error;
}
if (GST_CLOCK_TIME_IS_VALID (data->overlap_end_first_time) &&
end > data->overlap_end_first_time) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO (_ELEMENT_FORMAT " overlaps %s on its start and %s on its "
"end, but they already overlap each other", _CMP_ARGS, e->name,
data->overlaping_on_end->name);
set_triple_overlap_error (data->error, cmp, e, data->overlaping_on_end,
track);
goto error;
}
/* record the time at which the overlapped ends */
data->overlap_start_final_time = end;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
data->overlaping_on_start = e;
}
if (cmp_end < end && cmp_end > start) {
/* cmp_end is between the start and end of the node */
GST_LOG (_ELEMENT_FORMAT " is overlapped at its end by "
_ELEMENT_FORMAT ". Overlap starts at %" GST_TIME_FORMAT,
_CMP_ARGS, _E_ARGS, GST_TIME_ARGS (start));
if (data->overlaping_on_end) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO (_ELEMENT_FORMAT " is overlapped by %s and %s on its end",
_CMP_ARGS, data->overlaping_on_end->name, e->name);
set_triple_overlap_error (data->error, cmp, e, data->overlaping_on_end,
track);
goto error;
}
if (GST_CLOCK_TIME_IS_VALID (data->overlap_start_final_time) &&
start < data->overlap_start_final_time) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO (_ELEMENT_FORMAT " overlaps %s on its end and %s on its "
"start, but they already overlap each other", _CMP_ARGS, e->name,
data->overlaping_on_start->name);
set_triple_overlap_error (data->error, cmp, e, data->overlaping_on_start,
track);
goto error;
}
/* record the time at which the overlapped starts */
data->overlap_end_first_time = start;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
data->overlaping_on_end = e;
}
return FALSE;
error:
data->res = FALSE;
return TRUE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* check and find the overlaps with the element at node */
static gboolean
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
check_all_overlaps_with_element (GNode * node, TreeIterationData * data)
{
GESTimelineElement *element = node->data;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (GES_IS_SOURCE (element)) {
data->element = element;
data->overlaping_on_start = NULL;
data->overlaping_on_end = NULL;
data->overlap_start_final_time = GST_CLOCK_TIME_NONE;
data->overlap_end_first_time = GST_CLOCK_TIME_NONE;
if (data->moving)
data->pos_data = g_hash_table_lookup (data->moving, element);
else
data->pos_data = NULL;
g_node_traverse (data->root, G_IN_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) check_overlap_with_element, data);
return !data->res;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
static gboolean
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
check_moving_overlaps (GNode * node, TreeIterationData * data)
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (g_hash_table_contains (data->moving, node->data))
return check_all_overlaps_with_element (node, data);
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* whether the elements in moving can be moved to their corresponding
* PositionData */
static gboolean
timeline_tree_can_move_elements (GNode * root, GHashTable * moving,
GError ** error)
{
TreeIterationData data = tree_iteration_data_init;
if (ges_timeline_get_edit_apis_disabled (root->data)) {
return TRUE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
data.moving = moving;
data.root = root;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
data.res = TRUE;
data.error = error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* sufficient to check the leaves, which is all the track elements or
* empty clips
* should also be sufficient to only check the moving elements */
g_node_traverse (root, G_IN_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) check_moving_overlaps, &data);
return data.res;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/****************************************************
* Setting Edit Data *
****************************************************/
static void
set_negative_start_error (GError ** error, GESTimelineElement * element,
GstClockTime neg_start)
{
g_set_error (error, GES_ERROR, GES_ERROR_NEGATIVE_TIME,
"The element \"%s\" would have a negative start of -%"
GST_TIME_FORMAT, element->name, GST_TIME_ARGS (neg_start));
}
static void
set_negative_duration_error (GError ** error, GESTimelineElement * element,
GstClockTime neg_duration)
{
g_set_error (error, GES_ERROR, GES_ERROR_NEGATIVE_TIME,
"The element \"%s\" would have a negative duration of -%"
GST_TIME_FORMAT, element->name, GST_TIME_ARGS (neg_duration));
}
static void
set_negative_inpoint_error (GError ** error, GESTimelineElement * element,
GstClockTime neg_inpoint)
{
g_set_error (error, GES_ERROR, GES_ERROR_NEGATIVE_TIME,
"The element \"%s\" would have a negative in-point of -%"
GST_TIME_FORMAT, element->name, GST_TIME_ARGS (neg_inpoint));
}
static void
set_negative_layer_error (GError ** error, GESTimelineElement * element,
gint64 neg_layer)
{
g_set_error (error, GES_ERROR, GES_ERROR_NEGATIVE_LAYER,
"The element \"%s\" would have a negative layer priority of -%"
G_GINT64_FORMAT, element->name, neg_layer);
}
static void
set_breaks_duration_limit_error (GError ** error, GESClip * clip,
GstClockTime duration, GstClockTime duration_limit)
{
g_set_error (error, GES_ERROR, GES_ERROR_NOT_ENOUGH_INTERNAL_CONTENT,
"The clip \"%s\" would have a duration of %" GST_TIME_FORMAT
" that would break its duration-limit of %" GST_TIME_FORMAT,
GES_TIMELINE_ELEMENT_NAME (clip), GST_TIME_ARGS (duration),
GST_TIME_ARGS (duration_limit));
}
static void
set_inpoint_breaks_max_duration_error (GError ** error,
GESTimelineElement * element, GstClockTime inpoint,
GstClockTime max_duration)
{
g_set_error (error, GES_ERROR, GES_ERROR_NOT_ENOUGH_INTERNAL_CONTENT,
"The element \"%s\" would have an in-point of %" GST_TIME_FORMAT
" that would break its max-duration of %" GST_TIME_FORMAT,
GES_TIMELINE_ELEMENT_NAME (element), GST_TIME_ARGS (inpoint),
GST_TIME_ARGS (max_duration));
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
static gboolean
set_layer_priority (GESTimelineElement * element, EditData * data,
GError ** error)
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
gint64 layer_offset = data->layer_offset;
guint32 layer_prio = ges_timeline_element_get_layer_priority (element);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!layer_offset)
return TRUE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (layer_prio == GES_TIMELINE_ELEMENT_NO_LAYER_PRIORITY) {
GST_INFO_OBJECT (element, "Cannot shift %s to a new layer because it "
"has no layer priority", element->name);
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (layer_offset > (gint64) layer_prio) {
GST_INFO_OBJECT (element, "%s would have a negative layer priority (%"
G_GUINT32_FORMAT " - %" G_GINT64_FORMAT ")", element->name,
layer_prio, layer_offset);
set_negative_layer_error (error, element,
layer_offset - (gint64) layer_prio);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
if ((layer_prio - (gint64) layer_offset) >= G_MAXUINT32) {
GST_ERROR_OBJECT (element, "%s would have an overflowing layer priority",
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
element->name);
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
data->layer_priority = (guint32) (layer_prio - (gint64) layer_offset);
2019-03-28 14:08:58 +00:00
if (ges_timeline_layer_priority_in_gap (element->timeline,
data->layer_priority)) {
GST_ERROR_OBJECT (element, "Edit layer %" G_GUINT32_FORMAT " would "
"be within a gap in the timeline layers", data->layer_priority);
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO_OBJECT (element, "%s will move to layer %" G_GUINT32_FORMAT,
element->name, data->layer_priority);
return TRUE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
#define _CHECK_END(element, start, duration) \
if (!GST_CLOCK_TIME_IS_VALID (_clock_time_plus (start, duration))) { \
GST_INFO_OBJECT (element, "Cannot edit %s because it would result in " \
"an invalid end", element->name); \
return FALSE; \
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
static gboolean
set_edit_move_values (GESTimelineElement * element, EditData * data,
GError ** error)
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
{
gboolean negative = FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GstClockTime new_start =
_clock_time_minus_diff (element->start, data->offset, &negative);
if (negative || !GST_CLOCK_TIME_IS_VALID (new_start)) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO_OBJECT (element, "Cannot move %" GES_FORMAT " with offset %"
G_GINT64_FORMAT " because it would result in an invalid start",
GES_ARGS (element), data->offset);
if (negative)
set_negative_start_error (error, element, new_start);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
_CHECK_END (element, new_start, element->duration);
data->start = new_start;
if (GES_IS_GROUP (element))
return TRUE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO_OBJECT (element, "%s will move by setting start to %"
GST_TIME_FORMAT, element->name, GST_TIME_ARGS (data->start));
return set_layer_priority (element, data, error);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
}
static gboolean
set_edit_trim_start_clip_inpoints (GESClip * clip, EditData * clip_data,
GHashTable * edit_table, GError ** error)
{
gboolean ret = FALSE;
GList *tmp;
GstClockTime duration_limit;
GstClockTime clip_inpoint;
GstClockTime new_start = clip_data->start;
gboolean no_core = FALSE;
GHashTable *child_inpoints;
child_inpoints = g_hash_table_new_full (NULL, NULL, gst_object_unref, g_free);
clip_inpoint = ges_clip_get_core_internal_time_from_timeline_time (clip,
new_start, &no_core, error);
if (no_core) {
GST_INFO_OBJECT (clip, "Clip %" GES_FORMAT " has no active core "
"children with an internal source. Not setting in-point during "
"trim to start", GES_ARGS (clip));
clip_inpoint = GES_TIMELINE_ELEMENT_INPOINT (clip);
} else if (!GST_CLOCK_TIME_IS_VALID (clip_inpoint)) {
GST_INFO_OBJECT (clip, "Cannot trim start of %" GES_FORMAT
" with offset %" G_GINT64_FORMAT " because it would result in an "
"invalid in-point for its core children", GES_ARGS (clip),
clip_data->offset);
goto done;
} else {
GST_INFO_OBJECT (clip, "Clip %" GES_FORMAT " will have its in-point "
" set to %" GST_TIME_FORMAT " because its start is being trimmed "
"to %" GST_TIME_FORMAT, GES_ARGS (clip),
GST_TIME_ARGS (clip_inpoint), GST_TIME_ARGS (new_start));
clip_data->inpoint = clip_inpoint;
}
/* need to set in-point of active non-core children to keep their
* internal content at the same timeline position */
for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next) {
GESTimelineElement *child = tmp->data;
GESTrackElement *el = tmp->data;
GstClockTime new_inpoint = child->inpoint;
GstClockTime *inpoint_p;
if (ges_track_element_has_internal_source (el)) {
if (ges_track_element_is_core (el)) {
new_inpoint = clip_inpoint;
} else if (ges_track_element_is_active (el)) {
EditData *data;
if (g_hash_table_contains (edit_table, child)) {
GST_ERROR_OBJECT (child, "Already set to be edited");
goto done;
}
new_inpoint = ges_clip_get_internal_time_from_timeline_time (clip, el,
new_start, error);
if (!GST_CLOCK_TIME_IS_VALID (new_inpoint)) {
GST_INFO_OBJECT (clip, "Cannot trim start of %" GES_FORMAT
" to %" GST_TIME_FORMAT " because it would result in an "
"invalid in-point for the non-core child %" GES_FORMAT,
GES_ARGS (clip), GST_TIME_ARGS (new_start), GES_ARGS (child));
goto done;
}
GST_INFO_OBJECT (child, "Setting track element %s to trim "
"in-point to %" GST_TIME_FORMAT " since the parent clip %"
GES_FORMAT " is being trimmed to start %" GST_TIME_FORMAT,
child->name, GST_TIME_ARGS (new_inpoint), GES_ARGS (clip),
GST_TIME_ARGS (new_start));
data = new_edit_data (EDIT_TRIM_INPOINT_ONLY, 0, 0);
data->inpoint = new_inpoint;
g_hash_table_insert (edit_table, child, data);
}
}
if (GES_CLOCK_TIME_IS_LESS (child->maxduration, new_inpoint)) {
GST_INFO_OBJECT (clip, "Cannot trim start of %" GES_FORMAT
" to %" GST_TIME_FORMAT " because it would result in an "
"in-point of %" GST_TIME_FORMAT " for the child %" GES_FORMAT
", which breaks its max-duration", GES_ARGS (clip),
GST_TIME_ARGS (new_start), GST_TIME_ARGS (new_inpoint),
GES_ARGS (child));
set_inpoint_breaks_max_duration_error (error, child, new_inpoint,
child->maxduration);
goto done;
}
inpoint_p = g_new (GstClockTime, 1);
*inpoint_p = new_inpoint;
g_hash_table_insert (child_inpoints, gst_object_ref (child), inpoint_p);
}
duration_limit =
ges_clip_duration_limit_with_new_children_inpoints (clip, child_inpoints);
if (GES_CLOCK_TIME_IS_LESS (duration_limit, clip_data->duration)) {
GST_INFO_OBJECT (clip, "Cannot trim start of %" GES_FORMAT
" to %" GST_TIME_FORMAT " because it would result in a "
"duration of %" GST_TIME_FORMAT " that breaks its new "
"duration-limit of %" GST_TIME_FORMAT, GES_ARGS (clip),
GST_TIME_ARGS (new_start), GST_TIME_ARGS (clip_data->duration),
GST_TIME_ARGS (duration_limit));
set_breaks_duration_limit_error (error, clip, clip_data->duration,
duration_limit);
goto done;
}
ret = TRUE;
done:
g_hash_table_unref (child_inpoints);
return ret;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* trim the start of a clip or a track element */
static gboolean
set_edit_trim_start_values (GESTimelineElement * element, EditData * data,
GHashTable * edit_table, GError ** error)
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
{
gboolean negative = FALSE;
GstClockTime new_duration;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GstClockTime new_start =
_clock_time_minus_diff (element->start, data->offset, &negative);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (negative || !GST_CLOCK_TIME_IS_VALID (new_start)) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO_OBJECT (element, "Cannot trim start of %" GES_FORMAT
" with offset %" G_GINT64_FORMAT " because it would result in an "
"invalid start", GES_ARGS (element), data->offset);
if (negative)
set_negative_start_error (error, element, new_start);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
new_duration =
_clock_time_minus_diff (element->duration, -data->offset, &negative);
if (negative || !GST_CLOCK_TIME_IS_VALID (new_duration)) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO_OBJECT (element, "Cannot trim start of %" GES_FORMAT
" with offset %" G_GINT64_FORMAT " because it would result in an "
"invalid duration", GES_ARGS (element), data->offset);
if (negative)
set_negative_duration_error (error, element, new_duration);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
_CHECK_END (element, new_start, new_duration);
data->start = new_start;
data->duration = new_duration;
if (GES_IS_GROUP (element))
return TRUE;
if (GES_IS_CLIP (element)) {
if (!set_edit_trim_start_clip_inpoints (GES_CLIP (element), data,
edit_table, error))
return FALSE;
} else if (GES_IS_TRACK_ELEMENT (element)
&& ges_track_element_has_internal_source (GES_TRACK_ELEMENT (element))) {
GstClockTime new_inpoint =
_clock_time_minus_diff (element->inpoint, data->offset, &negative);
if (negative || !GST_CLOCK_TIME_IS_VALID (new_inpoint)) {
GST_INFO_OBJECT (element, "Cannot trim start of %" GES_FORMAT
" with offset %" G_GINT64_FORMAT " because it would result in "
"an invalid in-point", GES_ARGS (element), data->offset);
if (negative)
set_negative_inpoint_error (error, element, new_inpoint);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO_OBJECT (element, "%s will trim start by setting start to %"
GST_TIME_FORMAT ", in-point to %" GST_TIME_FORMAT " and duration "
"to %" GST_TIME_FORMAT, element->name, GST_TIME_ARGS (data->start),
GST_TIME_ARGS (data->inpoint), GST_TIME_ARGS (data->duration));
return set_layer_priority (element, data, error);
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* trim the end of a clip or a track element */
static gboolean
set_edit_trim_end_values (GESTimelineElement * element, EditData * data,
GError ** error)
{
gboolean negative = FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GstClockTime new_duration =
_clock_time_minus_diff (element->duration, data->offset, &negative);
if (negative || !GST_CLOCK_TIME_IS_VALID (new_duration)) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO_OBJECT (element, "Cannot trim end of %" GES_FORMAT
" with offset %" G_GINT64_FORMAT " because it would result in an "
"invalid duration", GES_ARGS (element), data->offset);
if (negative)
set_negative_duration_error (error, element, new_duration);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
_CHECK_END (element, element->start, new_duration);
if (GES_IS_CLIP (element)) {
GESClip *clip = GES_CLIP (element);
GstClockTime limit = ges_clip_get_duration_limit (clip);
if (GES_CLOCK_TIME_IS_LESS (limit, new_duration)) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO_OBJECT (element, "Cannot trim end of %" GES_FORMAT
" with offset %" G_GINT64_FORMAT " because the duration would "
"exceed the clip's duration-limit %" G_GINT64_FORMAT,
GES_ARGS (element), data->offset, limit);
set_breaks_duration_limit_error (error, clip, new_duration, limit);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
data->duration = new_duration;
if (GES_IS_GROUP (element))
return TRUE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GST_INFO_OBJECT (element, "%s will trim end by setting duration to %"
GST_TIME_FORMAT, element->name, GST_TIME_ARGS (data->duration));
return set_layer_priority (element, data, error);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
static gboolean
set_edit_values (GESTimelineElement * element, EditData * data,
GHashTable * edit_table, GError ** error)
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
{
switch (data->mode) {
case EDIT_MOVE:
return set_edit_move_values (element, data, error);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
case EDIT_TRIM_START:
return set_edit_trim_start_values (element, data, edit_table, error);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
case EDIT_TRIM_END:
return set_edit_trim_end_values (element, data, error);
case EDIT_TRIM_INPOINT_ONLY:
GST_ERROR_OBJECT (element, "Trim in-point only not handled");
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
static gboolean
add_clips_to_list (GNode * node, GList ** list)
{
GESTimelineElement *element = node->data;
GESTimelineElement *clip = NULL;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (GES_IS_CLIP (element))
clip = element;
else if (GES_IS_CLIP (element->parent))
clip = element->parent;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (clip && !g_list_find (*list, clip))
*list = g_list_append (*list, clip);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
static gboolean
replace_group_with_clip_edits (GNode * root, GESTimelineElement * group,
GHashTable * edit_table, GError ** err)
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
{
gboolean ret = TRUE;
GList *tmp, *clips = NULL;
GNode *node = find_node (root, group);
GstClockTime new_end, new_start;
ElementEditMode mode;
gint64 layer_offset;
if (!node) {
GST_ERROR_OBJECT (group, "Not being tracked");
goto error;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* new context for the lifespan of group_data */
{
EditData *group_edit = g_hash_table_lookup (edit_table, group);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!group_edit) {
GST_ERROR_OBJECT (group, "Edit data for group was missing");
goto error;
}
group_edit->start = group->start;
group_edit->duration = group->duration;
/* should only set the start and duration fields, table should not be
* needed, so we pass NULL */
if (!set_edit_values (group, group_edit, NULL, err))
goto error;
new_start = group_edit->start;
new_end = _clock_time_plus (group_edit->start, group_edit->duration);
if (!GST_CLOCK_TIME_IS_VALID (new_start)
|| !GST_CLOCK_TIME_IS_VALID (new_end)) {
GST_ERROR_OBJECT (group, "Edit data gave an invalid start or end");
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto error;
}
layer_offset = group_edit->layer_offset;
mode = group_edit->mode;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* can traverse leaves to find all the clips since they are at _most_
* one step above the track elements */
g_node_traverse (node, G_IN_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) add_clips_to_list, &clips);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!clips) {
GST_INFO_OBJECT (group, "Contains no clips, so cannot be edited");
goto error;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!g_hash_table_remove (edit_table, group)) {
GST_ERROR_OBJECT (group, "Could not replace the group in the edit list");
goto error;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* removing the group from the table frees group_edit */
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
for (tmp = clips; tmp; tmp = tmp->next) {
GESTimelineElement *clip = tmp->data;
gboolean edit = FALSE;
GstClockTimeDiff offset = G_MAXINT64;
ElementEditMode clip_mode = mode;
/* if at the edge of the group and being trimmed forward or backward */
if (mode == EDIT_MOVE) {
/* same offset as the group */
edit = TRUE;
offset = group->start - new_start;
GST_INFO_OBJECT (clip, "Setting clip %s to moving with offset %"
G_GINT64_FORMAT " since an ancestor group %" GES_FORMAT
" is moving to %" GST_TIME_FORMAT, clip->name, offset,
GES_ARGS (group), GST_TIME_ARGS (new_start));
} else if ((mode == EDIT_TRIM_START)
&& (clip->start <= new_start || clip->start == group->start)) {
/* trim to same start */
edit = TRUE;
offset = clip->start - new_start;
GST_INFO_OBJECT (clip, "Setting clip %s to trim start with offset %"
G_GINT64_FORMAT " since an ancestor group %" GES_FORMAT " is "
"being trimmed to start %" GST_TIME_FORMAT, clip->name, offset,
GES_ARGS (group), GST_TIME_ARGS (new_start));
} else if (mode == EDIT_TRIM_END
&& (_END (clip) >= new_end || _END (clip) == _END (group))) {
/* trim to same end */
edit = TRUE;
offset = _END (clip) - new_end;
GST_INFO_OBJECT (clip, "Setting clip %s to trim end with offset %"
G_GINT64_FORMAT " since an ancestor group %" GES_FORMAT " is "
"being trimmed to end %" GST_TIME_FORMAT, clip->name, offset,
GES_ARGS (group), GST_TIME_ARGS (new_end));
} else if (layer_offset) {
/* still need to move layer */
edit = TRUE;
clip_mode = EDIT_MOVE;
offset = 0;
}
if (edit) {
EditData *clip_data;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (layer_offset)
GST_INFO_OBJECT (clip, "Setting clip %s to move to new layer with "
"offset %" G_GINT64_FORMAT " since an ancestor group %"
GES_FORMAT " is being moved with the same offset", clip->name,
layer_offset, GES_ARGS (group));
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (g_hash_table_contains (edit_table, clip)) {
GST_ERROR_OBJECT (clip, "Already set to be edited");
goto error;
}
clip_data = new_edit_data (clip_mode, offset, layer_offset);
g_hash_table_insert (edit_table, clip, clip_data);
if (!set_edit_values (clip, clip_data, edit_table, err))
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto error;
}
}
done:
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
g_list_free (clips);
return ret;
error:
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
ret = FALSE;
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* set the edit values for the entries in @edits
* any groups in @edits will be replaced by their clip children */
static gboolean
timeline_tree_set_element_edit_values (GNode * root, GHashTable * edits,
GError ** err)
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
gboolean ret = TRUE;
GESTimelineElement *element;
EditData *edit_data;
/* content of edit table may change when group edits are replaced by
* clip edits and clip edits introduce edits for non-core children */
GList *tmp, *elements = g_hash_table_get_keys (edits);
for (tmp = elements; tmp; tmp = tmp->next) {
gboolean res;
element = tmp->data;
edit_data = g_hash_table_lookup (edits, element);
if (!edit_data) {
GST_ERROR_OBJECT (element, "No edit data for the element");
goto error;
}
if (GES_IS_GROUP (element))
res = replace_group_with_clip_edits (root, element, edits, err);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
else
res = set_edit_values (element, edit_data, edits, err);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!res)
goto error;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
done:
g_list_free (elements);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return ret;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
error:
ret = FALSE;
goto done;
}
/* set the moving PositionData by using their parent clips.
* @edit_table should already have had its values set, and any group edits
* replaced by clip edits. */
static void
set_moving_positions_from_edits (GHashTable * moving, GHashTable * edit_table)
{
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, moving);
while (g_hash_table_iter_next (&iter, &key, &value)) {
GESTimelineElement *element = key;
PositionData *pos = value;
GESTimelineElement *parent;
EditData *edit;
/* a track element will end up with the same start and end as its clip */
/* if no parent, act as own parent */
parent = element->parent ? element->parent : element;
edit = g_hash_table_lookup (edit_table, parent);
if (edit && GST_CLOCK_TIME_IS_VALID (edit->start))
pos->start = edit->start;
else
pos->start = element->start;
if (edit && GST_CLOCK_TIME_IS_VALID (edit->duration))
pos->end = pos->start + edit->duration;
else
pos->end = pos->start + element->duration;
if (edit && edit->layer_priority != GES_TIMELINE_ELEMENT_NO_LAYER_PRIORITY)
pos->layer_priority = edit->layer_priority;
else
pos->layer_priority = ges_timeline_element_get_layer_priority (element);
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
}
static void
give_edits_same_offset (GHashTable * edits, GstClockTimeDiff offset,
gint64 layer_offset)
{
GHashTableIter iter;
gpointer value;
g_hash_table_iter_init (&iter, edits);
while (g_hash_table_iter_next (&iter, NULL, &value)) {
EditData *edit_data = value;
edit_data->offset = offset;
edit_data->layer_offset = layer_offset;
}
}
/****************************************************
* Initialise Edit Data and Moving *
****************************************************/
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
static gboolean
add_track_elements_to_moving (GNode * node, GHashTable * track_elements)
{
GESTimelineElement *element = node->data;
if (GES_IS_TRACK_ELEMENT (element)) {
GST_LOG_OBJECT (element, "%s set as moving", element->name);
g_hash_table_insert (track_elements, element, g_new0 (PositionData, 1));
}
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* add all the track elements found under the elements in @edits to @moving,
* but does not set their position data */
static gboolean
timeline_tree_add_edited_to_moving (GNode * root, GHashTable * edits,
GHashTable * moving)
{
GHashTableIter iter;
gpointer key;
g_hash_table_iter_init (&iter, edits);
while (g_hash_table_iter_next (&iter, &key, NULL)) {
GESTimelineElement *element = key;
GNode *node = find_node (root, element);
if (!node) {
GST_ERROR_OBJECT (element, "Not being tracked");
return FALSE;
}
g_node_traverse (node, G_IN_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) add_track_elements_to_moving, moving);
}
return TRUE;
}
/* check we can handle the top and all of its children */
static gboolean
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
check_types (GESTimelineElement * element, gboolean is_top)
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!GES_IS_CLIP (element) && !GES_IS_GROUP (element)
&& !GES_IS_TRACK_ELEMENT (element)) {
GST_ERROR_OBJECT (element, "Cannot handle a GESTimelineElement of the "
"type %s", G_OBJECT_TYPE_NAME (element));
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!is_top && element->parent) {
if ((GES_IS_CLIP (element) && !GES_IS_GROUP (element->parent))
|| (GES_IS_GROUP (element) && !GES_IS_GROUP (element->parent))
|| (GES_IS_TRACK_ELEMENT (element) && !GES_IS_CLIP (element->parent))) {
GST_ERROR_OBJECT (element, "A parent of type %s is not handled",
G_OBJECT_TYPE_NAME (element->parent));
return FALSE;
}
}
if (GES_IS_CONTAINER (element)) {
GList *tmp;
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
if (!check_types (tmp->data, FALSE))
return FALSE;
}
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return TRUE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* @edits: The table to add the edit to
* @element: The element to edit
* @mode: The mode for editing @element
*
* Adds an edit for @element it to the table with its EditData only set
* with @mode.
*
* The offsets for the edit will have to be set later.
*/
static gboolean
add_element_edit (GHashTable * edits, GESTimelineElement * element,
ElementEditMode mode)
{
if (!check_types (element, TRUE))
return FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (g_hash_table_contains (edits, element)) {
GST_ERROR_OBJECT (element, "Already set to be edited");
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
switch (mode) {
case EDIT_MOVE:
GST_LOG_OBJECT (element, "%s set to move", element->name);
break;
case EDIT_TRIM_START:
GST_LOG_OBJECT (element, "%s set to trim start", element->name);
break;
case EDIT_TRIM_END:
GST_LOG_OBJECT (element, "%s set to trim end", element->name);
break;
case EDIT_TRIM_INPOINT_ONLY:
GST_ERROR_OBJECT (element, "%s set to trim in-point only", element->name);
return FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
}
g_hash_table_insert (edits, element, new_edit_data (mode, 0, 0));
return TRUE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/********************************************
* Check against current configuration *
********************************************/
/* can move with no snapping or change in parent! */
gboolean
timeline_tree_can_move_element (GNode * root,
GESTimelineElement * element, guint32 priority, GstClockTime start,
GstClockTime duration, GError ** error)
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
gboolean ret = FALSE;
guint32 layer_prio = ges_timeline_element_get_layer_priority (element);
GstClockTime distance, new_end;
GHashTable *move_edits, *trim_edits, *moving;
GHashTableIter iter;
gpointer key, value;
if (ges_timeline_get_edit_apis_disabled (root->data)) {
return TRUE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (layer_prio == GES_TIMELINE_ELEMENT_NO_LAYER_PRIORITY
&& priority != layer_prio) {
GST_INFO_OBJECT (element, "Cannot move to a layer when no layer "
"priority to begin with");
return FALSE;
}
distance = _abs_clock_time_distance (start, element->start);
if ((GstClockTimeDiff) distance >= G_MAXINT64) {
GST_WARNING_OBJECT (element, "Move in start from %" GST_TIME_FORMAT
" to %" GST_TIME_FORMAT " is too large to perform",
GST_TIME_ARGS (element->start), GST_TIME_ARGS (start));
return FALSE;
}
distance = _abs_clock_time_distance (duration, element->duration);
if ((GstClockTimeDiff) distance >= G_MAXINT64) {
GST_WARNING_OBJECT (element, "Move in duration from %" GST_TIME_FORMAT
" to %" GST_TIME_FORMAT " is too large to perform",
GST_TIME_ARGS (element->duration), GST_TIME_ARGS (duration));
return FALSE;
}
new_end = _clock_time_plus (start, duration);
if (!GST_CLOCK_TIME_IS_VALID (new_end)) {
GST_WARNING_OBJECT (element, "Move in start and duration to %"
GST_TIME_FORMAT " and %" GST_TIME_FORMAT " would produce an "
"invalid end", GST_TIME_ARGS (start), GST_TIME_ARGS (duration));
return FALSE;
}
/* treat as an EDIT_MOVE to the new priority, except on the element
* rather than the toplevel, followed by an EDIT_TRIM_END */
move_edits = new_edit_table ();
trim_edits = new_edit_table ();
moving = new_position_table ();
if (!add_element_edit (move_edits, element, EDIT_MOVE))
goto done;
/* moving should remain the same */
if (!add_element_edit (trim_edits, element, EDIT_TRIM_END))
goto done;
if (!timeline_tree_add_edited_to_moving (root, move_edits, moving)
|| !timeline_tree_add_edited_to_moving (root, trim_edits, moving))
goto done;
/* no snapping */
give_edits_same_offset (move_edits, element->start - start,
(gint64) layer_prio - (gint64) priority);
give_edits_same_offset (trim_edits, element->duration - duration, 0);
/* assume both edits can be performed if each could occur individually */
/* should not effect duration or in-point */
if (!timeline_tree_set_element_edit_values (root, move_edits, error))
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto done;
/* should not effect start or in-point or layer */
if (!timeline_tree_set_element_edit_values (root, trim_edits, error))
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto done;
/* merge the two edits into moving positions */
g_hash_table_iter_init (&iter, moving);
while (g_hash_table_iter_next (&iter, &key, &value)) {
GESTimelineElement *el = key;
PositionData *pos_data = value;
EditData *move = NULL;
EditData *trim = NULL;
if (el->parent) {
move = g_hash_table_lookup (move_edits, el->parent);
trim = g_hash_table_lookup (trim_edits, el->parent);
}
if (!move)
move = g_hash_table_lookup (move_edits, el);
if (!trim)
trim = g_hash_table_lookup (trim_edits, el);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* should always have move with a valid start */
if (!move || !GST_CLOCK_TIME_IS_VALID (move->start)) {
GST_ERROR_OBJECT (el, "Element set to moving but neither it nor its "
"parent are being edited");
goto done;
}
/* may not have trim if element is a group and the child is away
* from the edit position, but if we do it should have a valid duration */
if (trim && !GST_CLOCK_TIME_IS_VALID (trim->duration)) {
GST_ERROR_OBJECT (el, "Element set to trim end but neither it nor its "
"parent is being trimmed");
goto done;
}
pos_data->start = move->start;
if (move->layer_priority != GES_TIMELINE_ELEMENT_NO_LAYER_PRIORITY)
pos_data->layer_priority = move->layer_priority;
else
pos_data->layer_priority = ges_timeline_element_get_layer_priority (el);
if (trim)
pos_data->end = pos_data->start + trim->duration;
else
pos_data->end = pos_data->start + el->duration;
}
/* check overlaps */
if (!timeline_tree_can_move_elements (root, moving, error))
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto done;
ret = TRUE;
done:
g_hash_table_unref (trim_edits);
g_hash_table_unref (move_edits);
g_hash_table_unref (moving);
return ret;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/********************************************
* Perform Element Edit *
********************************************/
static gboolean
perform_element_edit (GESTimelineElement * element, EditData * edit)
{
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
gboolean ret = FALSE;
guint32 layer_prio = ges_timeline_element_get_layer_priority (element);
switch (edit->mode) {
case EDIT_MOVE:
GST_INFO_OBJECT (element, "Moving %s from %" GST_TIME_FORMAT " to %"
GST_TIME_FORMAT, element->name, GST_TIME_ARGS (element->start),
GST_TIME_ARGS (edit->start));
break;
case EDIT_TRIM_START:
GST_INFO_OBJECT (element, "Trimming %s start from %" GST_TIME_FORMAT
" to %" GST_TIME_FORMAT, element->name,
GST_TIME_ARGS (element->start), GST_TIME_ARGS (edit->start));
break;
case EDIT_TRIM_END:
GST_INFO_OBJECT (element, "Trimming %s end from %" GST_TIME_FORMAT
" to %" GST_TIME_FORMAT, element->name,
GST_TIME_ARGS (_END (element)),
GST_TIME_ARGS (element->start + edit->duration));
break;
case EDIT_TRIM_INPOINT_ONLY:
GST_INFO_OBJECT (element, "Trimming %s in-point from %"
GST_TIME_FORMAT " to %" GST_TIME_FORMAT, element->name,
GST_TIME_ARGS (element->inpoint), GST_TIME_ARGS (edit->inpoint));
break;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!GES_IS_CLIP (element) && !GES_IS_TRACK_ELEMENT (element)) {
GST_ERROR_OBJECT (element, "Cannot perform edit on group");
return FALSE;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!GES_IS_CLIP (element)
&& edit->layer_priority != GES_TIMELINE_ELEMENT_NO_LAYER_PRIORITY) {
GST_ERROR_OBJECT (element, "Cannot move an element that is not a "
"clip to a new layer");
return FALSE;
}
GES_TIMELINE_ELEMENT_SET_BEING_EDITED (element);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (GST_CLOCK_TIME_IS_VALID (edit->start)) {
if (!ges_timeline_element_set_start (element, edit->start)) {
GST_ERROR_OBJECT (element, "Failed to set the start");
goto done;
}
}
if (GST_CLOCK_TIME_IS_VALID (edit->inpoint)) {
if (!ges_timeline_element_set_inpoint (element, edit->inpoint)) {
GST_ERROR_OBJECT (element, "Failed to set the in-point");
goto done;
}
}
if (GST_CLOCK_TIME_IS_VALID (edit->duration)) {
if (!ges_timeline_element_set_duration (element, edit->duration)) {
GST_ERROR_OBJECT (element, "Failed to set the duration");
goto done;
}
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (edit->layer_priority != GES_TIMELINE_ELEMENT_NO_LAYER_PRIORITY) {
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (element);
GESLayer *layer = ges_timeline_get_layer (timeline, edit->layer_priority);
GST_INFO_OBJECT (element, "Moving %s from layer %" G_GUINT32_FORMAT
" to layer %" G_GUINT32_FORMAT, element->name, layer_prio,
edit->layer_priority);
if (layer == NULL) {
/* make sure we won't loop forever */
if (ges_timeline_layer_priority_in_gap (timeline, edit->layer_priority)) {
GST_ERROR_OBJECT (element, "Requested layer %" G_GUINT32_FORMAT
" is within a gap in the timeline layers", edit->layer_priority);
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
do {
layer = ges_timeline_append_layer (timeline);
} while (ges_layer_get_priority (layer) < edit->layer_priority);
} else {
gst_object_unref (layer);
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!ges_clip_move_to_layer (GES_CLIP (element), layer)) {
GST_ERROR_OBJECT (element, "Failed to move layers");
goto done;
}
}
ret = TRUE;
done:
GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED (element);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
return ret;
}
/* perform all the element edits found in @edits.
* These should only be clips of track elements. */
static gboolean
timeline_tree_perform_edits (GNode * root, GHashTable * edits)
{
gboolean no_errors = TRUE;
GHashTableIter iter;
gpointer key, value;
/* freeze the auto-transitions whilst we edit */
ges_timeline_freeze_auto_transitions (root->data, TRUE);
g_hash_table_iter_init (&iter, edits);
while (g_hash_table_iter_next (&iter, &key, &value)) {
if (GES_IS_TRACK_ELEMENT (key))
ges_track_element_freeze_control_sources (GES_TRACK_ELEMENT (key), TRUE);
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
g_hash_table_iter_init (&iter, edits);
while (g_hash_table_iter_next (&iter, &key, &value)) {
GESTimelineElement *element = key;
EditData *edit_data = value;
if (!perform_element_edit (element, edit_data))
no_errors = FALSE;
}
g_hash_table_iter_init (&iter, edits);
while (g_hash_table_iter_next (&iter, &key, &value)) {
if (GES_IS_TRACK_ELEMENT (key))
ges_track_element_freeze_control_sources (GES_TRACK_ELEMENT (key), FALSE);
}
/* allow the transitions to update if they can */
ges_timeline_freeze_auto_transitions (root->data, FALSE);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
timeline_tree_create_transitions (root, ges_timeline_find_auto_transition);
timeline_update_duration (root->data);
return no_errors;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
#define _REPLACE_TRACK_ELEMENT_WITH_PARENT(element) \
element = (GES_IS_TRACK_ELEMENT (element) && element->parent) ? element->parent : element
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/********************************************
* Ripple *
********************************************/
gboolean
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
timeline_tree_ripple (GNode * root, GESTimelineElement * element,
gint64 layer_priority_offset, GstClockTimeDiff offset, GESEdge edge,
GstClockTime snapping_distance, GError ** error)
{
gboolean res = TRUE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GNode *node;
GESTimelineElement *ripple_toplevel;
GstClockTime ripple_time;
GHashTable *edits = new_edit_table ();
GHashTable *moving = new_position_table ();
ElementEditMode mode;
SnappedPosition *snap = new_snapped_position (snapping_distance);
_REPLACE_TRACK_ELEMENT_WITH_PARENT (element);
ripple_toplevel = ges_timeline_element_peak_toplevel (element);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* if EDGE_END:
* TRIM_END the element, and MOVE all toplevels whose start is after
* the current end of the element by the same amount
* otherwise:
* MOVE the topevel of the element, and all other toplevel elements
* whose start is after the current start of the element */
switch (edge) {
case GES_EDGE_END:
GST_INFO_OBJECT (element, "Rippling end with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset);
mode = EDIT_TRIM_END;
break;
case GES_EDGE_START:
GST_INFO_OBJECT (element, "Rippling start with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset);
mode = EDIT_MOVE;
break;
case GES_EDGE_NONE:
GST_INFO_OBJECT (element, "Rippling with toplevel with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset);
element = ripple_toplevel;
mode = EDIT_MOVE;
break;
default:
GST_WARNING_OBJECT (element, "Edge not supported");
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
ripple_time = ELEMENT_EDGE_VALUE (element, edge);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* add edits */
if (!add_element_edit (edits, element, mode))
goto error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
for (node = root->children; node; node = node->next) {
GESTimelineElement *toplevel = node->data;
if (toplevel == ripple_toplevel)
continue;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (toplevel->start >= ripple_time) {
if (!add_element_edit (edits, toplevel, EDIT_MOVE))
goto error;
}
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!timeline_tree_add_edited_to_moving (root, edits, moving))
goto error;
/* snap */
if (!timeline_tree_snap (root, element, mode, &offset, moving, snap))
goto error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* check and set edits using snapped values */
give_edits_same_offset (edits, offset, layer_priority_offset);
if (!timeline_tree_set_element_edit_values (root, edits, error))
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto error;
/* check overlaps */
set_moving_positions_from_edits (moving, edits);
if (!timeline_tree_can_move_elements (root, moving, error))
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto error;
/* emit snapping now. Edits should only fail if a programming error
* occured */
if (snap)
ges_timeline_emit_snapping (root->data, snap->element, snap->snapped_to,
snap->snapped);
res = timeline_tree_perform_edits (root, edits);
done:
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
g_hash_table_unref (edits);
g_hash_table_unref (moving);
g_free (snap);
return res;
error:
res = FALSE;
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/********************************************
* Trim *
********************************************/
gboolean
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
timeline_tree_trim (GNode * root, GESTimelineElement * element,
gint64 layer_priority_offset, GstClockTimeDiff offset, GESEdge edge,
GstClockTime snapping_distance, GError ** error)
{
gboolean res = TRUE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GHashTable *edits = new_edit_table ();
GHashTable *moving = new_position_table ();
ElementEditMode mode;
SnappedPosition *snap = new_snapped_position (snapping_distance);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
_REPLACE_TRACK_ELEMENT_WITH_PARENT (element);
/* TODO: 2.0 remove this warning and simply fail if no edge is specified */
if (edge == GES_EDGE_NONE) {
g_warning ("No edge specified for trimming. Defaulting to GES_EDGE_START");
edge = GES_EDGE_START;
}
switch (edge) {
case GES_EDGE_END:
GST_INFO_OBJECT (element, "Trimming end with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset);
mode = EDIT_TRIM_END;
break;
case GES_EDGE_START:
GST_INFO_OBJECT (element, "Trimming start with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset);
mode = EDIT_TRIM_START;
break;
default:
GST_WARNING_OBJECT (element, "Edge not supported");
goto done;
}
/* add edits */
if (!add_element_edit (edits, element, mode))
goto error;
if (!timeline_tree_add_edited_to_moving (root, edits, moving))
goto error;
/* snap */
if (!timeline_tree_snap (root, element, mode, &offset, moving, snap))
goto error;
/* check and set edits using snapped values */
give_edits_same_offset (edits, offset, layer_priority_offset);
if (!timeline_tree_set_element_edit_values (root, edits, error))
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto error;
/* check overlaps */
set_moving_positions_from_edits (moving, edits);
if (!timeline_tree_can_move_elements (root, moving, error)) {
2019-03-28 14:08:58 +00:00
goto error;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* emit snapping now. Edits should only fail if a programming error
* occured */
if (snap)
ges_timeline_emit_snapping (root->data, snap->element, snap->snapped_to,
snap->snapped);
res = timeline_tree_perform_edits (root, edits);
done:
g_hash_table_unref (edits);
g_hash_table_unref (moving);
g_free (snap);
return res;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
error:
res = FALSE;
goto done;
}
/********************************************
* Move *
********************************************/
gboolean
timeline_tree_move (GNode * root, GESTimelineElement * element,
gint64 layer_priority_offset, GstClockTimeDiff offset, GESEdge edge,
GstClockTime snapping_distance, GError ** error)
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
{
gboolean res = TRUE;
GHashTable *edits = new_edit_table ();
GHashTable *moving = new_position_table ();
ElementEditMode mode;
SnappedPosition *snap = new_snapped_position (snapping_distance);
_REPLACE_TRACK_ELEMENT_WITH_PARENT (element);
switch (edge) {
case GES_EDGE_END:
GST_INFO_OBJECT (element, "Moving end with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset);
mode = EDIT_TRIM_END;
break;
case GES_EDGE_START:
GST_INFO_OBJECT (element, "Moving start with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset);
mode = EDIT_MOVE;
break;
case GES_EDGE_NONE:
GST_INFO_OBJECT (element, "Moving with toplevel with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset);
element = ges_timeline_element_peak_toplevel (element);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
mode = EDIT_MOVE;
break;
default:
GST_WARNING_OBJECT (element, "Edge not supported");
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* add edits */
if (!add_element_edit (edits, element, mode))
goto error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!timeline_tree_add_edited_to_moving (root, edits, moving))
goto error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* snap */
if (!timeline_tree_snap (root, element, mode, &offset, moving, snap))
goto error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* check and set edits using snapped values */
give_edits_same_offset (edits, offset, layer_priority_offset);
if (!timeline_tree_set_element_edit_values (root, edits, error))
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto error;
/* check overlaps */
set_moving_positions_from_edits (moving, edits);
if (!timeline_tree_can_move_elements (root, moving, error)) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto error;
}
/* emit snapping now. Edits should only fail if a programming error
* occured */
if (snap)
ges_timeline_emit_snapping (root->data, snap->element, snap->snapped_to,
snap->snapped);
res = timeline_tree_perform_edits (root, edits);
2019-03-28 14:08:58 +00:00
done:
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
g_hash_table_unref (edits);
g_hash_table_unref (moving);
g_free (snap);
return res;
error:
2019-03-28 14:08:58 +00:00
res = FALSE;
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/********************************************
* Roll *
********************************************/
static gboolean
is_descendant (GESTimelineElement * element, GESTimelineElement * ancestor)
{
GESTimelineElement *parent = element;
while ((parent = parent->parent)) {
if (parent == ancestor)
return TRUE;
}
return FALSE;
}
static gboolean
find_neighbour (GNode * node, TreeIterationData * data)
{
GList *tmp;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
gboolean in_same_track = FALSE;
GESTimelineElement *edge_element, *element = node->data;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!GES_IS_SOURCE (element))
return FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* if the element is controlled by the trimmed element (a group or a
* clip) it is not a neighbour */
if (is_descendant (element, data->element))
return FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* test if we share a track with one of the sources at the edge */
for (tmp = data->sources; tmp; tmp = tmp->next) {
if (ges_track_element_get_track (GES_TRACK_ELEMENT (element)) ==
ges_track_element_get_track (tmp->data)) {
in_same_track = TRUE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
break;
}
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!in_same_track)
return FALSE;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* get the most toplevel element whose edge touches the position */
edge_element = NULL;
while (element && ELEMENT_EDGE_VALUE (element, data->edge) == data->position) {
edge_element = element;
element = element->parent;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (edge_element && !g_list_find (data->neighbours, edge_element))
data->neighbours = g_list_prepend (data->neighbours, edge_element);
return FALSE;
}
static gboolean
find_sources_at_position (GNode * node, TreeIterationData * data)
{
GESTimelineElement *element = node->data;
if (!GES_IS_SOURCE (element))
return FALSE;
if (ELEMENT_EDGE_VALUE (element, data->edge) == data->position)
data->sources = g_list_append (data->sources, element);
return FALSE;
}
gboolean
timeline_tree_roll (GNode * root, GESTimelineElement * element,
GstClockTimeDiff offset, GESEdge edge, GstClockTime snapping_distance,
GError ** error)
{
gboolean res = TRUE;
GList *tmp;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GNode *node;
TreeIterationData data = tree_iteration_data_init;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
GHashTable *edits = new_edit_table ();
GHashTable *moving = new_position_table ();
ElementEditMode mode;
SnappedPosition *snap = new_snapped_position (snapping_distance);
_REPLACE_TRACK_ELEMENT_WITH_PARENT (element);
/* if EDGE_END:
* TRIM_END the element, and TRIM_START the neighbouring clips to the
* end edge
* otherwise:
* TRIM_START the element, and TRIM_END the neighbouring clips to the
* start edge */
switch (edge) {
case GES_EDGE_END:
GST_INFO_OBJECT (element, "Rolling end with offset %"
G_GINT64_FORMAT, offset);
mode = EDIT_TRIM_END;
break;
case GES_EDGE_START:
GST_INFO_OBJECT (element, "Rolling start with offset %"
G_GINT64_FORMAT, offset);
mode = EDIT_TRIM_START;
break;
case GES_EDGE_NONE:
GST_WARNING_OBJECT (element, "Need to select an edge when rolling.");
goto done;
default:
GST_WARNING_OBJECT (element, "Edge not supported");
goto done;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* add edits */
if (!add_element_edit (edits, element, mode))
goto error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* first, find all the sources at the edge */
node = find_node (root, element);
if (!node) {
GST_ERROR_OBJECT (element, "Not being tracked");
goto error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
data.element = element;
data.edge = (edge == GES_EDGE_END) ? GES_EDGE_END : GES_EDGE_START;
data.position = ELEMENT_EDGE_VALUE (element, data.edge);
data.sources = NULL;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
g_node_traverse (node, G_IN_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) find_sources_at_position, &data);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* find elements that whose opposite edge touches the edge of the
* element and shares a track with one of the found sources */
data.edge = (edge == GES_EDGE_END) ? GES_EDGE_START : GES_EDGE_END;
data.neighbours = NULL;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_LEAVES, -1,
(GNodeTraverseFunc) find_neighbour, &data);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
for (tmp = data.neighbours; tmp; tmp = tmp->next) {
GESTimelineElement *clip = tmp->data;
ElementEditMode opposite =
(mode == EDIT_TRIM_END) ? EDIT_TRIM_START : EDIT_TRIM_END;
if (!add_element_edit (edits, clip, opposite))
goto error;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
if (!timeline_tree_add_edited_to_moving (root, edits, moving))
goto error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* snap */
if (!timeline_tree_snap (root, element, mode, &offset, moving, snap))
goto error;
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* check and set edits using snapped values */
give_edits_same_offset (edits, offset, 0);
if (!timeline_tree_set_element_edit_values (root, edits, error))
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto error;
/* check overlaps */
set_moving_positions_from_edits (moving, edits);
if (!timeline_tree_can_move_elements (root, moving, error)) {
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
goto error;
}
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
/* emit snapping now. Edits should only fail if a programming error
* occured */
if (snap)
ges_timeline_emit_snapping (root->data, snap->element, snap->snapped_to,
snap->snapped);
res = timeline_tree_perform_edits (root, edits);
done:
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
g_hash_table_unref (edits);
g_hash_table_unref (moving);
2019-04-08 20:25:44 +00:00
g_list_free (data.neighbours);
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
g_list_free (data.sources);
g_free (snap);
return res;
error:
res = FALSE;
goto done;
}
static void
create_transition_if_needed (GESTimeline * timeline, GESTrackElement * prev,
GESTrackElement * next, GESTreeGetAutoTransitionFunc get_auto_transition)
{
GstClockTime duration = _END (prev) - _START (next);
GESAutoTransition *trans =
get_auto_transition (timeline, prev, next, duration);
if (!trans) {
GESLayer *layer = ges_timeline_get_layer (timeline,
GES_TIMELINE_ELEMENT_LAYER_PRIORITY (prev));
gst_object_unref (layer);
GST_INFO ("Creating transition [%" G_GINT64_FORMAT " - %" G_GINT64_FORMAT
"]", _START (next), duration);
ges_timeline_create_transition (timeline, prev, next, NULL, layer,
_START (next), duration);
} else {
GST_INFO ("Already have transition %" GST_PTR_FORMAT " between %" GES_FORMAT
" and %" GES_FORMAT, trans, GES_ARGS (prev), GES_ARGS (next));
}
}
static gboolean
create_transitions (GNode * node,
GESTreeGetAutoTransitionFunc get_auto_transition)
{
TreeIterationData data = tree_iteration_data_init;
GESTimeline *timeline;
GESLayer *layer;
if (!GES_IS_SOURCE (node->data))
return FALSE;
timeline = GES_TIMELINE_ELEMENT_TIMELINE (node->data);
if (!timeline) {
GST_INFO ("%" GES_FORMAT " not in timeline yet", GES_ARGS (node->data));
return FALSE;
}
layer =
ges_timeline_get_layer (timeline,
GES_TIMELINE_ELEMENT_LAYER_PRIORITY (node->data));
gst_object_unref (layer);
if (!ges_layer_get_auto_transition (layer))
return FALSE;
GST_LOG_OBJECT (node->data, "Checking for overlaps");
timeline-tree: simplify and fix editing Editing has been simplified by breaking down each edit into a combination of three basic single-element edits: MOVE, TRIM_START, and TRIM_END. Each edit follows these steps: + Determine which elements are to be edited and under which basic mode + Determine which track elements will move as a result + Snap the edit position to one of the edges of the main edited element, (or the edge of one of its descendants, in the case of MOVE), avoiding moving elements. NOTE: in particular, we can *not* snap to the edge of a neighbouring element in a roll edit. This was previously possible, even though the neighbour was moving! + Determine the edit positions for clips (or track elements with no parent) using the snapped value. In addition, we replace any edits of a group with an edit of its descendant clips. If any value would be out of bounds (e.g. negative start) we do not edit. NOTE: this is now done *after* checking the snapping. This allows the edit to succeed if snapping would cause it to go from being invalid to valid! + Determine whether the collection of edits would result in a valid timeline-configuration which does not break the rules for sources overlapping. + If all this succeeds, we emit snapping-started on the timeline. + We then perform all the edits. At this point they should all succeed. The simplification/unification should make it easier to make other changes. Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/97 Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/98 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-04-27 12:58:38 +00:00
data.root = g_node_get_root (node);
check_all_overlaps_with_element (node, &data);
if (data.overlaping_on_start)
create_transition_if_needed (timeline,
GES_TRACK_ELEMENT (data.overlaping_on_start), node->data,
get_auto_transition);
if (data.overlaping_on_end)
create_transition_if_needed (timeline, node->data,
GES_TRACK_ELEMENT (data.overlaping_on_end), get_auto_transition);
return FALSE;
}
void
timeline_tree_create_transitions_for_track_element (GNode * root,
GESTrackElement * element, GESTreeGetAutoTransitionFunc get_auto_transition)
{
GNode *node = find_node (root, element);
g_assert (node);
create_transitions (node, get_auto_transition);
}
void
timeline_tree_create_transitions (GNode * root,
GESTreeGetAutoTransitionFunc get_auto_transition)
{
g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_LEAFS, -1,
(GNodeTraverseFunc) create_transitions, get_auto_transition);
}
static gboolean
compute_duration (GNode * node, GstClockTime * duration)
{
*duration = MAX (_END (node->data), *duration);
return FALSE;
}
GstClockTime
timeline_tree_get_duration (GNode * root)
{
GstClockTime duration = 0;
if (root->children)
g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_LEAFS, -1,
(GNodeTraverseFunc) compute_duration, &duration);
return duration;
}
static gboolean
reset_layer_activness (GNode * node, GESLayer * layer)
{
GESTrack *track;
if (!GES_IS_TRACK_ELEMENT (node->data))
return FALSE;
track = ges_track_element_get_track (node->data);
if (!track || (ges_timeline_element_get_layer_priority (node->data) !=
ges_layer_get_priority (layer)))
return FALSE;
ges_track_element_set_layer_active (node->data,
ges_layer_get_active_for_track (layer, track));
return FALSE;
}
void
timeline_tree_reset_layer_active (GNode * root, GESLayer * layer)
{
g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_LEAFS, -1,
(GNodeTraverseFunc) reset_layer_activness, layer);
}
static gboolean
set_is_smart_rendering (GNode * node, gboolean * is_rendering_smartly)
{
if (!GES_IS_SOURCE (node->data))
return FALSE;
ges_source_set_rendering_smartly (GES_SOURCE (node->data),
*is_rendering_smartly);
return FALSE;
}
void
timeline_tree_set_smart_rendering (GNode * root, gboolean rendering_smartly)
{
g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_LEAFS, -1,
(GNodeTraverseFunc) set_is_smart_rendering, &rendering_smartly);
}