Instead of focusing on the instances of the clips and their children,
we relax the check to allow moving track element clip between clips
that share a common asset. This makes it as correct conceptually but
more flexible, and the code becomes simpler.
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
Before the max-duration could be set arbitrarily when the clip was empty,
to indicate what the max-duration would be once the core children were
created. Now, we can also do this whilst the clip only contains non-core
children.
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.
The in-point of a clip is kept in sync with its core children, unless they
have no has-internal-source.
The max-duration is defined as the minimum max-duration amongst the
clip's core children. If it is set to a new value, this sets the
max-duration of its core children to the same value if they have
has-internal-source set as TRUE.
Non-core children (such as effects on a source clip) do not influence
these values.
As part of this, we no longer track in-point in GESContainer. Unlike start
and duration, the in-point of a timeline element does not refer to its
extent in the timeline. As such, it has little meaning for most
collections of timeline-elements, in particular GESGroups. As such, there
is no generic way to relate the in-point of a container to its children.
Previously the control bindings were not properly copied into the pasted
clip. Also changed the order so that elements are added to the clip
before the clip is added to the timeline.
Hold the notify signals for the container and the children until after
the child has been fully added or removed.
After the previous commit, this was used to ensure that the
notify::priority signal was sent for children of a clip *after* the
child-removed signal. This stopped being the case when the code in
->child_removed was moved to ->remove_child (the latter is called before
the child-removed signal is emitted, whilst the former is called
afterwards). Rather than undo this move of code, which was necessary to
ensure that ->add_child was always reversed, the notify::priority signal
is now simply delayed until after removing the child has completed. This
was done for all notify signals, as well as in the add method, to ensure
consistency.
This allows the test_clips.py test_signal_order_when_removing_effect to
pass.
Also make subclasses take a copy of the list of the children before
setting the start and duration, since this can potentially re-order the
children (if they have the SET_SIMPLE flag set).
Previously, we relied on ->child_removed to reverse the priority changes
that occured in ->add_child. However, ->child_removed is not always
called (the signal child-removed is not always emitted) when a
->add_child needs to be removed. However, ->remove_child is always
called to reverse ->add_child, so the code was moved here. Otherwise, we
risk that the priorities of the clip will contain gaps, which will cause
problems when another child is added to the clip.
Handle the child priorities in a way that keeps the container children
list sorted by priority at all times. Also, no longer rely on the
control_mode of the container, since we have less control over its value,
compared to private variables.
Also fixed the changing of priorities in set_top_effect_index:
previously *all* children whose priority was above or below the new
priority were shifted, when we should have been only shifting priorities
for the children whose priority lied *between* the old and the new
priority of the effect. E.g.
effect: A B C D E F
index: 0 1 2 3 4 5
After moving effect E to index 1, previously, we would get
effect: A B C D E F
index: 0 2 3 4 1 6
(this would have also shifted the priority for the core children as
well!). Whereas now, we have the correct:
effect: A B C D E F
index: 0 2 3 4 1 5
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, either the track or track_type arguments had to be specified
in order to find **any** track elements. Now, you can specify neither,
which will match any track element, of the specified type.
In general, brought the behaviour of the `start`, `duration` and
`inpoint` setters in line with each other. In particular:
1. fixed return value the GESSourceClip `duration` setter
2. changed the GESClip `start` setter
3. fixed the inpoint callback for GESContainer
4. changed the type of `res` in GESTimelineElement to be gint to
emphasise that the GES library is using the hack that a return of -1
from klass->set_duration means no notify signal should be sent out.
Also added a new test for clips to ensure that the setters work for
clips within and outside of timelines, and that the `start`, `inpoint`
and `duration` of a clip will match its children.
Setters return values should return %FALSE **only** when the value
could not be set, not when unchanged or when the subclass handled
it itself!
This patches makes it so the return value is meaningul by allowing
subclasses return anything different than `TRUE` or `FALSE` (convention
is -1) to let the subclass now that it took care of everything and
no signal should be emited.
Now that the notion of layer has been moved down to #GESTimelineElement
(through the new #ges_timeline_element_get_layer_priority method), this
method make much more sense directly in the base class.
And handle the fact that adding to a layer can fail.
Also plug some leaks in the dispose method (and use the dispose
vmethod instead of finalize as appropriate).
Basically if we do not emit a "duration" change of the clip being
splitted first when executing the 'reverse' operations would lead
to fully overallaping clips.
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
Each timeline element is in a layer (potentially spanning
over several), it is very often useful to retrieve an element
layer priority (from an app perspective more than the element
priority itself as that is a bit of an implementation detail
in the end).
Port tests to it
Export GES library API in headers when we're building the
library itself, otherwise import the API from the headers.
This fixes linker warnings on Windows when building with MSVC.
Fix up some missing config.h includes when building the lib which
is needed to get the export api define from config.h
Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/issues/42
When removing an effect from a clip, first the notify::priority signals
were being emitted for the remaining effects which changed priority, and only
at the end the child-removed signal. Now the child-removed signal is emitted
first.
In the (now tested) scenario where we have a transition on the right
side of a clip we are splitting, auto transitions can't be created
because we resize the clip after adding the new one, meaning that
there are 3 elements in the "transition zone", we need to force
auto transition creation after the splitting.
Fixes https://gitlab.gnome.org/GNOME/pitivi/issues/2142
With two exceptions:
* ges_clip_create_track_elements_func
* ges_uri_clip_set_uri
which were never declared in headers and should always have been static.