mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-26 05:21:00 +00:00
gtk4: Create a window if running from gst-launch-1.0 or GST_GTK4_WINDOW=1 is set
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/482 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1454>
This commit is contained in:
parent
66ad059a47
commit
7274c725a6
1 changed files with 68 additions and 0 deletions
|
@ -61,6 +61,7 @@ pub(crate) static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct PaintableSink {
|
pub struct PaintableSink {
|
||||||
paintable: Mutex<Option<ThreadGuard<Paintable>>>,
|
paintable: Mutex<Option<ThreadGuard<Paintable>>>,
|
||||||
|
window: Mutex<Option<ThreadGuard<gtk::Window>>>,
|
||||||
info: Mutex<Option<gst_video::VideoInfo>>,
|
info: Mutex<Option<gst_video::VideoInfo>>,
|
||||||
sender: Mutex<Option<async_channel::Sender<SinkEvent>>>,
|
sender: Mutex<Option<async_channel::Sender<SinkEvent>>>,
|
||||||
pending_frame: Mutex<Option<Frame>>,
|
pending_frame: Mutex<Option<Frame>>,
|
||||||
|
@ -231,6 +232,18 @@ impl ElementImpl for PaintableSink {
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
let create_window = glib::program_name().as_deref() == Some("gst-launch-1.0")
|
||||||
|
|| std::env::var("GST_GTK4_WINDOW").as_deref() == Ok("1");
|
||||||
|
|
||||||
|
if create_window {
|
||||||
|
let res = utils::invoke_on_main_thread(gtk::init);
|
||||||
|
|
||||||
|
if let Err(err) = res {
|
||||||
|
gst::error!(CAT, imp: self, "Failed to create initialize GTK: {err}");
|
||||||
|
return Err(gst::StateChangeError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut paintable = self.paintable.lock().unwrap();
|
let mut paintable = self.paintable.lock().unwrap();
|
||||||
|
|
||||||
if paintable.is_none() {
|
if paintable.is_none() {
|
||||||
|
@ -273,6 +286,10 @@ impl ElementImpl for PaintableSink {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if create_window {
|
||||||
|
self.create_window();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -294,6 +311,17 @@ impl ElementImpl for PaintableSink {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
gst::StateChange::ReadyToNull => {
|
||||||
|
let mut window_guard = self.window.lock().unwrap();
|
||||||
|
if let Some(window) = window_guard.take() {
|
||||||
|
drop(window_guard);
|
||||||
|
|
||||||
|
glib::MainContext::default().invoke(move || {
|
||||||
|
let window = window.get_ref();
|
||||||
|
window.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,6 +548,46 @@ impl PaintableSink {
|
||||||
.replace(tmp_caps);
|
.replace(tmp_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_window(&self) {
|
||||||
|
let self_ = self.to_owned();
|
||||||
|
glib::MainContext::default().invoke(move || {
|
||||||
|
let mut window_guard = self_.window.lock().unwrap();
|
||||||
|
if window_guard.is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let paintable = match &*self_.paintable.lock().unwrap() {
|
||||||
|
Some(paintable) => paintable.get_ref().clone(),
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let window = gtk::Window::new();
|
||||||
|
let picture = gtk::Picture::new();
|
||||||
|
picture.set_paintable(Some(&paintable));
|
||||||
|
window.set_child(Some(&picture));
|
||||||
|
window.set_default_size(640, 480);
|
||||||
|
|
||||||
|
window.connect_close_request({
|
||||||
|
let self_ = self_.clone();
|
||||||
|
move |_window| {
|
||||||
|
if self_.window.lock().unwrap().is_some() {
|
||||||
|
gst::element_imp_error!(
|
||||||
|
self_,
|
||||||
|
gst::ResourceError::NotFound,
|
||||||
|
("Output window was closed")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
glib::Propagation::Proceed
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.show();
|
||||||
|
|
||||||
|
*window_guard = Some(ThreadGuard::new(window));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn create_paintable(&self, paintable_storage: &mut MutexGuard<Option<ThreadGuard<Paintable>>>) {
|
fn create_paintable(&self, paintable_storage: &mut MutexGuard<Option<ThreadGuard<Paintable>>>) {
|
||||||
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst-gl"))]
|
#[cfg(any(target_os = "macos", target_os = "windows", feature = "gst-gl"))]
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue