From 0fe4e0bf0bb52e00d7b6ea5812275eb02c39ce6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 7 Feb 2024 19:30:12 +0200 Subject: [PATCH] gtk4: Add property to the paintable for selecting the background color Part-of: --- video/gtk4/src/sink/imp.rs | 12 +++++----- video/gtk4/src/sink/paintable/imp.rs | 33 +++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/video/gtk4/src/sink/imp.rs b/video/gtk4/src/sink/imp.rs index c3e291e1..4701679f 100644 --- a/video/gtk4/src/sink/imp.rs +++ b/video/gtk4/src/sink/imp.rs @@ -17,6 +17,13 @@ use glib::thread_guard::ThreadGuard; use gtk::prelude::*; use gtk::{gdk, glib}; +#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst-gl"))] +use gst_gl::prelude::GLContextExt as GstGLContextExt; +#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst-gl"))] +use gst_gl::prelude::*; + +#[allow(unused_imports)] +use gst::prelude::*; use gst::subclass::prelude::*; use gst_base::subclass::prelude::*; use gst_video::subclass::prelude::*; @@ -26,11 +33,6 @@ use std::sync::{Mutex, MutexGuard}; use crate::utils; -#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst-gl"))] -use gst_gl::prelude::GLContextExt as GstGLContextExt; -#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst-gl"))] -use gst_gl::prelude::*; - // Global GL context that is created by the first sink and kept around until the end of the // process. This is provided to other elements in the pipeline to make sure they create GL contexts // that are sharing with the GTK GL context. diff --git a/video/gtk4/src/sink/paintable/imp.rs b/video/gtk4/src/sink/paintable/imp.rs index ee6a454f..243350b0 100644 --- a/video/gtk4/src/sink/paintable/imp.rs +++ b/video/gtk4/src/sink/paintable/imp.rs @@ -15,7 +15,7 @@ use gtk::{gdk, glib, graphene, gsk}; use crate::sink::frame::{Frame, Texture}; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::collections::HashMap; use once_cell::sync::Lazy; @@ -33,6 +33,7 @@ pub struct Paintable { paintables: RefCell>, cached_textures: RefCell>, gl_context: RefCell>, + background_color: Cell, #[cfg(not(feature = "gtk_v4_10"))] premult_shader: gsk::GLShader, } @@ -43,6 +44,7 @@ impl Default for Paintable { paintables: Default::default(), cached_textures: Default::default(), gl_context: Default::default(), + background_color: Cell::new(gdk::RGBA::BLACK), #[cfg(not(feature = "gtk_v4_10"))] premult_shader: gsk::GLShader::from_bytes(&glib::Bytes::from_static(include_bytes!( "premult.glsl" @@ -67,6 +69,11 @@ impl ObjectImpl for Paintable { .blurb("GL context to use for rendering") .construct_only() .build(), + glib::ParamSpecUInt::builder("background-color") + .nick("Background Color") + .blurb("Background color to render behind the video frame and in the borders") + .default_value(0) + .build(), ] }); @@ -76,6 +83,16 @@ impl ObjectImpl for Paintable { fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { match pspec.name() { "gl-context" => self.gl_context.borrow().to_value(), + "background-color" => { + let color = self.background_color.get(); + + let v = (f32::clamp(color.red() * 255.0, 0.0, 255.0) as u32) << 24 + | (f32::clamp(color.green() * 255.0, 0.0, 255.0) as u32) << 16 + | (f32::clamp(color.blue() * 255.0, 0.0, 255.0) as u32) << 8 + | (f32::clamp(color.alpha() * 255.0, 0.0, 255.0) as u32); + + v.to_value() + } _ => unimplemented!(), } } @@ -85,6 +102,15 @@ impl ObjectImpl for Paintable { "gl-context" => { *self.gl_context.borrow_mut() = value.get::>().unwrap(); } + "background-color" => { + let v = value.get::().unwrap(); + let red = ((v & 0xff_00_00_00) >> 24) as f32 / 255.0; + let green = ((v & 0x00_ff_00_00) >> 16) as f32 / 255.0; + let blue = ((v & 0x00_00_ff_00) >> 8) as f32 / 255.0; + let alpha = (v & 0x00_00_00_ff) as f32 / 255.0; + self.background_color + .set(gdk::RGBA::new(red, green, blue, alpha)) + } _ => unimplemented!(), } } @@ -118,6 +144,7 @@ impl PaintableImpl for Paintable { fn snapshot(&self, snapshot: &gdk::Snapshot, width: f64, height: f64) { let snapshot = snapshot.downcast_ref::().unwrap(); + let background_color = self.background_color.get(); let paintables = self.paintables.borrow(); if !paintables.is_empty() { @@ -145,7 +172,7 @@ impl PaintableImpl for Paintable { } snapshot.append_color( - &gdk::RGBA::BLACK, + &background_color, &graphene::Rect::new(0f32, 0f32, width as f32, height as f32), ); @@ -246,7 +273,7 @@ impl PaintableImpl for Paintable { } else { gst::trace!(CAT, imp: self, "Snapshotting black frame"); snapshot.append_color( - &gdk::RGBA::BLACK, + &background_color, &graphene::Rect::new(0f32, 0f32, width as f32, height as f32), ); }