1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{io, mem, ops};
4
5use glib::translate::*;
6
7use crate::Adapter;
8
9impl Adapter {
10 #[doc(alias = "gst_adapter_copy")]
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")]
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")]
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")]
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")]
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")]
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")]
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")]
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")]
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")]
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")]
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")]
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")]
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")]
235 pub fn push(&self, buf: gst::Buffer) {
236 unsafe {
237 ffi::gst_adapter_push(self.to_glib_none().0, buf.into_glib_ptr());
238 }
239 }
240}
241
242impl io::Read for Adapter {
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)]
271pub struct UniqueAdapter(Adapter);
272
273unsafe impl Send for UniqueAdapter {}
274unsafe impl Sync for UniqueAdapter {}
275
276impl UniqueAdapter {
277 pub fn new() -> Self {
278 Self(Adapter::new())
279 }
280
281 pub fn available(&self) -> usize {
282 self.0.available()
283 }
284
285 pub fn available_fast(&self) -> usize {
286 self.0.available_fast()
287 }
288
289 pub fn clear(&mut self) {
290 self.0.clear();
291 }
292
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 pub fn distance_from_discont(&self) -> u64 {
298 self.0.distance_from_discont()
299 }
300
301 pub fn dts_at_discont(&self) -> Option<gst::ClockTime> {
302 self.0.dts_at_discont()
303 }
304
305 pub fn flush(&mut self, flush: usize) {
306 self.0.flush(flush);
307 }
308
309 #[doc(alias = "get_buffer")]
310 pub fn buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
311 self.0.buffer(nbytes)
312 }
313
314 #[doc(alias = "get_buffer_fast")]
315 pub fn buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
316 self.0.buffer_fast(nbytes)
317 }
318
319 #[doc(alias = "get_buffer_list")]
320 pub fn buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
321 self.0.buffer_list(nbytes)
322 }
323
324 #[doc(alias = "get_list")]
325 pub fn list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
326 self.0.list(nbytes)
327 }
328
329 pub fn masked_scan_uint32(
330 &self,
331 mask: u32,
332 pattern: u32,
333 offset: usize,
334 size: usize,
335 ) -> Result<Option<usize>, glib::BoolError> {
336 self.0.masked_scan_uint32(mask, pattern, offset, size)
337 }
338
339 pub fn masked_scan_uint32_peek(
340 &self,
341 mask: u32,
342 pattern: u32,
343 offset: usize,
344 size: usize,
345 ) -> Result<Option<(usize, u32)>, glib::BoolError> {
346 self.0.masked_scan_uint32_peek(mask, pattern, offset, size)
347 }
348
349 pub fn offset_at_discont(&self) -> u64 {
350 self.0.offset_at_discont()
351 }
352
353 pub fn prev_dts(&self) -> (Option<gst::ClockTime>, u64) {
354 self.0.prev_dts()
355 }
356
357 pub fn prev_dts_at_offset(&self, offset: usize) -> (Option<gst::ClockTime>, u64) {
358 self.0.prev_dts_at_offset(offset)
359 }
360
361 pub fn prev_offset(&self) -> (u64, u64) {
362 self.0.prev_offset()
363 }
364
365 pub fn prev_pts(&self) -> (Option<gst::ClockTime>, u64) {
366 self.0.prev_pts()
367 }
368
369 pub fn prev_pts_at_offset(&self, offset: usize) -> (Option<gst::ClockTime>, u64) {
370 self.0.prev_pts_at_offset(offset)
371 }
372
373 pub fn pts_at_discont(&self) -> Option<gst::ClockTime> {
374 self.0.pts_at_discont()
375 }
376
377 pub fn take_buffer(&mut self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
378 self.0.take_buffer(nbytes)
379 }
380
381 pub fn take_buffer_fast(&mut self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
382 self.0.take_buffer_fast(nbytes)
383 }
384
385 pub fn take_buffer_list(&mut self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
386 self.0.take_buffer_list(nbytes)
387 }
388
389 pub fn take_list(&mut self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
390 self.0.take_list(nbytes)
391 }
392
393 pub fn copy(&self, offset: usize, dest: &mut [u8]) -> Result<(), glib::BoolError> {
394 self.0.copy(offset, dest)
395 }
396
397 pub fn push(&mut self, buf: gst::Buffer) {
398 self.0.push(buf);
399 }
400
401 #[doc(alias = "gst_adapter_map")]
402 pub fn map(&mut self, nbytes: usize) -> Result<UniqueAdapterMap, glib::error::BoolError> {
403 assert!(nbytes <= self.available());
404 assert!(nbytes != 0);
405
406 use std::slice;
407
408 unsafe {
409 let ptr = ffi::gst_adapter_map(self.0.to_glib_none().0, nbytes);
410 if ptr.is_null() {
411 Err(glib::bool_error!("size bytes are not available"))
412 } else {
413 Ok(UniqueAdapterMap(
414 self,
415 slice::from_raw_parts(ptr as *const u8, nbytes),
416 ))
417 }
418 }
419 }
420}
421
422#[derive(Debug)]
423pub struct UniqueAdapterMap<'a>(&'a UniqueAdapter, &'a [u8]);
424
425impl<'a> Drop for UniqueAdapterMap<'a> {
426 #[inline]
427 fn drop(&mut self) {
428 unsafe {
429 ffi::gst_adapter_unmap((self.0).0.to_glib_none().0);
430 }
431 }
432}
433
434impl<'a> ops::Deref for UniqueAdapterMap<'a> {
435 type Target = [u8];
436
437 #[inline]
438 fn deref(&self) -> &[u8] {
439 self.1
440 }
441}
442
443impl<'a> AsRef<[u8]> for UniqueAdapterMap<'a> {
444 #[inline]
445 fn as_ref(&self) -> &[u8] {
446 self.1
447 }
448}
449
450impl Default for UniqueAdapter {
451 #[inline]
452 fn default() -> Self {
453 Self::new()
454 }
455}
456
457impl io::Read for UniqueAdapter {
458 #[inline]
459 fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
460 self.0.read(buf)
461 }
462}
463