1 // Take a look at the license at the top of the repository in the LICENSE file.
2 
3 use crate::Adapter;
4 use glib::translate::*;
5 use std::io;
6 use std::mem;
7 use std::ops;
8 
9 impl Adapter {
10     #[doc(alias = "gst_adapter_copy")]
copy(&self, offset: usize, dest: &mut [u8]) -> Result<(), glib::BoolError>11     pub fn copy(&self, offset: usize, dest: &mut [u8]) -> Result<(), glib::BoolError> {
12         assert!(
13             offset
14                 .checked_add(dest.len())
15                 .map(|end| end <= self.available())
16                 == Some(true)
17         );
18 
19         if dest.is_empty() {
20             return Ok(());
21         }
22 
23         unsafe {
24             let size = dest.len();
25             ffi::gst_adapter_copy(
26                 self.to_glib_none().0,
27                 dest.as_mut_ptr() as *mut _,
28                 offset,
29                 size,
30             );
31         }
32 
33         Ok(())
34     }
35 
36     #[doc(alias = "gst_adapter_copy_bytes")]
copy_bytes(&self, offset: usize, size: usize) -> Result<glib::Bytes, glib::BoolError>37     pub fn copy_bytes(&self, offset: usize, size: usize) -> Result<glib::Bytes, glib::BoolError> {
38         assert!(offset.checked_add(size).map(|end| end <= self.available()) == Some(true));
39 
40         if size == 0 {
41             return Ok(glib::Bytes::from_static(&[]));
42         }
43 
44         unsafe {
45             Ok(from_glib_full(ffi::gst_adapter_copy_bytes(
46                 self.to_glib_none().0,
47                 offset,
48                 size,
49             )))
50         }
51     }
52 
53     #[doc(alias = "gst_adapter_flush")]
flush(&self, flush: usize)54     pub fn flush(&self, flush: usize) {
55         assert!(flush <= self.available());
56 
57         if flush == 0 {
58             return;
59         }
60 
61         unsafe {
62             ffi::gst_adapter_flush(self.to_glib_none().0, flush);
63         }
64     }
65 
66     #[doc(alias = "get_buffer")]
67     #[doc(alias = "gst_adapter_get_buffer")]
buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError>68     pub fn buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
69         assert!(nbytes <= self.available());
70         assert!(nbytes != 0);
71 
72         unsafe {
73             Option::<_>::from_glib_full(ffi::gst_adapter_get_buffer(self.to_glib_none().0, nbytes))
74                 .ok_or_else(|| glib::bool_error!("Failed to get buffer"))
75         }
76     }
77 
78     #[doc(alias = "get_buffer_fast")]
79     #[doc(alias = "gst_adapter_get_buffer_fast")]
buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError>80     pub fn buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
81         assert!(nbytes <= self.available());
82         assert!(nbytes != 0);
83 
84         unsafe {
85             Option::<_>::from_glib_full(ffi::gst_adapter_get_buffer_fast(
86                 self.to_glib_none().0,
87                 nbytes,
88             ))
89             .ok_or_else(|| glib::bool_error!("Failed to get buffer"))
90         }
91     }
92 
93     #[doc(alias = "get_buffer_list")]
94     #[doc(alias = "gst_adapter_get_buffer_list")]
buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError>95     pub fn buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
96         assert!(nbytes <= self.available());
97         assert!(nbytes != 0);
98 
99         unsafe {
100             Option::<_>::from_glib_full(ffi::gst_adapter_get_buffer_list(
101                 self.to_glib_none().0,
102                 nbytes,
103             ))
104             .ok_or_else(|| glib::bool_error!("Failed to get buffer list"))
105         }
106     }
107 
108     #[doc(alias = "get_list")]
109     #[doc(alias = "gst_adapter_get_list")]
list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError>110     pub fn list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
111         assert!(nbytes <= self.available());
112         assert!(nbytes != 0);
113 
114         unsafe {
115             Ok(FromGlibPtrContainer::from_glib_full(
116                 ffi::gst_adapter_get_list(self.to_glib_none().0, nbytes),
117             ))
118         }
119     }
120 
121     #[doc(alias = "gst_adapter_masked_scan_uint32")]
masked_scan_uint32( &self, mask: u32, pattern: u32, offset: usize, size: usize, ) -> Result<Option<usize>, glib::BoolError>122     pub fn masked_scan_uint32(
123         &self,
124         mask: u32,
125         pattern: u32,
126         offset: usize,
127         size: usize,
128     ) -> Result<Option<usize>, glib::BoolError> {
129         assert!(offset.checked_add(size).map(|end| end <= self.available()) == Some(true));
130         assert!(size != 0);
131         assert!(((!mask) & pattern) == 0);
132 
133         unsafe {
134             let ret = ffi::gst_adapter_masked_scan_uint32(
135                 self.to_glib_none().0,
136                 mask,
137                 pattern,
138                 offset,
139                 size,
140             );
141             if ret == -1 {
142                 Ok(None)
143             } else {
144                 assert!(ret >= 0);
145                 Ok(Some(ret as usize))
146             }
147         }
148     }
149 
150     #[doc(alias = "gst_adapter_masked_scan_uint32_peek")]
masked_scan_uint32_peek( &self, mask: u32, pattern: u32, offset: usize, size: usize, ) -> Result<Option<(usize, u32)>, glib::BoolError>151     pub fn masked_scan_uint32_peek(
152         &self,
153         mask: u32,
154         pattern: u32,
155         offset: usize,
156         size: usize,
157     ) -> Result<Option<(usize, u32)>, glib::BoolError> {
158         assert!(offset.checked_add(size).map(|end| end <= self.available()) == Some(true));
159         assert!(size != 0);
160         assert!(((!mask) & pattern) == 0);
161 
162         unsafe {
163             let mut value = mem::MaybeUninit::uninit();
164             let ret = ffi::gst_adapter_masked_scan_uint32_peek(
165                 self.to_glib_none().0,
166                 mask,
167                 pattern,
168                 offset,
169                 size,
170                 value.as_mut_ptr(),
171             );
172 
173             if ret == -1 {
174                 Ok(None)
175             } else {
176                 assert!(ret >= 0);
177                 let value = value.assume_init();
178                 Ok(Some((ret as usize, value)))
179             }
180         }
181     }
182 
183     #[doc(alias = "gst_adapter_take_buffer")]
take_buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError>184     pub fn take_buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
185         assert!(nbytes <= self.available());
186         assert!(nbytes != 0);
187 
188         unsafe {
189             Option::<_>::from_glib_full(ffi::gst_adapter_take_buffer(self.to_glib_none().0, nbytes))
190                 .ok_or_else(|| glib::bool_error!("Failed to take buffer"))
191         }
192     }
193 
194     #[doc(alias = "gst_adapter_take_buffer_fast")]
take_buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError>195     pub fn take_buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
196         assert!(nbytes <= self.available());
197         assert!(nbytes != 0);
198 
199         unsafe {
200             Option::<_>::from_glib_full(ffi::gst_adapter_take_buffer_fast(
201                 self.to_glib_none().0,
202                 nbytes,
203             ))
204             .ok_or_else(|| glib::bool_error!("Failed to take buffer"))
205         }
206     }
207 
208     #[doc(alias = "gst_adapter_take_buffer_list")]
take_buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError>209     pub fn take_buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
210         assert!(nbytes <= self.available());
211         assert!(nbytes != 0);
212 
213         unsafe {
214             Option::<_>::from_glib_full(ffi::gst_adapter_take_buffer_list(
215                 self.to_glib_none().0,
216                 nbytes,
217             ))
218             .ok_or_else(|| glib::bool_error!("Failed to take buffer list"))
219         }
220     }
221 
222     #[doc(alias = "gst_adapter_take_list")]
take_list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError>223     pub fn take_list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
224         assert!(nbytes <= self.available());
225         assert!(nbytes != 0);
226 
227         unsafe {
228             Ok(FromGlibPtrContainer::from_glib_full(
229                 ffi::gst_adapter_take_list(self.to_glib_none().0, nbytes),
230             ))
231         }
232     }
233 
234     #[doc(alias = "gst_adapter_push")]
push(&self, buf: gst::Buffer)235     pub fn push(&self, buf: gst::Buffer) {
236         unsafe {
237             ffi::gst_adapter_push(self.to_glib_none().0, buf.into_ptr());
238         }
239     }
240 }
241 
242 impl io::Read for Adapter {
read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error>243     fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
244         let mut len = self.available();
245 
246         if len == 0 {
247             return Err(io::Error::new(
248                 io::ErrorKind::WouldBlock,
249                 format!(
250                     "Missing data: requesting {} but only got {}.",
251                     buf.len(),
252                     len
253                 ),
254             ));
255         }
256 
257         if buf.len() < len {
258             len = buf.len();
259         }
260 
261         self.copy(0, &mut buf[0..len])
262             .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
263 
264         self.flush(len);
265 
266         Ok(len)
267     }
268 }
269 
270 #[derive(Debug)]
271 pub struct UniqueAdapter(Adapter);
272 
273 unsafe impl Send for UniqueAdapter {}
274 unsafe impl Sync for UniqueAdapter {}
275 
276 impl UniqueAdapter {
new() -> Self277     pub fn new() -> Self {
278         Self(Adapter::new())
279     }
280 
available(&self) -> usize281     pub fn available(&self) -> usize {
282         self.0.available()
283     }
284 
available_fast(&self) -> usize285     pub fn available_fast(&self) -> usize {
286         self.0.available_fast()
287     }
288 
clear(&mut self)289     pub fn clear(&mut self) {
290         self.0.clear();
291     }
292 
copy_bytes(&self, offset: usize, size: usize) -> Result<glib::Bytes, glib::BoolError>293     pub fn copy_bytes(&self, offset: usize, size: usize) -> Result<glib::Bytes, glib::BoolError> {
294         self.0.copy_bytes(offset, size)
295     }
296 
297     #[cfg(any(feature = "v1_10", feature = "dox"))]
298     #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_10")))]
distance_from_discont(&self) -> u64299     pub fn distance_from_discont(&self) -> u64 {
300         self.0.distance_from_discont()
301     }
302 
303     #[cfg(any(feature = "v1_10", feature = "dox"))]
304     #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_10")))]
dts_at_discont(&self) -> Option<gst::ClockTime>305     pub fn dts_at_discont(&self) -> Option<gst::ClockTime> {
306         self.0.dts_at_discont()
307     }
308 
flush(&mut self, flush: usize)309     pub fn flush(&mut self, flush: usize) {
310         self.0.flush(flush);
311     }
312 
313     #[doc(alias = "get_buffer")]
buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError>314     pub fn buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
315         self.0.buffer(nbytes)
316     }
317 
318     #[doc(alias = "get_buffer_fast")]
buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError>319     pub fn buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
320         self.0.buffer_fast(nbytes)
321     }
322 
323     #[doc(alias = "get_buffer_list")]
buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError>324     pub fn buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
325         self.0.buffer_list(nbytes)
326     }
327 
328     #[doc(alias = "get_list")]
list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError>329     pub fn list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
330         self.0.list(nbytes)
331     }
332 
masked_scan_uint32( &self, mask: u32, pattern: u32, offset: usize, size: usize, ) -> Result<Option<usize>, glib::BoolError>333     pub fn masked_scan_uint32(
334         &self,
335         mask: u32,
336         pattern: u32,
337         offset: usize,
338         size: usize,
339     ) -> Result<Option<usize>, glib::BoolError> {
340         self.0.masked_scan_uint32(mask, pattern, offset, size)
341     }
342 
masked_scan_uint32_peek( &self, mask: u32, pattern: u32, offset: usize, size: usize, ) -> Result<Option<(usize, u32)>, glib::BoolError>343     pub fn masked_scan_uint32_peek(
344         &self,
345         mask: u32,
346         pattern: u32,
347         offset: usize,
348         size: usize,
349     ) -> Result<Option<(usize, u32)>, glib::BoolError> {
350         self.0.masked_scan_uint32_peek(mask, pattern, offset, size)
351     }
352 
353     #[cfg(any(feature = "v1_10", feature = "dox"))]
354     #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_10")))]
offset_at_discont(&self) -> u64355     pub fn offset_at_discont(&self) -> u64 {
356         self.0.offset_at_discont()
357     }
358 
prev_dts(&self) -> (Option<gst::ClockTime>, u64)359     pub fn prev_dts(&self) -> (Option<gst::ClockTime>, u64) {
360         self.0.prev_dts()
361     }
362 
prev_dts_at_offset(&self, offset: usize) -> (Option<gst::ClockTime>, u64)363     pub fn prev_dts_at_offset(&self, offset: usize) -> (Option<gst::ClockTime>, u64) {
364         self.0.prev_dts_at_offset(offset)
365     }
366 
367     #[cfg(any(feature = "v1_10", feature = "dox"))]
368     #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_10")))]
prev_offset(&self) -> (u64, u64)369     pub fn prev_offset(&self) -> (u64, u64) {
370         self.0.prev_offset()
371     }
372 
prev_pts(&self) -> (Option<gst::ClockTime>, u64)373     pub fn prev_pts(&self) -> (Option<gst::ClockTime>, u64) {
374         self.0.prev_pts()
375     }
376 
prev_pts_at_offset(&self, offset: usize) -> (Option<gst::ClockTime>, u64)377     pub fn prev_pts_at_offset(&self, offset: usize) -> (Option<gst::ClockTime>, u64) {
378         self.0.prev_pts_at_offset(offset)
379     }
380 
381     #[cfg(any(feature = "v1_10", feature = "dox"))]
382     #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_10")))]
pts_at_discont(&self) -> Option<gst::ClockTime>383     pub fn pts_at_discont(&self) -> Option<gst::ClockTime> {
384         self.0.pts_at_discont()
385     }
386 
take_buffer(&mut self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError>387     pub fn take_buffer(&mut self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
388         self.0.take_buffer(nbytes)
389     }
390 
take_buffer_fast(&mut self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError>391     pub fn take_buffer_fast(&mut self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
392         self.0.take_buffer_fast(nbytes)
393     }
394 
take_buffer_list(&mut self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError>395     pub fn take_buffer_list(&mut self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
396         self.0.take_buffer_list(nbytes)
397     }
398 
take_list(&mut self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError>399     pub fn take_list(&mut self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
400         self.0.take_list(nbytes)
401     }
402 
copy(&self, offset: usize, dest: &mut [u8]) -> Result<(), glib::BoolError>403     pub fn copy(&self, offset: usize, dest: &mut [u8]) -> Result<(), glib::BoolError> {
404         self.0.copy(offset, dest)
405     }
406 
push(&mut self, buf: gst::Buffer)407     pub fn push(&mut self, buf: gst::Buffer) {
408         self.0.push(buf);
409     }
410 
411     #[doc(alias = "gst_adapter_map")]
map(&mut self, nbytes: usize) -> Result<UniqueAdapterMap, glib::error::BoolError>412     pub fn map(&mut self, nbytes: usize) -> Result<UniqueAdapterMap, glib::error::BoolError> {
413         assert!(nbytes <= self.available());
414         assert!(nbytes != 0);
415 
416         use std::slice;
417 
418         unsafe {
419             let ptr = ffi::gst_adapter_map(self.0.to_glib_none().0, nbytes);
420             if ptr.is_null() {
421                 Err(glib::bool_error!("size bytes are not available"))
422             } else {
423                 Ok(UniqueAdapterMap(
424                     self,
425                     slice::from_raw_parts(ptr as *const u8, nbytes),
426                 ))
427             }
428         }
429     }
430 }
431 
432 #[derive(Debug)]
433 pub struct UniqueAdapterMap<'a>(&'a UniqueAdapter, &'a [u8]);
434 
435 impl<'a> Drop for UniqueAdapterMap<'a> {
drop(&mut self)436     fn drop(&mut self) {
437         unsafe {
438             ffi::gst_adapter_unmap((self.0).0.to_glib_none().0);
439         }
440     }
441 }
442 
443 impl<'a> ops::Deref for UniqueAdapterMap<'a> {
444     type Target = [u8];
445 
deref(&self) -> &[u8]446     fn deref(&self) -> &[u8] {
447         self.1
448     }
449 }
450 
451 impl<'a> AsRef<[u8]> for UniqueAdapterMap<'a> {
as_ref(&self) -> &[u8]452     fn as_ref(&self) -> &[u8] {
453         self.1
454     }
455 }
456 
457 impl Default for UniqueAdapter {
default() -> Self458     fn default() -> Self {
459         Self::new()
460     }
461 }
462 
463 impl io::Read for UniqueAdapter {
read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error>464     fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
465         self.0.read(buf)
466     }
467 }
468