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 {}