Skip to main content

gstreamer_pbutils/
discoverer_audio_info.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::fmt;
4
5use glib::prelude::*;
6
7use crate::{DiscovererAudioInfo, DiscovererStreamInfo};
8
9#[cfg(feature = "v1_30")]
10use glib::translate::*;
11
12#[cfg(feature = "v1_30")]
13use crate::ffi;
14
15pub struct Debug<'a>(&'a DiscovererAudioInfo);
16
17impl fmt::Debug for Debug<'_> {
18    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19        let info = self.0.upcast_ref::<DiscovererStreamInfo>();
20
21        f.debug_struct("DiscovererAudioInfo")
22            .field("channels", &self.0.channels())
23            .field("sample-rate", &self.0.sample_rate())
24            .field("depth", &self.0.depth())
25            .field("bitrate", &self.0.bitrate())
26            .field("max-bitrate", &self.0.max_bitrate())
27            .field("channel-mask", &self.0.channel_mask())
28            .field("language", &self.0.language())
29            .field("stream", &info.debug())
30            .finish()
31    }
32}
33
34impl DiscovererAudioInfo {
35    pub fn debug(&self) -> Debug<'_> {
36        Debug(self)
37    }
38
39    #[cfg(feature = "v1_30")]
40    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
41    #[doc(alias = "gst_discoverer_audio_info_builder_new")]
42    pub fn builder(stream_id: &str, caps: &gst::Caps) -> DiscovererAudioInfoBuilder {
43        skip_assert_initialized!();
44
45        DiscovererAudioInfoBuilder::new(stream_id, caps)
46    }
47}
48
49/// Opaque structure for building [`DiscovererAudioInfo`][crate::DiscovererAudioInfo] objects programmatically.
50#[cfg(feature = "v1_30")]
51#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
52#[derive(Debug)]
53#[doc(alias = "GstDiscovererAudioInfoBuilder")]
54#[repr(transparent)]
55pub struct DiscovererAudioInfoBuilder(std::ptr::NonNull<ffi::GstDiscovererAudioInfoBuilder>);
56
57#[cfg(feature = "v1_30")]
58#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
59impl DiscovererAudioInfoBuilder {
60    /// Creates a new [`DiscovererAudioInfoBuilder`][crate::DiscovererAudioInfoBuilder].
61    /// Audio properties (channels, sample_rate, depth) will be extracted from caps.
62    /// ## `stream_id`
63    /// the stream ID
64    /// ## `caps`
65    /// the audio caps
66    ///
67    /// # Returns
68    ///
69    /// a new [`DiscovererAudioInfoBuilder`][crate::DiscovererAudioInfoBuilder]
70    #[doc(alias = "gst_discoverer_audio_info_builder_new")]
71    pub fn new(stream_id: &str, caps: &gst::Caps) -> Self {
72        skip_assert_initialized!();
73        unsafe {
74            let ptr = ffi::gst_discoverer_audio_info_builder_new(
75                stream_id.to_glib_none().0,
76                caps.to_glib_none().0,
77            );
78            DiscovererAudioInfoBuilder(std::ptr::NonNull::new_unchecked(ptr))
79        }
80    }
81
82    #[doc(alias = "gst_discoverer_audio_info_builder_set_bitrate")]
83    pub fn bitrate(self, bitrate: u32) -> Self {
84        unsafe {
85            ffi::gst_discoverer_audio_info_builder_set_bitrate(self.0.as_ptr(), bitrate);
86        }
87        self
88    }
89
90    #[doc(alias = "gst_discoverer_audio_info_builder_set_max_bitrate")]
91    pub fn max_bitrate(self, max_bitrate: u32) -> Self {
92        unsafe {
93            ffi::gst_discoverer_audio_info_builder_set_max_bitrate(self.0.as_ptr(), max_bitrate);
94        }
95        self
96    }
97
98    #[doc(alias = "gst_discoverer_audio_info_builder_set_language")]
99    pub fn language(self, language: &str) -> Self {
100        unsafe {
101            ffi::gst_discoverer_audio_info_builder_set_language(
102                self.0.as_ptr(),
103                language.to_glib_none().0,
104            );
105        }
106        self
107    }
108
109    #[doc(alias = "gst_discoverer_audio_info_builder_set_tags")]
110    pub fn tags(self, tags: &gst::TagList) -> Self {
111        unsafe {
112            ffi::gst_discoverer_audio_info_builder_set_tags(self.0.as_ptr(), tags.to_glib_none().0);
113        }
114        self
115    }
116
117    /// Builds and returns a new [`DiscovererAudioInfo`][crate::DiscovererAudioInfo]. This frees the builder.
118    ///
119    /// # Returns
120    ///
121    /// a new [`DiscovererAudioInfo`][crate::DiscovererAudioInfo]
122    #[doc(alias = "gst_discoverer_audio_info_builder_build")]
123    pub fn build(self) -> DiscovererAudioInfo {
124        unsafe {
125            // the gst_discoverer_audio_info_builder_build frees the builder before creating new
126            // so prevent it from being dropped at the end of this scope/function
127            let s = std::mem::ManuallyDrop::new(self);
128
129            from_glib_full(ffi::gst_discoverer_audio_info_builder_build(s.0.as_ptr()))
130        }
131    }
132}
133
134#[cfg(feature = "v1_30")]
135#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
136impl Drop for DiscovererAudioInfoBuilder {
137    #[inline]
138    #[doc(alias = "gst_discoverer_audio_info_builder_free")]
139    fn drop(&mut self) {
140        unsafe {
141            ffi::gst_discoverer_audio_info_builder_free(self.0.as_ptr());
142        }
143    }
144}
145
146#[cfg(test)]
147mod tests {
148    #[test]
149    #[cfg(feature = "v1_30")]
150    fn discoverer_audio_info_builder_basic() {
151        use super::*;
152        use std::str::FromStr;
153
154        use crate::traits::DiscovererStreamInfoExt;
155
156        gst::init().unwrap();
157
158        let caps = gst::Caps::from_str("audio/x-raw, rate=96000, channels=6, depth=24").unwrap();
159
160        let mut tags = gst::TagList::new();
161        tags.get_mut()
162            .unwrap()
163            .add::<gst::tags::Title>(&"some title", gst::TagMergeMode::Append);
164
165        let info = DiscovererAudioInfoBuilder::new("audio_builder_test", &caps)
166            .bitrate(20000000)
167            .language("en")
168            .max_bitrate(30000000)
169            .tags(&tags)
170            .build();
171
172        assert_eq!(
173            info.stream_id(),
174            Some(glib::GString::from("audio_builder_test"))
175        );
176        assert_eq!(info.language(), Some(glib::GString::from("en")));
177        assert_eq!(info.bitrate(), 20000000);
178        assert_eq!(info.max_bitrate(), 30000000);
179        assert_eq!(info.depth(), 24);
180        assert_eq!(info.channels(), 6);
181        assert_eq!(info.sample_rate(), 96000);
182        assert_eq!(
183            info.tags()
184                .unwrap()
185                .get::<gst::tags::Title>()
186                .unwrap()
187                .get(),
188            "some title"
189        );
190    }
191}