diff --git a/Cargo.lock b/Cargo.lock index 8cbfd0d5..a26ccece 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -652,11 +652,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "162762eb8df14f696707ff54382b3c02f58706255ab3a37a61d59bc1d0c0115a" dependencies = [ "async-channel", + "gdk4-wayland", "gdk4-win32", + "gdk4-x11", "gst-plugin-version-helper", "gstreamer", "gstreamer-base", "gstreamer-gl", + "gstreamer-gl-egl", + "gstreamer-gl-wayland", + "gstreamer-gl-x11", "gstreamer-video", "gtk4", "once_cell", @@ -740,6 +745,31 @@ dependencies = [ "once_cell", ] +[[package]] +name = "gstreamer-gl-egl" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfde7bf67f5f7c87e1ff29cdeea4918530d677b51e3f4847121ada44f1fab139" +dependencies = [ + "glib", + "gstreamer", + "gstreamer-gl", + "gstreamer-gl-egl-sys", + "libc", +] + +[[package]] +name = "gstreamer-gl-egl-sys" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9ec3c03af5d4ed3e58ddbca4eea13e90e01b88e37f6c0689b26e05168eb7bf" +dependencies = [ + "glib-sys", + "gstreamer-gl-sys", + "libc", + "system-deps", +] + [[package]] name = "gstreamer-gl-sys" version = "0.22.0" @@ -755,6 +785,56 @@ dependencies = [ "system-deps", ] +[[package]] +name = "gstreamer-gl-wayland" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbfe3d0c2469023b73df8408a4b19daaf7bd30141e9fc67e4ab63d41db5ee2" +dependencies = [ + "glib", + "gstreamer", + "gstreamer-gl", + "gstreamer-gl-wayland-sys", + "libc", +] + +[[package]] +name = "gstreamer-gl-wayland-sys" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83bc79debd1ef92795a3bd411986b19dbfe2527424f396e460aacc59d5fab4f1" +dependencies = [ + "glib-sys", + "gstreamer-gl-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gstreamer-gl-x11" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ed82941c84668d89dbf81f220083422268c22ec6ab4991806649ed6758cec8" +dependencies = [ + "glib", + "gstreamer", + "gstreamer-gl", + "gstreamer-gl-x11-sys", + "libc", +] + +[[package]] +name = "gstreamer-gl-x11-sys" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b59f2782f5e71e3ef5fd534598938966a4dc3911f2540807f7d13b586e4ed1" +dependencies = [ + "glib-sys", + "gstreamer-gl-sys", + "libc", + "system-deps", +] + [[package]] name = "gstreamer-sys" version = "0.22.1" diff --git a/Cargo.toml b/Cargo.toml index 4c28e743..d4e76f1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,12 @@ gettext-rs = { version = "0.7.0", features = ["gettext-system"] } gsettings-macro = "0.2" gst = { package = "gstreamer", version = "0.22", features = ["v1_20"] } gst-plugin-gif = "0.12" -gst-plugin-gtk4 = { version = "0.12", features = ["gtk_v4_14"] } +gst-plugin-gtk4 = { version = "0.12", features = [ + "gtk_v4_14", + "wayland", + "x11egl", + "x11glx", +] } gtk = { package = "gtk4", version = "0.8", features = ["v4_14"] } num-rational = { version = "0.4", default-features = false } num-traits = "0.2" diff --git a/src/area_selector/mod.rs b/src/area_selector/mod.rs index d5d96eb3..d361c32b 100644 --- a/src/area_selector/mod.rs +++ b/src/area_selector/mod.rs @@ -218,16 +218,33 @@ impl AreaSelector { // Setup pipeline let pipeline = gst::Pipeline::new(); - let videosrc_bin = pipeline::make_pipewiresrc_bin(fd, streams, PREVIEW_FRAMERATE, None)?; - let videoconvert = gst::ElementFactory::make("videoconvert").build()?; - let sink = gst::ElementFactory::make("gtk4paintablesink").build()?; - pipeline.add_many([videosrc_bin.upcast_ref(), &videoconvert, &sink])?; - gst::Element::link_many([videosrc_bin.upcast_ref(), &videoconvert, &sink])?; imp.pipeline.set(pipeline.clone()).unwrap(); - // Setup paintable - let paintable = sink.property::("paintable"); - imp.view_port.set_paintable(Some(paintable)); + let videosrc_bin = pipeline::make_pipewiresrc_bin(fd, streams, PREVIEW_FRAMERATE, None)?; + let gtksink = gst::ElementFactory::make("gtk4paintablesink").build()?; + + let paintable = gtksink.property::("paintable"); + paintable.set_property("use-scaling-filter", true); + imp.view_port.set_paintable(Some(paintable.clone())); + + if paintable + .property::>("gl-context") + .is_some() + { + tracing::debug!("Using gl pipeline"); + + let glsinkbin = gst::ElementFactory::make("glsinkbin") + .property("sink", >ksink) + .build()?; + pipeline.add_many([videosrc_bin.upcast_ref(), &glsinkbin])?; + videosrc_bin.link(&glsinkbin)?; + } else { + tracing::debug!("Falling back to non-gl pipeline"); + + let videoconvert = gst::ElementFactory::make("videoconvert").build()?; + pipeline.add_many([videosrc_bin.upcast_ref(), &videoconvert, >ksink])?; + gst::Element::link_many([videosrc_bin.upcast_ref(), &videoconvert, >ksink])?; + } let (async_done_tx, async_done_rx) = oneshot::channel(); imp.async_done_tx.replace(Some(async_done_tx));