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