Skip to main content

gstreamer_editing_services/auto/
clip.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5#![allow(deprecated)]
6
7#[cfg(feature = "v1_18")]
8#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
9use crate::FrameNumber;
10use crate::{
11    Asset, BaseEffect, Container, Extractable, Layer, MetaContainer, TimelineElement, Track,
12    TrackElement, TrackType, ffi,
13};
14use glib::{
15    prelude::*,
16    signal::{SignalHandlerId, connect_raw},
17    translate::*,
18};
19use std::boxed::Box as Box_;
20
21glib::wrapper! {
22    /// data, TRUE);
23    ///
24    ///  g_list_free_full (children, gst_object_unref);
25    ///  gst_object_unref (source);
26    /// }
27    /// ```text
28    ///
29    ///
30    /// This is an Abstract Base Class, you cannot instantiate it.
31    ///
32    /// ## Properties
33    ///
34    ///
35    /// #### `duration-limit`
36    ///  The maximum [`duration`][struct@crate::TimelineElement#duration] that can be *currently* set
37    /// for the clip, taking into account the [`in-point`][struct@crate::TimelineElement#in-point],
38    /// [`max-duration`][struct@crate::TimelineElement#max-duration], [`active`][struct@crate::TrackElement#active], and
39    /// [`track`][struct@crate::TrackElement#track] properties of its children, as well as any
40    /// time effects. If there is no limit, this will be set to
41    /// `GST_CLOCK_TIME_NONE`.
42    ///
43    /// Note that whilst a clip has no children in any tracks, the limit will
44    /// be unknown, and similarly set to `GST_CLOCK_TIME_NONE`.
45    ///
46    /// If the duration-limit would ever go below the current
47    /// [`duration`][struct@crate::TimelineElement#duration] of the clip due to a change in the above
48    /// variables, its [`duration`][struct@crate::TimelineElement#duration] will be set to the new
49    /// limit.
50    ///
51    /// Readable
52    ///
53    ///
54    /// #### `layer`
55    ///  The layer this clip lies in.
56    ///
57    /// If you want to connect to this property's [`notify`][struct@crate::glib::Object#notify] signal,
58    /// you should connect to it with `g_signal_connect_after()` since the
59    /// signal emission may be stopped internally.
60    ///
61    /// Readable
62    ///
63    ///
64    /// #### `supported-formats`
65    ///  The [`TrackType`][crate::TrackType]-s that the clip supports, which it can create
66    /// [`TrackElement`][crate::TrackElement]-s for. Note that this can be a combination of
67    /// [`TrackType`][crate::TrackType] flags to indicate support for several
68    /// [`track-type`][struct@crate::TrackElement#track-type] elements.
69    ///
70    /// Readable | Writable | Construct
71    /// <details><summary><h4>Container</h4></summary>
72    ///
73    ///
74    /// #### `height`
75    ///  The span of the container's children's [`priority`][struct@crate::TimelineElement#priority]
76    /// values, which is the number of integers that lie between (inclusive)
77    /// the minimum and maximum priorities found amongst the container's
78    /// children (maximum - minimum + 1).
79    ///
80    /// Readable
81    /// </details>
82    /// <details><summary><h4>TimelineElement</h4></summary>
83    ///
84    ///
85    /// #### `duration`
86    ///  The duration that the element is in effect for in the timeline (a
87    /// time difference in nanoseconds using the time coordinates of the
88    /// timeline). For example, for a source element, this would determine
89    /// for how long it should output its internal content for. For an
90    /// operation element, this would determine for how long its effect
91    /// should be applied to any source content.
92    ///
93    /// Readable | Writable
94    ///
95    ///
96    /// #### `in-point`
97    ///  The initial offset to use internally when outputting content (in
98    /// nanoseconds, but in the time coordinates of the internal content).
99    ///
100    /// For example, for a [`VideoUriSource`][crate::VideoUriSource] that references some media
101    /// file, the "internal content" is the media file data, and the
102    /// in-point would correspond to some timestamp in the media file.
103    /// When playing the timeline, and when the element is first reached at
104    /// timeline-time [`start`][struct@crate::TimelineElement#start], it will begin outputting the
105    /// data from the timestamp in-point **onwards**, until it reaches the
106    /// end of its [`duration`][struct@crate::TimelineElement#duration] in the timeline.
107    ///
108    /// For elements that have no internal content, this should be kept
109    /// as 0.
110    ///
111    /// Readable | Writable
112    ///
113    ///
114    /// #### `max-duration`
115    ///  The full duration of internal content that is available (a time
116    /// difference in nanoseconds using the time coordinates of the internal
117    /// content).
118    ///
119    /// This will act as a cap on the [`in-point`][struct@crate::TimelineElement#in-point] of the
120    /// element (which is in the same time coordinates), and will sometimes
121    /// be used to limit the [`duration`][struct@crate::TimelineElement#duration] of the element in
122    /// the timeline.
123    ///
124    /// For example, for a [`VideoUriSource`][crate::VideoUriSource] that references some media
125    /// file, this would be the length of the media file.
126    ///
127    /// For elements that have no internal content, or whose content is
128    /// indefinite, this should be kept as `GST_CLOCK_TIME_NONE`.
129    ///
130    /// Readable | Writable | Construct
131    ///
132    ///
133    /// #### `name`
134    ///  The name of the element. This should be unique within its timeline.
135    ///
136    /// Readable | Writable | Construct
137    ///
138    ///
139    /// #### `parent`
140    ///  The parent container of the element.
141    ///
142    /// Readable | Writable
143    ///
144    ///
145    /// #### `priority`
146    ///  The priority of the element.
147    ///
148    /// Readable | Writable
149    ///
150    ///
151    /// #### `serialize`
152    ///  Whether the element should be serialized.
153    ///
154    /// Readable | Writable
155    ///
156    ///
157    /// #### `start`
158    ///  The starting position of the element in the timeline (in nanoseconds
159    /// and in the time coordinates of the timeline). For example, for a
160    /// source element, this would determine the time at which it should
161    /// start outputting its internal content. For an operation element, this
162    /// would determine the time at which it should start applying its effect
163    /// to any source content.
164    ///
165    /// Readable | Writable
166    ///
167    ///
168    /// #### `timeline`
169    ///  The timeline that the element lies within.
170    ///
171    /// Readable | Writable
172    /// </details>
173    ///
174    /// # Implements
175    ///
176    /// [`ClipExt`][trait@crate::prelude::ClipExt], [`GESContainerExt`][trait@crate::prelude::GESContainerExt], [`TimelineElementExt`][trait@crate::prelude::TimelineElementExt], [`trait@glib::ObjectExt`], [`ExtractableExt`][trait@crate::prelude::ExtractableExt], [`MetaContainerExt`][trait@crate::prelude::MetaContainerExt], [`TimelineElementExtManual`][trait@crate::prelude::TimelineElementExtManual]
177    #[doc(alias = "GESClip")]
178    pub struct Clip(Object<ffi::GESClip, ffi::GESClipClass>) @extends Container, TimelineElement, @implements Extractable, MetaContainer;
179
180    match fn {
181        type_ => || ffi::ges_clip_get_type(),
182    }
183}
184
185impl Clip {
186    pub const NONE: Option<&'static Clip> = None;
187}
188
189/// Trait containing all [`struct@Clip`] methods.
190///
191/// # Implementors
192///
193/// [`Clip`][struct@crate::Clip], [`OperationClip`][struct@crate::OperationClip], [`SourceClip`][struct@crate::SourceClip]
194pub trait ClipExt: IsA<Clip> + 'static {
195    /// Extracts a [`TrackElement`][crate::TrackElement] from an asset and adds it to the clip.
196    /// This can be used to add effects that derive from the asset to the
197    /// clip, but this method is not intended to be used to create the core
198    /// elements of the clip.
199    ///
200    /// # Deprecated since 1.30
201    ///
202    /// Use [`add_asset_full()`][Self::add_asset_full()] instead for MT-safety.
203    /// ## `asset`
204    /// An asset with `GES_TYPE_TRACK_ELEMENT` as its
205    /// [`extractable-type`][struct@crate::Asset#extractable-type]
206    ///
207    /// # Returns
208    ///
209    /// The newly created element, or
210    /// [`None`] if an error occurred.
211    #[cfg_attr(feature = "v1_30", deprecated = "Since 1.30")]
212    #[allow(deprecated)]
213    #[doc(alias = "ges_clip_add_asset")]
214    fn add_asset(&self, asset: &impl IsA<Asset>) -> Result<TrackElement, glib::BoolError> {
215        unsafe {
216            Option::<_>::from_glib_none(ffi::ges_clip_add_asset(
217                self.as_ref().to_glib_none().0,
218                asset.as_ref().to_glib_none().0,
219            ))
220            .ok_or_else(|| glib::bool_error!("Failed to add asset"))
221        }
222    }
223
224    /// Extracts a [`TrackElement`][crate::TrackElement] from an asset and adds it to the clip.
225    /// This can be used to add effects that derive from the asset to the
226    /// clip, but this method is not intended to be used to create the core
227    /// elements of the clip.
228    /// ## `asset`
229    /// An asset with `GES_TYPE_TRACK_ELEMENT` as its
230    /// [`extractable-type`][struct@crate::Asset#extractable-type]
231    ///
232    /// # Returns
233    ///
234    /// The newly created element, or
235    /// [`None`] if an error occurred.
236    #[cfg(feature = "v1_30")]
237    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
238    #[doc(alias = "ges_clip_add_asset_full")]
239    fn add_asset_full(&self, asset: &impl IsA<Asset>) -> Option<TrackElement> {
240        unsafe {
241            from_glib_full(ffi::ges_clip_add_asset_full(
242                self.as_ref().to_glib_none().0,
243                asset.as_ref().to_glib_none().0,
244            ))
245        }
246    }
247
248    /// Adds the track element child of the clip to a specific track.
249    ///
250    /// If the given child is already in another track, this will create a copy
251    /// of the child, add it to the clip, and add this copy to the track.
252    ///
253    /// You should only call this whilst a clip is part of a [`Timeline`][crate::Timeline], and
254    /// for tracks that are in the same timeline.
255    ///
256    /// This method is an alternative to using the
257    /// [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object] signal, but can be used to
258    /// complement it when, say, you wish to copy a clip's children from one
259    /// track into a new one.
260    ///
261    /// When the child is a core child, it must be added to a track that does
262    /// not already contain another core child of the same clip. If it is not a
263    /// core child (an additional effect), then it must be added to a track
264    /// that already contains one of the core children of the same clip.
265    ///
266    /// This method can also fail if the adding the track element to the track
267    /// would break a configuration rule of the corresponding [`Timeline`][crate::Timeline],
268    /// such as causing three sources to overlap at a single time, or causing
269    /// a source to completely overlap another in the same track.
270    ///
271    /// # Deprecated since 1.30
272    ///
273    /// Use [`add_child_to_track_full()`][Self::add_child_to_track_full()] instead for MT-safety.
274    /// ## `child`
275    /// A child of `self`
276    /// ## `track`
277    /// The track to add `child` to
278    ///
279    /// # Returns
280    ///
281    /// The element that was added to `track`, either
282    /// `child` or a copy of child, or [`None`] if the element could not be added.
283    #[cfg_attr(feature = "v1_30", deprecated = "Since 1.30")]
284    #[cfg(feature = "v1_18")]
285    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
286    #[allow(deprecated)]
287    #[doc(alias = "ges_clip_add_child_to_track")]
288    fn add_child_to_track(
289        &self,
290        child: &impl IsA<TrackElement>,
291        track: &impl IsA<Track>,
292    ) -> Result<TrackElement, glib::Error> {
293        unsafe {
294            let mut error = std::ptr::null_mut();
295            let ret = ffi::ges_clip_add_child_to_track(
296                self.as_ref().to_glib_none().0,
297                child.as_ref().to_glib_none().0,
298                track.as_ref().to_glib_none().0,
299                &mut error,
300            );
301            if error.is_null() {
302                Ok(from_glib_none(ret))
303            } else {
304                Err(from_glib_full(error))
305            }
306        }
307    }
308
309    /// Adds the track element child of the clip to a specific track.
310    ///
311    /// If the given child is already in another track, this will create a copy
312    /// of the child, add it to the clip, and add this copy to the track.
313    ///
314    /// You should only call this whilst a clip is part of a [`Timeline`][crate::Timeline], and
315    /// for tracks that are in the same timeline.
316    ///
317    /// This method is an alternative to using the
318    /// [`select-tracks-for-object`][struct@crate::Timeline#select-tracks-for-object] signal, but can be used to
319    /// complement it when, say, you wish to copy a clip's children from one
320    /// track into a new one.
321    ///
322    /// When the child is a core child, it must be added to a track that does
323    /// not already contain another core child of the same clip. If it is not a
324    /// core child (an additional effect), then it must be added to a track
325    /// that already contains one of the core children of the same clip.
326    ///
327    /// This method can also fail if the adding the track element to the track
328    /// would break a configuration rule of the corresponding [`Timeline`][crate::Timeline],
329    /// such as causing three sources to overlap at a single time, or causing
330    /// a source to completely overlap another in the same track.
331    /// ## `child`
332    /// A child of `self`
333    /// ## `track`
334    /// The track to add `child` to
335    ///
336    /// # Returns
337    ///
338    /// The element that was added to `track`, either
339    /// `child` or a copy of child, or [`None`] if the element could not be added.
340    #[cfg(feature = "v1_30")]
341    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
342    #[doc(alias = "ges_clip_add_child_to_track_full")]
343    fn add_child_to_track_full(
344        &self,
345        child: &impl IsA<TrackElement>,
346        track: &impl IsA<Track>,
347    ) -> Result<TrackElement, glib::Error> {
348        unsafe {
349            let mut error = std::ptr::null_mut();
350            let ret = ffi::ges_clip_add_child_to_track_full(
351                self.as_ref().to_glib_none().0,
352                child.as_ref().to_glib_none().0,
353                track.as_ref().to_glib_none().0,
354                &mut error,
355            );
356            if error.is_null() {
357                Ok(from_glib_full(ret))
358            } else {
359                Err(from_glib_full(error))
360            }
361        }
362    }
363
364    /// Add a top effect to a clip at the given index.
365    ///
366    /// Unlike using [`GESContainerExt::add()`][crate::prelude::GESContainerExt::add()], this allows you to set the index
367    /// in advance. It will also check that no error occurred during the track
368    /// selection for the effect.
369    ///
370    /// Note, only subclasses of `GESClipClass` that have
371    /// `GES_CLIP_CLASS_CAN_ADD_EFFECTS` set to [`true`] (such as [`SourceClip`][crate::SourceClip]
372    /// and [`BaseEffectClip`][crate::BaseEffectClip]) can have additional top effects added.
373    ///
374    /// Note, if the effect is a time effect, this may be refused if the clip
375    /// would not be able to adapt itself once the effect is added.
376    /// ## `effect`
377    /// A top effect to add
378    /// ## `index`
379    /// The index to add `effect` at, or -1 to add at the highest,
380    ///  see `ges_clip_get_top_effect_index` for more information
381    ///
382    /// # Returns
383    ///
384    /// [`true`] if `effect` was successfully added to `self` at `index`.
385    #[cfg(feature = "v1_18")]
386    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
387    #[doc(alias = "ges_clip_add_top_effect")]
388    fn add_top_effect(&self, effect: &impl IsA<BaseEffect>, index: i32) -> Result<(), glib::Error> {
389        unsafe {
390            let mut error = std::ptr::null_mut();
391            let is_ok = ffi::ges_clip_add_top_effect(
392                self.as_ref().to_glib_none().0,
393                effect.as_ref().to_glib_none().0,
394                index,
395                &mut error,
396            );
397            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
398            if error.is_null() {
399                Ok(())
400            } else {
401                Err(from_glib_full(error))
402            }
403        }
404    }
405
406    /// Finds an element controlled by the clip. If `track` is given,
407    /// then only the track elements in `track` are searched for. If `type_` is
408    /// given, then this function searches for a track element of the given
409    /// `type_`.
410    ///
411    /// Note, if multiple track elements in the clip match the given criteria,
412    /// this will return the element amongst them with the highest
413    /// [`priority`][struct@crate::TimelineElement#priority] (numerically, the smallest). See
414    /// [`find_track_elements()`][Self::find_track_elements()] if you wish to find all such elements.
415    /// ## `track`
416    /// The track to search in, or [`None`] to search in
417    /// all tracks
418    /// ## `type_`
419    /// The type of track element to search for, or `G_TYPE_NONE` to
420    /// match any type
421    ///
422    /// # Returns
423    ///
424    /// The element controlled by
425    /// `self`, in `track`, and of the given `type_`, or [`None`] if no such element
426    /// could be found.
427    #[doc(alias = "ges_clip_find_track_element")]
428    fn find_track_element(
429        &self,
430        track: Option<&impl IsA<Track>>,
431        type_: glib::types::Type,
432    ) -> Option<TrackElement> {
433        unsafe {
434            from_glib_full(ffi::ges_clip_find_track_element(
435                self.as_ref().to_glib_none().0,
436                track.map(|p| p.as_ref()).to_glib_none().0,
437                type_.into_glib(),
438            ))
439        }
440    }
441
442    /// Finds the [`TrackElement`][crate::TrackElement]-s controlled by the clip that match the
443    /// given criteria. If `track` is given as [`None`] and `track_type` is given as
444    /// [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN], then the search will match all elements in any
445    /// track, including those with no track, and of any
446    /// [`track-type`][struct@crate::TrackElement#track-type]. Otherwise, if `track` is not [`None`], but
447    /// `track_type` is [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN], then only the track elements in
448    /// `track` are searched for. Otherwise, if `track_type` is not
449    /// [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN], but `track` is [`None`], then only the track
450    /// elements whose [`track-type`][struct@crate::TrackElement#track-type] matches `track_type` are
451    /// searched for. Otherwise, when both are given, the track elements that
452    /// match **either** criteria are searched for. Therefore, if you wish to
453    /// only find elements in a specific track, you should give the track as
454    /// `track`, but you should not give the track's [`track-type`][struct@crate::Track#track-type] as
455    /// `track_type` because this would also select elements from other tracks
456    /// of the same type.
457    ///
458    /// You may also give `type_` to _further_ restrict the search to track
459    /// elements of the given `type_`.
460    /// ## `track`
461    /// The track to search in, or [`None`] to search in
462    /// all tracks
463    /// ## `track_type`
464    /// The track-type of the track element to search for, or
465    /// [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN] to match any track type
466    /// ## `type_`
467    /// The type of track element to search for, or `G_TYPE_NONE` to
468    /// match any type
469    ///
470    /// # Returns
471    ///
472    /// A list of all
473    /// the [`TrackElement`][crate::TrackElement]-s controlled by `self`, in `track` or of the given
474    /// `track_type`, and of the given `type_`.
475    #[doc(alias = "ges_clip_find_track_elements")]
476    fn find_track_elements(
477        &self,
478        track: Option<&impl IsA<Track>>,
479        track_type: TrackType,
480        type_: glib::types::Type,
481    ) -> Vec<TrackElement> {
482        unsafe {
483            FromGlibPtrContainer::from_glib_full(ffi::ges_clip_find_track_elements(
484                self.as_ref().to_glib_none().0,
485                track.map(|p| p.as_ref()).to_glib_none().0,
486                track_type.into_glib(),
487                type_.into_glib(),
488            ))
489        }
490    }
491
492    /// Gets the [`duration-limit`][struct@crate::Clip#duration-limit] of the clip.
493    ///
494    /// # Returns
495    ///
496    /// The duration-limit of `self`.
497    #[cfg(feature = "v1_18")]
498    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
499    #[doc(alias = "ges_clip_get_duration_limit")]
500    #[doc(alias = "get_duration_limit")]
501    #[doc(alias = "duration-limit")]
502    fn duration_limit(&self) -> gst::ClockTime {
503        unsafe {
504            try_from_glib(ffi::ges_clip_get_duration_limit(
505                self.as_ref().to_glib_none().0,
506            ))
507            .expect("mandatory glib value is None")
508        }
509    }
510
511    /// Convert the timeline time to an internal source time of the child.
512    /// This will take any time effects placed on the clip into account (see
513    /// [`BaseEffect`][crate::BaseEffect] for what time effects are supported, and how to
514    /// declare them in GES).
515    ///
516    /// When `timeline_time` is above the [`start`][struct@crate::TimelineElement#start] of `self`,
517    /// this will return the internal time at which the content that appears at
518    /// `timeline_time` in the output of the timeline is created in `child`. For
519    /// example, if `timeline_time` corresponds to the current seek position,
520    /// this would let you know which part of a media file is being read.
521    ///
522    /// This will be done assuming the clip has an indefinite end, so the
523    /// internal time may be beyond the current out-point of the child, or even
524    /// its [`max-duration`][struct@crate::TimelineElement#max-duration].
525    ///
526    /// If, instead, `timeline_time` is below the current
527    /// [`start`][struct@crate::TimelineElement#start] of `self`, this will return what you would
528    /// need to set the [`in-point`][struct@crate::TimelineElement#in-point] of `child` to if you set
529    /// the [`start`][struct@crate::TimelineElement#start] of `self` to `timeline_time` and wanted
530    /// to keep the content of `child` currently found at the current
531    /// [`start`][struct@crate::TimelineElement#start] of `self` at the same timeline position. If
532    /// this would be negative, the conversion fails. This is useful for
533    /// determining what [`in-point`][struct@crate::TimelineElement#in-point] would result from a
534    /// [`EditMode::Trim`][crate::EditMode::Trim] to `timeline_time`.
535    ///
536    /// Note that whilst a clip has no time effects, this second return is
537    /// equivalent to finding the internal time at which the content that
538    /// appears at `timeline_time` in the timeline can be found in `child` if it
539    /// had indefinite extent in both directions. However, with non-linear time
540    /// effects this second return will be more distinct.
541    ///
542    /// In either case, the returned time would be appropriate to use for the
543    /// [`in-point`][struct@crate::TimelineElement#in-point] or [`max-duration`][struct@crate::TimelineElement#max-duration] of the
544    /// child.
545    ///
546    /// See [`timeline_time_from_internal_time()`][Self::timeline_time_from_internal_time()], which performs the
547    /// reverse.
548    /// ## `child`
549    /// An [`active`][struct@crate::TrackElement#active] child of `self` with a
550    /// [`track`][struct@crate::TrackElement#track]
551    /// ## `timeline_time`
552    /// A time in the timeline time coordinates
553    ///
554    /// # Returns
555    ///
556    /// The time in the internal coordinates of `child` corresponding
557    /// to `timeline_time`, or `GST_CLOCK_TIME_NONE` if the conversion could not
558    /// be performed.
559    #[cfg(feature = "v1_18")]
560    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
561    #[doc(alias = "ges_clip_get_internal_time_from_timeline_time")]
562    #[doc(alias = "get_internal_time_from_timeline_time")]
563    fn internal_time_from_timeline_time(
564        &self,
565        child: &impl IsA<TrackElement>,
566        timeline_time: impl Into<Option<gst::ClockTime>>,
567    ) -> Result<Option<gst::ClockTime>, glib::Error> {
568        unsafe {
569            let mut error = std::ptr::null_mut();
570            let ret = ffi::ges_clip_get_internal_time_from_timeline_time(
571                self.as_ref().to_glib_none().0,
572                child.as_ref().to_glib_none().0,
573                timeline_time.into().into_glib(),
574                &mut error,
575            );
576            if error.is_null() {
577                Ok(from_glib(ret))
578            } else {
579                Err(from_glib_full(error))
580            }
581        }
582    }
583
584    /// Gets the [`layer`][struct@crate::Clip#layer] of the clip.
585    ///
586    /// # Returns
587    ///
588    /// The layer `self` is in, or [`None`] if
589    /// `self` is not in any layer.
590    #[doc(alias = "ges_clip_get_layer")]
591    #[doc(alias = "get_layer")]
592    fn layer(&self) -> Option<Layer> {
593        unsafe { from_glib_full(ffi::ges_clip_get_layer(self.as_ref().to_glib_none().0)) }
594    }
595
596    /// Gets the [`supported-formats`][struct@crate::Clip#supported-formats] of the clip.
597    ///
598    /// # Returns
599    ///
600    /// The [`TrackType`][crate::TrackType]-s supported by `self`.
601    #[doc(alias = "ges_clip_get_supported_formats")]
602    #[doc(alias = "get_supported_formats")]
603    #[doc(alias = "supported-formats")]
604    fn supported_formats(&self) -> TrackType {
605        unsafe {
606            from_glib(ffi::ges_clip_get_supported_formats(
607                self.as_ref().to_glib_none().0,
608            ))
609        }
610    }
611
612    /// Convert the internal source time from the child to a timeline time.
613    /// This will take any time effects placed on the clip into account (see
614    /// [`BaseEffect`][crate::BaseEffect] for what time effects are supported, and how to
615    /// declare them in GES).
616    ///
617    /// When `internal_time` is above the [`in-point`][struct@crate::TimelineElement#in-point] of
618    /// `child`, this will return the timeline time at which the internal
619    /// content found at `internal_time` appears in the output of the timeline's
620    /// track. For example, this would let you know where in the timeline a
621    /// particular scene in a media file would appear.
622    ///
623    /// This will be done assuming the clip has an indefinite end, so the
624    /// timeline time may be beyond the end of the clip, or even breaking its
625    /// [`duration-limit`][struct@crate::Clip#duration-limit].
626    ///
627    /// If, instead, `internal_time` is below the current
628    /// [`in-point`][struct@crate::TimelineElement#in-point] of `child`, this will return what you would
629    /// need to set the [`start`][struct@crate::TimelineElement#start] of `self` to if you set the
630    /// [`in-point`][struct@crate::TimelineElement#in-point] of `child` to `internal_time` and wanted to
631    /// keep the content of `child` currently found at the current
632    /// [`start`][struct@crate::TimelineElement#start] of `self` at the same timeline position. If
633    /// this would be negative, the conversion fails. This is useful for
634    /// determining what position to use in a [`EditMode::Trim`][crate::EditMode::Trim] if you wish
635    /// to trim to a specific point in the internal content, such as a
636    /// particular scene in a media file.
637    ///
638    /// Note that whilst a clip has no time effects, this second return is
639    /// equivalent to finding the timeline time at which the content of `child`
640    /// at `internal_time` would be found in the timeline if it had indefinite
641    /// extent in both directions. However, with non-linear time effects this
642    /// second return will be more distinct.
643    ///
644    /// In either case, the returned time would be appropriate to use in
645    /// [`TimelineElementExt::edit()`][crate::prelude::TimelineElementExt::edit()] for [`EditMode::Trim`][crate::EditMode::Trim], and similar, if
646    /// you wish to use a particular internal point as a reference. For
647    /// example, you could choose to end a clip at a certain internal
648    /// 'out-point', similar to the [`in-point`][struct@crate::TimelineElement#in-point], by
649    /// translating the desired end time into the timeline coordinates, and
650    /// using this position to trim the end of a clip.
651    ///
652    /// See [`internal_time_from_timeline_time()`][Self::internal_time_from_timeline_time()], which performs the
653    /// reverse, or [`timeline_time_from_source_frame()`][Self::timeline_time_from_source_frame()] which does
654    /// the same conversion, but using frame numbers.
655    /// ## `child`
656    /// An [`active`][struct@crate::TrackElement#active] child of `self` with a
657    /// [`track`][struct@crate::TrackElement#track]
658    /// ## `internal_time`
659    /// A time in the internal time coordinates of `child`
660    ///
661    /// # Returns
662    ///
663    /// The time in the timeline coordinates corresponding to
664    /// `internal_time`, or `GST_CLOCK_TIME_NONE` if the conversion could not be
665    /// performed.
666    #[cfg(feature = "v1_18")]
667    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
668    #[doc(alias = "ges_clip_get_timeline_time_from_internal_time")]
669    #[doc(alias = "get_timeline_time_from_internal_time")]
670    fn timeline_time_from_internal_time(
671        &self,
672        child: &impl IsA<TrackElement>,
673        internal_time: impl Into<Option<gst::ClockTime>>,
674    ) -> Result<Option<gst::ClockTime>, glib::Error> {
675        unsafe {
676            let mut error = std::ptr::null_mut();
677            let ret = ffi::ges_clip_get_timeline_time_from_internal_time(
678                self.as_ref().to_glib_none().0,
679                child.as_ref().to_glib_none().0,
680                internal_time.into().into_glib(),
681                &mut error,
682            );
683            if error.is_null() {
684                Ok(from_glib(ret))
685            } else {
686                Err(from_glib_full(error))
687            }
688        }
689    }
690
691    /// Convert the source frame number to a timeline time. This acts the same
692    /// as [`timeline_time_from_internal_time()`][Self::timeline_time_from_internal_time()] using the core
693    /// children of the clip and using the frame number to specify the internal
694    /// position, rather than a timestamp.
695    ///
696    /// The returned timeline time can be used to seek or edit to a specific
697    /// frame.
698    ///
699    /// Note that you can get the frame timestamp of a particular clip asset
700    /// with [`ClipAssetExt::frame_time()`][crate::prelude::ClipAssetExt::frame_time()].
701    /// ## `frame_number`
702    /// The frame number to get the corresponding timestamp of
703    /// in the timeline coordinates
704    ///
705    /// # Returns
706    ///
707    /// The timestamp corresponding to `frame_number` in the core
708    /// children of `self`, in the timeline coordinates, or `GST_CLOCK_TIME_NONE`
709    /// if the conversion could not be performed.
710    #[cfg(feature = "v1_18")]
711    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
712    #[doc(alias = "ges_clip_get_timeline_time_from_source_frame")]
713    #[doc(alias = "get_timeline_time_from_source_frame")]
714    fn timeline_time_from_source_frame(
715        &self,
716        frame_number: FrameNumber,
717    ) -> Result<Option<gst::ClockTime>, glib::Error> {
718        unsafe {
719            let mut error = std::ptr::null_mut();
720            let ret = ffi::ges_clip_get_timeline_time_from_source_frame(
721                self.as_ref().to_glib_none().0,
722                frame_number,
723                &mut error,
724            );
725            if error.is_null() {
726                Ok(from_glib(ret))
727            } else {
728                Err(from_glib_full(error))
729            }
730        }
731    }
732
733    /// Gets the internal index of an effect in the clip. The index of effects
734    /// in a clip will run from 0 to n-1, where n is the total number of
735    /// effects. If two effects share the same [`track`][struct@crate::TrackElement#track], the
736    /// effect with the numerically lower index will be applied to the source
737    /// data **after** the other effect, i.e. output data will always flow from
738    /// a higher index effect to a lower index effect.
739    /// ## `effect`
740    /// The effect we want to get the index of
741    ///
742    /// # Returns
743    ///
744    /// The index of `effect` in `self`, or -1 if something went wrong.
745    #[doc(alias = "ges_clip_get_top_effect_index")]
746    #[doc(alias = "get_top_effect_index")]
747    fn top_effect_index(&self, effect: &impl IsA<BaseEffect>) -> i32 {
748        unsafe {
749            ffi::ges_clip_get_top_effect_index(
750                self.as_ref().to_glib_none().0,
751                effect.as_ref().to_glib_none().0,
752            )
753        }
754    }
755
756    #[doc(alias = "ges_clip_get_top_effect_position")]
757    #[doc(alias = "get_top_effect_position")]
758    fn top_effect_position(&self, effect: &impl IsA<BaseEffect>) -> i32 {
759        unsafe {
760            ffi::ges_clip_get_top_effect_position(
761                self.as_ref().to_glib_none().0,
762                effect.as_ref().to_glib_none().0,
763            )
764        }
765    }
766
767    /// Gets the [`BaseEffect`][crate::BaseEffect]-s that have been added to the clip. The
768    /// returned list is ordered by their internal index in the clip. See
769    /// [`top_effect_index()`][Self::top_effect_index()].
770    ///
771    /// # Returns
772    ///
773    /// A list of all
774    /// [`BaseEffect`][crate::BaseEffect]-s that have been added to `self`.
775    #[doc(alias = "ges_clip_get_top_effects")]
776    #[doc(alias = "get_top_effects")]
777    fn top_effects(&self) -> Vec<TrackElement> {
778        unsafe {
779            FromGlibPtrContainer::from_glib_full(ffi::ges_clip_get_top_effects(
780                self.as_ref().to_glib_none().0,
781            ))
782        }
783    }
784
785    /// Tells you if the clip is currently in the process of being moved from
786    /// one layer to another. This is useful from the layer::clip-added and
787    /// layer::clip-removed callbacks to know if the clip is being moved between
788    /// layers, or is being added/removed for other reasons (like being added
789    /// for the first time, or being actually removed).
790    ///
791    /// # Returns
792    ///
793    /// [`true`] if `self` is currently being moved between layers,
794    /// [`false`] otherwise.
795    #[cfg(feature = "v1_28")]
796    #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
797    #[doc(alias = "ges_clip_is_moving_between_layers")]
798    fn is_moving_between_layers(&self) -> bool {
799        unsafe {
800            from_glib(ffi::ges_clip_is_moving_between_layers(
801                self.as_ref().to_glib_none().0,
802            ))
803        }
804    }
805
806    /// See [`move_to_layer_full()`][Self::move_to_layer_full()], which also gives an error.
807    /// ## `layer`
808    /// The new layer
809    ///
810    /// # Returns
811    ///
812    /// [`true`] if `self` was successfully moved to `layer`.
813    #[doc(alias = "ges_clip_move_to_layer")]
814    fn move_to_layer(&self, layer: &impl IsA<Layer>) -> Result<(), glib::error::BoolError> {
815        unsafe {
816            glib::result_from_gboolean!(
817                ffi::ges_clip_move_to_layer(
818                    self.as_ref().to_glib_none().0,
819                    layer.as_ref().to_glib_none().0
820                ),
821                "Failed to move clip to specified layer"
822            )
823        }
824    }
825
826    /// Moves a clip to a new layer. If the clip already exists in a layer, it
827    /// is first removed from its current layer before being added to the new
828    /// layer.
829    /// ## `layer`
830    /// The new layer
831    ///
832    /// # Returns
833    ///
834    /// [`true`] if `self` was successfully moved to `layer`.
835    #[cfg(feature = "v1_18")]
836    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
837    #[doc(alias = "ges_clip_move_to_layer_full")]
838    fn move_to_layer_full(&self, layer: &impl IsA<Layer>) -> Result<(), glib::Error> {
839        unsafe {
840            let mut error = std::ptr::null_mut();
841            let is_ok = ffi::ges_clip_move_to_layer_full(
842                self.as_ref().to_glib_none().0,
843                layer.as_ref().to_glib_none().0,
844                &mut error,
845            );
846            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
847            if error.is_null() {
848                Ok(())
849            } else {
850                Err(from_glib_full(error))
851            }
852        }
853    }
854
855    /// Remove a top effect from the clip.
856    ///
857    /// Note, if the effect is a time effect, this may be refused if the clip
858    /// would not be able to adapt itself once the effect is removed.
859    /// ## `effect`
860    /// The top effect to remove
861    ///
862    /// # Returns
863    ///
864    /// [`true`] if `effect` was successfully added to `self` at `index`.
865    #[cfg(feature = "v1_18")]
866    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
867    #[doc(alias = "ges_clip_remove_top_effect")]
868    fn remove_top_effect(&self, effect: &impl IsA<BaseEffect>) -> Result<(), glib::Error> {
869        unsafe {
870            let mut error = std::ptr::null_mut();
871            let is_ok = ffi::ges_clip_remove_top_effect(
872                self.as_ref().to_glib_none().0,
873                effect.as_ref().to_glib_none().0,
874                &mut error,
875            );
876            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
877            if error.is_null() {
878                Ok(())
879            } else {
880                Err(from_glib_full(error))
881            }
882        }
883    }
884
885    /// Sets the [`supported-formats`][struct@crate::Clip#supported-formats] of the clip. This should normally
886    /// only be called by subclasses, which should be responsible for updating
887    /// its value, rather than the user.
888    /// ## `supportedformats`
889    /// The [`TrackType`][crate::TrackType]-s supported by `self`
890    #[doc(alias = "ges_clip_set_supported_formats")]
891    #[doc(alias = "supported-formats")]
892    fn set_supported_formats(&self, supportedformats: TrackType) {
893        unsafe {
894            ffi::ges_clip_set_supported_formats(
895                self.as_ref().to_glib_none().0,
896                supportedformats.into_glib(),
897            );
898        }
899    }
900
901    /// See [`set_top_effect_index_full()`][Self::set_top_effect_index_full()], which also gives an error.
902    /// ## `effect`
903    /// An effect within `self` to move
904    /// ## `newindex`
905    /// The index for `effect` in `self`
906    ///
907    /// # Returns
908    ///
909    /// [`true`] if `effect` was successfully moved to `newindex`.
910    #[doc(alias = "ges_clip_set_top_effect_index")]
911    fn set_top_effect_index(
912        &self,
913        effect: &impl IsA<BaseEffect>,
914        newindex: u32,
915    ) -> Result<(), glib::error::BoolError> {
916        unsafe {
917            glib::result_from_gboolean!(
918                ffi::ges_clip_set_top_effect_index(
919                    self.as_ref().to_glib_none().0,
920                    effect.as_ref().to_glib_none().0,
921                    newindex
922                ),
923                "Failed to move effect"
924            )
925        }
926    }
927
928    /// Set the index of an effect within the clip. See
929    /// [`top_effect_index()`][Self::top_effect_index()]. The new index must be an existing
930    /// index of the clip. The effect is moved to the new index, and the other
931    /// effects may be shifted in index accordingly to otherwise maintain the
932    /// ordering.
933    /// ## `effect`
934    /// An effect within `self` to move
935    /// ## `newindex`
936    /// The index for `effect` in `self`
937    ///
938    /// # Returns
939    ///
940    /// [`true`] if `effect` was successfully moved to `newindex`.
941    #[cfg(feature = "v1_18")]
942    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
943    #[doc(alias = "ges_clip_set_top_effect_index_full")]
944    fn set_top_effect_index_full(
945        &self,
946        effect: &impl IsA<BaseEffect>,
947        newindex: u32,
948    ) -> Result<(), glib::Error> {
949        unsafe {
950            let mut error = std::ptr::null_mut();
951            let is_ok = ffi::ges_clip_set_top_effect_index_full(
952                self.as_ref().to_glib_none().0,
953                effect.as_ref().to_glib_none().0,
954                newindex,
955                &mut error,
956            );
957            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
958            if error.is_null() {
959                Ok(())
960            } else {
961                Err(from_glib_full(error))
962            }
963        }
964    }
965
966    #[doc(alias = "ges_clip_set_top_effect_priority")]
967    fn set_top_effect_priority(
968        &self,
969        effect: &impl IsA<BaseEffect>,
970        newpriority: u32,
971    ) -> Result<(), glib::error::BoolError> {
972        unsafe {
973            glib::result_from_gboolean!(
974                ffi::ges_clip_set_top_effect_priority(
975                    self.as_ref().to_glib_none().0,
976                    effect.as_ref().to_glib_none().0,
977                    newpriority
978                ),
979                "Failed to the set top effect priority"
980            )
981        }
982    }
983
984    /// See [`split_full()`][Self::split_full()], which also gives an error.
985    /// ## `position`
986    /// The timeline position at which to perform the split
987    ///
988    /// # Returns
989    ///
990    /// The newly created clip resulting
991    /// from the splitting `self`, or [`None`] if `self` can't be split.
992    #[doc(alias = "ges_clip_split")]
993    fn split(&self, position: u64) -> Result<Clip, glib::BoolError> {
994        unsafe {
995            Option::<_>::from_glib_none(ffi::ges_clip_split(
996                self.as_ref().to_glib_none().0,
997                position,
998            ))
999            .ok_or_else(|| glib::bool_error!("Failed to split clip"))
1000        }
1001    }
1002
1003    /// Splits a clip at the given timeline position into two clips. The clip
1004    /// must already have a [`layer`][struct@crate::Clip#layer].
1005    ///
1006    /// The original clip's [`duration`][struct@crate::TimelineElement#duration] is reduced such that
1007    /// its end point matches the split position. Then a new clip is created in
1008    /// the same layer, whose [`start`][struct@crate::TimelineElement#start] matches the split
1009    /// position and [`duration`][struct@crate::TimelineElement#duration] will be set such that its end
1010    /// point matches the old end point of the original clip. Thus, the two
1011    /// clips together will occupy the same positions in the timeline as the
1012    /// original clip did.
1013    ///
1014    /// The children of the new clip will be new copies of the original clip's
1015    /// children, so it will share the same sources and use the same
1016    /// operations.
1017    ///
1018    /// The new clip will also have its [`in-point`][struct@crate::TimelineElement#in-point] set so
1019    /// that any internal data will appear in the timeline at the same time.
1020    /// Thus, when the timeline is played, the playback of data should
1021    /// appear the same. This may be complicated by any additional
1022    /// [`Effect`][crate::Effect]-s that have been placed on the original clip that depend on
1023    /// the playback time or change the data consumption rate of sources. This
1024    /// method will attempt to translate these effects such that the playback
1025    /// appears the same. In such complex situations, you may get a better
1026    /// result if you place the clip in a separate sub [`Project`][crate::Project], which only
1027    /// contains this clip (and its effects), and in the original layer
1028    /// create two neighbouring [`UriClip`][crate::UriClip]-s that reference this sub-project,
1029    /// but at a different [`in-point`][struct@crate::TimelineElement#in-point].
1030    /// ## `position`
1031    /// The timeline position at which to perform the split, between
1032    /// the start and end of the clip
1033    ///
1034    /// # Returns
1035    ///
1036    /// The newly created clip resulting
1037    /// from the splitting `self`, or [`None`] if `self` can't be split.
1038    #[cfg(feature = "v1_18")]
1039    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1040    #[doc(alias = "ges_clip_split_full")]
1041    fn split_full(&self, position: u64) -> Result<Option<Clip>, glib::Error> {
1042        unsafe {
1043            let mut error = std::ptr::null_mut();
1044            let ret =
1045                ffi::ges_clip_split_full(self.as_ref().to_glib_none().0, position, &mut error);
1046            if error.is_null() {
1047                Ok(from_glib_none(ret))
1048            } else {
1049                Err(from_glib_full(error))
1050            }
1051        }
1052    }
1053
1054    #[cfg(feature = "v1_18")]
1055    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1056    #[doc(alias = "duration-limit")]
1057    fn connect_duration_limit_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1058        unsafe extern "C" fn notify_duration_limit_trampoline<P: IsA<Clip>, F: Fn(&P) + 'static>(
1059            this: *mut ffi::GESClip,
1060            _param_spec: glib::ffi::gpointer,
1061            f: glib::ffi::gpointer,
1062        ) {
1063            unsafe {
1064                let f: &F = &*(f as *const F);
1065                f(Clip::from_glib_borrow(this).unsafe_cast_ref())
1066            }
1067        }
1068        unsafe {
1069            let f: Box_<F> = Box_::new(f);
1070            connect_raw(
1071                self.as_ptr() as *mut _,
1072                c"notify::duration-limit".as_ptr(),
1073                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1074                    notify_duration_limit_trampoline::<Self, F> as *const (),
1075                )),
1076                Box_::into_raw(f),
1077            )
1078        }
1079    }
1080
1081    #[doc(alias = "layer")]
1082    fn connect_layer_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1083        unsafe extern "C" fn notify_layer_trampoline<P: IsA<Clip>, F: Fn(&P) + 'static>(
1084            this: *mut ffi::GESClip,
1085            _param_spec: glib::ffi::gpointer,
1086            f: glib::ffi::gpointer,
1087        ) {
1088            unsafe {
1089                let f: &F = &*(f as *const F);
1090                f(Clip::from_glib_borrow(this).unsafe_cast_ref())
1091            }
1092        }
1093        unsafe {
1094            let f: Box_<F> = Box_::new(f);
1095            connect_raw(
1096                self.as_ptr() as *mut _,
1097                c"notify::layer".as_ptr(),
1098                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1099                    notify_layer_trampoline::<Self, F> as *const (),
1100                )),
1101                Box_::into_raw(f),
1102            )
1103        }
1104    }
1105
1106    #[doc(alias = "supported-formats")]
1107    fn connect_supported_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1108        unsafe extern "C" fn notify_supported_formats_trampoline<
1109            P: IsA<Clip>,
1110            F: Fn(&P) + 'static,
1111        >(
1112            this: *mut ffi::GESClip,
1113            _param_spec: glib::ffi::gpointer,
1114            f: glib::ffi::gpointer,
1115        ) {
1116            unsafe {
1117                let f: &F = &*(f as *const F);
1118                f(Clip::from_glib_borrow(this).unsafe_cast_ref())
1119            }
1120        }
1121        unsafe {
1122            let f: Box_<F> = Box_::new(f);
1123            connect_raw(
1124                self.as_ptr() as *mut _,
1125                c"notify::supported-formats".as_ptr(),
1126                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1127                    notify_supported_formats_trampoline::<Self, F> as *const (),
1128                )),
1129                Box_::into_raw(f),
1130            )
1131        }
1132    }
1133}
1134
1135impl<O: IsA<Clip>> ClipExt for O {}