video_frame: refactor traits

this adds an IsVideoFrame trait that makes it easier to provide all the
shared methods between VideoFrame, VideoFrameRef, GLVideoFrame and
GLVideoFrameRef. Now only a single method, `as_non_null_ptr()` has to be
implemented and the rest of the shared methods will be provided by the
`VideoFrameExt` trait.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1312>
This commit is contained in:
Anders Hellerup Madsen 2023-09-30 23:08:03 +02:00
parent 61d559521b
commit 6eb01dc916
4 changed files with 63 additions and 108 deletions

View file

@ -4,7 +4,7 @@ use std::{marker::PhantomData, mem, ptr};
use crate::GLMemoryRef; use crate::GLMemoryRef;
use glib::translate::{from_glib, Borrowed, ToGlibPtr}; use glib::translate::{from_glib, Borrowed, ToGlibPtr};
use gst_video::VideoFrameExt; use gst_video::{video_frame::IsVideoFrame, VideoFrameExt};
pub enum Readable {} pub enum Readable {}
pub enum Writable {} pub enum Writable {}
@ -23,23 +23,10 @@ unsafe impl<T> Sync for GLVideoFrame<T> {}
// TODO implement Debug for GLVideoFrame // TODO implement Debug for GLVideoFrame
impl<T> VideoFrameExt for GLVideoFrame<T> { impl<T> IsVideoFrame for GLVideoFrame<T> {
#[inline] #[inline]
fn info(&self) -> &gst_video::VideoInfo { fn as_non_null_ptr(&self) -> std::ptr::NonNull<gst_video::ffi::GstVideoFrame> {
unsafe { std::ptr::NonNull::from(&self.frame)
&*(&self.frame.info as *const gst_video::ffi::GstVideoInfo
as *const gst_video::VideoInfo)
}
}
#[inline]
fn flags(&self) -> gst_video::VideoFrameFlags {
unsafe { from_glib(self.frame.flags) }
}
#[inline]
fn id(&self) -> i32 {
self.frame.id
} }
} }
@ -82,11 +69,6 @@ impl<T> GLVideoFrame<T> {
} }
} }
#[inline]
pub fn buffer(&self) -> &gst::BufferRef {
unsafe { gst::BufferRef::from_ptr(self.frame.buffer) }
}
#[inline] #[inline]
pub unsafe fn from_glib_full(frame: gst_video::ffi::GstVideoFrame) -> Self { pub unsafe fn from_glib_full(frame: gst_video::ffi::GstVideoFrame) -> Self {
let buffer = gst::Buffer::from_glib_none(frame.buffer); let buffer = gst::Buffer::from_glib_none(frame.buffer);
@ -97,11 +79,6 @@ impl<T> GLVideoFrame<T> {
} }
} }
#[inline]
pub fn as_ptr(&self) -> *const gst_video::ffi::GstVideoFrame {
&self.frame
}
#[inline] #[inline]
pub fn into_raw(self) -> gst_video::ffi::GstVideoFrame { pub fn into_raw(self) -> gst_video::ffi::GstVideoFrame {
unsafe { unsafe {
@ -248,33 +225,13 @@ pub struct GLVideoFrameRef<T> {
unsafe impl<T> Send for GLVideoFrameRef<T> {} unsafe impl<T> Send for GLVideoFrameRef<T> {}
unsafe impl<T> Sync for GLVideoFrameRef<T> {} unsafe impl<T> Sync for GLVideoFrameRef<T> {}
impl<T> VideoFrameExt for GLVideoFrameRef<T> { impl<T> IsVideoFrame for GLVideoFrameRef<T> {
#[inline] #[inline]
fn info(&self) -> &gst_video::VideoInfo { fn as_non_null_ptr(&self) -> std::ptr::NonNull<gst_video::ffi::GstVideoFrame> {
unsafe { std::ptr::NonNull::from(&self.frame)
&*(&self.frame.info as *const gst_video::ffi::GstVideoInfo
as *const gst_video::VideoInfo)
}
}
#[inline]
fn flags(&self) -> gst_video::VideoFrameFlags {
unsafe { from_glib(self.frame.flags) }
}
#[inline]
fn id(&self) -> i32 {
self.frame.id
} }
} }
// TODO implement Debug for GLVideoFrameRef // TODO implement Debug for GLVideoFrameRef
//
impl<T> GLVideoFrameRef<T> {
#[inline]
pub fn as_ptr(&self) -> *const gst_video::ffi::GstVideoFrame {
&self.frame
}
}
impl<'a> GLVideoFrameRef<&'a gst::BufferRef> { impl<'a> GLVideoFrameRef<&'a gst::BufferRef> {
#[inline] #[inline]
@ -351,10 +308,6 @@ impl<'a> GLVideoFrameRef<&'a gst::BufferRef> {
} }
} }
pub fn buffer(&self) -> &gst::BufferRef {
unsafe { gst::BufferRef::from_ptr(self.frame.buffer) }
}
pub fn texture_id(&self, idx: u32) -> Option<u32> { pub fn texture_id(&self, idx: u32) -> Option<u32> {
let len = buffer_n_gl_memory(self.buffer())?; let len = buffer_n_gl_memory(self.buffer())?;

View file

@ -3,7 +3,7 @@
use glib::translate::*; use glib::translate::*;
use gst_base::{prelude::*, subclass::prelude::*}; use gst_base::{prelude::*, subclass::prelude::*};
use crate::{VideoFilter, VideoFrameRef, VideoInfo}; use crate::{VideoFilter, VideoFrameExt, VideoFrameRef, VideoInfo};
pub trait VideoFilterImpl: VideoFilterImplExt + BaseTransformImpl { pub trait VideoFilterImpl: VideoFilterImplExt + BaseTransformImpl {
fn set_info( fn set_info(

View file

@ -2,6 +2,7 @@
use std::{ops, ptr}; use std::{ops, ptr};
use crate::VideoFrameExt;
use glib::translate::*; use glib::translate::*;
#[derive(Debug)] #[derive(Debug)]

View file

@ -7,6 +7,17 @@ use glib::translate::{from_glib, from_glib_none, Borrowed, ToGlibPtr};
pub enum Readable {} pub enum Readable {}
pub enum Writable {} pub enum Writable {}
pub trait IsVideoFrame {
fn as_non_null_ptr(&self) -> std::ptr::NonNull<ffi::GstVideoFrame>;
}
impl<T> IsVideoFrame for VideoFrame<T> {
#[inline]
fn as_non_null_ptr(&self) -> std::ptr::NonNull<ffi::GstVideoFrame> {
std::ptr::NonNull::from(&self.frame)
}
}
pub struct VideoFrame<T> { pub struct VideoFrame<T> {
frame: ffi::GstVideoFrame, frame: ffi::GstVideoFrame,
buffer: gst::Buffer, buffer: gst::Buffer,
@ -27,10 +38,40 @@ impl<T> fmt::Debug for VideoFrame<T> {
} }
} }
pub trait VideoFrameExt { mod sealed {
fn id(&self) -> i32; pub trait Sealed {}
fn info(&self) -> &crate::VideoInfo; impl<T: super::IsVideoFrame> Sealed for T {}
fn flags(&self) -> crate::VideoFrameFlags; }
pub trait VideoFrameExt: sealed::Sealed + IsVideoFrame {
#[inline]
fn as_ptr(&self) -> *const ffi::GstVideoFrame {
self.as_non_null_ptr().as_ptr() as _
}
#[inline]
fn info(&self) -> &crate::VideoInfo {
unsafe {
let frame = self.as_non_null_ptr().as_ref();
let info = &frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo;
&*info
}
}
#[inline]
fn flags(&self) -> crate::VideoFrameFlags {
unsafe { from_glib(self.as_non_null_ptr().as_ref().flags) }
}
#[inline]
fn id(&self) -> i32 {
unsafe { self.as_non_null_ptr().as_ref().id }
}
#[inline]
fn buffer(&self) -> &gst::BufferRef {
unsafe { gst::BufferRef::from_ptr(self.as_non_null_ptr().as_ref().buffer) }
}
#[inline] #[inline]
fn format(&self) -> crate::VideoFormat { fn format(&self) -> crate::VideoFormat {
@ -150,22 +191,7 @@ pub trait VideoFrameExt {
} }
} }
impl<T> VideoFrameExt for VideoFrame<T> { impl<O: IsVideoFrame> VideoFrameExt for O {}
#[inline]
fn info(&self) -> &crate::VideoInfo {
unsafe { &*(&self.frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo) }
}
#[inline]
fn flags(&self) -> crate::VideoFrameFlags {
unsafe { from_glib(self.frame.flags) }
}
#[inline]
fn id(&self) -> i32 {
self.frame.id
}
}
impl<T> VideoFrame<T> { impl<T> VideoFrame<T> {
#[inline] #[inline]
@ -219,7 +245,7 @@ impl<T> VideoFrame<T> {
} }
#[inline] #[inline]
fn buffer(&self) -> &gst::BufferRef { pub fn buffer(&self) -> &gst::BufferRef {
unsafe { gst::BufferRef::from_ptr(self.frame.buffer) } unsafe { gst::BufferRef::from_ptr(self.frame.buffer) }
} }
@ -279,11 +305,6 @@ impl<T> VideoFrame<T> {
} }
} }
#[inline]
pub fn as_ptr(&self) -> *const ffi::GstVideoFrame {
&self.frame
}
#[inline] #[inline]
pub fn into_raw(self) -> ffi::GstVideoFrame { pub fn into_raw(self) -> ffi::GstVideoFrame {
unsafe { unsafe {
@ -511,6 +532,13 @@ pub struct VideoFrameRef<T> {
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
impl<T> IsVideoFrame for VideoFrameRef<T> {
#[inline]
fn as_non_null_ptr(&self) -> std::ptr::NonNull<ffi::GstVideoFrame> {
std::ptr::NonNull::from(&self.frame)
}
}
impl<T> fmt::Debug for VideoFrameRef<T> { impl<T> fmt::Debug for VideoFrameRef<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("VideoFrameRef") f.debug_struct("VideoFrameRef")
@ -524,23 +552,6 @@ impl<T> fmt::Debug for VideoFrameRef<T> {
} }
} }
impl<T> VideoFrameExt for VideoFrameRef<T> {
#[inline]
fn info(&self) -> &crate::VideoInfo {
unsafe { &*(&self.frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo) }
}
#[inline]
fn flags(&self) -> crate::VideoFrameFlags {
unsafe { from_glib(self.frame.flags) }
}
#[inline]
fn id(&self) -> i32 {
self.frame.id
}
}
impl<T> VideoFrameRef<T> { impl<T> VideoFrameRef<T> {
#[doc(alias = "gst_video_frame_copy")] #[doc(alias = "gst_video_frame_copy")]
pub fn copy( pub fn copy(
@ -619,11 +630,6 @@ impl<T> VideoFrameRef<T> {
)) ))
} }
} }
#[inline]
pub fn as_ptr(&self) -> *const ffi::GstVideoFrame {
&self.frame
}
} }
impl<'a> VideoFrameRef<&'a gst::BufferRef> { impl<'a> VideoFrameRef<&'a gst::BufferRef> {
@ -711,11 +717,6 @@ impl<'a> VideoFrameRef<&'a gst::BufferRef> {
} }
} }
} }
#[inline]
pub fn buffer(&self) -> &gst::BufferRef {
unsafe { gst::BufferRef::from_ptr(self.frame.buffer) }
}
} }
impl<'a> VideoFrameRef<&'a mut gst::BufferRef> { impl<'a> VideoFrameRef<&'a mut gst::BufferRef> {