1use std::{fmt, marker::PhantomData, mem, ops, ptr, slice};
4
5use crate::ffi;
6use glib::translate::*;
7
8use smallvec::SmallVec;
9
10pub enum Readable {}
11pub enum Writable {}
12
13pub struct AudioBuffer<T> {
22 audio_buffer: Box<ffi::GstAudioBuffer>,
24 phantom: PhantomData<T>,
25}
26
27unsafe impl<T> Send for AudioBuffer<T> {}
28unsafe impl<T> Sync for AudioBuffer<T> {}
29
30impl<T> fmt::Debug for AudioBuffer<T> {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 f.debug_struct("AudioBuffer")
33 .field("n_samples", &self.n_samples())
34 .field("n_planes", &self.n_planes())
35 .field("buffer", &self.buffer())
36 .field("info", &self.info())
37 .finish()
38 }
39}
40
41impl<T> AudioBuffer<T> {
42 #[inline]
43 pub fn info(&self) -> &crate::AudioInfo {
44 unsafe {
45 &*(&self.audio_buffer.info as *const ffi::GstAudioInfo as *const crate::AudioInfo)
46 }
47 }
48
49 #[inline]
50 pub fn into_buffer(self) -> gst::Buffer {
51 unsafe {
52 let mut s = mem::ManuallyDrop::new(self);
53 let buffer = from_glib_none(s.audio_buffer.buffer);
55 ffi::gst_audio_buffer_unmap(&mut *s.audio_buffer);
56 ptr::drop_in_place(&mut s.audio_buffer);
57
58 buffer
59 }
60 }
61
62 #[inline]
63 pub fn format(&self) -> crate::AudioFormat {
64 self.info().format()
65 }
66
67 #[inline]
68 pub fn format_info(&self) -> crate::AudioFormatInfo {
69 self.info().format_info()
70 }
71
72 #[inline]
73 pub fn channels(&self) -> u32 {
74 self.info().channels()
75 }
76
77 #[inline]
78 pub fn rate(&self) -> u32 {
79 self.info().rate()
80 }
81
82 #[inline]
83 pub fn layout(&self) -> crate::AudioLayout {
84 self.info().layout()
85 }
86
87 #[inline]
88 pub fn width(&self) -> u32 {
89 self.info().width()
90 }
91
92 #[inline]
93 pub fn depth(&self) -> u32 {
94 self.info().depth()
95 }
96
97 #[inline]
98 pub fn sample_stride(&self) -> u32 {
99 self.info().width() / 8
100 }
101
102 #[inline]
103 pub fn bps(&self) -> u32 {
104 self.info().bps()
105 }
106
107 #[inline]
108 pub fn bpf(&self) -> u32 {
109 self.info().bpf()
110 }
111
112 #[inline]
113 pub fn n_samples(&self) -> usize {
114 self.audio_buffer.n_samples
115 }
116
117 #[inline]
118 pub fn n_planes(&self) -> u32 {
119 self.audio_buffer.n_planes as u32
120 }
121
122 #[inline]
123 pub fn plane_size(&self) -> usize {
124 (self.n_samples() * self.sample_stride() as usize * self.channels() as usize)
125 / self.n_planes() as usize
126 }
127
128 #[inline]
129 pub fn buffer(&self) -> &gst::BufferRef {
130 unsafe { gst::BufferRef::from_ptr(self.audio_buffer.buffer) }
131 }
132
133 pub fn plane_data(&self, plane: u32) -> Result<&[u8], glib::BoolError> {
134 if plane >= self.n_planes() {
135 return Err(glib::bool_error!(
136 "Plane index higher than number of planes"
137 ));
138 }
139
140 unsafe {
141 Ok(slice::from_raw_parts(
142 (*self.audio_buffer.planes.add(plane as usize)) as *const u8,
143 self.plane_size(),
144 ))
145 }
146 }
147
148 pub fn planes_data(&self) -> SmallVec<[&[u8]; 8]> {
149 let mut planes = SmallVec::default();
150
151 for plane in 0..self.n_planes() {
152 planes[plane as usize] = self.plane_data(plane).unwrap();
153 }
154
155 planes
156 }
157
158 #[inline]
159 pub fn as_audio_buffer_ref(&self) -> AudioBufferRef<&gst::BufferRef> {
160 AudioBufferRef {
161 audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::from(&*self.audio_buffer)),
162 phantom: PhantomData,
163 }
164 }
165
166 #[inline]
167 pub fn as_ptr(&self) -> *const ffi::GstAudioBuffer {
168 &*self.audio_buffer
169 }
170}
171
172impl<T> Drop for AudioBuffer<T> {
173 #[inline]
174 fn drop(&mut self) {
175 unsafe {
176 let buffer = gst::Buffer::from_glib_full(self.audio_buffer.buffer);
179 ffi::gst_audio_buffer_unmap(&mut *self.audio_buffer);
180 drop(buffer);
181 }
182 }
183}
184
185impl AudioBuffer<Readable> {
186 #[inline]
187 pub fn from_buffer_readable(
188 buffer: gst::Buffer,
189 info: &crate::AudioInfo,
190 ) -> Result<Self, gst::Buffer> {
191 skip_assert_initialized!();
192
193 assert!(info.is_valid());
194
195 unsafe {
196 let buffer = mem::ManuallyDrop::new(buffer);
199 let mut audio_buffer = Box::new(mem::MaybeUninit::zeroed().assume_init());
200 let res: bool = from_glib(ffi::gst_audio_buffer_map(
201 &mut *audio_buffer,
202 info.to_glib_none().0 as *mut _,
203 buffer.to_glib_none().0,
204 gst::ffi::GST_MAP_READ,
205 ));
206
207 if !res {
208 Err(mem::ManuallyDrop::into_inner(buffer))
209 } else {
210 Ok(Self {
211 audio_buffer,
212 phantom: PhantomData,
213 })
214 }
215 }
216 }
217
218 #[inline]
219 pub fn buffer_owned(&self) -> gst::Buffer {
220 unsafe { from_glib_none(self.audio_buffer.buffer) }
221 }
222}
223
224impl AudioBuffer<Writable> {
225 #[inline]
226 pub fn from_buffer_writable(
227 buffer: gst::Buffer,
228 info: &crate::AudioInfo,
229 ) -> Result<Self, gst::Buffer> {
230 skip_assert_initialized!();
231
232 assert!(info.is_valid());
233
234 unsafe {
235 let buffer = mem::ManuallyDrop::new(buffer);
238 let mut audio_buffer = Box::new(mem::MaybeUninit::zeroed().assume_init());
239 let res: bool = from_glib(ffi::gst_audio_buffer_map(
240 &mut *audio_buffer,
241 info.to_glib_none().0 as *mut _,
242 buffer.to_glib_none().0,
243 gst::ffi::GST_MAP_READ | gst::ffi::GST_MAP_WRITE,
244 ));
245
246 if !res {
247 Err(mem::ManuallyDrop::into_inner(buffer))
248 } else {
249 Ok(Self {
250 audio_buffer,
251 phantom: PhantomData,
252 })
253 }
254 }
255 }
256
257 pub fn plane_data_mut(&mut self, plane: u32) -> Result<&mut [u8], glib::BoolError> {
258 if plane >= self.n_planes() {
259 return Err(glib::bool_error!(
260 "Plane index higher than number of planes"
261 ));
262 }
263
264 unsafe {
265 Ok(slice::from_raw_parts_mut(
266 (*self.audio_buffer.planes.add(plane as usize)) as *mut u8,
267 self.plane_size(),
268 ))
269 }
270 }
271
272 pub fn planes_data_mut(&mut self) -> SmallVec<[&mut [u8]; 8]> {
273 let mut planes = SmallVec::default();
274
275 unsafe {
276 for plane in 0..self.n_planes() {
277 let slice = self.plane_data_mut(plane).unwrap();
278 planes.push(slice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()));
279 }
280 }
281
282 planes
283 }
284
285 #[inline]
286 pub fn as_mut_audio_buffer_ref(&mut self) -> AudioBufferRef<&mut gst::BufferRef> {
287 AudioBufferRef {
288 audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::from(&mut *self.audio_buffer)),
289 phantom: PhantomData,
290 }
291 }
292
293 #[inline]
294 pub fn as_mut_ptr(&mut self) -> *mut ffi::GstAudioBuffer {
295 &mut *self.audio_buffer
296 }
297}
298
299#[derive(Debug)]
300enum AudioBufferPtr {
301 Owned(Box<ffi::GstAudioBuffer>),
303 Borrowed(ptr::NonNull<ffi::GstAudioBuffer>),
304}
305
306impl ops::Deref for AudioBufferPtr {
307 type Target = ffi::GstAudioBuffer;
308
309 #[inline]
310 fn deref(&self) -> &Self::Target {
311 match self {
312 Self::Owned(ref b) => b,
313 Self::Borrowed(ref b) => unsafe { b.as_ref() },
314 }
315 }
316}
317
318impl ops::DerefMut for AudioBufferPtr {
319 #[inline]
320 fn deref_mut(&mut self) -> &mut Self::Target {
321 match self {
322 Self::Owned(ref mut b) => &mut *b,
323 Self::Borrowed(ref mut b) => unsafe { b.as_mut() },
324 }
325 }
326}
327
328pub struct AudioBufferRef<T> {
329 audio_buffer: AudioBufferPtr,
330 phantom: PhantomData<T>,
331}
332
333impl<T> fmt::Debug for AudioBufferRef<T> {
334 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
335 f.debug_struct("AudioBufferRef")
336 .field("n_samples", &self.n_samples())
337 .field("n_planes", &self.n_planes())
338 .field("buffer", &unsafe {
339 gst::BufferRef::from_ptr(self.audio_buffer.buffer)
340 })
341 .field("info", &self.info())
342 .finish()
343 }
344}
345
346impl<T> AudioBufferRef<T> {
347 #[inline]
348 pub fn info(&self) -> &crate::AudioInfo {
349 unsafe {
350 &*(&self.audio_buffer.info as *const ffi::GstAudioInfo as *const crate::AudioInfo)
351 }
352 }
353
354 #[inline]
355 pub fn format(&self) -> crate::AudioFormat {
356 self.info().format()
357 }
358
359 #[inline]
360 pub fn format_info(&self) -> crate::AudioFormatInfo {
361 self.info().format_info()
362 }
363
364 #[inline]
365 pub fn channels(&self) -> u32 {
366 self.info().channels()
367 }
368
369 #[inline]
370 pub fn rate(&self) -> u32 {
371 self.info().rate()
372 }
373
374 #[inline]
375 pub fn layout(&self) -> crate::AudioLayout {
376 self.info().layout()
377 }
378
379 #[inline]
380 pub fn width(&self) -> u32 {
381 self.info().width()
382 }
383
384 #[inline]
385 pub fn depth(&self) -> u32 {
386 self.info().depth()
387 }
388
389 #[inline]
390 pub fn sample_stride(&self) -> u32 {
391 self.info().width() / 8
392 }
393
394 #[inline]
395 pub fn bps(&self) -> u32 {
396 self.info().bps()
397 }
398
399 #[inline]
400 pub fn bpf(&self) -> u32 {
401 self.info().bpf()
402 }
403
404 #[inline]
405 pub fn n_samples(&self) -> usize {
406 self.audio_buffer.n_samples
407 }
408
409 #[inline]
410 pub fn n_planes(&self) -> u32 {
411 self.audio_buffer.n_planes as u32
412 }
413
414 #[inline]
415 pub fn plane_size(&self) -> usize {
416 (self.n_samples() * self.sample_stride() as usize * self.channels() as usize)
417 / self.n_planes() as usize
418 }
419
420 pub fn plane_data(&self, plane: u32) -> Result<&[u8], glib::BoolError> {
421 if plane >= self.n_planes() {
422 return Err(glib::bool_error!(
423 "Plane index higher than number of planes"
424 ));
425 }
426
427 if self.plane_size() == 0 {
428 return Ok(&[]);
429 }
430
431 unsafe {
432 Ok(slice::from_raw_parts(
433 (*self.audio_buffer.planes.add(plane as usize)) as *const u8,
434 self.plane_size(),
435 ))
436 }
437 }
438
439 pub fn planes_data(&self) -> SmallVec<[&[u8]; 8]> {
440 let mut planes = SmallVec::default();
441
442 for plane in 0..self.n_planes() {
443 planes[plane as usize] = self.plane_data(plane).unwrap();
444 }
445
446 planes
447 }
448
449 #[inline]
450 pub fn as_ptr(&self) -> *const ffi::GstAudioBuffer {
451 &*self.audio_buffer
452 }
453}
454
455impl<'a> AudioBufferRef<&'a gst::BufferRef> {
456 #[inline]
457 pub unsafe fn from_glib_borrow(audio_buffer: *const ffi::GstAudioBuffer) -> Borrowed<Self> {
458 debug_assert!(!audio_buffer.is_null());
459
460 Borrowed::new(Self {
461 audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::new_unchecked(
462 audio_buffer as *mut _,
463 )),
464 phantom: PhantomData,
465 })
466 }
467
468 #[inline]
469 pub fn from_buffer_ref_readable<'b>(
470 buffer: &'a gst::BufferRef,
471 info: &'b crate::AudioInfo,
472 ) -> Result<Self, glib::BoolError> {
473 skip_assert_initialized!();
474
475 assert!(info.is_valid());
476
477 unsafe {
478 let mut audio_buffer = Box::new(mem::MaybeUninit::zeroed().assume_init());
479 let res: bool = from_glib(ffi::gst_audio_buffer_map(
480 &mut *audio_buffer,
481 info.to_glib_none().0 as *mut _,
482 buffer.as_mut_ptr(),
483 gst::ffi::GST_MAP_READ,
484 ));
485
486 if !res {
487 Err(glib::bool_error!("Failed to map AudioBuffer"))
488 } else {
489 Ok(Self {
490 audio_buffer: AudioBufferPtr::Owned(audio_buffer),
491 phantom: PhantomData,
492 })
493 }
494 }
495 }
496
497 #[inline]
498 pub fn buffer(&self) -> &gst::BufferRef {
499 unsafe { gst::BufferRef::from_ptr(self.audio_buffer.buffer) }
500 }
501}
502
503impl<'a> AudioBufferRef<&'a mut gst::BufferRef> {
504 #[inline]
505 pub unsafe fn from_glib_borrow_mut(audio_buffer: *mut ffi::GstAudioBuffer) -> Borrowed<Self> {
506 debug_assert!(!audio_buffer.is_null());
507
508 Borrowed::new(Self {
509 audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::new_unchecked(audio_buffer)),
510 phantom: PhantomData,
511 })
512 }
513
514 #[inline]
515 pub fn from_buffer_ref_writable<'b>(
516 buffer: &'a mut gst::BufferRef,
517 info: &'b crate::AudioInfo,
518 ) -> Result<Self, glib::BoolError> {
519 skip_assert_initialized!();
520
521 assert!(info.is_valid());
522
523 unsafe {
524 let mut audio_buffer = Box::new(mem::MaybeUninit::zeroed().assume_init());
525 let res: bool = from_glib(ffi::gst_audio_buffer_map(
526 &mut *audio_buffer,
527 info.to_glib_none().0 as *mut _,
528 buffer.as_mut_ptr(),
529 gst::ffi::GST_MAP_READ | gst::ffi::GST_MAP_WRITE,
530 ));
531
532 if !res {
533 Err(glib::bool_error!("Failed to map AudioBuffer"))
534 } else {
535 Ok(Self {
536 audio_buffer: AudioBufferPtr::Owned(audio_buffer),
537 phantom: PhantomData,
538 })
539 }
540 }
541 }
542
543 #[inline]
544 pub fn plane_data_mut(&mut self, plane: u32) -> Result<&mut [u8], glib::BoolError> {
545 if plane >= self.n_planes() {
546 return Err(glib::bool_error!(
547 "Plane index higher than number of planes"
548 ));
549 }
550
551 if self.plane_size() == 0 {
552 return Ok(&mut []);
553 }
554
555 unsafe {
556 Ok(slice::from_raw_parts_mut(
557 (*self.audio_buffer.planes.add(plane as usize)) as *mut u8,
558 self.plane_size(),
559 ))
560 }
561 }
562
563 pub fn planes_data_mut(&mut self) -> SmallVec<[&mut [u8]; 8]> {
564 let mut planes = SmallVec::default();
565
566 unsafe {
567 for plane in 0..self.n_planes() {
568 let slice = self.plane_data_mut(plane).unwrap();
569 planes.push(slice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()));
570 }
571 }
572
573 planes
574 }
575
576 #[inline]
577 pub fn as_mut_ptr(&mut self) -> *mut ffi::GstAudioBuffer {
578 &mut *self.audio_buffer
579 }
580}
581
582impl<'a> ops::Deref for AudioBufferRef<&'a mut gst::BufferRef> {
583 type Target = AudioBufferRef<&'a gst::BufferRef>;
584
585 #[inline]
586 fn deref(&self) -> &Self::Target {
587 unsafe { &*(self as *const Self as *const Self::Target) }
588 }
589}
590
591unsafe impl<T> Send for AudioBufferRef<T> {}
592unsafe impl<T> Sync for AudioBufferRef<T> {}
593
594impl<T> Drop for AudioBufferRef<T> {
595 #[inline]
596 fn drop(&mut self) {
597 unsafe {
598 if matches!(self.audio_buffer, AudioBufferPtr::Owned(..)) {
599 ffi::gst_audio_buffer_unmap(&mut *self.audio_buffer);
600 }
601 }
602 }
603}
604
605#[cfg(test)]
606mod tests {
607 use super::*;
608
609 #[test]
610 fn test_map_read() {
611 gst::init().unwrap();
612
613 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
614 .build()
615 .unwrap();
616 let buffer = gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
617 let buffer = AudioBuffer::from_buffer_readable(buffer, &info).unwrap();
618
619 assert!(buffer.plane_data(0).is_ok());
620 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 2 * 48000);
621 assert!(buffer.plane_data(1).is_err());
622 assert!(buffer.info() == &info);
623
624 {
625 let buffer = buffer.as_audio_buffer_ref();
626
627 assert!(buffer.plane_data(0).is_ok());
628 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 2 * 48000);
629 assert!(buffer.plane_data(1).is_err());
630 assert!(buffer.info() == &info);
631 }
632
633 assert!(buffer.plane_data(0).is_ok());
634 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 2 * 48000);
635 assert!(buffer.plane_data(1).is_err());
636 assert!(buffer.info() == &info);
637 }
638
639 #[test]
640 fn test_map_read_planar() {
641 gst::init().unwrap();
642
643 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
644 .layout(crate::AudioLayout::NonInterleaved)
645 .build()
646 .unwrap();
647 let mut buffer =
648 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
649 {
650 let buffer = buffer.get_mut().unwrap();
651 crate::AudioMeta::add(buffer, &info, 48000, &[]).unwrap();
652 }
653 let buffer = AudioBuffer::from_buffer_readable(buffer, &info).unwrap();
654
655 assert!(buffer.plane_data(0).is_ok());
656 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
657 assert!(buffer.plane_data(1).is_ok());
658 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
659 assert!(buffer.info() == &info);
660
661 {
662 let buffer = buffer.as_audio_buffer_ref();
663
664 assert!(buffer.plane_data(0).is_ok());
665 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
666 assert!(buffer.plane_data(1).is_ok());
667 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
668 assert!(buffer.info() == &info);
669 }
670
671 assert!(buffer.plane_data(0).is_ok());
672 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
673 assert!(buffer.plane_data(1).is_ok());
674 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
675 assert!(buffer.info() == &info);
676 }
677
678 #[test]
679 fn test_map_write() {
680 gst::init().unwrap();
681
682 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
683 .build()
684 .unwrap();
685 let buffer = gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
686 let mut buffer = AudioBuffer::from_buffer_writable(buffer, &info).unwrap();
687
688 assert!(buffer.plane_data_mut(0).is_ok());
689 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 2 * 48000);
690 assert!(buffer.plane_data_mut(1).is_err());
691 assert!(buffer.info() == &info);
692
693 {
694 let mut buffer = buffer.as_mut_audio_buffer_ref();
695
696 assert!(buffer.plane_data_mut(0).is_ok());
697 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 2 * 48000);
698 assert!(buffer.plane_data_mut(1).is_err());
699 assert!(buffer.info() == &info);
700 }
701
702 assert!(buffer.plane_data_mut(0).is_ok());
703 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 2 * 48000);
704 assert!(buffer.plane_data_mut(1).is_err());
705 assert!(buffer.info() == &info);
706 }
707
708 #[test]
709 fn test_map_write_planar() {
710 gst::init().unwrap();
711
712 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
713 .layout(crate::AudioLayout::NonInterleaved)
714 .build()
715 .unwrap();
716 let mut buffer =
717 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
718 {
719 let buffer = buffer.get_mut().unwrap();
720 crate::AudioMeta::add(buffer, &info, 48000, &[]).unwrap();
721 }
722 let mut buffer = AudioBuffer::from_buffer_writable(buffer, &info).unwrap();
723
724 assert!(buffer.plane_data_mut(0).is_ok());
725 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
726 assert!(buffer.plane_data_mut(1).is_ok());
727 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
728 assert!(buffer.info() == &info);
729
730 {
731 let mut buffer = buffer.as_mut_audio_buffer_ref();
732
733 assert!(buffer.plane_data_mut(0).is_ok());
734 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
735 assert!(buffer.plane_data_mut(1).is_ok());
736 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
737 assert!(buffer.info() == &info);
738 }
739
740 assert!(buffer.plane_data_mut(0).is_ok());
741 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
742 assert!(buffer.plane_data_mut(1).is_ok());
743 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
744 assert!(buffer.info() == &info);
745 }
746
747 #[test]
748 fn test_map_ref_read() {
749 gst::init().unwrap();
750
751 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
752 .build()
753 .unwrap();
754 let buffer = gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
755 let buffer = AudioBufferRef::from_buffer_ref_readable(&buffer, &info).unwrap();
756
757 assert!(buffer.plane_data(0).is_ok());
758 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 2 * 48000);
759 assert!(buffer.plane_data(1).is_err());
760 assert!(buffer.info() == &info);
761
762 assert!(buffer.plane_data(0).is_ok());
763 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 2 * 48000);
764 assert!(buffer.plane_data(1).is_err());
765 assert!(buffer.info() == &info);
766 }
767
768 #[test]
769 fn test_map_ref_read_planar() {
770 gst::init().unwrap();
771
772 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
773 .layout(crate::AudioLayout::NonInterleaved)
774 .build()
775 .unwrap();
776 let mut buffer =
777 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
778 {
779 let buffer = buffer.get_mut().unwrap();
780 crate::AudioMeta::add(buffer, &info, 48000, &[]).unwrap();
781 }
782 let buffer = AudioBufferRef::from_buffer_ref_readable(&buffer, &info).unwrap();
783
784 assert!(buffer.plane_data(0).is_ok());
785 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
786 assert!(buffer.plane_data(1).is_ok());
787 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
788 assert!(buffer.info() == &info);
789
790 assert!(buffer.plane_data(0).is_ok());
791 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
792 assert!(buffer.plane_data(1).is_ok());
793 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
794 assert!(buffer.info() == &info);
795 }
796
797 #[test]
798 fn test_map_ref_write() {
799 gst::init().unwrap();
800
801 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
802 .build()
803 .unwrap();
804 let mut buffer =
805 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
806
807 {
808 let buffer = buffer.get_mut().unwrap();
809 let mut buffer = AudioBufferRef::from_buffer_ref_writable(buffer, &info).unwrap();
810
811 assert!(buffer.plane_data_mut(0).is_ok());
812 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 2 * 48000);
813 assert!(buffer.plane_data_mut(1).is_err());
814 assert!(buffer.info() == &info);
815
816 assert!(buffer.plane_data_mut(0).is_ok());
817 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 2 * 48000);
818 assert!(buffer.plane_data_mut(1).is_err());
819 assert!(buffer.info() == &info);
820 }
821 }
822
823 #[test]
824 fn test_map_ref_write_planar() {
825 gst::init().unwrap();
826
827 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
828 .layout(crate::AudioLayout::NonInterleaved)
829 .build()
830 .unwrap();
831 let mut buffer =
832 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
833 {
834 let buffer = buffer.get_mut().unwrap();
835 crate::AudioMeta::add(buffer, &info, 48000, &[]).unwrap();
836 }
837
838 {
839 let buffer = buffer.get_mut().unwrap();
840 let mut buffer = AudioBufferRef::from_buffer_ref_writable(buffer, &info).unwrap();
841
842 assert!(buffer.plane_data_mut(0).is_ok());
843 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
844 assert!(buffer.plane_data_mut(1).is_ok());
845 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
846 assert!(buffer.info() == &info);
847
848 assert!(buffer.plane_data_mut(0).is_ok());
849 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
850 assert!(buffer.plane_data_mut(1).is_ok());
851 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
852 assert!(buffer.info() == &info);
853 }
854 }
855}