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: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1367>
This commit is contained in:
Sebastian Dröge 2023-12-19 10:14:00 +02:00
parent 38a9b7a242
commit 86cf7a7d81
3 changed files with 50 additions and 0 deletions

1
Cargo.lock generated
View file

@ -920,6 +920,7 @@ dependencies = [
"libc", "libc",
"serde", "serde",
"serde_json", "serde_json",
"smallvec",
] ]
[[package]] [[package]]

View file

@ -21,6 +21,7 @@ glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" } gst = { package = "gstreamer", path = "../gstreamer" }
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" } gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
serde = { version = "1.0", optional = true } serde = { version = "1.0", optional = true }
smallvec = "1.0"
[dev-dependencies] [dev-dependencies]
itertools = "0.12" itertools = "0.12"

View file

@ -4,6 +4,8 @@ use std::{fmt, marker::PhantomData, mem, ops, ptr, slice};
use glib::translate::{from_glib, Borrowed, ToGlibPtr}; use glib::translate::{from_glib, Borrowed, ToGlibPtr};
use smallvec::SmallVec;
pub enum Readable {} pub enum Readable {}
pub enum Writable {} pub enum Writable {}
@ -134,6 +136,16 @@ impl<T> AudioBuffer<T> {
} }
} }
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] #[inline]
pub fn as_audio_buffer_ref(&self) -> AudioBufferRef<&gst::BufferRef> { pub fn as_audio_buffer_ref(&self) -> AudioBufferRef<&gst::BufferRef> {
AudioBufferRef { AudioBufferRef {
@ -241,6 +253,19 @@ impl AudioBuffer<Writable> {
} }
} }
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] #[inline]
pub fn as_mut_audio_buffer_ref(&mut self) -> AudioBufferRef<&mut gst::BufferRef> { pub fn as_mut_audio_buffer_ref(&mut self) -> AudioBufferRef<&mut gst::BufferRef> {
AudioBufferRef { AudioBufferRef {
@ -397,6 +422,16 @@ impl<T> AudioBufferRef<T> {
} }
} }
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] #[inline]
pub fn as_ptr(&self) -> *const ffi::GstAudioBuffer { pub fn as_ptr(&self) -> *const ffi::GstAudioBuffer {
&*self.audio_buffer &*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] #[inline]
pub fn as_mut_ptr(&mut self) -> *mut ffi::GstAudioBuffer { pub fn as_mut_ptr(&mut self) -> *mut ffi::GstAudioBuffer {
&mut *self.audio_buffer &mut *self.audio_buffer