Commit graph

134 commits

Author SHA1 Message Date
Henry Wilkes fd353705b9 clip: make sure core child is active for non-core in same track
Each active non-core child must have a corresponding active core child
in the same track. Therefore, if we de-activate a core child, we also
need to de-activate all the non-core children in the same track.
Similarly, if we activate a non-core child, we need to activate the
corresponding core child as well.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes 5159d367e2 clip: be more robust in handling priority
Make less assumptions about the priority of effects and core elements so
that the code would still work if the priority of an element was set
directly. In particular, the index of a top effect will always be its
position in the effect ordering.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes 52c22efea6 container: stop storing priority offset in child mapping
GESGroup no longer uses this, and GESClip can be made simpler without
it.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes 0a3da79e97 clip: preserve auto-transition in split
When splitting a clip, keep the auto-transition at the end of the clip
alive and move its source to that of the corresponding split track
element.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes 5c546c6fe7 clip: change order of split
We first change the duration of the splitted clip, then we add the new
clip to the layer and assign the tracks for its children. Normally, when
a clip is added to a layer it will have its track elements created, if
needed, and then assigned to their tracks. This will fail if any sources
would fully or triple overlap existing sources in the same track.

However, here we were adding the clip to the layer *and* avoiding the
track assignment process and instead setting the tracks explicitly. In
particular, the order was:

+ add new clip to layer with no tracks assigned
+ shrink the split clip
+ assign the tracks for the new clip

This has been changed to:

+ shrink the split clip
+ add new clip to layer with no tracks assigned
+ assign the tracks for the new clip

Thus, the order of events for any users connecting to object signals
will be close to that of adding another clip to the layer.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes a4cfa6d1e1 timeline: create auto-transitions during track-element-added
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>
2020-05-07 09:37:15 +01:00
Henry Wilkes 30a821e136 clip: make auto-transitions less expensive when adding to track
Only check the overlaps with the actual track element that was just added
to the track. This reduces the tree traversal by one order.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes aefc992ef1 timeline-element: stop using edit vmethods
These were all redirecting to essentially ges_timeline_element_edit
anyway.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes bac0df294e timeline-element: simplify check for being edited
It should be sufficient to set the edit flag only on the toplevel, which
allows all of its children to know they are being edited and should not
move in response.

Also, removed some unnecessary setting/checking of this.

Also, supplied the ges_timeline_element_peak_toplevel, which unlike
ges_timeline_element_get_toplevel_parent, does not add a reference to
the toplevel. Some corresponding leaks in auto-transition have been
fixed by using this instead.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes 39097f5574 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-05-07 09:37:15 +01:00
Henry Wilkes 4b62749336 clip: add the duration-limit property
The duration-limit is the maximum duration that can be set for the clip
given its current children and their properties. If a change in the
children properties causes this to drop below the current duration, it
is automatically capped by this limit.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Thibault Saunier 8f4688811f ges: Always check return value of ges_container_add
Making coverity happy

CIDs: 1461460, 1461461, 1461462, 1461463, 1461464, 1461465, 1461466, 1461468,
2020-04-10 11:12:12 -04:00
Thibault Saunier e41a6b6fac ges: Rework the way we ensure core elements are not wrongly moved between clips
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.
2020-04-08 14:35:28 +01:00
Henry Wilkes f698408176 clip: tidy grouping
Make the grouping of clips cleaner by checking that the clips share the
same asset.
2020-04-08 14:35:28 +01:00
Henry Wilkes e57c345f72 clip: secure adding clip to layer
Add more checks when adding a clip to a layer, or moving a clip to a new
layer. Also, mark the "layer" property as explicit-notify.
2020-04-08 14:35:28 +01:00
Henry Wilkes 269c2d1dc0 timeline: re-handle clip children track selection
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
2020-04-08 14:35:28 +01:00
Henry Wilkes a93e873402 clip: allow arbitrary max-duration when no core children
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.
2020-04-07 11:17:54 +01:00
Henry Wilkes 278a5fd796 track-element: change owner to creator
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.
2020-04-07 11:17:44 +01:00
Thibault Saunier e835042f04 ges: Add APIs to have a sens of frame numbers
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.
2020-03-25 11:26:29 -03:00
Thibault Saunier 7f0fc6fbed ges: Ensure GESClips assets are always ClipAssets 2020-03-25 11:26:29 -03:00
Thibault Saunier bd33ed972c ges: Add API to retrieve the natural framerate of an element 2020-03-25 11:26:27 -03:00
Thibault Saunier 314db9f1bd clip: Allow setting max-duration clips without TrackElements
Otherwise this breaks quite a few assumption in user code, several
pitivi tests broke because of that.
2020-03-18 21:58:11 -03:00
Thibault Saunier fc0333922f ges: Make it so core elements can be re added to their 'owners'
The user might want to add/remove/add core children to clips and be able
to regroup ungrouped clip. This is needed for undo/redo in Pitivi for
example
2020-03-18 21:58:11 -03:00
Henry Wilkes 658e64432d timeline-element: make max-duration cap in-point
Do not allow the in-point to exceed the max-duration of any timeline
element.
2020-03-16 14:19:52 +00:00
Henry Wilkes d03e0fa8c5 clip: only allow children with the same timeline
Refuse the addition of children whose timeline is neither NULL nor the
clip's timeline.
2020-03-16 14:19:52 +00:00
Henry Wilkes cd9cba55c0 clip: re-handle child in-point and max-duration
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.
2020-03-16 14:19:52 +00:00
Henry Wilkes dc4ca15ba8 clip: copy and paste control bindings
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.
2020-03-16 14:19:52 +00:00
Henry Wilkes 74ae0ba5df container: freeze notifies during add and remove
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).
2020-03-16 14:19:52 +00:00
Henry Wilkes 3af38e1719 clip: make remove_child a reverse of add_child
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.
2020-03-16 14:19:52 +00:00
Henry Wilkes d1276ed29b clip: tidy handling of child priorities
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
2020-03-16 14:19:52 +00:00
Henry Wilkes 91b5a5804a clip: only allow core elements as children
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.
2020-03-16 14:19:51 +00:00
Thibault Saunier 6b7c658b6a ges: Make setting start/duration move or trim generic
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
2020-03-09 11:48:37 -03:00
Thibault Saunier f8091262b5 clip: Don't split clips at illegal position
Make sure that when we split a clip, the resulting timeline would
not be in an illegal state.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/issues/94
2020-03-06 18:18:28 +00:00
Henry Wilkes f1d29e10e6 clip: allow for neither track nor type in search
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.
2020-03-05 17:04:51 -03:00
Henry Wilkes ac2da96144 docs: update GESClip 2020-03-05 16:59:37 -03:00
Henry Wilkes 7b5f655c9a ges-source-clip: fixed return of duration setter
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.
2019-12-14 18:12:51 +00:00
Thibault Saunier 3b95bec095 clip: Fix layer managament when copying a clip that was pasted 2019-06-05 00:43:48 +00:00
Thibault Saunier ded3a5fb2f element: Properly handle the fact that pasting can return NULL
And fix paste annotation
2019-06-05 00:43:48 +00:00
Thibault Saunier d87578c843 element: Make return value of setters mean something
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.
2019-05-02 12:10:11 -04:00
Thibault Saunier 2ab26ab306 ges: Move ges_container_edit to GESTimelineElement
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.
2019-05-01 12:24:30 -04:00
Alexandru Băluț 056198b15e clip: Optimize set_top_effect_index by checking parent sooner 2019-04-17 21:56:21 +00:00
Alexandru Băluț 5e008dbc77 clip: Return TRUE when the the effect index does not change 2019-04-17 21:56:21 +00:00
Alexandru Băluț 547a340629 clip: Remove obsolete FIXME 2019-04-17 21:56:21 +00:00
Thibault Saunier 521b0fc8b7 clip: Make sure to set the pasted clip start before adding to layer
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).
2019-03-15 23:51:55 +00:00
Thibault Saunier b294b56a76 clip: Emit signals while splitting in a way the operation is undoable
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.
2019-03-15 23:51:55 +00:00
Thibault Saunier a46390ff56 Reimplement the timeline editing API
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
2019-03-15 23:51:55 +00:00
Thibault Saunier 7c5f2d11b2 timeline-element: Add a method to retrieve layer priority
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
2019-03-15 23:51:55 +00:00
Thibault Saunier 69456e4f14 ges: Move GESClipFlags to GESTimelineElementFlags
Keeping it internal

And add an internal method to get layer priority for GESTimelineElements
(dirty implementation to make it simple for now)
2019-03-15 23:51:55 +00:00
Thibault Saunier 1c2784daa6 clip: Add a method to get the priority of the layer it is in
Just an helper method to get the 'priority of a the clip'
2019-03-15 23:51:55 +00:00
Thibault Saunier c901e4289a clip: Rollback moving clips when moving a contained TrackElement fails
And fix unit tests to match the correct behaviour
2019-03-15 23:51:55 +00:00