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