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