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