If a layer priority sits between the priorities of two layers in the
timeline, i.e. it references a gap in the timeline's layers, then
ges_timeline_append_layer will never fill this gap and create the
desired layer, so the edit in timeline-tree would loop forever. So a
check was added to avoid this.
This would be a usage error, but a user can reasonably end up with a gap
in their layers if they remove a layer from the timeline.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/177>
Unlike ges_container_add, this lets you set the index and will check
that track selection did not fail. This is useful for time effects whose
addition would create an unsupported timeline configuration.
Also can use the clip add error in ges_timeline_add_clip to let the user
know when adding a clip to a layer that its in-point is set larger than
the max-duration of its core children.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/177>
While this is not correct, we can't predict from what thread a
GstElement will be disposed as it might still be referenced by
a GstMessage somewhere which is freed by, any thread.
In this specific case we can assume that GES user will already have
let go his timeline reference and we should not avoid assert in that
specific case as it should be safe to let the timeline be destroyed
at that point.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/175>
Any time a track element is added to a track, we need to check whether
we need to create a new corresponding auto-transition. This simply moves
the code from ges-clip.c to ges-timeline.c, where it is more appropriate.
Moreover, it technically opens the possibility for creating
auto-transitions for track elements in the timeline that have no
corresponding clip.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
Make sure that the priority of an appended layer is the lowest (highest
in value) when appending a layer to the timeline. This change is
important when appending a layer to a timeline, which can easily have a
gap in priorities if a layer has been removed.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
Only emit snapping-ended if we have a valid snap time. Moreover, we
should emit a new snapping-started even if we are snapping at the same
location. This is because a new snap will always correspond to a new edit,
possibly involving different snapping elements, which a user would want
to know about.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
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>
Made sure that adding a new track only uses select-tracks-for-object for
core children to determine whether a track elements should be added to the
new track or not, and *not* any other track. In particular, there should
be *no* change in the existing tracks of the timeline when adding another
track. Moreover, a new track should not invoke the creation of track
elements for other tracks.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/160>
Previously, the GESContainer ->paste method and GESGroup ->paste methods
were unnecessarily setting the timeline of groups, even though this is
handled by the GESGroup ->child_added method. This could result in the
group being added multiple times.
Technically, an element can still be floating on the return from
`->paste` (e.g. a clip not in a layer). Since the return of the `_paste`
methods are (return full) a non-floating object is probably expected in
all cases.
By-pass the select-tracks-for-object signal for auto-transitions since
their track element must land in the same track as the elements it is
the auto-transition for.
The way a clip's track elements are added to tracks was re-handled. This
doesn't affect the normal usage of a simple audio-video timeline, where
the tracks are added before any clips, but usage for multi-track
timelines has improved. The main changes are:
+ We can now handle a track being selected for more than one track,
including a full copy of their children properties and bindings.
(Previously broken.)
+ When a clip is split, we copy the new elements directly into the same
track, avoiding select-tracks-for-object.
+ When a clip is grouped or ungrouped, we avoid moving the elements to
or from tracks.
+ Added API to allow users to copy the core elements of a clip directly
into a track, complementing select-tracks-for-object.
+ Enforced the rule that a clip can only contain one core child in a
track, and all the non-core children must be added to tracks that
already contains a core child. This extends the previous condition
that two sources from the same clip should not be added to the same
track.
+ Made ges_track_add_element check that the newly added track element
does not break the configuration rules of the timeline.
+ When adding a track to a timeline, we only use
select-tracks-for-object to check whether track elements should be
added to the new track, not existing ones.
+ When removing a track from a timeline, we empty it of all the track
elements that are controlled by a clip. Thus, we ensure that a clip
only contains elements that are in the tracks of the same timeline, or
no track. Similarly, when removing a clip from a timeline.
+ We can now avoid unsupported timeline configurations when a layer is
added to a timeline, and already contains clips.
+ We can now avoid unsupported timeline configurations when a track is
added to a timeline, and the timeline already contains clips.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/issues/84
This was used to connect to the track element's notify::start signal in
order to update the duration of the timeline (it is not clear why the
notify::duration signal was not also connected to for the same reason).
However, this is already covered by the timeline_tree_move method, which
is always called to update the start of a track element, even if it is not
part of a clip (and similarly for timeline_tree_trim, which is called
when the duration is set).
Rename the private "owners" to "creators" to avoid confusing this with
the owner of the track element's memory.
Also made the ungroup method for GESClip symmetric by making all the
children of the resulting clips share their creators, which allows them
to be added to any of the other ungrouped clips. Once the clips are
grouped back together, the tracks loose these extra creators.
APIs:
- ges_timeline_get_frame_time
- ges_timeline_get_frame_at
- ges_clip_asset_get_frame_time
- ges_clip_get_timeline_time_from_source_frame
Extracting ges_util_structure_get_clocktime to internal utilities adding
support for specifying timing values in frames with the special
f<frame-number> synthax.
Only allow elements that were created by ges_clip_create_track_elements
(or copied from such an element) to be added to a clip. This prevents
users from adding arbitrary elements to a clip.
As an exception, a user can add GESBaseEffects to clips whose class
supports it, i.e. to a GESSourceClip and a GESBaseEffectClip.
This change also introduces a distinction between the core elements of a
clip (created by ges_clip_create_track_elements) and non-core elements
(currently, only GESBaseEffects, for some classes). In particular,
GESBaseEffectClip will now distinguish between its core elements and
effects added by the user. This means that the core elements will always
have the lowest priority, and will not be listed as top effects. This is
desirable because it brings the behaviour of GESBaseEffectClip in line
with other clip types.
We were implementing the logic for moving/trimming elements specific
to SourceClip but this was not correct ass the new timeline tree allows
us to handle that for all element types in a generic and nice way.
This make us need to have groups trimming properly implemented in the
timeline tree, leading to some fixes in the group tests.
This adds tests for the various cases known to not be handled properly
by the previous code.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/issues/92
Previously, we tested that the given priority was `>0`, when it seems
that `>=0` was intended. A priority of `-1` means leave the priority
unchanged, whilst a priority of 0, or more, means move to this layer
priority.
The method steals ownership of `copied_from`, so should be responsible
for unreffing it. Also make sure we fail when `layer != -1`, since this
functionality is not supported.
By passing NULL to `g_signal_new` instead of a marshaller, GLib will
actually internally optimize the signal (if the marshaller is available
in GLib itself) by also setting the valist marshaller. This makes the
signal emission a bit more performant than the regular marshalling,
which still needs to box into `GValue` and call libffi in case of a
generic marshaller.
Note that for custom marshallers, one would use
`g_signal_set_va_marshaller()` with the valist marshaller instead.
In the case of nested timeline in the toplevel timeline we ended up
with CompositionUpdate for seeks sent by our own composition to
granchildren composition. This was not causing essential issues
if all tracks where containing nested timelines but in cases
where one of the tracks only had a nested timelines, then we
were waiting forever for a `CompositionUpdateDone`.
CompositionUpdate translated into ASYNC_START/ASYNC_DONE should
be kept inside the GESTimeline and not travel up (possibly to some
parent GESTimeline).
This is implemented on top of a Tree that represents the whole timeline.
SourceClips can not fully overlap anymore and the tests have been
updated to take that into account. Some new tests were added to verify
that behaviour in greater details