From 4eddd377e1fa16c34c917d71f78028155f3d1c65 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Fri, 28 Aug 2020 14:32:53 +0200 Subject: [PATCH] gl/gl_base_memory: Provide manual GLBaseMemory miniobject implementation Also enable all dependencies used by this type. Copying AllocationParams is possible without borrowing the source mutable. The offset and size parameters of `memcpy` are unchecked and may result in out-of-bounds reads/writes, which is why this function is marked as `unsafe`. --- gstreamer-gl/Gir.toml | 39 +++++++++++-- gstreamer-gl/src/gl_base_memory.rs | 90 ++++++++++++++++++++++++++++++ gstreamer-gl/src/lib.rs | 2 + 3 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 gstreamer-gl/src/gl_base_memory.rs diff --git a/gstreamer-gl/Gir.toml b/gstreamer-gl/Gir.toml index a1dfd2e13..5530d3198 100644 --- a/gstreamer-gl/Gir.toml +++ b/gstreamer-gl/Gir.toml @@ -30,14 +30,12 @@ generate = [ "GstGL.GLSLError", "GstGL.GLWindowError", # Records - #"GstGL.GLAllocationParams", #"GstGL.GLRenderbufferAllocationParams", - #"GstGL.GLVideoAllocationParams", # Objects #"GstGL.GLBufferPool", "GstGL.GLFramebuffer", - #"GstGL.GLBaseMemory", - #"GstGL.GLBaseMemoryAllocator", + "GstGL.GLBaseMemoryAllocator", + "GstGL.GLMemoryAllocator", #"GstGL.GLMemoryPBOAllocator", #"GstGL.GLRenderbufferAllocator", ] @@ -56,6 +54,7 @@ manual = [ "Gst.PadDirection", "GstBase.BaseTransform", "GstBase.PushSrc", + "GstGL.GLBaseMemory", "GstVideo.VideoAlignment", "GstVideo.VideoInfo", "GstVideo.VideoMultiviewFlags", @@ -467,3 +466,35 @@ status = "generate" [[object.member]] name = "any" ignore = true + +[[object]] +name = "GstGL.GLAllocationParams" +status = "generate" + + [[object.function]] + name = "free_data" + # Function should only be called by subclasses from + # an overridden `free` vfunc. + ignore = true + + [[object.function]] + name = "copy_data" + [[object.function.parameter]] + name = "src" + const = true + +[[object]] +name = "GstGL.GLVideoAllocationParams" +status = "generate" + + [[object.function]] + name = "free_data" + # Function should only be called by subclasses from + # an overridden `free` vfunc. + ignore = true + + [[object.function]] + name = "copy_data" + [[object.function.parameter]] + name = "src_vid" + const = true diff --git a/gstreamer-gl/src/gl_base_memory.rs b/gstreamer-gl/src/gl_base_memory.rs new file mode 100644 index 000000000..b6fa91c10 --- /dev/null +++ b/gstreamer-gl/src/gl_base_memory.rs @@ -0,0 +1,90 @@ +use glib::object::IsA; +use glib::translate::*; + +use crate::GLAllocationParams; +use crate::GLBaseMemoryAllocator; + +use ffi::GstGLBaseMemory; +use gst::ffi::GstMemory; +use gst::MemoryRef; +use gst::{result_from_gboolean, LoggableError, CAT_RUST}; + +gst::mini_object_wrapper!( + GLBaseMemory, + GLBaseMemoryRef, + GstGLBaseMemory, + ffi::gst_gl_base_memory_get_type +); + +impl std::ops::Deref for GLBaseMemoryRef { + type Target = MemoryRef; + + fn deref(&self) -> &Self::Target { + unsafe { &*(&self.0.mem as *const GstMemory).cast::() } + } +} + +impl std::ops::DerefMut for GLBaseMemoryRef { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { &mut *(&mut self.0.mem as *mut GstMemory).cast::() } + } +} + +impl GLBaseMemoryRef { + // Note: only intended for subclass usage to allocate the system memory buffer + // on demand. If there is already a non-NULL data pointer in @gl_mem->data, + // then this function imply returns TRUE. + // #[doc(alias = "gst_gl_base_memory_alloc_data")] + // pub fn alloc_data(&mut self) -> bool { + // Self::init_once(); + // unsafe { from_glib(ffi::gst_gl_base_memory_alloc_data(&mut self.0)) } + // } + + //#[doc(alias = "gst_gl_base_memory_init")] + //pub fn init, Q: IsA>(&mut self, allocator: &P, parent: Option<&mut gst::Memory>, context: &Q, params: Option<&mut gst::AllocationParams>, size: usize, user_data: /*Unimplemented*/Option) { + // unsafe { TODO: call ffi:gst_gl_base_memory_init() } + //} + + #[doc(alias = "gst_gl_base_memory_memcpy")] + pub unsafe fn memcpy( + &self, + dest: &mut GLBaseMemory, + offset: isize, + size: isize, + ) -> Result<(), LoggableError> { + Self::init_once(); + result_from_gboolean!( + ffi::gst_gl_base_memory_memcpy( + mut_override(&self.0), + dest.to_glib_none_mut().0, + offset, + size, + ), + CAT_RUST, + "Failed to copy memory" + ) + } + + #[doc(alias = "gst_gl_base_memory_alloc")] + pub fn alloc>( + allocator: &P, + params: &GLAllocationParams, + ) -> Option { + skip_assert_initialized!(); + Self::init_once(); + unsafe { + from_glib_full(ffi::gst_gl_base_memory_alloc( + allocator.as_ref().to_glib_none().0, + mut_override(params.to_glib_none().0), + )) + } + } + + #[doc(alias = "gst_gl_base_memory_init_once")] + fn init_once() { + assert_initialized_main_thread!(); + unsafe { + ffi::gst_gl_base_memory_init_once(); + } + } +} diff --git a/gstreamer-gl/src/lib.rs b/gstreamer-gl/src/lib.rs index 4ce1f86d3..ee6c6243d 100644 --- a/gstreamer-gl/src/lib.rs +++ b/gstreamer-gl/src/lib.rs @@ -37,6 +37,8 @@ mod gl_video_frame; pub use crate::gl_video_frame::VideoFrameGLExt; mod gl_sync_meta; pub use crate::gl_sync_meta::*; +mod gl_base_memory; +pub use self::gl_base_memory::*; // Re-export all the traits in a prelude module, so that applications // can always "use gst::prelude::*" without getting conflicts