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