GstAppLeakyType in Rust

Hi,

I’ve a simple issue with appsrc in Rust. The following code compiles but raises the error

property ‘leaky-type’ of type ‘GstAppSrc’ can’t be set from the given type (expected: ‘GstAppLeakyType’, got: ‘gint’)

        let appsrc = gst::ElementFactory::make("appsrc")
            .property("name", name)
            .property("format", gst::Format::Time)
            .property("is-live", true)
            .property("leaky-type", gst_app_sys::GST_APP_LEAKY_TYPE_DOWNSTREAM)
            .property("min-latency", latency)
            .property("max-buffers", 100u64)
            .build()
            .unwrap();

I don’t know how to set the leaky-type. The Cargo.toml contains this
gst-app-sys = { version = "0.23.0", package = "gstreamer-app-sys" }

Thanks,
Fabien

try something like appsrc.set_property_from_str("leaky-type", "downstream") ?

Ah yes, sorry I asked about the same question here

However I found another to make the appsrc, which allows me to do appsrc.push_buffer later on

        let appsrc = AppSrc::builder()
            .is_live(true)
            .format(gst::Format::Time)
            .min_latency(cam_latency)
            .build();

But all properties are not there (such as max-buffers)

What’s the preferred way to use appsrc? As a gst_element (but then I need how to I call push_buffer), or as a gst_appsrc (but access to the properties is different)

As a gst element and whenever you need the AppSrc, cast it? let foo = appsrc.dynamic_cast::<AppSrc>().unwrap() ?

It raises this error unfortunately

124 | let appsrc = self.appsrc.dynamic_cast::().unwrap();
| ^^^^^^^^^^^ ------------------------ self.appsrc moved due to this method call
| |
| move occurs because self.appsrc has type gstreamer::Element, which does not implement the Copy trait

But something like this seems to be ok

        let appsrc = gst::ElementFactory::make("appsrc")
            .property("format", gst::Format::Time)
            .property("is-live", true)
            .property_from_str("leaky-type", "2")
            .property("min-latency", cam_latency)
            .property("max-buffers", 100u64)
            .build()
            .unwrap()
            .dynamic_cast::<AppSrc>()
            .unwrap();

You should keep the element around, otherwise how do you add it to the pipeline?

The compilation error can be avoided if you clone the element before casting (iirc), but there might be a cleaner solution.

Yes it’s a member of my class. I can do self.appsrc when I need it

Why do you think it is not there? It’s at least in the docs :slight_smile:

As gst_app::AppSrc so you can use a strongly typed API.

Use dynamic_cast_ref() instead of dynamic_cast(). But as said above, the recommended way is to go via gst_app::AppSrc::builder() etc.

Because of

error[E0599]: no method named `max_buffers` found for struct `AppSrcBuilder` in the current scope
  --> src/gst_av_pipeline.rs:28:14
   |
25 |           let appsrc = AppSrc::builder()
   |  ______________________-
26 | |             .is_live(true)
27 | |             .format(gst::Format::Time)
28 | |             .max_buffers(100)
   | |_____________-^^^^^^^^^^^
   |

I see this in the source code (gstreamer-app-0.23.0/src/app_src.rs)

    #[cfg(feature = "v1_20")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
    pub fn max_buffers(self, max_buffers: u64) -> Self {
        Self {
            builder: self.builder.property("max-buffers", max_buffers),
            ..self
        }
    }

So this feature should be explicitly set in the my Cargo.toml

gst-app = { version = “0.23.0”, package = “gstreamer-app”, features = [“v1_20”] }

Indeed. I’m not sure why that feature requirement doesn’t show up in the docs.