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