1 // Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 use std::fmt;
10 use std::marker::PhantomData;
11 use std::mem;
12 use std::ops;
13 use std::ptr;
14 use std::slice;
15 use std::u64;
16 use std::usize;
17 
18 use meta::*;
19 use miniobject::*;
20 use BufferFlags;
21 use ClockTime;
22 use Memory;
23 use MemoryRef;
24 
25 use glib;
26 use glib::translate::{from_glib, from_glib_full, FromGlib, FromGlibPtrFull, ToGlib};
27 use glib_sys;
28 use gst_sys;
29 
30 pub enum Readable {}
31 pub enum Writable {}
32 
33 gst_define_mini_object_wrapper!(
34     Buffer,
35     BufferRef,
36     gst_sys::GstBuffer,
37     [Debug, PartialEq, Eq,],
38     || gst_sys::gst_buffer_get_type()
39 );
40 
41 pub struct BufferMap<'a, T> {
42     buffer: &'a BufferRef,
43     map_info: gst_sys::GstMapInfo,
44     phantom: PhantomData<T>,
45 }
46 
47 pub struct MappedBuffer<T> {
48     buffer: Option<Buffer>,
49     map_info: gst_sys::GstMapInfo,
50     phantom: PhantomData<T>,
51 }
52 
53 impl Buffer {
new() -> Self54     pub fn new() -> Self {
55         assert_initialized_main_thread!();
56 
57         unsafe { from_glib_full(gst_sys::gst_buffer_new()) }
58     }
59 
with_size(size: usize) -> Result<Self, glib::BoolError>60     pub fn with_size(size: usize) -> Result<Self, glib::BoolError> {
61         assert_initialized_main_thread!();
62 
63         unsafe {
64             Option::<_>::from_glib_full(gst_sys::gst_buffer_new_allocate(
65                 ptr::null_mut(),
66                 size,
67                 ptr::null_mut(),
68             ))
69             .ok_or_else(|| glib_bool_error!("Failed to allocate buffer"))
70         }
71     }
72 
drop_box<T>(vec: glib_sys::gpointer)73     unsafe extern "C" fn drop_box<T>(vec: glib_sys::gpointer) {
74         let slice: Box<T> = Box::from_raw(vec as *mut T);
75         drop(slice);
76     }
77 
from_mut_slice<T: AsMut<[u8]> + Send + 'static>(slice: T) -> Self78     pub fn from_mut_slice<T: AsMut<[u8]> + Send + 'static>(slice: T) -> Self {
79         assert_initialized_main_thread!();
80 
81         unsafe {
82             let mut b = Box::new(slice);
83             let (size, data) = {
84                 let slice = (*b).as_mut();
85                 (slice.len(), slice.as_mut_ptr())
86             };
87             let user_data = Box::into_raw(b);
88             from_glib_full(gst_sys::gst_buffer_new_wrapped_full(
89                 0,
90                 data as glib_sys::gpointer,
91                 size,
92                 0,
93                 size,
94                 user_data as glib_sys::gpointer,
95                 Some(Self::drop_box::<T>),
96             ))
97         }
98     }
99 
from_slice<T: AsRef<[u8]> + Send + 'static>(slice: T) -> Self100     pub fn from_slice<T: AsRef<[u8]> + Send + 'static>(slice: T) -> Self {
101         assert_initialized_main_thread!();
102 
103         unsafe {
104             let b = Box::new(slice);
105             let (size, data) = {
106                 let slice = (*b).as_ref();
107                 (slice.len(), slice.as_ptr())
108             };
109             let user_data = Box::into_raw(b);
110             from_glib_full(gst_sys::gst_buffer_new_wrapped_full(
111                 gst_sys::GST_MEMORY_FLAG_READONLY,
112                 data as glib_sys::gpointer,
113                 size,
114                 0,
115                 size,
116                 user_data as glib_sys::gpointer,
117                 Some(Self::drop_box::<T>),
118             ))
119         }
120     }
121 
into_mapped_buffer_readable(self) -> Result<MappedBuffer<Readable>, Self>122     pub fn into_mapped_buffer_readable(self) -> Result<MappedBuffer<Readable>, Self> {
123         unsafe {
124             let mut map_info = mem::MaybeUninit::zeroed();
125             let res: bool = from_glib(gst_sys::gst_buffer_map(
126                 self.as_mut_ptr(),
127                 map_info.as_mut_ptr(),
128                 gst_sys::GST_MAP_READ,
129             ));
130             if res {
131                 Ok(MappedBuffer {
132                     buffer: Some(self),
133                     map_info: map_info.assume_init(),
134                     phantom: PhantomData,
135                 })
136             } else {
137                 Err(self)
138             }
139         }
140     }
141 
into_mapped_buffer_writable(self) -> Result<MappedBuffer<Writable>, Self>142     pub fn into_mapped_buffer_writable(self) -> Result<MappedBuffer<Writable>, Self> {
143         unsafe {
144             let mut map_info = mem::MaybeUninit::zeroed();
145             let res: bool = from_glib(gst_sys::gst_buffer_map(
146                 self.as_mut_ptr(),
147                 map_info.as_mut_ptr(),
148                 gst_sys::GST_MAP_READWRITE,
149             ));
150             if res {
151                 Ok(MappedBuffer {
152                     buffer: Some(self),
153                     map_info: map_info.assume_init(),
154                     phantom: PhantomData,
155                 })
156             } else {
157                 Err(self)
158             }
159         }
160     }
161 
append(buffer: Self, other: Self) -> Self162     pub fn append(buffer: Self, other: Self) -> Self {
163         skip_assert_initialized!();
164         unsafe {
165             from_glib_full(gst_sys::gst_buffer_append(
166                 buffer.into_ptr(),
167                 other.into_ptr(),
168             ))
169         }
170     }
171 }
172 
173 impl Default for Buffer {
default() -> Self174     fn default() -> Self {
175         Self::new()
176     }
177 }
178 
179 impl BufferRef {
map_readable(&self) -> Result<BufferMap<Readable>, glib::BoolError>180     pub fn map_readable(&self) -> Result<BufferMap<Readable>, glib::BoolError> {
181         unsafe {
182             let mut map_info = mem::MaybeUninit::zeroed();
183             let res = gst_sys::gst_buffer_map(
184                 self.as_mut_ptr(),
185                 map_info.as_mut_ptr(),
186                 gst_sys::GST_MAP_READ,
187             );
188             if res == glib_sys::GTRUE {
189                 Ok(BufferMap {
190                     buffer: self,
191                     map_info: map_info.assume_init(),
192                     phantom: PhantomData,
193                 })
194             } else {
195                 Err(glib_bool_error!("Failed to map buffer readable"))
196             }
197         }
198     }
199 
map_writable(&mut self) -> Result<BufferMap<Writable>, glib::BoolError>200     pub fn map_writable(&mut self) -> Result<BufferMap<Writable>, glib::BoolError> {
201         unsafe {
202             let mut map_info = mem::MaybeUninit::zeroed();
203             let res = gst_sys::gst_buffer_map(
204                 self.as_mut_ptr(),
205                 map_info.as_mut_ptr(),
206                 gst_sys::GST_MAP_READWRITE,
207             );
208             if res == glib_sys::GTRUE {
209                 Ok(BufferMap {
210                     buffer: self,
211                     map_info: map_info.assume_init(),
212                     phantom: PhantomData,
213                 })
214             } else {
215                 Err(glib_bool_error!("Failed to map buffer writable"))
216             }
217         }
218     }
219 
copy_region( &self, flags: ::BufferCopyFlags, offset: usize, size: Option<usize>, ) -> Result<Buffer, glib::BoolError>220     pub fn copy_region(
221         &self,
222         flags: ::BufferCopyFlags,
223         offset: usize,
224         size: Option<usize>,
225     ) -> Result<Buffer, glib::BoolError> {
226         let size_real = size.unwrap_or(usize::MAX);
227         unsafe {
228             Option::<_>::from_glib_full(gst_sys::gst_buffer_copy_region(
229                 self.as_mut_ptr(),
230                 flags.to_glib(),
231                 offset,
232                 size_real,
233             ))
234             .ok_or_else(|| glib_bool_error!("Failed to copy region of buffer"))
235         }
236     }
237 
copy_into( &self, dest: &mut BufferRef, flags: ::BufferCopyFlags, offset: usize, size: Option<usize>, ) -> Result<(), glib::BoolError>238     pub fn copy_into(
239         &self,
240         dest: &mut BufferRef,
241         flags: ::BufferCopyFlags,
242         offset: usize,
243         size: Option<usize>,
244     ) -> Result<(), glib::BoolError> {
245         let size_real = size.unwrap_or(usize::MAX);
246         unsafe {
247             glib_result_from_gboolean!(
248                 gst_sys::gst_buffer_copy_into(
249                     dest.as_mut_ptr(),
250                     self.as_mut_ptr(),
251                     flags.to_glib(),
252                     offset,
253                     size_real,
254                 ),
255                 "Failed to copy into destination buffer",
256             )
257         }
258     }
259 
copy_from_slice(&mut self, offset: usize, slice: &[u8]) -> Result<(), usize>260     pub fn copy_from_slice(&mut self, offset: usize, slice: &[u8]) -> Result<(), usize> {
261         let maxsize = self.get_maxsize();
262         let size = slice.len();
263 
264         assert!(maxsize >= offset && maxsize - offset >= size);
265 
266         let copied = unsafe {
267             let src = slice.as_ptr();
268             gst_sys::gst_buffer_fill(
269                 self.as_mut_ptr(),
270                 offset,
271                 src as glib_sys::gconstpointer,
272                 size,
273             )
274         };
275 
276         if copied == size {
277             Ok(())
278         } else {
279             Err(copied)
280         }
281     }
282 
copy_to_slice(&self, offset: usize, slice: &mut [u8]) -> Result<(), usize>283     pub fn copy_to_slice(&self, offset: usize, slice: &mut [u8]) -> Result<(), usize> {
284         let maxsize = self.get_size();
285         let size = slice.len();
286 
287         assert!(maxsize >= offset && maxsize - offset >= size);
288 
289         let copied = unsafe {
290             let dest = slice.as_mut_ptr();
291             gst_sys::gst_buffer_extract(self.as_mut_ptr(), offset, dest as glib_sys::gpointer, size)
292         };
293 
294         if copied == size {
295             Ok(())
296         } else {
297             Err(copied)
298         }
299     }
300 
copy_deep(&self) -> Result<Buffer, glib::BoolError>301     pub fn copy_deep(&self) -> Result<Buffer, glib::BoolError> {
302         unsafe {
303             Option::<_>::from_glib_full(gst_sys::gst_buffer_copy_deep(self.as_ptr()))
304                 .ok_or_else(|| glib_bool_error!("Failed to deep copy buffer"))
305         }
306     }
307 
get_size(&self) -> usize308     pub fn get_size(&self) -> usize {
309         unsafe { gst_sys::gst_buffer_get_size(self.as_mut_ptr()) }
310     }
311 
get_maxsize(&self) -> usize312     pub fn get_maxsize(&self) -> usize {
313         unsafe {
314             let mut maxsize = mem::MaybeUninit::uninit();
315             gst_sys::gst_buffer_get_sizes_range(
316                 self.as_mut_ptr(),
317                 0,
318                 -1,
319                 ptr::null_mut(),
320                 maxsize.as_mut_ptr(),
321             );
322 
323             maxsize.assume_init()
324         }
325     }
326 
set_size(&mut self, size: usize)327     pub fn set_size(&mut self, size: usize) {
328         assert!(self.get_maxsize() >= size);
329 
330         unsafe {
331             gst_sys::gst_buffer_set_size(self.as_mut_ptr(), size as isize);
332         }
333     }
334 
get_offset(&self) -> u64335     pub fn get_offset(&self) -> u64 {
336         self.0.offset
337     }
338 
set_offset(&mut self, offset: u64)339     pub fn set_offset(&mut self, offset: u64) {
340         self.0.offset = offset;
341     }
342 
get_offset_end(&self) -> u64343     pub fn get_offset_end(&self) -> u64 {
344         self.0.offset_end
345     }
346 
set_offset_end(&mut self, offset_end: u64)347     pub fn set_offset_end(&mut self, offset_end: u64) {
348         self.0.offset_end = offset_end;
349     }
350 
get_pts(&self) -> ClockTime351     pub fn get_pts(&self) -> ClockTime {
352         from_glib(self.0.pts)
353     }
354 
set_pts(&mut self, pts: ClockTime)355     pub fn set_pts(&mut self, pts: ClockTime) {
356         self.0.pts = pts.to_glib();
357     }
358 
get_dts(&self) -> ClockTime359     pub fn get_dts(&self) -> ClockTime {
360         from_glib(self.0.dts)
361     }
362 
set_dts(&mut self, dts: ClockTime)363     pub fn set_dts(&mut self, dts: ClockTime) {
364         self.0.dts = dts.to_glib();
365     }
366 
get_dts_or_pts(&self) -> ClockTime367     pub fn get_dts_or_pts(&self) -> ClockTime {
368         let val = self.get_dts();
369         if val.is_none() {
370             self.get_pts()
371         } else {
372             val
373         }
374     }
375 
get_duration(&self) -> ClockTime376     pub fn get_duration(&self) -> ClockTime {
377         from_glib(self.0.duration)
378     }
379 
set_duration(&mut self, duration: ClockTime)380     pub fn set_duration(&mut self, duration: ClockTime) {
381         self.0.duration = duration.to_glib();
382     }
383 
get_flags(&self) -> BufferFlags384     pub fn get_flags(&self) -> BufferFlags {
385         BufferFlags::from_bits_truncate(self.0.mini_object.flags)
386     }
387 
set_flags(&mut self, flags: BufferFlags)388     pub fn set_flags(&mut self, flags: BufferFlags) {
389         self.0.mini_object.flags |= flags.bits();
390     }
391 
unset_flags(&mut self, flags: BufferFlags)392     pub fn unset_flags(&mut self, flags: BufferFlags) {
393         self.0.mini_object.flags &= !flags.bits();
394     }
395 
get_meta<T: MetaAPI>(&self) -> Option<MetaRef<T>>396     pub fn get_meta<T: MetaAPI>(&self) -> Option<MetaRef<T>> {
397         unsafe {
398             let meta = gst_sys::gst_buffer_get_meta(self.as_mut_ptr(), T::get_meta_api().to_glib());
399             if meta.is_null() {
400                 None
401             } else {
402                 Some(T::from_ptr(self, meta as *const <T as MetaAPI>::GstType))
403             }
404         }
405     }
406 
get_meta_mut<T: MetaAPI>(&mut self) -> Option<MetaRefMut<T, ::meta::Standalone>>407     pub fn get_meta_mut<T: MetaAPI>(&mut self) -> Option<MetaRefMut<T, ::meta::Standalone>> {
408         unsafe {
409             let meta = gst_sys::gst_buffer_get_meta(self.as_mut_ptr(), T::get_meta_api().to_glib());
410             if meta.is_null() {
411                 None
412             } else {
413                 Some(T::from_mut_ptr(self, meta as *mut <T as MetaAPI>::GstType))
414             }
415         }
416     }
417 
iter_meta<T: MetaAPI>(&self) -> MetaIter<T>418     pub fn iter_meta<T: MetaAPI>(&self) -> MetaIter<T> {
419         MetaIter::new(self)
420     }
421 
iter_meta_mut<T: MetaAPI>(&mut self) -> MetaIterMut<T>422     pub fn iter_meta_mut<T: MetaAPI>(&mut self) -> MetaIterMut<T> {
423         MetaIterMut::new(self)
424     }
425 
append_memory(&mut self, mem: Memory)426     pub fn append_memory(&mut self, mem: Memory) {
427         unsafe { gst_sys::gst_buffer_append_memory(self.as_mut_ptr(), mem.into_ptr()) }
428     }
429 
find_memory(&self, offset: usize, size: Option<usize>) -> Option<(u32, u32, usize)>430     pub fn find_memory(&self, offset: usize, size: Option<usize>) -> Option<(u32, u32, usize)> {
431         unsafe {
432             let mut idx = mem::MaybeUninit::uninit();
433             let mut length = mem::MaybeUninit::uninit();
434             let mut skip = mem::MaybeUninit::uninit();
435 
436             let res = from_glib(gst_sys::gst_buffer_find_memory(
437                 self.as_mut_ptr(),
438                 offset,
439                 size.unwrap_or(usize::MAX),
440                 idx.as_mut_ptr(),
441                 length.as_mut_ptr(),
442                 skip.as_mut_ptr(),
443             ));
444 
445             if res {
446                 Some((idx.assume_init(), length.assume_init(), skip.assume_init()))
447             } else {
448                 None
449             }
450         }
451     }
452 
get_all_memory(&self) -> Option<Memory>453     pub fn get_all_memory(&self) -> Option<Memory> {
454         unsafe {
455             let res = gst_sys::gst_buffer_get_all_memory(self.as_mut_ptr());
456             if res.is_null() {
457                 None
458             } else {
459                 Some(from_glib_full(res))
460             }
461         }
462     }
463 
get_max_memory() -> u32464     pub fn get_max_memory() -> u32 {
465         unsafe { gst_sys::gst_buffer_get_max_memory() }
466     }
467 
get_memory(&self, idx: u32) -> Option<Memory>468     pub fn get_memory(&self, idx: u32) -> Option<Memory> {
469         if idx >= self.n_memory() {
470             None
471         } else {
472             unsafe {
473                 let res = gst_sys::gst_buffer_get_memory(self.as_mut_ptr(), idx);
474                 if res.is_null() {
475                     None
476                 } else {
477                     Some(from_glib_full(res))
478                 }
479             }
480         }
481     }
482 
get_memory_range(&self, idx: u32, length: Option<u32>) -> Option<Memory>483     pub fn get_memory_range(&self, idx: u32, length: Option<u32>) -> Option<Memory> {
484         assert!(idx + length.unwrap_or(0) < self.n_memory());
485         unsafe {
486             let res = gst_sys::gst_buffer_get_memory_range(
487                 self.as_mut_ptr(),
488                 idx,
489                 match length {
490                     Some(val) => val as i32,
491                     None => -1,
492                 },
493             );
494             if res.is_null() {
495                 None
496             } else {
497                 Some(from_glib_full(res))
498             }
499         }
500     }
501 
insert_memory(&mut self, idx: Option<u32>, mem: Memory)502     pub fn insert_memory(&mut self, idx: Option<u32>, mem: Memory) {
503         unsafe {
504             gst_sys::gst_buffer_insert_memory(
505                 self.as_mut_ptr(),
506                 match idx {
507                     Some(val) => val as i32,
508                     None => -1,
509                 },
510                 mem.into_ptr(),
511             )
512         }
513     }
514 
is_all_memory_writable(&self) -> bool515     pub fn is_all_memory_writable(&self) -> bool {
516         unsafe {
517             from_glib(gst_sys::gst_buffer_is_all_memory_writable(
518                 self.as_mut_ptr(),
519             ))
520         }
521     }
522 
is_memory_range_writable(&self, idx: u32, length: Option<u16>) -> bool523     pub fn is_memory_range_writable(&self, idx: u32, length: Option<u16>) -> bool {
524         unsafe {
525             from_glib(gst_sys::gst_buffer_is_memory_range_writable(
526                 self.as_mut_ptr(),
527                 idx,
528                 match length {
529                     Some(val) => val as i32,
530                     None => -1,
531                 },
532             ))
533         }
534     }
535 
n_memory(&self) -> u32536     pub fn n_memory(&self) -> u32 {
537         unsafe { gst_sys::gst_buffer_n_memory(self.as_ptr() as *mut _) }
538     }
539 
peek_memory(&self, idx: u32) -> &MemoryRef540     pub fn peek_memory(&self, idx: u32) -> &MemoryRef {
541         assert!(idx < self.n_memory());
542         unsafe { MemoryRef::from_ptr(gst_sys::gst_buffer_peek_memory(self.as_mut_ptr(), idx)) }
543     }
544 
peek_memory_mut(&mut self, idx: u32) -> Result<&mut MemoryRef, glib::BoolError>545     pub fn peek_memory_mut(&mut self, idx: u32) -> Result<&mut MemoryRef, glib::BoolError> {
546         assert!(idx < self.n_memory());
547         unsafe {
548             let mem = gst_sys::gst_buffer_peek_memory(self.as_mut_ptr(), idx);
549             if gst_sys::gst_mini_object_is_writable(mem as *mut _) == glib_sys::GFALSE {
550                 Err(glib_bool_error!("Memory not writable"))
551             } else {
552                 Ok(MemoryRef::from_mut_ptr(gst_sys::gst_buffer_peek_memory(
553                     self.as_mut_ptr(),
554                     idx,
555                 )))
556             }
557         }
558     }
559 
prepend_memory(&mut self, mem: Memory)560     pub fn prepend_memory(&mut self, mem: Memory) {
561         unsafe { gst_sys::gst_buffer_prepend_memory(self.as_mut_ptr(), mem.into_ptr()) }
562     }
563 
remove_all_memory(&mut self)564     pub fn remove_all_memory(&mut self) {
565         unsafe { gst_sys::gst_buffer_remove_all_memory(self.as_mut_ptr()) }
566     }
567 
remove_memory(&mut self, idx: u32)568     pub fn remove_memory(&mut self, idx: u32) {
569         assert!(idx < self.n_memory());
570         unsafe { gst_sys::gst_buffer_remove_memory(self.as_mut_ptr(), idx) }
571     }
572 
remove_memory_range(&mut self, idx: u32, length: Option<u32>)573     pub fn remove_memory_range(&mut self, idx: u32, length: Option<u32>) {
574         assert!(idx + length.unwrap_or(0) < self.n_memory());
575         unsafe {
576             gst_sys::gst_buffer_remove_memory_range(
577                 self.as_mut_ptr(),
578                 idx,
579                 match length {
580                     Some(val) => val as i32,
581                     None => -1,
582                 },
583             )
584         }
585     }
586 
replace_all_memory(&mut self, mem: Memory)587     pub fn replace_all_memory(&mut self, mem: Memory) {
588         unsafe { gst_sys::gst_buffer_replace_all_memory(self.as_mut_ptr(), mem.into_ptr()) }
589     }
590 
replace_memory(&mut self, idx: u32, mem: Memory)591     pub fn replace_memory(&mut self, idx: u32, mem: Memory) {
592         assert!(idx < self.n_memory());
593         unsafe { gst_sys::gst_buffer_replace_memory(self.as_mut_ptr(), idx, mem.into_ptr()) }
594     }
595 
replace_memory_range(&mut self, idx: u32, length: Option<u32>, mem: Memory)596     pub fn replace_memory_range(&mut self, idx: u32, length: Option<u32>, mem: Memory) {
597         assert!(idx + length.unwrap_or(0) < self.n_memory());
598         unsafe {
599             gst_sys::gst_buffer_replace_memory_range(
600                 self.as_mut_ptr(),
601                 idx,
602                 match length {
603                     Some(val) => val as i32,
604                     None => -1,
605                 },
606                 mem.into_ptr(),
607             )
608         }
609     }
610 
iter_memories(&self) -> Iter611     pub fn iter_memories(&self) -> Iter {
612         Iter::new(self)
613     }
614 
iter_memories_mut(&mut self) -> Result<IterMut, glib::BoolError>615     pub fn iter_memories_mut(&mut self) -> Result<IterMut, glib::BoolError> {
616         if !self.is_all_memory_writable() {
617             Err(glib_bool_error!("Not all memory are writable"))
618         } else {
619             Ok(IterMut::new(self))
620         }
621     }
622 
iter_memories_owned(&self) -> IterOwned623     pub fn iter_memories_owned(&self) -> IterOwned {
624         IterOwned::new(self)
625     }
626 }
627 
628 macro_rules! define_meta_iter(
629     ($name:ident, $typ:ty, $mtyp:ty, $prepare_buffer:expr, $from_ptr:expr) => {
630     pub struct $name<'a, T: MetaAPI + 'a> {
631         buffer: $typ,
632         state: glib_sys::gpointer,
633         meta_api: glib::Type,
634         items: PhantomData<$mtyp>,
635     }
636 
637     unsafe impl<'a, T: MetaAPI> Send for $name<'a, T> { }
638     unsafe impl<'a, T: MetaAPI> Sync for $name<'a, T> { }
639 
640     impl<'a, T: MetaAPI> fmt::Debug for $name<'a, T> {
641         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
642             f.debug_struct(stringify!($name))
643                 .field("buffer", &self.buffer)
644                 .field("state", &self.state)
645                 .field("meta_api", &self.meta_api)
646                 .field("items", &self.items)
647                 .finish()
648         }
649     }
650 
651     impl<'a, T: MetaAPI> $name<'a, T> {
652         fn new(buffer: $typ) -> $name<'a, T> {
653             skip_assert_initialized!();
654 
655             $name {
656                 buffer,
657                 state: ptr::null_mut(),
658                 meta_api: T::get_meta_api(),
659                 items: PhantomData,
660             }
661         }
662     }
663 
664     impl<'a, T: MetaAPI> Iterator for $name<'a, T> {
665         type Item = $mtyp;
666 
667         fn next(&mut self) -> Option<Self::Item> {
668             loop {
669                 unsafe {
670                     let meta = gst_sys::gst_buffer_iterate_meta(self.buffer.as_mut_ptr(), &mut self.state);
671 
672                     if meta.is_null() {
673                         return None;
674                     } else if self.meta_api == glib::Type::Invalid || glib::Type::from_glib((*(*meta).info).api) == self.meta_api {
675                         // FIXME: Workaround for a lifetime issue with the mutable iterator only
676                         let buffer = $prepare_buffer(self.buffer.as_mut_ptr());
677                         let item = $from_ptr(buffer, meta);
678                         return Some(item);
679                     }
680                 }
681             }
682         }
683     }
684 
685     impl<'a, T: MetaAPI> ExactSizeIterator for $name<'a, T> {}
686     }
687 );
688 
689 define_meta_iter!(
690     MetaIter,
691     &'a BufferRef,
692     MetaRef<'a, T>,
693     |buffer: *const gst_sys::GstBuffer| BufferRef::from_ptr(buffer),
694     |buffer, meta| T::from_ptr(buffer, meta as *const <T as MetaAPI>::GstType)
695 );
696 define_meta_iter!(
697     MetaIterMut,
698     &'a mut BufferRef,
699     MetaRefMut<'a, T, ::meta::Iterated>,
700     |buffer: *mut gst_sys::GstBuffer| BufferRef::from_mut_ptr(buffer),
701     |buffer: &'a mut BufferRef, meta| T::from_mut_ptr(buffer, meta as *mut <T as MetaAPI>::GstType)
702 );
703 
704 macro_rules! define_iter(
705     ($name:ident, $typ:ty, $mtyp:ty, $get_item:expr) => {
706     pub struct $name<'a> {
707         buffer: $typ,
708         idx: u32,
709         n_memory: u32,
710     }
711 
712     impl<'a> fmt::Debug for $name<'a> {
713         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
714             f.debug_struct(stringify!($name))
715                 .field("buffer", &self.buffer)
716                 .field("idx", &self.idx)
717                 .field("n_memory", &self.n_memory)
718                 .finish()
719         }
720     }
721 
722     impl<'a> $name<'a> {
723         fn new(buffer: $typ) -> $name<'a> {
724             skip_assert_initialized!();
725 
726             let n_memory = buffer.n_memory();
727 
728             $name {
729                 buffer,
730                 idx: 0,
731                 n_memory,
732             }
733         }
734     }
735 
736     impl<'a> Iterator for $name<'a> {
737         type Item = $mtyp;
738 
739         fn next(&mut self) -> Option<Self::Item> {
740             if self.idx >= self.n_memory {
741                 return None;
742             }
743 
744             #[allow(unused_unsafe)]
745             unsafe {
746                 let item = $get_item(self.buffer, self.idx)?;
747                 self.idx += 1;
748                 Some(item)
749             }
750         }
751 
752         fn size_hint(&self) -> (usize, Option<usize>) {
753             if self.idx == self.n_memory {
754                 return (0, Some(0));
755             }
756 
757             let remaining = (self.n_memory - self.idx) as usize;
758 
759             (remaining, Some(remaining))
760         }
761     }
762 
763     impl<'a> DoubleEndedIterator for $name<'a> {
764         fn next_back(&mut self) -> Option<Self::Item> {
765             if self.idx == self.n_memory {
766                 return None;
767             }
768 
769             self.n_memory -= 1;
770 
771             #[allow(unused_unsafe)]
772             unsafe {
773                 $get_item(self.buffer, self.n_memory)
774             }
775         }
776     }
777 
778     impl<'a> ExactSizeIterator for $name<'a> {}
779     }
780 );
781 
782 define_iter!(
783     Iter,
784     &'a BufferRef,
785     &'a MemoryRef,
786     |buffer: &BufferRef, idx| {
787         let ptr = gst_sys::gst_buffer_peek_memory(buffer.as_mut_ptr(), idx);
788         if ptr.is_null() {
789             None
790         } else {
791             Some(MemoryRef::from_ptr(ptr as *const gst_sys::GstMemory))
792         }
793     }
794 );
795 
796 define_iter!(
797     IterMut,
798     &'a mut BufferRef,
799     &'a mut MemoryRef,
800     |buffer: &mut BufferRef, idx| {
801         let ptr = gst_sys::gst_buffer_peek_memory(buffer.as_mut_ptr(), idx);
802         if ptr.is_null() {
803             None
804         } else {
805             Some(MemoryRef::from_mut_ptr(ptr as *mut gst_sys::GstMemory))
806         }
807     }
808 );
809 
810 define_iter!(
811     IterOwned,
812     &'a BufferRef,
813     Memory,
814     |buffer: &BufferRef, idx| { buffer.get_memory(idx) }
815 );
816 
817 impl fmt::Debug for BufferRef {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result818     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
819         use std::cell::RefCell;
820 
821         struct DebugIter<I>(RefCell<I>);
822         impl<I: Iterator> fmt::Debug for DebugIter<I>
823         where
824             I::Item: fmt::Debug,
825         {
826             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
827                 f.debug_list().entries(&mut *self.0.borrow_mut()).finish()
828             }
829         }
830 
831         f.debug_struct("Buffer")
832             .field("ptr", unsafe { &self.as_ptr() })
833             .field("pts", &self.get_pts().to_string())
834             .field("dts", &self.get_dts().to_string())
835             .field("duration", &self.get_duration().to_string())
836             .field("size", &self.get_size())
837             .field("offset", &self.get_offset())
838             .field("offset_end", &self.get_offset_end())
839             .field("flags", &self.get_flags())
840             .field(
841                 "metas",
842                 &DebugIter(RefCell::new(
843                     self.iter_meta::<::Meta>().map(|m| m.get_api()),
844                 )),
845             )
846             .finish()
847     }
848 }
849 
850 impl PartialEq for BufferRef {
eq(&self, other: &BufferRef) -> bool851     fn eq(&self, other: &BufferRef) -> bool {
852         if self.get_size() != other.get_size() {
853             return false;
854         }
855 
856         let self_map = self.map_readable();
857         let other_map = other.map_readable();
858 
859         match (self_map, other_map) {
860             (Ok(self_map), Ok(other_map)) => self_map.as_slice().eq(other_map.as_slice()),
861             _ => false,
862         }
863     }
864 }
865 
866 impl Eq for BufferRef {}
867 
868 impl<'a, T> BufferMap<'a, T> {
get_size(&self) -> usize869     pub fn get_size(&self) -> usize {
870         self.map_info.size
871     }
872 
get_buffer(&self) -> &BufferRef873     pub fn get_buffer(&self) -> &BufferRef {
874         self.buffer
875     }
876 
as_slice(&self) -> &[u8]877     pub fn as_slice(&self) -> &[u8] {
878         unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
879     }
880 }
881 
882 impl<'a> BufferMap<'a, Writable> {
as_mut_slice(&mut self) -> &mut [u8]883     pub fn as_mut_slice(&mut self) -> &mut [u8] {
884         unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
885     }
886 }
887 
888 impl<'a, T> AsRef<[u8]> for BufferMap<'a, T> {
as_ref(&self) -> &[u8]889     fn as_ref(&self) -> &[u8] {
890         self.as_slice()
891     }
892 }
893 
894 impl<'a> AsMut<[u8]> for BufferMap<'a, Writable> {
as_mut(&mut self) -> &mut [u8]895     fn as_mut(&mut self) -> &mut [u8] {
896         self.as_mut_slice()
897     }
898 }
899 
900 impl<'a, T> ops::Deref for BufferMap<'a, T> {
901     type Target = [u8];
902 
deref(&self) -> &[u8]903     fn deref(&self) -> &[u8] {
904         self.as_slice()
905     }
906 }
907 
908 impl<'a> ops::DerefMut for BufferMap<'a, Writable> {
deref_mut(&mut self) -> &mut [u8]909     fn deref_mut(&mut self) -> &mut [u8] {
910         self.as_mut_slice()
911     }
912 }
913 
914 impl<'a, T> fmt::Debug for BufferMap<'a, T> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result915     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
916         f.debug_tuple("BufferMap")
917             .field(&self.get_buffer())
918             .finish()
919     }
920 }
921 
922 impl<'a, T> PartialEq for BufferMap<'a, T> {
eq(&self, other: &BufferMap<'a, T>) -> bool923     fn eq(&self, other: &BufferMap<'a, T>) -> bool {
924         self.as_slice().eq(other.as_slice())
925     }
926 }
927 
928 impl<'a, T> Eq for BufferMap<'a, T> {}
929 
930 impl<'a, T> Drop for BufferMap<'a, T> {
drop(&mut self)931     fn drop(&mut self) {
932         unsafe {
933             gst_sys::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
934         }
935     }
936 }
937 
938 unsafe impl<'a, T> Send for BufferMap<'a, T> {}
939 unsafe impl<'a, T> Sync for BufferMap<'a, T> {}
940 
941 impl<T> MappedBuffer<T> {
as_slice(&self) -> &[u8]942     pub fn as_slice(&self) -> &[u8] {
943         unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
944     }
945 
get_size(&self) -> usize946     pub fn get_size(&self) -> usize {
947         self.map_info.size
948     }
949 
get_buffer(&self) -> &BufferRef950     pub fn get_buffer(&self) -> &BufferRef {
951         self.buffer.as_ref().unwrap().as_ref()
952     }
953 
into_buffer(mut self) -> Buffer954     pub fn into_buffer(mut self) -> Buffer {
955         let buffer = self.buffer.take().unwrap();
956         unsafe {
957             gst_sys::gst_buffer_unmap(buffer.as_mut_ptr(), &mut self.map_info);
958         }
959 
960         buffer
961     }
962 }
963 
964 impl MappedBuffer<Writable> {
as_mut_slice(&mut self) -> &mut [u8]965     pub fn as_mut_slice(&mut self) -> &mut [u8] {
966         unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
967     }
968 }
969 
970 impl<T> AsRef<[u8]> for MappedBuffer<T> {
as_ref(&self) -> &[u8]971     fn as_ref(&self) -> &[u8] {
972         self.as_slice()
973     }
974 }
975 
976 impl AsMut<[u8]> for MappedBuffer<Writable> {
as_mut(&mut self) -> &mut [u8]977     fn as_mut(&mut self) -> &mut [u8] {
978         self.as_mut_slice()
979     }
980 }
981 
982 impl<T> ops::Deref for MappedBuffer<T> {
983     type Target = [u8];
984 
deref(&self) -> &[u8]985     fn deref(&self) -> &[u8] {
986         self.as_slice()
987     }
988 }
989 
990 impl ops::DerefMut for MappedBuffer<Writable> {
deref_mut(&mut self) -> &mut [u8]991     fn deref_mut(&mut self) -> &mut [u8] {
992         self.as_mut_slice()
993     }
994 }
995 
996 impl<T> Drop for MappedBuffer<T> {
drop(&mut self)997     fn drop(&mut self) {
998         if let Some(ref buffer) = self.buffer {
999             unsafe {
1000                 gst_sys::gst_buffer_unmap(buffer.as_mut_ptr(), &mut self.map_info);
1001             }
1002         }
1003     }
1004 }
1005 
1006 impl<T> fmt::Debug for MappedBuffer<T> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1007     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1008         f.debug_tuple("MappedBuffer")
1009             .field(&self.get_buffer())
1010             .finish()
1011     }
1012 }
1013 
1014 impl<T> PartialEq for MappedBuffer<T> {
eq(&self, other: &MappedBuffer<T>) -> bool1015     fn eq(&self, other: &MappedBuffer<T>) -> bool {
1016         self.as_slice().eq(other.as_slice())
1017     }
1018 }
1019 
1020 impl<T> Eq for MappedBuffer<T> {}
1021 
1022 unsafe impl<T> Send for MappedBuffer<T> {}
1023 unsafe impl<T> Sync for MappedBuffer<T> {}
1024 
1025 lazy_static! {
1026     pub static ref BUFFER_COPY_METADATA: ::BufferCopyFlags =
1027         ::BufferCopyFlags::FLAGS | ::BufferCopyFlags::TIMESTAMPS | ::BufferCopyFlags::META;
1028     pub static ref BUFFER_COPY_ALL: ::BufferCopyFlags =
1029         *BUFFER_COPY_METADATA | ::BufferCopyFlags::MEMORY;
1030 }
1031 
1032 #[cfg(test)]
1033 mod tests {
1034     use super::*;
1035 
1036     #[test]
test_fields()1037     fn test_fields() {
1038         ::init().unwrap();
1039 
1040         let mut buffer = Buffer::new();
1041 
1042         {
1043             let buffer = buffer.get_mut().unwrap();
1044             buffer.set_pts(1.into());
1045             buffer.set_dts(2.into());
1046             buffer.set_offset(3);
1047             buffer.set_offset_end(4);
1048             buffer.set_duration(5.into());
1049         }
1050         assert_eq!(buffer.get_pts(), 1.into());
1051         assert_eq!(buffer.get_dts(), 2.into());
1052         assert_eq!(buffer.get_offset(), 3);
1053         assert_eq!(buffer.get_offset_end(), 4);
1054         assert_eq!(buffer.get_duration(), 5.into());
1055     }
1056 
1057     #[test]
test_writability()1058     fn test_writability() {
1059         ::init().unwrap();
1060 
1061         let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
1062         {
1063             let data = buffer.map_readable().unwrap();
1064             assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
1065         }
1066         assert_ne!(buffer.get_mut(), None);
1067         {
1068             let buffer = buffer.get_mut().unwrap();
1069             buffer.set_pts(1.into());
1070         }
1071 
1072         let mut buffer2 = buffer.clone();
1073         assert_eq!(buffer.get_mut(), None);
1074 
1075         unsafe {
1076             assert_eq!(buffer2.as_ptr(), buffer.as_ptr());
1077         }
1078 
1079         {
1080             let buffer2 = buffer2.make_mut();
1081             unsafe {
1082                 assert_ne!(buffer2.as_ptr(), buffer.as_ptr());
1083             }
1084 
1085             buffer2.set_pts(2.into());
1086 
1087             let mut data = buffer2.map_writable().unwrap();
1088             assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
1089             data.as_mut_slice()[0] = 0;
1090         }
1091 
1092         assert_eq!(buffer.get_pts(), 1.into());
1093         assert_eq!(buffer2.get_pts(), 2.into());
1094 
1095         {
1096             let data = buffer.map_readable().unwrap();
1097             assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
1098 
1099             let data = buffer2.map_readable().unwrap();
1100             assert_eq!(data.as_slice(), vec![0, 2, 3, 4].as_slice());
1101         }
1102     }
1103 
1104     #[test]
test_memories()1105     fn test_memories() {
1106         ::init().unwrap();
1107 
1108         let mut buffer = Buffer::new();
1109         {
1110             let buffer = buffer.get_mut().unwrap();
1111             buffer.append_memory(::Memory::from_mut_slice(vec![0; 5]));
1112             buffer.append_memory(::Memory::from_mut_slice(vec![0; 5]));
1113             buffer.append_memory(::Memory::from_mut_slice(vec![0; 5]));
1114             buffer.append_memory(::Memory::from_mut_slice(vec![0; 5]));
1115             buffer.append_memory(::Memory::from_mut_slice(vec![0; 10]));
1116         }
1117 
1118         assert!(buffer.is_all_memory_writable());
1119         assert_eq!(buffer.n_memory(), 5);
1120         assert_eq!(buffer.get_size(), 30);
1121 
1122         for i in 0..5 {
1123             {
1124                 let mem = buffer.get_memory(i).unwrap();
1125                 assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1126                 let map = mem.map_readable().unwrap();
1127                 assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1128             }
1129 
1130             {
1131                 let mem = buffer.peek_memory(i);
1132                 assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1133                 let map = mem.map_readable().unwrap();
1134                 assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1135             }
1136 
1137             {
1138                 let buffer = buffer.get_mut().unwrap();
1139                 let mem = buffer.peek_memory_mut(i).unwrap();
1140                 assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1141                 let map = mem.map_writable().unwrap();
1142                 assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1143             }
1144         }
1145 
1146         {
1147             let buffer = buffer.get_mut().unwrap();
1148             let mut last = 0;
1149             for (i, mem) in buffer.iter_memories_mut().unwrap().enumerate() {
1150                 {
1151                     assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1152                     let map = mem.map_readable().unwrap();
1153                     assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1154                 }
1155 
1156                 {
1157                     assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1158                     let map = mem.map_readable().unwrap();
1159                     assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1160                 }
1161 
1162                 {
1163                     assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1164                     let map = mem.map_writable().unwrap();
1165                     assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1166                 }
1167 
1168                 last = i;
1169             }
1170 
1171             assert_eq!(last, 4);
1172         }
1173 
1174         let mut last = 0;
1175         for (i, mem) in buffer.iter_memories().enumerate() {
1176             {
1177                 assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1178                 let map = mem.map_readable().unwrap();
1179                 assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1180             }
1181 
1182             {
1183                 assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1184                 let map = mem.map_readable().unwrap();
1185                 assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1186             }
1187 
1188             last = i;
1189         }
1190 
1191         assert_eq!(last, 4);
1192 
1193         let mut last = 0;
1194         for (i, mem) in buffer.iter_memories_owned().enumerate() {
1195             {
1196                 assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1197                 let map = mem.map_readable().unwrap();
1198                 assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1199             }
1200 
1201             {
1202                 assert_eq!(mem.get_size(), if i < 4 { 5 } else { 10 });
1203                 let map = mem.map_readable().unwrap();
1204                 assert_eq!(map.get_size(), if i < 4 { 5 } else { 10 });
1205             }
1206 
1207             last = i;
1208         }
1209 
1210         assert_eq!(last, 4);
1211     }
1212 }
1213