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(b) => b,
313 Self::Borrowed(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(b) => &mut *b,
323 Self::Borrowed(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 unsafe {
459 debug_assert!(!audio_buffer.is_null());
460
461 Borrowed::new(Self {
462 audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::new_unchecked(
463 audio_buffer as *mut _,
464 )),
465 phantom: PhantomData,
466 })
467 }
468 }
469
470 #[inline]
471 pub fn from_buffer_ref_readable<'b>(
472 buffer: &'a gst::BufferRef,
473 info: &'b crate::AudioInfo,
474 ) -> Result<Self, glib::BoolError> {
475 skip_assert_initialized!();
476
477 assert!(info.is_valid());
478
479 unsafe {
480 let mut audio_buffer = Box::new(mem::MaybeUninit::zeroed().assume_init());
481 let res: bool = from_glib(ffi::gst_audio_buffer_map(
482 &mut *audio_buffer,
483 info.to_glib_none().0 as *mut _,
484 buffer.as_mut_ptr(),
485 gst::ffi::GST_MAP_READ,
486 ));
487
488 if !res {
489 Err(glib::bool_error!("Failed to map AudioBuffer"))
490 } else {
491 Ok(Self {
492 audio_buffer: AudioBufferPtr::Owned(audio_buffer),
493 phantom: PhantomData,
494 })
495 }
496 }
497 }
498
499 #[inline]
500 pub fn buffer(&self) -> &gst::BufferRef {
501 unsafe { gst::BufferRef::from_ptr(self.audio_buffer.buffer) }
502 }
503}
504
505impl<'a> AudioBufferRef<&'a mut gst::BufferRef> {
506 #[inline]
507 pub unsafe fn from_glib_borrow_mut(audio_buffer: *mut ffi::GstAudioBuffer) -> Borrowed<Self> {
508 unsafe {
509 debug_assert!(!audio_buffer.is_null());
510
511 Borrowed::new(Self {
512 audio_buffer: AudioBufferPtr::Borrowed(ptr::NonNull::new_unchecked(audio_buffer)),
513 phantom: PhantomData,
514 })
515 }
516 }
517
518 #[inline]
519 pub fn from_buffer_ref_writable<'b>(
520 buffer: &'a mut gst::BufferRef,
521 info: &'b crate::AudioInfo,
522 ) -> Result<Self, glib::BoolError> {
523 skip_assert_initialized!();
524
525 assert!(info.is_valid());
526
527 unsafe {
528 let mut audio_buffer = Box::new(mem::MaybeUninit::zeroed().assume_init());
529 let res: bool = from_glib(ffi::gst_audio_buffer_map(
530 &mut *audio_buffer,
531 info.to_glib_none().0 as *mut _,
532 buffer.as_mut_ptr(),
533 gst::ffi::GST_MAP_READ | gst::ffi::GST_MAP_WRITE,
534 ));
535
536 if !res {
537 Err(glib::bool_error!("Failed to map AudioBuffer"))
538 } else {
539 Ok(Self {
540 audio_buffer: AudioBufferPtr::Owned(audio_buffer),
541 phantom: PhantomData,
542 })
543 }
544 }
545 }
546
547 #[inline]
548 pub fn plane_data_mut(&mut self, plane: u32) -> Result<&mut [u8], glib::BoolError> {
549 if plane >= self.n_planes() {
550 return Err(glib::bool_error!(
551 "Plane index higher than number of planes"
552 ));
553 }
554
555 if self.plane_size() == 0 {
556 return Ok(&mut []);
557 }
558
559 unsafe {
560 Ok(slice::from_raw_parts_mut(
561 (*self.audio_buffer.planes.add(plane as usize)) as *mut u8,
562 self.plane_size(),
563 ))
564 }
565 }
566
567 pub fn planes_data_mut(&mut self) -> SmallVec<[&mut [u8]; 8]> {
568 let mut planes = SmallVec::default();
569
570 unsafe {
571 for plane in 0..self.n_planes() {
572 let slice = self.plane_data_mut(plane).unwrap();
573 planes.push(slice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()));
574 }
575 }
576
577 planes
578 }
579
580 #[inline]
581 pub fn as_mut_ptr(&mut self) -> *mut ffi::GstAudioBuffer {
582 &mut *self.audio_buffer
583 }
584}
585
586impl<'a> ops::Deref for AudioBufferRef<&'a mut gst::BufferRef> {
587 type Target = AudioBufferRef<&'a gst::BufferRef>;
588
589 #[inline]
590 fn deref(&self) -> &Self::Target {
591 unsafe { &*(self as *const Self as *const Self::Target) }
592 }
593}
594
595unsafe impl<T> Send for AudioBufferRef<T> {}
596unsafe impl<T> Sync for AudioBufferRef<T> {}
597
598impl<T> Drop for AudioBufferRef<T> {
599 #[inline]
600 fn drop(&mut self) {
601 unsafe {
602 if matches!(self.audio_buffer, AudioBufferPtr::Owned(..)) {
603 ffi::gst_audio_buffer_unmap(&mut *self.audio_buffer);
604 }
605 }
606 }
607}
608
609#[cfg(test)]
610mod tests {
611 use super::*;
612
613 #[test]
614 fn test_map_read() {
615 gst::init().unwrap();
616
617 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
618 .build()
619 .unwrap();
620 let buffer = gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
621 let buffer = AudioBuffer::from_buffer_readable(buffer, &info).unwrap();
622
623 assert!(buffer.plane_data(0).is_ok());
624 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 2 * 48000);
625 assert!(buffer.plane_data(1).is_err());
626 assert!(buffer.info() == &info);
627
628 {
629 let buffer = buffer.as_audio_buffer_ref();
630
631 assert!(buffer.plane_data(0).is_ok());
632 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 2 * 48000);
633 assert!(buffer.plane_data(1).is_err());
634 assert!(buffer.info() == &info);
635 }
636
637 assert!(buffer.plane_data(0).is_ok());
638 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 2 * 48000);
639 assert!(buffer.plane_data(1).is_err());
640 assert!(buffer.info() == &info);
641 }
642
643 #[test]
644 fn test_map_read_planar() {
645 gst::init().unwrap();
646
647 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
648 .layout(crate::AudioLayout::NonInterleaved)
649 .build()
650 .unwrap();
651 let mut buffer =
652 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
653 {
654 let buffer = buffer.get_mut().unwrap();
655 crate::AudioMeta::add(buffer, &info, 48000, &[]).unwrap();
656 }
657 let buffer = AudioBuffer::from_buffer_readable(buffer, &info).unwrap();
658
659 assert!(buffer.plane_data(0).is_ok());
660 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
661 assert!(buffer.plane_data(1).is_ok());
662 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
663 assert!(buffer.info() == &info);
664
665 {
666 let buffer = buffer.as_audio_buffer_ref();
667
668 assert!(buffer.plane_data(0).is_ok());
669 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
670 assert!(buffer.plane_data(1).is_ok());
671 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
672 assert!(buffer.info() == &info);
673 }
674
675 assert!(buffer.plane_data(0).is_ok());
676 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
677 assert!(buffer.plane_data(1).is_ok());
678 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
679 assert!(buffer.info() == &info);
680 }
681
682 #[test]
683 fn test_map_write() {
684 gst::init().unwrap();
685
686 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
687 .build()
688 .unwrap();
689 let buffer = gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
690 let mut buffer = AudioBuffer::from_buffer_writable(buffer, &info).unwrap();
691
692 assert!(buffer.plane_data_mut(0).is_ok());
693 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 2 * 48000);
694 assert!(buffer.plane_data_mut(1).is_err());
695 assert!(buffer.info() == &info);
696
697 {
698 let mut buffer = buffer.as_mut_audio_buffer_ref();
699
700 assert!(buffer.plane_data_mut(0).is_ok());
701 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 2 * 48000);
702 assert!(buffer.plane_data_mut(1).is_err());
703 assert!(buffer.info() == &info);
704 }
705
706 assert!(buffer.plane_data_mut(0).is_ok());
707 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 2 * 48000);
708 assert!(buffer.plane_data_mut(1).is_err());
709 assert!(buffer.info() == &info);
710 }
711
712 #[test]
713 fn test_map_write_planar() {
714 gst::init().unwrap();
715
716 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
717 .layout(crate::AudioLayout::NonInterleaved)
718 .build()
719 .unwrap();
720 let mut buffer =
721 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
722 {
723 let buffer = buffer.get_mut().unwrap();
724 crate::AudioMeta::add(buffer, &info, 48000, &[]).unwrap();
725 }
726 let mut buffer = AudioBuffer::from_buffer_writable(buffer, &info).unwrap();
727
728 assert!(buffer.plane_data_mut(0).is_ok());
729 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
730 assert!(buffer.plane_data_mut(1).is_ok());
731 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
732 assert!(buffer.info() == &info);
733
734 {
735 let mut buffer = buffer.as_mut_audio_buffer_ref();
736
737 assert!(buffer.plane_data_mut(0).is_ok());
738 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
739 assert!(buffer.plane_data_mut(1).is_ok());
740 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
741 assert!(buffer.info() == &info);
742 }
743
744 assert!(buffer.plane_data_mut(0).is_ok());
745 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
746 assert!(buffer.plane_data_mut(1).is_ok());
747 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
748 assert!(buffer.info() == &info);
749 }
750
751 #[test]
752 fn test_map_ref_read() {
753 gst::init().unwrap();
754
755 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
756 .build()
757 .unwrap();
758 let buffer = gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
759 let buffer = AudioBufferRef::from_buffer_ref_readable(&buffer, &info).unwrap();
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 assert!(buffer.plane_data(0).is_ok());
767 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 2 * 48000);
768 assert!(buffer.plane_data(1).is_err());
769 assert!(buffer.info() == &info);
770 }
771
772 #[test]
773 fn test_map_ref_read_planar() {
774 gst::init().unwrap();
775
776 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
777 .layout(crate::AudioLayout::NonInterleaved)
778 .build()
779 .unwrap();
780 let mut buffer =
781 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
782 {
783 let buffer = buffer.get_mut().unwrap();
784 crate::AudioMeta::add(buffer, &info, 48000, &[]).unwrap();
785 }
786 let buffer = AudioBufferRef::from_buffer_ref_readable(&buffer, &info).unwrap();
787
788 assert!(buffer.plane_data(0).is_ok());
789 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
790 assert!(buffer.plane_data(1).is_ok());
791 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
792 assert!(buffer.info() == &info);
793
794 assert!(buffer.plane_data(0).is_ok());
795 assert_eq!(buffer.plane_data(0).unwrap().len(), 2 * 48000);
796 assert!(buffer.plane_data(1).is_ok());
797 assert_eq!(buffer.plane_data(1).unwrap().len(), 2 * 48000);
798 assert!(buffer.info() == &info);
799 }
800
801 #[test]
802 fn test_map_ref_write() {
803 gst::init().unwrap();
804
805 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
806 .build()
807 .unwrap();
808 let mut buffer =
809 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
810
811 {
812 let buffer = buffer.get_mut().unwrap();
813 let mut buffer = AudioBufferRef::from_buffer_ref_writable(buffer, &info).unwrap();
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 assert!(buffer.plane_data_mut(0).is_ok());
821 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 2 * 48000);
822 assert!(buffer.plane_data_mut(1).is_err());
823 assert!(buffer.info() == &info);
824 }
825 }
826
827 #[test]
828 fn test_map_ref_write_planar() {
829 gst::init().unwrap();
830
831 let info = crate::AudioInfo::builder(crate::AUDIO_FORMAT_S16, 48000, 2)
832 .layout(crate::AudioLayout::NonInterleaved)
833 .build()
834 .unwrap();
835 let mut buffer =
836 gst::Buffer::with_size(info.rate() as usize * info.bpf() as usize).unwrap();
837 {
838 let buffer = buffer.get_mut().unwrap();
839 crate::AudioMeta::add(buffer, &info, 48000, &[]).unwrap();
840 }
841
842 {
843 let buffer = buffer.get_mut().unwrap();
844 let mut buffer = AudioBufferRef::from_buffer_ref_writable(buffer, &info).unwrap();
845
846 assert!(buffer.plane_data_mut(0).is_ok());
847 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
848 assert!(buffer.plane_data_mut(1).is_ok());
849 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
850 assert!(buffer.info() == &info);
851
852 assert!(buffer.plane_data_mut(0).is_ok());
853 assert_eq!(buffer.plane_data_mut(0).unwrap().len(), 2 * 48000);
854 assert!(buffer.plane_data_mut(1).is_ok());
855 assert_eq!(buffer.plane_data_mut(1).unwrap().len(), 2 * 48000);
856 assert!(buffer.info() == &info);
857 }
858 }
859}