From 450ffbe4523be05f9afb21cd88ee097c78d57f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 2 Oct 2023 13:25:25 +0300 Subject: [PATCH] Update for `VideoFrame` / `GLVideoFrame` API changes Part-of: --- net/ndi/src/ndi.rs | 2 + tutorial/src/rgb2gray/imp.rs | 1 + video/gtk4/src/sink/frame.rs | 111 ++++++++++++------ video/gtk4/src/sink/imp.rs | 1 - video/hsv/src/hsvdetector/imp.rs | 1 + video/hsv/src/hsvfilter/imp.rs | 1 + .../videofx/src/videocompare/hashed_image.rs | 2 +- video/videofx/src/videocompare/imp.rs | 2 +- 8 files changed, 85 insertions(+), 36 deletions(-) diff --git a/net/ndi/src/ndi.rs b/net/ndi/src/ndi.rs index 35c7ad90..237d5805 100644 --- a/net/ndi/src/ndi.rs +++ b/net/ndi/src/ndi.rs @@ -9,6 +9,8 @@ use std::ptr; use byte_slice_cast::*; +use gst_video::prelude::*; + pub fn load() -> Result<(), glib::BoolError> { ndisys::load() } diff --git a/tutorial/src/rgb2gray/imp.rs b/tutorial/src/rgb2gray/imp.rs index e11fe37b..211ea503 100644 --- a/tutorial/src/rgb2gray/imp.rs +++ b/tutorial/src/rgb2gray/imp.rs @@ -12,6 +12,7 @@ use gst::glib; use gst::prelude::*; use gst::subclass::prelude::*; use gst_base::subclass::prelude::*; +use gst_video::prelude::*; use gst_video::subclass::prelude::*; use std::sync::Mutex; diff --git a/video/gtk4/src/sink/frame.rs b/video/gtk4/src/sink/frame.rs index d5223a61..600a7ff8 100644 --- a/video/gtk4/src/sink/frame.rs +++ b/video/gtk4/src/sink/frame.rs @@ -17,11 +17,53 @@ use gtk::{gdk, glib}; use std::collections::{HashMap, HashSet}; #[derive(Debug)] -pub(crate) struct Frame { - frame: gst_video::VideoFrame, - overlays: Vec, +enum MappedFrame { + SysMem(gst_video::VideoFrame), #[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))] - wrapped_context: Option, + GL { + frame: gst_gl::GLVideoFrame, + wrapped_context: gst_gl::GLContext, + }, +} + +impl MappedFrame { + fn buffer(&self) -> &gst::BufferRef { + match self { + MappedFrame::SysMem(frame) => frame.buffer(), + #[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))] + MappedFrame::GL { frame, .. } => frame.buffer(), + } + } + + fn width(&self) -> u32 { + match self { + MappedFrame::SysMem(frame) => frame.width(), + #[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))] + MappedFrame::GL { frame, .. } => frame.width(), + } + } + + fn height(&self) -> u32 { + match self { + MappedFrame::SysMem(frame) => frame.height(), + #[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))] + MappedFrame::GL { frame, .. } => frame.height(), + } + } + + fn format_info(&self) -> gst_video::VideoFormatInfo { + match self { + MappedFrame::SysMem(frame) => frame.format_info(), + #[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))] + MappedFrame::GL { frame, .. } => frame.format_info(), + } + } +} + +#[derive(Debug)] +pub(crate) struct Frame { + frame: MappedFrame, + overlays: Vec, } #[derive(Debug)] @@ -97,7 +139,7 @@ fn video_frame_to_memory_texture( #[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))] fn video_frame_to_gl_texture( - frame: gst_video::VideoFrame, + frame: gst_gl::GLVideoFrame, cached_textures: &mut HashMap, used_textures: &mut HashSet, gdk_context: &gdk::GLContext, @@ -151,30 +193,28 @@ impl Frame { let width = self.frame.width(); let height = self.frame.height(); let has_alpha = self.frame.format_info().has_alpha(); - let (texture, pixel_aspect_ratio) = { - #[cfg(not(any(target_os = "macos", target_os = "windows", feature = "gst_gl")))] - { - video_frame_to_memory_texture(self.frame, cached_textures, &mut used_textures) + let (texture, pixel_aspect_ratio) = match self.frame { + MappedFrame::SysMem(frame) => { + video_frame_to_memory_texture(frame, cached_textures, &mut used_textures) } #[cfg(any(target_os = "macos", target_os = "windows", feature = "gst_gl"))] - { - if let (Some(gdk_ctx), Some(wrapped_ctx)) = - (gdk_context, self.wrapped_context.as_ref()) - { - video_frame_to_gl_texture( - self.frame, - cached_textures, - &mut used_textures, - gdk_ctx, - wrapped_ctx, - ) - } else { + MappedFrame::GL { + frame, + wrapped_context, + } => { + let Some(gdk_context) = gdk_context else { // This will fail badly if the video frame was actually mapped as GL texture // but this case can't really happen as we only do that if we actually have a // GDK GL context. - assert!(self.wrapped_context.is_none()); - video_frame_to_memory_texture(self.frame, cached_textures, &mut used_textures) - } + unreachable!(); + }; + video_frame_to_gl_texture( + frame, + cached_textures, + &mut used_textures, + gdk_context, + &wrapped_context, + ) } }; @@ -230,8 +270,10 @@ impl Frame { #[cfg(not(any(target_os = "macos", target_os = "windows", feature = "gst_gl")))] { frame = Self { - frame: gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info) - .map_err(|_| gst::FlowError::Error)?, + frame: MappedFrame::SysMem( + gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info) + .map_err(|_| gst::FlowError::Error)?, + ), overlays: vec![], }; } @@ -259,7 +301,7 @@ impl Frame { // If there is no GLSyncMeta yet then we need to add one here now, which requires // obtaining a writable buffer. let mapped_frame = if buffer.meta::().is_some() { - gst_video::VideoFrame::from_buffer_readable_gl(buffer.clone(), info) + gst_gl::GLVideoFrame::from_buffer_readable(buffer.clone(), info) .map_err(|_| gst::FlowError::Error)? } else { let mut buffer = buffer.clone(); @@ -267,7 +309,7 @@ impl Frame { let buffer = buffer.make_mut(); gst_gl::GLSyncMeta::add(buffer, memory_ctx); } - gst_video::VideoFrame::from_buffer_readable_gl(buffer, info) + gst_gl::GLVideoFrame::from_buffer_readable(buffer, info) .map_err(|_| gst::FlowError::Error)? }; @@ -278,16 +320,19 @@ impl Frame { meta.set_sync_point(memory_ctx); frame = Self { - frame: mapped_frame, + frame: MappedFrame::GL { + frame: mapped_frame, + wrapped_context: wrapped_context.unwrap().clone(), + }, overlays: vec![], - wrapped_context: Some(wrapped_context.unwrap().clone()), }; } else { frame = Self { - frame: gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info) - .map_err(|_| gst::FlowError::Error)?, + frame: MappedFrame::SysMem( + gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info) + .map_err(|_| gst::FlowError::Error)?, + ), overlays: vec![], - wrapped_context: None, }; } } diff --git a/video/gtk4/src/sink/imp.rs b/video/gtk4/src/sink/imp.rs index 6b23b71d..3a1059d6 100644 --- a/video/gtk4/src/sink/imp.rs +++ b/video/gtk4/src/sink/imp.rs @@ -14,7 +14,6 @@ use crate::sink::frame::Frame; use crate::sink::paintable::Paintable; use glib::{thread_guard::ThreadGuard, Sender}; -use gtk::prelude::GLContextExt; use gtk::prelude::*; use gtk::{gdk, glib}; diff --git a/video/hsv/src/hsvdetector/imp.rs b/video/hsv/src/hsvdetector/imp.rs index d4568023..4f10ce59 100644 --- a/video/hsv/src/hsvdetector/imp.rs +++ b/video/hsv/src/hsvdetector/imp.rs @@ -13,6 +13,7 @@ use gst::prelude::*; use gst::subclass::prelude::*; use gst_base::subclass::prelude::*; +use gst_video::prelude::*; use gst_video::subclass::prelude::*; use std::sync::Mutex; diff --git a/video/hsv/src/hsvfilter/imp.rs b/video/hsv/src/hsvfilter/imp.rs index faf6e36a..8cbeeeec 100644 --- a/video/hsv/src/hsvfilter/imp.rs +++ b/video/hsv/src/hsvfilter/imp.rs @@ -12,6 +12,7 @@ use gst::glib; use gst::prelude::*; use gst::subclass::prelude::*; use gst_base::subclass::prelude::*; +use gst_video::prelude::*; use gst_video::subclass::prelude::*; use std::sync::Mutex; diff --git a/video/videofx/src/videocompare/hashed_image.rs b/video/videofx/src/videocompare/hashed_image.rs index 333fde21..33484c47 100644 --- a/video/videofx/src/videocompare/hashed_image.rs +++ b/video/videofx/src/videocompare/hashed_image.rs @@ -9,7 +9,7 @@ use crate::HashAlgorithm; #[cfg(feature = "dssim")] use dssim_core::{Dssim, DssimImage}; -use gst_video::VideoFormat; +use gst_video::{prelude::*, VideoFormat}; use image_hasher::{HashAlg, Hasher, HasherConfig, ImageHash}; #[cfg(feature = "dssim")] use rgb::FromSlice; diff --git a/video/videofx/src/videocompare/imp.rs b/video/videofx/src/videocompare/imp.rs index afd88890..d8cf983b 100644 --- a/video/videofx/src/videocompare/imp.rs +++ b/video/videofx/src/videocompare/imp.rs @@ -14,7 +14,7 @@ use gst::subclass::prelude::*; use gst::{glib, glib::prelude::*, prelude::*}; use gst_base::prelude::*; use gst_base::AggregatorPad; -use gst_video::prelude::VideoAggregatorPadExtManual; +use gst_video::prelude::*; use gst_video::subclass::prelude::*; use gst_video::subclass::AggregateFramesToken; use gst_video::VideoFormat;