1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT

use crate::{Extractable, MetaContainer, Operation, TimelineElement, TrackElement};
use glib::prelude::*;
#[cfg(feature = "v1_18")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
use glib::translate::*;

glib::wrapper! {
    /// A [`BaseEffect`][crate::BaseEffect] is some operation that applies an effect to the data
    /// it receives.
    ///
    /// ## Time Effects
    ///
    /// Some operations will change the timing of the stream data they receive
    /// in some way. In particular, the [`gst::Element`][crate::gst::Element] that they wrap could alter
    /// the times of the segment they receive in a [`gst::EventType::Segment`][crate::gst::EventType::Segment] event,
    /// or the times of a seek they receive in a [`gst::EventType::Seek`][crate::gst::EventType::Seek] event. Such
    /// operations would be considered time effects since they translate the
    /// times they receive on their source to different times at their sink,
    /// and vis versa. This introduces two sets of time coordinates for the
    /// event: (internal) sink coordinates and (internal) source coordinates,
    /// where segment times are translated from the sink coordinates to the
    /// source coordinates, and seek times are translated from the source
    /// coordinates to the sink coordinates.
    ///
    /// If you use such an effect in GES, you will need to inform GES of the
    /// properties that control the timing with
    /// [`BaseEffectExt::register_time_property()`][crate::prelude::BaseEffectExt::register_time_property()], and the effect's timing
    /// behaviour using `ges_base_effect_set_time_translation_funcs()`.
    ///
    /// Note that a time effect should not have its
    /// [`has-internal-source`][struct@crate::TrackElement#has-internal-source] set to [`true`].
    ///
    /// In addition, note that GES only *fully* supports time effects whose
    /// mapping from the source to sink coordinates (those applied to seeks)
    /// obeys:
    ///
    /// + Maps the time `0` to `0`. So initial time-shifting effects are
    ///  excluded.
    /// + Is monotonically increasing. So reversing effects, and effects that
    ///  jump backwards in the stream are excluded.
    /// + Can handle a reasonable `GstClockTime`, relative to the project. So
    ///  this would exclude a time effect with an extremely large speed-up
    ///  that would cause the converted `GstClockTime` seeks to overflow.
    /// + Is 'continuously reversible'. This essentially means that for every
    ///  time in the sink coordinates, we can, to 'good enough' accuracy,
    ///  calculate the corresponding time in the source coordinates. Moreover,
    ///  this should correspond to how segment times are translated from
    ///  sink to source.
    /// + Only depends on the registered time properties, rather than the
    ///  state of the [`gst::Element`][crate::gst::Element] or the data it receives. This would exclude,
    ///  say, an effect that would speedup if there is more red in the image
    ///  it receives.
    ///
    /// Note that a constant-rate-change effect that is not extremely fast or
    /// slow would satisfy these conditions. For such effects, you may wish to
    /// use `ges_effect_class_register_rate_property()`.
    ///
    /// This is an Abstract Base Class, you cannot instantiate it.
    ///
    /// # Implements
    ///
    /// [`BaseEffectExt`][trait@crate::prelude::BaseEffectExt], [`OperationExt`][trait@crate::prelude::OperationExt], [`TrackElementExt`][trait@crate::prelude::TrackElementExt], [`TimelineElementExt`][trait@crate::prelude::TimelineElementExt], [`trait@glib::ObjectExt`], [`ExtractableExt`][trait@crate::prelude::ExtractableExt], [`MetaContainerExt`][trait@crate::prelude::MetaContainerExt], [`TimelineElementExtManual`][trait@crate::prelude::TimelineElementExtManual]
    #[doc(alias = "GESBaseEffect")]
    pub struct BaseEffect(Object<ffi::GESBaseEffect, ffi::GESBaseEffectClass>) @extends Operation, TrackElement, TimelineElement, @implements Extractable, MetaContainer;

    match fn {
        type_ => || ffi::ges_base_effect_get_type(),
    }
}

impl BaseEffect {
    pub const NONE: Option<&'static BaseEffect> = None;
}

mod sealed {
    pub trait Sealed {}
    impl<T: super::IsA<super::BaseEffect>> Sealed for T {}
}

/// Trait containing all [`struct@BaseEffect`] methods.
///
/// # Implementors
///
/// [`BaseEffect`][struct@crate::BaseEffect], [`Effect`][struct@crate::Effect]
pub trait BaseEffectExt: IsA<BaseEffect> + sealed::Sealed + 'static {
    /// Get whether the effect is considered a time effect or not. An effect
    /// with registered time properties or set translation functions is
    /// considered a time effect.
    ///
    /// # Returns
    ///
    /// [`true`] if `self` is considered a time effect.
    #[cfg(feature = "v1_18")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
    #[doc(alias = "ges_base_effect_is_time_effect")]
    fn is_time_effect(&self) -> bool {
        unsafe {
            from_glib(ffi::ges_base_effect_is_time_effect(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    /// Register a child property of the effect as a property that, when set,
    /// can change the timing of its input data. The child property should be
    /// specified as in [`TimelineElementExt::lookup_child()`][crate::prelude::TimelineElementExt::lookup_child()].
    ///
    /// You should also set the corresponding time translation using
    /// `ges_base_effect_set_time_translation_funcs()`.
    ///
    /// Note that `self` must not be part of a clip, nor can it have
    /// [`has-internal-source`][struct@crate::TrackElement#has-internal-source] set to [`true`].
    /// ## `child_property_name`
    /// The name of the child property to register as
    /// a time property
    ///
    /// # Returns
    ///
    /// [`true`] if the child property was found and newly registered.
    #[cfg(feature = "v1_18")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
    #[doc(alias = "ges_base_effect_register_time_property")]
    fn register_time_property(&self, child_property_name: &str) -> bool {
        unsafe {
            from_glib(ffi::ges_base_effect_register_time_property(
                self.as_ref().to_glib_none().0,
                child_property_name.to_glib_none().0,
            ))
        }
    }
}

impl<O: IsA<BaseEffect>> BaseEffectExt for O {}