Search code examples
rustgstreamergstreamer-rs

Sharing metadata across multiple GStreamer Rust plugins


I'm trying to create my own collection of GStreamer plugins similar to @slomo's repo here. One thing I've run across when using my own metadata is that it only (easily) works within a single plugin. If I duplicate the code within a second plugin, when it attempts to run gst_meta_api_type_register, the result comes back as Invalid, since it's already been registered, but there doesn't seem to be a way to retrieve that already-registered Type. Based on this discussion, it seems the solution may be to have a separate shared library that registers the metadata format once and that both of my plugins can reference, but I'm unsure how to set this up in Rust.


Solution

  • After much frustration, I’ve found a solution that actually avoids the need for a separate shared library. The gst_meta_api_type_register function still returns Invalid if the Type has already been registered, but GLib Types can be retrieved by name, so that’s what my code does, and I’ve updated the relevant method to look like

    // Function to register the meta API and get a type back.
    pub(super) fn bbox_meta_api_get_type() -> gst::glib::Type {
        static TYPE: Lazy<gst::glib::Type> = Lazy::new(|| unsafe {
            let t = from_glib(gst::ffi::gst_meta_api_type_register(
                b"BboxMetaAPI\0".as_ptr() as *const _,
                // We provide no tags here as our meta is just values and does
                // not refer to any specific aspect of the buffer.
                [ptr::null::<std::os::raw::c_char>()].as_ptr() as *mut *const _,
            ));
    
            // Return newly registered type, or existing type if previously registered
            if t != gst::glib::Type::INVALID {
                t
            } else {
                gst::glib::Type::from_name("BboxMetaAPI").unwrap()
            }
        });
    
        *TYPE
    }
    

    So now the first plugin that tries to use the metadata registers it, and the second one gets the retrieved Type. This code lives in a separate module that is a dependency of both plugins.