Getting the OutputStream from a giostreamsink

Hello!

First post here, so I’m not really sure if this is the appropriate place to do so? But I see questions about glib/gstreamer asked here, so I guess I’m good :stuck_out_tongue:!

So, I am trying to create a GTK4 rust app which process a video through gstreamer and play it. I know the ecosystem is still quite young and unstable, but I like danger :sunglasses:!

Since GTK4 introduced gtk::Video, and it takes a gio::InputStream, I figured out that the best way to display that video would be using the giostreamsink which create a gio::OutputStream and is available in gstreamer-good.

The problem is, I have trouble getting that OutputStream… Indeed, this fails:

let output = sink.get_property("stream")?
    .get::<gio::OutputStream>()?
    .unwrap();
error[E0277]: the trait bound `OutputStream: gstreamer::glib::value::FromValueOptional<'_>` is not satisfied
  --> src/backend/video.rs:68:14
   |
68 |             .get::<gio::OutputStream>()?
   |              ^^^ the trait `gstreamer::glib::value::FromValueOptional<'_>` is not implemented for `OutputStream`

So, I head to the documentation, and, indeed, FromValueOptional is not implemented for OutputStream. But neither is gtk::Widget? Yet, I see other projects, like glide, using that without issue? So what’s the issue in my code? How might I do that anyway?

Maybe is there a use statement missing? But neither gio::prelude::* nor glib::prelude::* work…

Can you provide some code to reproduce this problem? The exact same code (with ? replaced by unwrap()) builds just fine for me.

    let output = sink.get_property("stream")
        .unwrap()
        .get::<gio::OutputStream>()
        .unwrap()
        .unwrap();

I would recommend using gtkglsink or the sink that @bilelmoussaoui wrote here. Going from a giostreamsink to a gtk::Video is not going to work very nicely.

If you’re using GStreamer API directly anyway you’ll have more flexible APIs available.

1 Like

Thank you for your answer :smiley:!

My suspicion are confirmed…

I don’t know if you want me to include the whole file in which this happens? As I don’t really know how to reproduce it… It works fine in glide ¯\_(ツ)_/¯…

What “use” statement are you using? And what libraries are you including?

Well, I am using GTK4 for gtk::Video specifically :stuck_out_tongue:! I’ve originally started writing all this in Vala for GTK3, but when I saw that a new Video widget would be introduced, I decided to wait for a stable release to finally use it! So, I really want to use it, but I’d be happy to hear if there are better ways to do it, but unless it really won’t work, I think I’ll be sticking with it (at least for now :stuck_out_tongue:!).

And thank you for showing me camera-rs, until now, I was quite lost using GTK4 and Gstreamer along!

use gtk::prelude::*;
use gio;

Best to put your code into a git repository somewhere and then I can take a look.

For that to work you would have to (AFAIU at least, I don’t really know the GTK API) encode the video again before your giostreamsink just for having gtk::Video decode it again for you.

If you already have a GStreamer pipeline, use a GStreamer sink that allows you to render into GTK. Like the one from camera-rs (which provides you with a gdk::Paintable) or the one from the MR I linked (which provides you with a gtk::Widget).

1 Like

Well, I have one :stuck_out_tongue:! Since it’s also my first big GTK+Rust project, don’t mind to leave advice on bad coding practices!

The problematic code is found in src/backend/video.rs!

Yeah, I might do that…

You’re mixing dependencies from git and crates.io. That means you have two FromValueOptional (etc), one from the crates.io glib (pulled in via gstreamer) and another from the git glib.

You can’t mix different versions because then the traits don’t match anymore.

The following diff solves that

diff --git a/Cargo.toml b/Cargo.toml
index 069b5e1..d281142 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -37,4 +37,4 @@ features = ["gettext-system"]
 [dependencies.gst]
 package = "gstreamer"
 features = ["v1_16"]
-version = "0.16"
+git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git"
1 Like

Oh! So that’s it?

It still fails to compile though:

   Compiling gstreamer-sys v0.17.0 (https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git#fc2d7fc4)
   Compiling gstreamer v0.17.0 (https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git#fc2d7fc4)
error[E0308]: mismatched types
   --> /home/lyes/.cargo/git/checkouts/gstreamer-rs-79e52a2d27eb91a3/fc2d7fc/gstreamer/src/date_time.rs:299:31
    |
299 |                 .and_then(|d| d.to_utc())
    |                               ^^^^^^^^^^
    |                               |
    |                               expected enum `std::result::Result`, found enum `Option`
    |                               help: try using a variant of the expected enum: `Ok(d.to_utc())`
    |
    = note: expected enum `std::result::Result<_, BoolError>`
               found enum `Option<glib::DateTime>`

error[E0308]: mismatched types
   --> /home/lyes/.cargo/git/checkouts/gstreamer-rs-79e52a2d27eb91a3/fc2d7fc/gstreamer/src/date_time.rs:316:27
    |
316 |             .and_then(|d| d.to_utc())
    |                           ^^^^^^^^^^
    |                           |
    |                           expected enum `std::result::Result`, found enum `Option`
    |                           help: try using a variant of the expected enum: `Ok(d.to_utc())`
    |
    = note: expected enum `std::result::Result<_, BoolError>`
               found enum `Option<glib::DateTime>`

Do you have a rev that works?

Anyway, thank you again for your help!

Never mind, a cargo update works! Thanks!

1 Like

Feel free to look at https://gitlab.gnome.org/bilelmoussaoui/decoder/ which uses GStreamer’s GTKGLSink along with a custom pipeline :slight_smile:

2 Likes

Thank you for that :smiley:!

I was trying to build gstreamer with the gtk4sink in a Flatpak myself, but I see this was already done :tada:!

The logic to get the gtk4sink is quite straightforward for what I wrote, but the usage of the gtk4glsink makes me wonder, which is better for performance and usage overall, gtk4sink or gtk4glsink ?

It depends on what you’re doing and where your video data comes from. The GL-based on in theory uses less CPU.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.