From f8effdda6131363983741dfa08dfd03de10df602 Mon Sep 17 00:00:00 2001 From: Anders Hellerup Madsen Date: Sun, 1 Oct 2023 11:11:52 +0200 Subject: [PATCH] gl: export GLMemory getter methods on GLVideoFrame also change `as_non_null_ptr()` to `as_raw()` Part-of: --- examples/src/glupload.rs | 2 +- gstreamer-gl/src/gl_video_frame.rs | 148 +++++++++++++++-------------- gstreamer-gl/src/lib.rs | 3 +- gstreamer-video/src/video_frame.rs | 20 ++-- 4 files changed, 90 insertions(+), 83 deletions(-) diff --git a/examples/src/glupload.rs b/examples/src/glupload.rs index 5f779ce73..1221ae9ec 100644 --- a/examples/src/glupload.rs +++ b/examples/src/glupload.rs @@ -667,7 +667,7 @@ pub(crate) fn main_loop(app: App) -> Result<(), Error> { if let Some(frame) = curr_frame.as_ref() { let sync_meta = frame.buffer().meta::().unwrap(); sync_meta.wait(&shared_context); - if let Some(texture) = frame.texture_id(0) { + if let Ok(texture) = frame.texture_id(0) { gl.draw_frame(texture as gl::types::GLuint); } } diff --git a/gstreamer-gl/src/gl_video_frame.rs b/gstreamer-gl/src/gl_video_frame.rs index ae691b7e7..224c91f71 100644 --- a/gstreamer-gl/src/gl_video_frame.rs +++ b/gstreamer-gl/src/gl_video_frame.rs @@ -10,7 +10,66 @@ pub enum Readable {} pub enum Writable {} // TODO: implement copy for videoframes. This would need to go through all the individual -// memoryies and copy them. Some GL textures can be copied, others cannot. +// memories and copy them. Some GL textures can be copied, others cannot. + +pub trait IsGLVideoFrame: IsVideoFrame + Sized {} + +mod sealed { + pub trait Sealed {} + impl Sealed for T {} +} + +pub trait GLVideoFrameExt: sealed::Sealed + IsGLVideoFrame { + #[inline] + fn memory(&self, idx: u32) -> Result<&GLMemoryRef, glib::BoolError> { + if idx >= self.info().n_planes() { + return Err(glib::bool_error!( + "Memory index higher than number of memories" + )); + } + + unsafe { + let ptr = self.as_raw().map[idx as usize].memory; + if ffi::gst_is_gl_memory(ptr) == glib::ffi::GTRUE { + Ok(GLMemoryRef::from_ptr(ptr as _)) + } else { + Err(glib::bool_error!("Memory is not a GLMemory")) + } + } + } + + #[inline] + #[doc(alias = "get_texture_id")] + fn texture_id(&self, idx: u32) -> Result { + Ok(self.memory(idx)?.texture_id()) + } + + #[inline] + #[doc(alias = "get_texture_format")] + fn texture_format(&self, idx: u32) -> Result { + Ok(self.memory(idx)?.texture_format()) + } + + #[inline] + #[doc(alias = "get_texture_height")] + fn texture_height(&self, idx: u32) -> Result { + Ok(self.memory(idx)?.texture_height()) + } + + #[inline] + #[doc(alias = "get_texture_target")] + fn texture_target(&self, idx: u32) -> Result { + Ok(self.memory(idx)?.texture_target()) + } + + #[inline] + #[doc(alias = "get_texture_width")] + fn texture_width(&self, idx: u32) -> Result { + Ok(self.memory(idx)?.texture_width()) + } +} + +impl GLVideoFrameExt for O {} pub struct GLVideoFrame { frame: gst_video::ffi::GstVideoFrame, @@ -25,40 +84,14 @@ unsafe impl Sync for GLVideoFrame {} impl IsVideoFrame for GLVideoFrame { #[inline] - fn as_non_null_ptr(&self) -> std::ptr::NonNull { - std::ptr::NonNull::from(&self.frame) + fn as_raw(&self) -> &gst_video::ffi::GstVideoFrame { + &self.frame } } +impl IsGLVideoFrame for GLVideoFrame {} + impl GLVideoFrame { - #[inline] - #[doc(alias = "get_texture_id")] - pub fn texture_id(&self, idx: u32) -> Option { - self.as_video_frame_gl_ref().texture_id(idx) - } - - pub fn memory(&self, idx: u32) -> Option<&GLMemoryRef> { - if idx >= buffer_n_gl_memory(self.buffer())? { - return None; - } - - unsafe { - let ptr = (*self.as_ptr()).map[idx as usize].memory as _; - Some(GLMemoryRef::from_ptr(ptr)) - } - } - - pub fn memory_mut(&self, idx: u32) -> Option<&mut GLMemoryRef> { - if idx >= buffer_n_gl_memory(self.buffer())? { - return None; - } - - unsafe { - let ptr = (*self.as_ptr()).map[idx as usize].memory as _; - Some(GLMemoryRef::from_mut_ptr(ptr)) - } - } - #[inline] pub fn into_buffer(self) -> gst::Buffer { unsafe { @@ -210,6 +243,11 @@ impl GLVideoFrame { } } + #[inline] + pub fn memory_mut(&self, idx: u32) -> Result<&mut GLMemoryRef, glib::BoolError> { + unsafe { Ok(GLMemoryRef::from_mut_ptr(self.memory(idx)?.as_ptr() as _)) } + } + #[inline] pub fn buffer_mut(&mut self) -> &mut gst::BufferRef { unsafe { gst::BufferRef::from_mut_ptr(self.frame.buffer) } @@ -227,10 +265,13 @@ unsafe impl Sync for GLVideoFrameRef {} impl IsVideoFrame for GLVideoFrameRef { #[inline] - fn as_non_null_ptr(&self) -> std::ptr::NonNull { - std::ptr::NonNull::from(&self.frame) + fn as_raw(&self) -> &gst_video::ffi::GstVideoFrame { + &self.frame } } + +impl IsGLVideoFrame for GLVideoFrameRef {} + // TODO implement Debug for GLVideoFrameRef impl<'a> GLVideoFrameRef<&'a gst::BufferRef> { @@ -307,35 +348,6 @@ impl<'a> GLVideoFrameRef<&'a gst::BufferRef> { } } } - - pub fn texture_id(&self, idx: u32) -> Option { - let len = buffer_n_gl_memory(self.buffer())?; - - if idx >= len { - return None; - } - - // FIXME: planes are not memories - if idx > self.n_planes() { - return None; - } - - unsafe { - let ptr = (*self.as_ptr()).data[idx as usize] as *const u32; - Some(*ptr) - } - } - - pub fn memory(&self, idx: u32) -> Option<&GLMemoryRef> { - if idx >= buffer_n_gl_memory(self.buffer())? { - return None; - } - - unsafe { - let ptr = (*self.as_ptr()).map[idx as usize].memory as _; - Some(GLMemoryRef::from_ptr(ptr)) - } - } } impl<'a> GLVideoFrameRef<&'a mut gst::BufferRef> { @@ -424,15 +436,9 @@ impl<'a> GLVideoFrameRef<&'a mut gst::BufferRef> { &mut self.frame } - pub fn memory_mut(&self, idx: u32) -> Option<&mut GLMemoryRef> { - if idx >= buffer_n_gl_memory(self.buffer())? { - return None; - } - - unsafe { - let ptr = (*self.as_ptr()).map[idx as usize].memory as _; - Some(GLMemoryRef::from_mut_ptr(ptr)) - } + #[inline] + pub fn memory_mut(&self, idx: u32) -> Result<&mut GLMemoryRef, glib::BoolError> { + unsafe { Ok(GLMemoryRef::from_mut_ptr(self.memory(idx)?.as_ptr() as _)) } } } diff --git a/gstreamer-gl/src/lib.rs b/gstreamer-gl/src/lib.rs index d14c527a2..6801d5d85 100644 --- a/gstreamer-gl/src/lib.rs +++ b/gstreamer-gl/src/lib.rs @@ -38,7 +38,7 @@ mod gl_display; mod gl_sync_meta; pub mod gl_video_frame; pub use crate::gl_sync_meta::*; -pub use crate::gl_video_frame::{GLVideoFrame, GLVideoFrameRef, Readable}; +pub use crate::gl_video_frame::{GLVideoFrame, GLVideoFrameExt, GLVideoFrameRef}; mod gl_base_memory; pub use self::gl_base_memory::*; mod gl_memory; @@ -56,6 +56,7 @@ pub mod prelude { pub use crate::{ auto::traits::*, context::ContextGLExt, gl_context::GLContextExtManual, gl_display::GLDisplayExtManual, gl_framebuffer::GLFramebufferExtManual, + gl_video_frame::GLVideoFrameExt, gl_video_frame::IsGLVideoFrame, }; } diff --git a/gstreamer-video/src/video_frame.rs b/gstreamer-video/src/video_frame.rs index e88b5e491..950acf291 100644 --- a/gstreamer-video/src/video_frame.rs +++ b/gstreamer-video/src/video_frame.rs @@ -8,13 +8,13 @@ pub enum Readable {} pub enum Writable {} pub trait IsVideoFrame { - fn as_non_null_ptr(&self) -> std::ptr::NonNull; + fn as_raw(&self) -> &ffi::GstVideoFrame; } impl IsVideoFrame for VideoFrame { #[inline] - fn as_non_null_ptr(&self) -> std::ptr::NonNull { - std::ptr::NonNull::from(&self.frame) + fn as_raw(&self) -> &ffi::GstVideoFrame { + &self.frame } } @@ -46,13 +46,13 @@ mod sealed { pub trait VideoFrameExt: sealed::Sealed + IsVideoFrame { #[inline] fn as_ptr(&self) -> *const ffi::GstVideoFrame { - self.as_non_null_ptr().as_ptr() as _ + self.as_raw() as _ } #[inline] fn info(&self) -> &crate::VideoInfo { unsafe { - let frame = self.as_non_null_ptr().as_ref(); + let frame = self.as_raw(); let info = &frame.info as *const ffi::GstVideoInfo as *const crate::VideoInfo; &*info } @@ -60,17 +60,17 @@ pub trait VideoFrameExt: sealed::Sealed + IsVideoFrame { #[inline] fn flags(&self) -> crate::VideoFrameFlags { - unsafe { from_glib(self.as_non_null_ptr().as_ref().flags) } + unsafe { from_glib(self.as_raw().flags) } } #[inline] fn id(&self) -> i32 { - unsafe { self.as_non_null_ptr().as_ref().id } + self.as_raw().id } #[inline] fn buffer(&self) -> &gst::BufferRef { - unsafe { gst::BufferRef::from_ptr(self.as_non_null_ptr().as_ref().buffer) } + unsafe { gst::BufferRef::from_ptr(self.as_raw().buffer) } } #[inline] @@ -534,8 +534,8 @@ pub struct VideoFrameRef { impl IsVideoFrame for VideoFrameRef { #[inline] - fn as_non_null_ptr(&self) -> std::ptr::NonNull { - std::ptr::NonNull::from(&self.frame) + fn as_raw(&self) -> &ffi::GstVideoFrame { + &self.frame } }