{"id":430,"date":"2017-07-31T17:21:51","date_gmt":"2017-07-31T15:21:51","guid":{"rendered":"https:\/\/coaxion.net\/blog\/?p=430"},"modified":"2017-07-31T17:34:29","modified_gmt":"2017-07-31T15:34:29","slug":"writing-gstreamer-applications-in-rust","status":"publish","type":"post","link":"https:\/\/coaxion.net\/blog\/2017\/07\/writing-gstreamer-applications-in-rust\/","title":{"rendered":"Writing GStreamer Applications in Rust"},"content":{"rendered":"<p><strong>tl;dr:<\/strong> GStreamer bindings for Rust can be found here: <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\" target=\"_blank\">https:\/\/github.com\/sdroege\/gstreamer-rs<\/a><\/p>\n<p>In the last few months since <a href=\"http:\/\/2017.rustfest.eu\/\" target=\"_blank\">RustFest in Kiev<\/a>, I was working (as promised during Luis and my talk at the conference) on creating (mostly autogenerated) <a href=\"https:\/\/www.rust-lang.org\" target=\"_blank\">Rust<\/a> bindings for <a href=\"https:\/\/gstreamer.freedesktop.org\/\" target=\"_blank\">GStreamer<\/a>, with a nice API and properly integrating with <a href=\"http:\/\/gtk-rs.org\" target=\"_blank\">gtk-rs<\/a> and other software. But the main goal was to autogenerate as much as possible with the help of <a href=\"https:\/\/wiki.gnome.org\/Projects\/GObjectIntrospection\" target=\"_blank\">GObject-Introspection<\/a> to keep the maintenance effort low, and re-use \/ have all kinds of infrastructure for GLib\/GObject that already exists in the gtk-rs ecosystem.<\/p>\n<p>There are already GStreamer bindings <a href=\"https:\/\/github.com\/arturoc\/gstreamer1.0-rs\" target=\"_blank\">available<\/a>, which hopefully can be <a href=\"https:\/\/github.com\/arturoc\/gstreamer1.0-rs\/issues\/2#issuecomment-312672817\" target=\"_blank\">replaced by this very soon<\/a>.<\/p>\n<p>Most of the time working on this in the last months was spent on making the <a href=\"https:\/\/github.com\/gtk-rs\/gir\/\" target=\"_blank\">code generator<\/a> work well with GStreamer and add lots of missing features, and also add missing bits and pieces to the <a href=\"https:\/\/github.com\/gtk-rs\/glib\/\" target=\"_blank\">GLib\/GObject<\/a> bindings. That should all be in place now, and now at <a href=\"https:\/\/2017.guadec.org\/\" target=\"_blank\">GUADEC<\/a>, I had some time to finish the last pieces of the GStreamer core API. Every needed piece of the GStreamer core API should be covered now, and lots of pieces that are not needed very often. The code can currently be found <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\" target=\"_blank\">here<\/a>.<\/p>\n<h3>Example code<\/h3>\n<p>There currently is no real documentation available. The goal is the autogenerate this too, from the existing C documentation. But until then, the main GStreamer documentation like the <a href=\"https:\/\/gstreamer.freedesktop.org\/documentation\/application-development\/\" target=\"_blank\">Application Development Manual<\/a> and <a href=\"https:\/\/gstreamer.freedesktop.org\/data\/doc\/gstreamer\/head\/gstreamer\/html\/\" target=\"_blank\">Core API Reference<\/a> should be helpful. Almost everything is mapping 1:1.<\/p>\n<p>I&#8217;ve written some example applications though, which can be found in the <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/master\/examples\/\" target=\"_blank\">same GIT repository<\/a>.<\/p>\n<h4>GTK<\/h4>\n<p>The first example is a <a href=\"https:\/\/www.gtk.org\/\" target=\"_blank\">GTK<\/a> application, using the gtkglsink (or gtksink if no GL support is available) GStreamer elements to show a test video in a GTK window and the current playback position in a GTK label below the video. It&#8217;s using the GLib event loop for handling GTK events (closing the window), timeouts (query position every few hundred ms) and handling the GStreamer messages (errors, etc.).<\/p>\n<p>The code can be found <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/master\/examples\/src\/bin\/gtksink.rs\" target=\"_blank\">here<\/a>.<\/p>\n<h4>Tokio<\/h4>\n<p>The next example is using <a href=\"https:\/\/tokio.rs\/\" target=\"_blank\">Tokio<\/a> instead of the GLib event loop for handling the GStreamer messages. The same should also work with anything else working with <a href=\"https:\/\/github.com\/alexcrichton\/futures-rs\/\" target=\"_blank\">future-rs<\/a>. Tokio is a Rust library for asynchronous IO, based on Futures.<\/p>\n<p>For this to work, a BusStream struct is defined that implements the Stream trait (from future-rs), and produces all messages that are available on the bus. Then this stream is passed to the Tokio Core (basically the event loop) and each message is handled from there.<\/p>\n<p>The code can be found <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/master\/examples\/src\/bin\/tokio.rs\" target=\"_blank\">here<\/a>.<\/p>\n<h4>Pipeline building, Pad Probes, Buffers, Events, Queries, &#8230;<\/h4>\n<p>Various other examples also exist.<\/p>\n<p><a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/master\/examples\/src\/bin\/decodebin.rs\" target=\"_blank\">There is one example<\/a> that is dynamically building a pipeline with decodebin for decoding a file with audio and\/or video.<\/p>\n<p><a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/master\/examples\/src\/bin\/launch.rs\" target=\"_blank\">Another example<\/a> is building a minimal version (without any features other than creating a pipeline from a string and running it) of the gst-launch-1.0 tool. This is not using the GLib main loop for handling the GStreamer messages, but there is a <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/master\/examples\/src\/bin\/launch_glib_main.rs\" target=\"_blank\">slightly modified variant<\/a> of the same example that uses the GLib main loop instead.<\/p>\n<p><a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/master\/examples\/src\/bin\/pad_probes.rs\" target=\"_blank\">Yet another example<\/a> is building a small pipeline with an audio test source, producing a 440Hz sine wave, and calculates the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Root_mean_square\" target=\"_blank\">RMS<\/a> of the audio. For this <a href=\"https:\/\/gstreamer.freedesktop.org\/data\/doc\/gstreamer\/head\/gstreamer\/html\/GstPad.html#gst-pad-add-probe\" target=\"_blank\">a pad probe<\/a> is <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/db1f0f7bfb73e0da4a1fbf04fd39d5d464cf44d2\/examples\/src\/bin\/pad_probes.rs#L22\" target=\"_blank\">installed<\/a> on the source pad of the audio source, and the samples of each buffer are analyzed.<\/p>\n<p>And three last examples are showing how to work with <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/db1f0f7bfb73e0da4a1fbf04fd39d5d464cf44d2\/examples\/src\/bin\/queries.rs#L25\" target=\"_blank\">queries<\/a> and <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/db1f0f7bfb73e0da4a1fbf04fd39d5d464cf44d2\/examples\/src\/bin\/events.rs#L21\" target=\"_blank\">events<\/a>, and a rather boring example that just uses <a href=\"https:\/\/github.com\/sdroege\/gstreamer-rs\/blob\/master\/examples\/src\/bin\/playbin.rs\" target=\"_blank\">playbin<\/a>.<\/p>\n<h3>What next?<\/h3>\n<p>Overall I have to say that using the bindings is already much more convenient and fun than to write any GStreamer code in C. So if you&#8217;re thinking of writing a new GStreamer application and would consider Rust for that: I can highly recommend that \ud83d\ude42<\/p>\n<p>So what comes next. First of all, the next steps would be to make sure that the bindings work for everybody. So if you are using <a href=\"https:\/\/github.com\/arturoc\/gstreamer1.0-rs\" target=\"_blank\">the old bindings<\/a>, or if you want to use GStreamer from Rust, now is a good time to start testing and let me know of any problems, any inconveniences, anything that seems ugly, or anything that is still missing but you need it.<\/p>\n<p>In the meantime I&#8217;m going to make the bindings a full replacement of <a href=\"https:\/\/github.com\/arturoc\/gstreamer1.0-rs\" target=\"_blank\">the old ones<\/a>. For this various non-core GStreamer libraries have to be added too: gstreamer-app, gstreamer-video, gstreamer-audio and gstreamer-pbutils. Hopefully this can all be done over the next few weeks, but at this point all API that is needed to use GStreamer is already available. Only some convenience\/helper API is missing.<\/p>\n<p>And of course my efforts to make it easy to <a href=\"https:\/\/coaxion.net\/blog\/2016\/05\/writing-gstreamer-plugins-and-elements-in-rust\/\" target=\"_blank\">write GStreamer plugins in Rust<\/a> didn&#8217;t end yet. I&#8217;ll continue working on that, and will also move all that over to these bindings too to remove a lot of code duplication.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>tl;dr: GStreamer bindings for Rust can be found here: https:\/\/github.com\/sdroege\/gstreamer-rs In the last few months since RustFest in Kiev, I was working (as promised during Luis and my talk at the conference) on creating (mostly autogenerated) Rust bindings for GStreamer, with a nice API and properly integrating with gtk-rs and other software. But the main &hellip; <a href=\"https:\/\/coaxion.net\/blog\/2017\/07\/writing-gstreamer-applications-in-rust\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Writing GStreamer Applications in Rust<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3,6,5,53],"tags":[],"class_list":["post-430","post","type-post","status-publish","format-standard","hentry","category-free-software","category-gnome","category-gstreamer","category-rust"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/posts\/430","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/comments?post=430"}],"version-history":[{"count":7,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/posts\/430\/revisions"}],"predecessor-version":[{"id":437,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/posts\/430\/revisions\/437"}],"wp:attachment":[{"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/media?parent=430"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/categories?post=430"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coaxion.net\/blog\/wp-json\/wp\/v2\/tags?post=430"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}