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, mut_override, IntoGlibPtr, ToGlibPtr};
6
7use crate::{
8 format::FormattedValueIntrinsic, Buffer, BufferList, BufferListRef, BufferRef, Caps, CapsRef,
9 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_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
91impl 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
105impl 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
227impl fmt::Debug for Sample {
228 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
229 SampleRef::fmt(self, f)
230 }
231}
232
233impl 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)]
245mod 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