mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-25 13:01:07 +00:00
gtk4: add window-{width,height} property
Allow the application to pass the actual rendering size so overlays can be rendered accordingly. Fix #562 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1680>
This commit is contained in:
parent
ba0265970e
commit
17910dd532
2 changed files with 114 additions and 4 deletions
|
@ -2567,6 +2567,34 @@
|
|||
"readable": true,
|
||||
"type": "GstGtk4Paintable",
|
||||
"writable": false
|
||||
},
|
||||
"window-height": {
|
||||
"blurb": "the height of the main widget rendering the paintable",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "0",
|
||||
"max": "-1",
|
||||
"min": "0",
|
||||
"mutable": "playing",
|
||||
"readable": true,
|
||||
"type": "guint",
|
||||
"writable": true
|
||||
},
|
||||
"window-width": {
|
||||
"blurb": "the width of the main widget rendering the paintable",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "0",
|
||||
"max": "-1",
|
||||
"min": "0",
|
||||
"mutable": "playing",
|
||||
"readable": true,
|
||||
"type": "guint",
|
||||
"writable": true
|
||||
}
|
||||
},
|
||||
"rank": "none"
|
||||
|
|
|
@ -26,10 +26,13 @@ use gst_gl::prelude::*;
|
|||
use gst::prelude::*;
|
||||
use gst::subclass::prelude::*;
|
||||
use gst_base::subclass::prelude::*;
|
||||
use gst_video::subclass::prelude::*;
|
||||
use gst_video::{prelude::*, subclass::prelude::*};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Mutex, MutexGuard,
|
||||
};
|
||||
|
||||
use crate::utils;
|
||||
|
||||
|
@ -84,6 +87,14 @@ pub struct PaintableSink {
|
|||
sender: Mutex<Option<async_channel::Sender<SinkEvent>>>,
|
||||
pending_frame: Mutex<Option<Frame>>,
|
||||
cached_caps: Mutex<Option<gst::Caps>>,
|
||||
settings: Mutex<Settings>,
|
||||
window_resized: AtomicBool,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Settings {
|
||||
window_width: u32,
|
||||
window_height: u32,
|
||||
}
|
||||
|
||||
impl Drop for PaintableSink {
|
||||
|
@ -112,6 +123,16 @@ impl ObjectImpl for PaintableSink {
|
|||
.blurb("The Paintable the sink renders to")
|
||||
.read_only()
|
||||
.build(),
|
||||
glib::ParamSpecUInt::builder("window-width")
|
||||
.nick("Window width")
|
||||
.blurb("the width of the main widget rendering the paintable")
|
||||
.mutable_playing()
|
||||
.build(),
|
||||
glib::ParamSpecUInt::builder("window-height")
|
||||
.nick("Window height")
|
||||
.blurb("the height of the main widget rendering the paintable")
|
||||
.mutable_playing()
|
||||
.build(),
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -171,6 +192,36 @@ impl ObjectImpl for PaintableSink {
|
|||
|
||||
paintable.to_value()
|
||||
}
|
||||
"window-width" => {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
settings.window_width.to_value()
|
||||
}
|
||||
"window-height" => {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
settings.window_height.to_value()
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
||||
match pspec.name() {
|
||||
"window-width" => {
|
||||
let mut settings = self.settings.lock().unwrap();
|
||||
let value = value.get().expect("type checked upstream");
|
||||
if settings.window_width != value {
|
||||
self.window_resized.store(true, Ordering::SeqCst);
|
||||
}
|
||||
settings.window_width = value;
|
||||
}
|
||||
"window-height" => {
|
||||
let mut settings = self.settings.lock().unwrap();
|
||||
let value = value.get().expect("type checked upstream");
|
||||
if settings.window_height != value {
|
||||
self.window_resized.store(true, Ordering::SeqCst);
|
||||
}
|
||||
settings.window_height = value;
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
@ -495,8 +546,32 @@ impl BaseSinkImpl for PaintableSink {
|
|||
self.parent_propose_allocation(query)?;
|
||||
|
||||
query.add_allocation_meta::<gst_video::VideoMeta>(None);
|
||||
// TODO: Provide a preferred "window size" here for higher-resolution rendering
|
||||
query.add_allocation_meta::<gst_video::VideoOverlayCompositionMeta>(None);
|
||||
|
||||
let s = {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
if (settings.window_width, settings.window_height) != (0, 0) {
|
||||
gst::debug!(
|
||||
CAT,
|
||||
imp = self,
|
||||
"answering alloc query with size {}x{}",
|
||||
settings.window_width,
|
||||
settings.window_height
|
||||
);
|
||||
|
||||
self.window_resized.store(false, Ordering::SeqCst);
|
||||
|
||||
Some(
|
||||
gst::Structure::builder("GstVideoOverlayCompositionMeta")
|
||||
.field("width", settings.window_width)
|
||||
.field("height", settings.window_height)
|
||||
.build(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
query.add_allocation_meta::<gst_video::VideoOverlayCompositionMeta>(s.as_deref());
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst-gl"))]
|
||||
{
|
||||
|
@ -583,6 +658,13 @@ impl VideoSinkImpl for PaintableSink {
|
|||
fn show_frame(&self, buffer: &gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
gst::trace!(CAT, imp = self, "Rendering buffer {:?}", buffer);
|
||||
|
||||
if self.window_resized.swap(false, Ordering::SeqCst) {
|
||||
gst::debug!(CAT, imp = self, "Window size changed, needs to reconfigure");
|
||||
let obj = self.obj();
|
||||
let sink = obj.sink_pad();
|
||||
sink.push_event(gst::event::Reconfigure::builder().build());
|
||||
}
|
||||
|
||||
// Empty buffer, nothing to render
|
||||
if buffer.n_memory() == 0 {
|
||||
gst::trace!(
|
||||
|
|
Loading…
Reference in a new issue