Commit graph

309 commits

Author SHA1 Message Date
Henry Wilkes
34719efa17 timeline-tree: make sure the layer priority refers to an existing layer
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>
2020-05-25 11:20:38 +01:00
Henry Wilkes
53d335b4ed clip: add method for adding top effects
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>
2020-05-25 11:20:38 +01:00
Henry Wilkes
142456d8ba errors: added edit errors
Added more errors to GES_ERROR for when edits fail (other than
programming or usage errors). Also promoted some GST messages if they
related to a usage error.

Also added explanation of timeline overlap rules in user docs.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/177>
2020-05-22 19:15:57 +01:00
Thibault Saunier
56544604bc timeline: No thread checking while disposing
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>
2020-05-19 13:27:13 +00:00
Thibault Saunier
cb02c15d57 ges: Ensure that assets are added to project before adding clip to timeline
It is the right ordering and in Pitivi we set the project size
when adding the first (relevant) asset, meaning that our code to
reposition clips would kick in (in the unit tests) if we do not respect
that ordering.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/176>
2020-05-18 12:19:22 -04:00
Henry Wilkes
e89411527a track-element: Add is_core method to API
Open up the method to the user, since they may need the information.
Also added more documentation on what a core track element is to a clip
and how they are treated.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-13 12:57:10 +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
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
faa9d3990b timeline: make sure appended layer has lowest priority
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>
2020-05-07 09:37:15 +01:00
Henry Wilkes
36223e25b9 layer: don't set timeline when moving clip
If a clip is moving we should not unset its timeline when it is removed
from the layer. Logic has been moved to ges_timeline_add_clip and
ges_timeline_remove_clip.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes
343e8581f2 timeline-tree: freeze auto-transitions whilst editing
Freeze the auto-tranistions so they do not destroy themselves during an
edit. Once complete the auto-transitions can move themselves back into
position, or remove themselves if their sources are no longer
overlapping.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
2020-05-07 09:37:15 +01:00
Henry Wilkes
cda1cfa0df timeline: emit snapping-started with new valid time
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>
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
4daa0ecba4 timeline: fix adding track when layers contains clips
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>
2020-04-29 12:32:52 +00:00
Thibault Saunier
f548bb9232 timeline: Fix wrong usage of scale_int
We are multiplying the framerate by GST_SECOND and thus have no
guarantee that it won't overflow.
2020-04-16 12:56:10 -04:00
Thibault Saunier
d1444581f6 asset: Avoid dereferencing NULL pointer
CID 1461286
2020-04-10 11:12:12 -04:00
Thibault Saunier
fadde5cfb9 timeline: Ensure setting framerate in timeline_get_framerate
CID: 1461250, 1461288
2020-04-10 11:12:12 -04:00
Thibault Saunier
86c2681da6 ges: Cast to signed int to compare agasint 0
The check made sense but we were not casting to be able to check
signess of subtraction result.

CID: 1444923
2020-04-10 11:12:12 -04:00
Thibault Saunier
d81548a28a timeline: Do not compare unsigned with 0
Layer priorities are always positive the check was making no
sense in any case.

Fixes CID: 1444922, 1461284
2020-04-10 11:12:12 -04:00
Henry Wilkes
ef1c0f0faa group: tidied timeline membership in copy-paste
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.
2020-04-08 14:35:28 +01:00
Henry Wilkes
fe854bba69 timeline: return sunk element on pasting
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.
2020-04-08 14:35:28 +01:00
Henry Wilkes
067304a05f auto-transition: select track directly
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.
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
f7a1bdb289 timeline: stop connecting to track-element-added
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).
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
f9f30c4ced ges: Add a way to set layer activeness by track
a.k.a muting layers.

Adding unit tests and making sure serialization works properly
2020-03-25 15:40:25 -03:00
Thibault Saunier
dcb3ad620d ges: Plug some leaks 2020-03-25 11:26:29 -03: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
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
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
Henry Wilkes
a8458d59de timeline: fix layer priority argument in trim
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.
2020-03-05 17:04:51 -03:00
Henry Wilkes
615bf9e47a timeline: fix paste ownership
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.
2020-03-05 16:59:37 -03:00
Henry Wilkes
8ad9952cdb docs: update GESTimeline and GESLayer 2020-03-05 16:59:37 -03:00
Niels De Graef
35d140ad92 Don't pass default GLib marshallers for signals
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.
2019-10-24 15:19:09 +02:00
Thibault Saunier
d3e2cf55e3 tests: Fix transition project tests
Basically the test project was plain broken as it had fully overlapping
clips is prohibited since the timeline edition API was reimplemented.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-editing-services/issues/62
2019-08-28 13:51:02 +00:00
Matthew Waters
2e8528bb40 ges/timeline: remove unused function get_toplevel_container
Fixes -Werror build with clang:

../subprojects/gst-editing-services/ges/ges-timeline.c:695:1: warning: unused function 'get_toplevel_container' [-Wunused-function]
get_toplevel_container (gpointer element)
^
2019-08-27 03:58:42 +00:00
Thibault Saunier
a2b0dd3859 timeline: Make adding/removing track MT safe
It was almost the case already so make it happen fully
2019-07-05 18:11:04 -04:00
Thibault Saunier
eb53e62c6d timeline: Drop ASYNC_/START/DONE messages
When we have nested timelines, we do not want those messages to pop
to the parent timelines as we handle the sequence ourself in the
timeline.
2019-07-05 17:58:13 -04:00
Thibault Saunier
31ccb3106f timeline: Do not post upstream translated composition update messages
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).
2019-07-05 17:53:57 -04:00
Thibault Saunier
5ea4667be6 Implement and use the GstStream API 2019-07-05 17:53:15 -04:00
Thibault Saunier
5be359cf7f timeline: Create stable stream IDs 2019-07-05 17:52:55 -04:00
Thibault Saunier
b8c0894f34 docs: Minor documentation fixes 2019-05-23 18:54:42 -04:00
Sebastian Dröge
214987bd8a ges: Sprinkle around some Since: 1.16 markers 2019-05-16 15:09:13 +03:00
Thibault Saunier
d04bffc541 timeline: Plug leak of the auto transition asset 2019-04-15 17:11:48 -04: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
fa909a7cef timeline: Rename group_id to stream_start_group_id 2019-03-15 23:51:55 +00:00
Thibault Saunier
72519e6c5c timeline: No error when moving an object as part of the context
It will just happen from the context
2019-03-15 23:51:55 +00:00
Thibault Saunier
1a69f0d535 timeline: Not being able to trim and object is an error
So error out when that happens.
2019-03-15 23:51:55 +00:00
Thibault Saunier
100276d02a timeline: Setting duration to the same value is valid
And should not be advertised as if the operation failed.
2019-03-15 23:51:55 +00:00