| 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, IntoGlibPtr, ToGlibPtr}; |
| 6 | |
| 7 | use crate::{ |
| 8 | ffi, format::FormattedValueIntrinsic, Buffer, BufferList, BufferListRef, BufferRef, Caps, |
| 9 | CapsRef, 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_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 | |
| 134 | impl 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 | |
| 148 | impl 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 | |
| 270 | impl fmt::Debug for Sample { |
| 271 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 272 | SampleRef::fmt(self, f) |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | impl fmt::Debug for SampleRef { |
| 277 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 278 | f&mut DebugStruct<'_, '_>.debug_struct("Sample" ) |
| 279 | .field("buffer" , &self.buffer()) |
| 280 | .field("caps" , &self.caps()) |
| 281 | .field("segment" , &self.segment()) |
| 282 | .field(name:"info" , &self.info()) |
| 283 | .finish() |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | #[cfg (test)] |
| 288 | mod 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 | } |
| 303 | |