1 // Copyright (C) 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 glib; 10 use glib::translate::{from_glib_full, from_glib_none}; 11 use gst_sys; 12 use std::fmt; 13 14 use miniobject::*; 15 use Buffer; 16 use BufferRef; 17 18 gst_define_mini_object_wrapper!( 19 BufferList, 20 BufferListRef, 21 gst_sys::GstBufferList, 22 [Debug,], 23 || gst_sys::gst_buffer_list_get_type() 24 ); 25 26 impl BufferList { new() -> Self27 pub fn new() -> Self { 28 assert_initialized_main_thread!(); 29 unsafe { from_glib_full(gst_sys::gst_buffer_list_new()) } 30 } 31 new_sized(size: usize) -> Self32 pub fn new_sized(size: usize) -> Self { 33 assert_initialized_main_thread!(); 34 unsafe { from_glib_full(gst_sys::gst_buffer_list_new_sized(size as u32)) } 35 } 36 } 37 38 impl BufferListRef { insert(&mut self, idx: i32, buffer: Buffer)39 pub fn insert(&mut self, idx: i32, buffer: Buffer) { 40 unsafe { 41 gst_sys::gst_buffer_list_insert(self.as_mut_ptr(), idx, buffer.into_ptr()); 42 } 43 } 44 add(&mut self, buffer: Buffer)45 pub fn add(&mut self, buffer: Buffer) { 46 self.insert(-1, buffer); 47 } 48 copy_deep(&self) -> BufferList49 pub fn copy_deep(&self) -> BufferList { 50 unsafe { from_glib_full(gst_sys::gst_buffer_list_copy_deep(self.as_ptr())) } 51 } 52 remove(&mut self, idx: u32, len: u32)53 pub fn remove(&mut self, idx: u32, len: u32) { 54 unsafe { gst_sys::gst_buffer_list_remove(self.as_mut_ptr(), idx, len) } 55 } 56 get(&self, idx: u32) -> Option<&BufferRef>57 pub fn get(&self, idx: u32) -> Option<&BufferRef> { 58 unsafe { 59 let ptr = gst_sys::gst_buffer_list_get(self.as_mut_ptr(), idx); 60 if ptr.is_null() { 61 None 62 } else { 63 Some(BufferRef::from_ptr(ptr)) 64 } 65 } 66 } 67 get_owned(&self, idx: u32) -> Option<Buffer>68 pub fn get_owned(&self, idx: u32) -> Option<Buffer> { 69 unsafe { 70 let ptr = gst_sys::gst_buffer_list_get(self.as_mut_ptr(), idx); 71 from_glib_none(ptr) 72 } 73 } 74 75 #[cfg(any(feature = "v1_14", feature = "dox"))] get_writable(&mut self, idx: u32) -> Option<&mut BufferRef>76 pub fn get_writable(&mut self, idx: u32) -> Option<&mut BufferRef> { 77 unsafe { 78 let ptr = gst_sys::gst_buffer_list_get_writable(self.as_mut_ptr(), idx); 79 if ptr.is_null() { 80 None 81 } else { 82 Some(BufferRef::from_mut_ptr(ptr)) 83 } 84 } 85 } 86 len(&self) -> usize87 pub fn len(&self) -> usize { 88 unsafe { gst_sys::gst_buffer_list_length(self.as_mut_ptr()) as usize } 89 } 90 91 #[cfg(any(feature = "v1_14", feature = "dox"))] calculate_size(&self) -> usize92 pub fn calculate_size(&self) -> usize { 93 unsafe { gst_sys::gst_buffer_list_calculate_size(self.as_mut_ptr()) as usize } 94 } 95 is_empty(&self) -> bool96 pub fn is_empty(&self) -> bool { 97 self.len() == 0 98 } 99 iter(&self) -> Iter100 pub fn iter(&self) -> Iter { 101 Iter::new(self) 102 } 103 iter_owned(&self) -> IterOwned104 pub fn iter_owned(&self) -> IterOwned { 105 IterOwned::new(self) 106 } 107 } 108 109 impl Default for BufferList { default() -> Self110 fn default() -> Self { 111 Self::new() 112 } 113 } 114 115 impl fmt::Debug for BufferListRef { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 117 let size = self.iter().map(|b| b.get_size()).sum::<usize>(); 118 let (pts, dts) = self 119 .get(0) 120 .map(|b| (b.get_pts(), b.get_dts())) 121 .unwrap_or((::ClockTime::none(), ::ClockTime::none())); 122 123 f.debug_struct("BufferList") 124 .field("ptr", unsafe { &self.as_ptr() }) 125 .field("buffers", &self.len()) 126 .field("pts", &pts.to_string()) 127 .field("dts", &dts.to_string()) 128 .field("size", &size) 129 .finish() 130 } 131 } 132 133 macro_rules! define_iter( 134 ($name:ident, $styp:ty, $get_item:expr) => { 135 #[derive(Debug)] 136 pub struct $name<'a> { 137 list: &'a BufferListRef, 138 idx: u32, 139 size: u32, 140 } 141 142 impl<'a> $name<'a> { 143 fn new(list: &'a BufferListRef) -> $name<'a> { 144 skip_assert_initialized!(); 145 $name { 146 list, 147 idx: 0, 148 size: list.len() as u32, 149 } 150 } 151 } 152 153 impl<'a> Iterator for $name<'a> { 154 type Item = $styp; 155 156 fn next(&mut self) -> Option<Self::Item> { 157 if self.idx >= self.size { 158 return None; 159 } 160 161 let item = $get_item(self.list, self.idx)?; 162 self.idx += 1; 163 164 Some(item) 165 } 166 167 fn size_hint(&self) -> (usize, Option<usize>) { 168 if self.idx == self.size { 169 return (0, Some(0)); 170 } 171 172 let remaining = (self.size - self.idx) as usize; 173 174 (remaining, Some(remaining)) 175 } 176 } 177 178 impl<'a> DoubleEndedIterator for $name<'a> { 179 fn next_back(&mut self) -> Option<Self::Item> { 180 if self.idx == self.size { 181 return None; 182 } 183 184 self.size -= 1; 185 $get_item(self.list, self.size) 186 } 187 } 188 189 impl<'a> ExactSizeIterator for $name<'a> {} 190 } 191 ); 192 193 define_iter!(Iter, &'a BufferRef, |list: &'a BufferListRef, idx| { 194 list.get(idx) 195 }); 196 197 define_iter!(IterOwned, Buffer, |list: &BufferListRef, idx| { 198 list.get_owned(idx) 199 }); 200