Centricular

Expertise, Straight from the Source



« Devlog
Taruntej Kanakamalla

GStreamer Rust plugins in the Yocto Project


Using GStreamer's Rust plugins (gst-plugins-rs) on Embedded Linux just became easier, thanks to the new bitbake recipe that is now a part of OpenEmbedded-Core (OE-Core).

Yocto project and OpenEmbedded

The Yocto project has been the de facto provider of build infrastructure for creating custom Linux images, especially for embedded systems, regardless of the hardware architecture.

The OpenEmbedded build framework is the build system used by the Yocto project. It uses Bitbake to execute various build related tasks such as fetching and compiling the code, installing and packaging of the binaries etc. Bitbake executes these tasks according to the instructions provided in the form of a recipe (.bb) and other metadata files (e.g., .bbappend, .inc, .bbclass).

OE-Core contains metadata that comprises foundational recipes, classes, and associated files that are meant to be commonly-used by many different OpenEmbedded-derived systems, including the Yocto Project.

A recipe for Gstreamer Rust plugins

bitbake recipes for GStreamer have already existed in the OE-Core layer for a long time. These recipes build plugins and libraries belonging to various submodules of GStreamer.

We created a new recipe for the GStreamer Rust plugins, which was merged into OE-Core recently.

This recipe was inspired by a pre-existing patch submitted by Bartosz Golaszewski 4 years ago, but significant changes were needed. Some of them are listed below.

  • Use dependencies only from crates.io

    For reproducibility, cargo.bbclass uses the --frozen flag to ensure that cargo doesn't update Cargo.lock and doesn't fetch anything from the network at build time. The necessary fetching is done by bitbake in an earlier step do_fetch, which downloads source code and other files based on the path(s) listed in SRC_URI. Refer “file download support” for more information.

    To add all the plugin dependencies to SRC_URI, we execute update_crates, which is a one-time task that auto-generates a <recipe>-update-crates.inc file. The update_crates function captures the URLs and checksums of the packages present in Cargo.lock, but only those that use the crates.io registry. It ignores all other (for e.g. git-based source) packages.

    By default, some of the dependencies of gst-plugins-rs, such as gstreamer-rs and gtk-rs, point to Git repositories in the manifest (Cargo.toml) and lock (Cargo.lock) files. As a result, they are not added to SRC_URI automatically and are not downloaded during the do_fetch stage unless we add them manually. However, as pointed out in a review comment, all the dependencies should be in the auto-generated gstreamer1.0-plguins-rs-update-crates.inc file and should not be manually specified in SRC_URI.

    To address this problem, starting with gst-plugins-rs release 0.15.3, we changed the root manifest file (Cargo.toml) for workspace dependencies like gstreamer-rs, gtk-rs etc from git repositories to the corresponding crates.io package names.

    It's also worth noting that the plugins gst-plugin-ffv1 and gst-plugin-flavors have been skipped in the recipe because they are not part of gst-plugins-rs releases, and hence do not have crates.io packages.

  • Use cargo-c.bbclass instead of cargo.bbclass

    Switching to cargo-c helped to generate and ship C-ABI compatible libraries and pkg-config files. It also required a minor fix in cargo_c.bbclass to always specify the path to the directory where the library files should be installed, because the default value <prefix>/lib is not the correct lib directory for some targets.

  • Skip recipe for 32-bit x86 platforms without SSE

    The ring crate, which is pulled as a dependency by various plugins, fails on 32-bit x86 platform builds that do not have SSE support. These plugins include reqwest, rswebrtc, quinn etc. It is not trivial to fix this without moving away from the ring dependency, so taking into account the small number of affected users, we decided to skip the recipe for these platforms.

Usage

By default, this recipe ships only the plugins marked essential and important, namely audiofx, closedcaption, file, fallbackswitch, tracers, threadshare, rtp, inter, isobmff, hlssink3, mpegtslive, reqwest, rtsp, webrtc, webrtc-signalling, videofx, webp.

If you want to install some or all of these in your image/rootfs, you can append those package names to IMAGE_INSTALL, f.ex.,

  • IMAGE_INSTALL:append = " gstreamer1.0-plugins-rs-meta" for all plugins in the default-members list, or
  • IMAGE_INSTALL:append = " gstreamer1.0-plugins-rs-audiofx gstreamer1.0-plugins-rs-webrtc gstreamer1.0-plugins-rs-reqwest" for specific plugins

You can also override the PACKAGECONFIG variable to add or remove the plugins from the default list.

Acknowledgements

Finally, a big thanks to the maintainers and reviewers from the OpenEmbedded community as well as my peers at Centricular for their valuable feedback on the patches.

Availability

This recipe is available in the master branch at moment and is expected to be part of the upcoming Yocto project release (Blacksail 6.1). This recipe will not be added to the upstream stable branches (Wrynose/Scarthgap) because Yocto policy dictates that features cannot be backported to a stable release.

If you are keen to use this recipe in the released Yocto branches, it should be straightforward on Wrynose (Yocto release 6.0). Cherry-pick the cargo-c and gstreamer1.0-plugins-rs patches, and use the License expression as per older syntax (expand the below block for the exact diff).

License expression change for Wrynose
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-rs_0.15.3.bb b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-rs_0.15.3.bb
index 1800dfc543..af488e1587 100644
--- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-rs_0.15.3.bb
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-rs_0.15.3.bb
@@ -1,7 +1,7 @@
SUMMARY = "GStreamer Rust Plugins"
HOMEPAGE = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"

-LICENSE = "Apache-2.0 OR MPL-2.0"
+LICENSE = "Apache-2.0 | MPL-2.0"

SRC_URI += "\
git://gitlab.freedesktop.org/gstreamer/gst-plugins-rs;protocol=https;tag=${PV};nobranch=1;name=default \

However, to make it work on Scarthgap (Yocto release 5.0), in addition to the above patches, further work is required - such as bumping up the rust and cargo family recipes to 1.92 (minimum supported version for gst-plugins-rs) or later, and fixing other dependents of the rust/cargo packages.

If you have questions, comments, or if you need any help using this recipe in your project, please feel free to get in touch.


Got any questions or comments?

Get in touch!
Contact us »