gstreamer/
sample.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{fmt, ptr};
4
5use glib::translate::{from_glib_full, from_glib_none, IntoGlibPtr, ToGlibPtr};
6
7use crate::{
8    ffi, format::FormattedValueIntrinsic, Buffer, BufferList, BufferListRef, BufferRef, Caps,
9    CapsRef, FormattedSegment, Segment, Structure, StructureRef,
10};
11
12mini_object_wrapper!(Sample, SampleRef, ffi::GstSample, || {
13    ffi::gst_sample_get_type()
14});
15
16#[derive(Debug, Clone)]
17#[must_use = "The builder must be built to be used"]
18pub struct SampleBuilder<'a> {
19    buffer: Option<&'a Buffer>,
20    buffer_list: Option<&'a BufferList>,
21    caps: Option<&'a Caps>,
22    segment: Option<&'a Segment>,
23    info: Option<Structure>,
24}
25
26impl<'a> SampleBuilder<'a> {
27    pub fn buffer(self, buffer: &'a Buffer) -> Self {
28        Self {
29            buffer: Some(buffer),
30            buffer_list: None,
31            ..self
32        }
33    }
34
35    pub fn buffer_if_some(self, buffer: Option<&'a Buffer>) -> Self {
36        if let Some(buffer) = buffer {
37            self.buffer(buffer)
38        } else {
39            self
40        }
41    }
42
43    pub fn buffer_list(self, buffer_list: &'a BufferList) -> Self {
44        Self {
45            buffer: None,
46            buffer_list: Some(buffer_list),
47            ..self
48        }
49    }
50
51    pub fn buffer_list_if_some(self, buffer_list: Option<&'a BufferList>) -> Self {
52        if let Some(buffer_list) = buffer_list {
53            self.buffer_list(buffer_list)
54        } else {
55            self
56        }
57    }
58
59    pub fn caps(self, caps: &'a Caps) -> Self {
60        Self {
61            caps: Some(caps),
62            ..self
63        }
64    }
65
66    pub fn caps_if_some(self, caps: Option<&'a Caps>) -> Self {
67        if let Some(caps) = caps {
68            self.caps(caps)
69        } else {
70            self
71        }
72    }
73
74    pub fn segment<F: FormattedValueIntrinsic>(self, segment: &'a FormattedSegment<F>) -> Self {
75        Self {
76            segment: Some(segment.upcast_ref()),
77            ..self
78        }
79    }
80
81    pub fn segment_if_some<F: FormattedValueIntrinsic>(
82        self,
83        segment: Option<&'a FormattedSegment<F>>,
84    ) -> Self {
85        if let Some(segment) = segment {
86            self.segment(segment)
87        } else {
88            self
89        }
90    }
91
92    pub fn info(self, info: Structure) -> Self {
93        Self {
94            info: Some(info),
95            ..self
96        }
97    }
98
99    pub fn info_if_some(self, info: Option<Structure>) -> Self {
100        if let Some(info) = info {
101            self.info(info)
102        } else {
103            self
104        }
105    }
106
107    #[must_use = "Building the sample without using it has no effect"]
108    pub fn build(self) -> Sample {
109        unsafe {
110            let info = self
111                .info
112                .map(|i| i.into_glib_ptr())
113                .unwrap_or(ptr::null_mut());
114
115            let sample: Sample = from_glib_full(ffi::gst_sample_new(
116                self.buffer.to_glib_none().0,
117                self.caps.to_glib_none().0,
118                self.segment.to_glib_none().0,
119                info,
120            ));
121
122            if let Some(buffer_list) = self.buffer_list {
123                ffi::gst_sample_set_buffer_list(
124                    sample.to_glib_none().0,
125                    buffer_list.to_glib_none().0,
126                );
127            }
128
129            sample
130        }
131    }
132}
133
134impl Sample {
135    pub fn builder<'a>() -> SampleBuilder<'a> {
136        assert_initialized_main_thread!();
137
138        SampleBuilder {
139            buffer: None,
140            buffer_list: None,
141            caps: None,
142            segment: None,
143            info: None,
144        }
145    }
146}
147
148impl SampleRef {
149    #[doc(alias = "get_buffer")]
150    #[doc(alias = "gst_sample_get_buffer")]
151    pub fn buffer(&self) -> Option<&BufferRef> {
152        unsafe {
153            let ptr = ffi::gst_sample_get_buffer(self.as_mut_ptr());
154            if ptr.is_null() {
155                None
156            } else {
157                Some(BufferRef::from_ptr(ptr))
158            }
159        }
160    }
161
162    #[doc(alias = "get_buffer_owned")]
163    pub fn buffer_owned(&self) -> Option<Buffer> {
164        unsafe { self.buffer().map(|buffer| from_glib_none(buffer.as_ptr())) }
165    }
166
167    #[doc(alias = "get_buffer_list")]
168    #[doc(alias = "gst_sample_get_buffer_list")]
169    pub fn buffer_list(&self) -> Option<&BufferListRef> {
170        unsafe {
171            let ptr = ffi::gst_sample_get_buffer_list(self.as_mut_ptr());
172            if ptr.is_null() {
173                None
174            } else {
175                Some(BufferListRef::from_ptr(ptr))
176            }
177        }
178    }
179
180    #[doc(alias = "get_buffer_list_owned")]
181    pub fn buffer_list_owned(&self) -> Option<BufferList> {
182        unsafe { self.buffer_list().map(|list| from_glib_none(list.as_ptr())) }
183    }
184
185    #[doc(alias = "get_caps")]
186    #[doc(alias = "gst_sample_get_caps")]
187    pub fn caps(&self) -> Option<&CapsRef> {
188        unsafe {
189            let ptr = ffi::gst_sample_get_caps(self.as_mut_ptr());
190            if ptr.is_null() {
191                None
192            } else {
193                Some(CapsRef::from_ptr(ptr))
194            }
195        }
196    }
197
198    #[doc(alias = "get_caps_owned")]
199    pub fn caps_owned(&self) -> Option<Caps> {
200        unsafe { self.caps().map(|caps| from_glib_none(caps.as_ptr())) }
201    }
202
203    #[doc(alias = "get_segment")]
204    #[doc(alias = "gst_sample_get_segment")]
205    pub fn segment(&self) -> Option<&Segment> {
206        unsafe {
207            let ptr = ffi::gst_sample_get_segment(self.as_mut_ptr());
208            if ptr.is_null() {
209                None
210            } else {
211                Some(crate::Segment::from_glib_ptr_borrow(ptr))
212            }
213        }
214    }
215
216    #[doc(alias = "get_info")]
217    #[doc(alias = "gst_sample_get_info")]
218    pub fn info(&self) -> Option<&StructureRef> {
219        unsafe {
220            let ptr = ffi::gst_sample_get_info(self.as_mut_ptr());
221            if ptr.is_null() {
222                None
223            } else {
224                Some(StructureRef::from_glib_borrow(ptr))
225            }
226        }
227    }
228
229    #[cfg(feature = "v1_16")]
230    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
231    #[doc(alias = "gst_sample_set_buffer")]
232    pub fn set_buffer(&mut self, buffer: Option<&Buffer>) {
233        unsafe { ffi::gst_sample_set_buffer(self.as_mut_ptr(), buffer.to_glib_none().0) }
234    }
235
236    #[cfg(feature = "v1_16")]
237    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
238    #[doc(alias = "gst_sample_set_buffer_list")]
239    pub fn set_buffer_list(&mut self, buffer_list: Option<&BufferList>) {
240        unsafe { ffi::gst_sample_set_buffer_list(self.as_mut_ptr(), buffer_list.to_glib_none().0) }
241    }
242
243    #[cfg(feature = "v1_16")]
244    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
245    #[doc(alias = "gst_sample_set_caps")]
246    pub fn set_caps(&mut self, caps: Option<&Caps>) {
247        unsafe { ffi::gst_sample_set_caps(self.as_mut_ptr(), caps.to_glib_none().0) }
248    }
249
250    #[cfg(feature = "v1_16")]
251    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
252    #[doc(alias = "gst_sample_set_segment")]
253    pub fn set_segment(&mut self, segment: Option<&Segment>) {
254        unsafe { ffi::gst_sample_set_segment(self.as_mut_ptr(), segment.to_glib_none().0) }
255    }
256
257    #[cfg(feature = "v1_16")]
258    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
259    #[doc(alias = "gst_sample_set_info")]
260    pub fn set_info(&mut self, info: Option<Structure>) {
261        unsafe {
262            ffi::gst_sample_set_info(
263                self.as_mut_ptr(),
264                info.map(|i| i.into_glib_ptr()).unwrap_or(ptr::null_mut()),
265            );
266        }
267    }
268}
269
270impl fmt::Debug for Sample {
271    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
272        SampleRef::fmt(self, f)
273    }
274}
275
276impl fmt::Debug for SampleRef {
277    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
278        f.debug_struct("Sample")
279            .field("buffer", &self.buffer())
280            .field("caps", &self.caps())
281            .field("segment", &self.segment())
282            .field("info", &self.info())
283            .finish()
284    }
285}
286
287#[cfg(test)]
288mod tests {
289    #[test]
290    fn test_sample_new_with_info() {
291        use crate::{Sample, Structure};
292
293        crate::init().unwrap();
294
295        let info = Structure::builder("sample.info")
296            .field("f3", 123i32)
297            .build();
298        let sample = Sample::builder().info(info).build();
299
300        assert!(sample.info().is_some());
301    }
302}