From 86cf7a7d8181690e69e89f6f172c53148726426e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 19 Dec 2023 10:14:00 +0200 Subject: [PATCH] audio: Add array-based accessor for all audio buffer planes' data at once This is mostly useful for getting mutable access to all planes at once. Using `plane_data_mut()` for this is not possible as it would require borrowing the frame mutably multiple times. As each plane's data is not overlapping with any other plane we can still provide such functionality safely. Part-of: --- Cargo.lock | 1 + gstreamer-audio/Cargo.toml | 1 + gstreamer-audio/src/audio_buffer.rs | 48 +++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index af89e3048..90f5e7871 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -920,6 +920,7 @@ dependencies = [ "libc", "serde", "serde_json", + "smallvec", ] [[package]] diff --git a/gstreamer-audio/Cargo.toml b/gstreamer-audio/Cargo.toml index 4019fea2e..aafb2b3ed 100644 --- a/gstreamer-audio/Cargo.toml +++ b/gstreamer-audio/Cargo.toml @@ -21,6 +21,7 @@ glib = { git = "https://github.com/gtk-rs/gtk-rs-core" } gst = { package = "gstreamer", path = "../gstreamer" } gst-base = { package = "gstreamer-base", path = "../gstreamer-base" } serde = { version = "1.0", optional = true } +smallvec = "1.0" [dev-dependencies] itertools = "0.12" diff --git a/gstreamer-audio/src/audio_buffer.rs b/gstreamer-audio/src/audio_buffer.rs index 88b5a093c..bc5b66cc3 100644 --- a/gstreamer-audio/src/audio_buffer.rs +++ b/gstreamer-audio/src/audio_buffer.rs @@ -4,6 +4,8 @@ use std::{fmt, marker::PhantomData, mem, ops, ptr, slice}; use glib::translate::{from_glib, Borrowed, ToGlibPtr}; +use smallvec::SmallVec; + pub enum Readable {} pub enum Writable {} @@ -134,6 +136,16 @@ impl AudioBuffer { } } + pub fn planes_data(&self) -> SmallVec<[&[u8]; 8]> { + let mut planes = SmallVec::default(); + + for plane in 0..self.n_planes() { + planes[plane as usize] = self.plane_data(plane).unwrap(); + } + + planes + } + #[inline] pub fn as_audio_buffer_ref(&self) -> AudioBufferRef<&gst::BufferRef> { AudioBufferRef { @@ -241,6 +253,19 @@ impl AudioBuffer { } } + pub fn planes_data_mut(&mut self) -> SmallVec<[&mut [u8]; 8]> { + let mut planes = SmallVec::default(); + + unsafe { + for plane in 0..self.n_planes() { + let slice = self.plane_data_mut(plane).unwrap(); + planes.push(slice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len())); + } + } + + planes + } + #[inline] pub fn as_mut_audio_buffer_ref(&mut self) -> AudioBufferRef<&mut gst::BufferRef> { AudioBufferRef { @@ -397,6 +422,16 @@ impl AudioBufferRef { } } + pub fn planes_data(&self) -> SmallVec<[&[u8]; 8]> { + let mut planes = SmallVec::default(); + + for plane in 0..self.n_planes() { + planes[plane as usize] = self.plane_data(plane).unwrap(); + } + + planes + } + #[inline] pub fn as_ptr(&self) -> *const ffi::GstAudioBuffer { &*self.audio_buffer @@ -520,6 +555,19 @@ impl<'a> AudioBufferRef<&'a mut gst::BufferRef> { } } + pub fn planes_data_mut(&mut self) -> SmallVec<[&mut [u8]; 8]> { + let mut planes = SmallVec::default(); + + unsafe { + for plane in 0..self.n_planes() { + let slice = self.plane_data_mut(plane).unwrap(); + planes.push(slice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len())); + } + } + + planes + } + #[inline] pub fn as_mut_ptr(&mut self) -> *mut ffi::GstAudioBuffer { &mut *self.audio_buffer