video: Add array-based accessor for all video frame 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:01:28 +02:00
parent 2fb93e1c12
commit 38a9b7a242

View file

@ -285,6 +285,16 @@ impl<T> VideoFrame<T> {
} }
} }
pub fn planes_data(&self) -> [&[u8]; 4] {
let mut planes = [[].as_slice(); 4];
for plane in 0..self.n_planes() {
planes[plane as usize] = self.plane_data(plane).unwrap();
}
planes
}
#[inline] #[inline]
pub unsafe fn from_glib_full(frame: ffi::GstVideoFrame) -> Self { pub unsafe fn from_glib_full(frame: ffi::GstVideoFrame) -> Self {
let buffer = gst::Buffer::from_glib_none(frame.buffer); let buffer = gst::Buffer::from_glib_none(frame.buffer);
@ -510,6 +520,24 @@ impl VideoFrame<Writable> {
} }
} }
pub fn planes_data_mut(&mut self) -> [&mut [u8]; 4] {
unsafe {
let mut planes = [
[].as_mut_slice(),
[].as_mut_slice(),
[].as_mut_slice(),
[].as_mut_slice(),
];
for plane in 0..self.n_planes() {
let slice = self.plane_data_mut(plane).unwrap();
planes[plane as usize] = slice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len());
}
planes
}
}
#[inline] #[inline]
pub fn as_mut_video_frame_ref(&mut self) -> VideoFrameRef<&mut gst::BufferRef> { pub fn as_mut_video_frame_ref(&mut self) -> VideoFrameRef<&mut gst::BufferRef> {
let frame = unsafe { ptr::read(&self.frame) }; let frame = unsafe { ptr::read(&self.frame) };
@ -630,6 +658,16 @@ impl<T> VideoFrameRef<T> {
)) ))
} }
} }
pub fn planes_data(&self) -> [&[u8]; 4] {
let mut planes = [[].as_slice(); 4];
for plane in 0..self.n_planes() {
planes[plane as usize] = self.plane_data(plane).unwrap();
}
planes
}
} }
impl<'a> VideoFrameRef<&'a gst::BufferRef> { impl<'a> VideoFrameRef<&'a gst::BufferRef> {
@ -855,6 +893,24 @@ impl<'a> VideoFrameRef<&'a mut gst::BufferRef> {
} }
} }
pub fn planes_data_mut(&mut self) -> [&mut [u8]; 4] {
unsafe {
let mut planes = [
[].as_mut_slice(),
[].as_mut_slice(),
[].as_mut_slice(),
[].as_mut_slice(),
];
for plane in 0..self.n_planes() {
let slice = self.plane_data_mut(plane).unwrap();
planes[plane as usize] = slice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len());
}
planes
}
}
#[inline] #[inline]
pub fn as_mut_ptr(&mut self) -> *mut ffi::GstVideoFrame { pub fn as_mut_ptr(&mut self) -> *mut ffi::GstVideoFrame {
&mut self.frame &mut self.frame