<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Base-Art - GStreamer</title><link href="https://base-art.net/" rel="alternate"></link><link href="https://base-art.net/feeds/tag-gstreamer.atom.xml" rel="self"></link><id>https://base-art.net/</id><updated>2024-04-16T22:15:00+02:00</updated><entry><title>From WebKit/GStreamer to rust-av, a journey on our stack’s layers</title><link href="https://base-art.net/Articles/from-webkitgstreamer-to-rust-av-a-journey-on-our-stacks-layers/" rel="alternate"></link><published>2024-04-16T22:15:00+02:00</published><updated>2024-04-16T22:14:33+02:00</updated><author><name>Philippe Normand</name></author><id>tag:base-art.net,2024-04-16:/Articles/from-webkitgstreamer-to-rust-av-a-journey-on-our-stacks-layers/</id><summary type="html">&lt;p&gt;In this post I&amp;#8217;ll try to document the journey starting from a WebKit issue and
ending up improving third-party projects that WebKitGTK and WPEWebKit depend&amp;nbsp;on.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been working on WebKit&amp;#8217;s GStreamer backends for a while. Usually some new
feature needed on WebKit side would trigger work …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In this post I&amp;#8217;ll try to document the journey starting from a WebKit issue and
ending up improving third-party projects that WebKitGTK and WPEWebKit depend&amp;nbsp;on.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been working on WebKit&amp;#8217;s GStreamer backends for a while. Usually some new
feature needed on WebKit side would trigger work on GStreamer. That&amp;#8217;s quite
common and healthy actually, by improving GStreamer (bug fixes or implementing
new features) we make the whole stack stronger (hopefully). It&amp;#8217;s not hard to
imagine other web-engines, such as Servo for instance, leveraging fixes made in
GStreamer in the context of WebKit&amp;nbsp;use-cases.&lt;/p&gt;
&lt;p&gt;Sometimes though we have to go deeper and this is what this post is&amp;nbsp;about!&lt;/p&gt;
&lt;p&gt;Since version 2.44, WebKitGTK and WPEWebKit ship with a
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API"&gt;WebCodecs&lt;/a&gt;
backend. That backend leverages the wide range of GStreamer audio and video
decoders/encoders to give low-level access to encoded (or decoded) audio/video
frames to Web developers. I delivered a &lt;a href="https://gstconf.ubicast.tv/videos/webcodecs-in-webkit-with-gstreamer/"&gt;lightning
talk&lt;/a&gt; at
gst-conf 2023 about this&amp;nbsp;topic.&lt;/p&gt;
&lt;p&gt;There are still some issues to fix regarding performance and some &lt;span class="caps"&gt;W3C&lt;/span&gt; web
platform tests are still failing. The &lt;span class="caps"&gt;AV1&lt;/span&gt; decoding tests were flagged early on
while I was working on WebCodecs, I didn&amp;#8217;t have time back then to investigate
the failures further, but a couple weeks ago I went back to those specific&amp;nbsp;issues.&lt;/p&gt;
&lt;p&gt;The WebKit layout tests harness is executed by various post-commit bots, on
various platforms. The WebKitGTK and WPEWebKit bots run on Linux. The WebCodec
tests for &lt;span class="caps"&gt;AV1&lt;/span&gt; currently make use of the GStreamer &lt;code&gt;av1enc&lt;/code&gt; and
&lt;a href="https://gstreamer.freedesktop.org/documentation/dav1d"&gt;dav1ddec&lt;/a&gt; elements. We
currently don&amp;#8217;t run the tests using the modern and hardware-accelerated
&lt;code&gt;vaav1enc&lt;/code&gt; and &lt;code&gt;vaav1dec&lt;/code&gt; elements because the bots don&amp;#8217;t have compatible&amp;nbsp;GPUs.&lt;/p&gt;
&lt;p&gt;The decoding tests were failing, &lt;a href="https://github.com/WebKit/WebKit/tree/main/LayoutTests/imported/w3c/web-platform-tests/webcodecs/full-cycle-test.https.any.js"&gt;this
one&lt;/a&gt;
for instance (the &lt;code&gt;?av1&lt;/code&gt; variant). In that test both encoding and decoding are
tested, but decoding was failing, for a couple reasons. Rabbit hole starts here.
After debugging this for a while, it was clear that the colorspace information
was lost between the encoded chunks and the decoded frames. The decoded video
frames didn&amp;#8217;t have the expected colorimetry&amp;nbsp;values.&lt;/p&gt;
&lt;p&gt;The
&lt;a href="https://github.com/WebKit/WebKit/blob/main/Source/WebCore/platform/graphics/gstreamer/VideoDecoderGStreamer.h"&gt;VideoDecoderGStreamer&lt;/a&gt;
class basically takes encoded chunks and notifies decoded
&lt;a href="https://github.com/WebKit/WebKit/blob/main/Source/WebCore/platform/graphics/gstreamer/VideoFrameGStreamer.h"&gt;VideoFrameGStreamer&lt;/a&gt;
objects to the upper layers (&lt;span class="caps"&gt;JS&lt;/span&gt;) in WebCore. A video frame is basically a
GstSample (Buffer and Caps) and we have code in place to interpret the
colorimetry parameters exposed in the sample caps and translate those to the
various WebCore equivalents. So far so good, but the caps set on the &lt;code&gt;dav1ddec&lt;/code&gt;
elements didn&amp;#8217;t have those informations! I thought the &lt;code&gt;dav1ddec&lt;/code&gt; element could
be fixed, &amp;#8220;shouldn&amp;#8217;t be that hard&amp;#8221; and I knew that code because I wrote it in
2018&amp;nbsp;:)&lt;/p&gt;
&lt;p&gt;So let&amp;#8217;s fix the GStreamer &lt;code&gt;dav1ddec&lt;/code&gt; element. It&amp;#8217;s a video decoder written in
Rust, relying on the &lt;a href="https://github.com/rust-av/dav1d-rs"&gt;dav1d-rs&lt;/a&gt; bindings of
the popular C &lt;code&gt;libdav1d&lt;/code&gt; library. The &lt;code&gt;dav1ddec&lt;/code&gt; element basically feeds encoded
chunks of data to dav1d using the dav1d-rs bindings. In return, the bindings
provide the decoded frames using a &lt;code&gt;Dav1dPicture&lt;/code&gt; Rust structure and the
&lt;code&gt;dav1ddec&lt;/code&gt; GStreamer element basically makes buffers and caps out of this
decoded picture. The dav1d-rs bindings are quite minimal, we implemented &lt;span class="caps"&gt;API&lt;/span&gt; on
a per-need basis so far, so it wasn&amp;#8217;t very surprising that&amp;#8230; colorimetry
information for decoded pictures was not exposed! Rabbit hole goes one level&amp;nbsp;deeper.&lt;/p&gt;
&lt;p&gt;So let&amp;#8217;s add colorimetry &lt;span class="caps"&gt;API&lt;/span&gt; in &lt;code&gt;dav1d-rs&lt;/code&gt;. When working on (Rust) bindings of a
C library, if you need to expose additional &lt;span class="caps"&gt;API&lt;/span&gt; the answer is quite often in the
C headers of the library. Every &lt;code&gt;Dav1dPicture&lt;/code&gt; has a &lt;code&gt;Dav1dSequenceHeader&lt;/code&gt;, in
which we can see a few interesting&amp;nbsp;fields:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Dav1dSequenceHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;enum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dav1dColorPrimaries&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;///&amp;lt; color primaries (av1)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;enum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dav1dTransferCharacteristics&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;trc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;///&amp;lt; transfer characteristics (av1)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;enum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dav1dMatrixCoefficients&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mtrx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;///&amp;lt; matrix coefficients (av1)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;enum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dav1dChromaSamplePosition&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;///&amp;lt; chroma sample position (av1)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;uint8_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;color_range&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dav1dSequenceHeader&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After sharing a naive branch with rust-av co-maintainers &lt;a href="https://github.com/lu-zero"&gt;Luca
Barbato&lt;/a&gt; and &lt;a href="https://github.com/sdroege"&gt;Sebastian
Dröge&lt;/a&gt;, I came up with a
&lt;a href="https://github.com/rust-av/dav1d-rs/pull/94"&gt;couple&lt;/a&gt;
&lt;a href="https://github.com/rust-av/dav1d-rs/pull/97"&gt;pull-requests&lt;/a&gt; that eventually
were shipped in version 0.10.3 of dav1d-rs. I won&amp;#8217;t deny matching primaries,
transfer, matrix and chroma-site enum values to &lt;code&gt;rust-av&lt;/code&gt;&lt;span class="quo"&gt;&amp;#8216;&lt;/span&gt;s Pixel enum was a bit
challenging :P Anyway, with &lt;code&gt;dav1d-rs&lt;/code&gt; fixed up, rabbit hole level goes up one
level&amp;nbsp;:)&lt;/p&gt;
&lt;p&gt;Now with the needed &lt;code&gt;dav1d-rs&lt;/code&gt; &lt;span class="caps"&gt;API&lt;/span&gt;, the GStreamer &lt;code&gt;dav1ddec&lt;/code&gt; element could be
fixed. Again, matching the various enum values to their GStreamer equivalent was
an interesting exercise. The &lt;a href="https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1514"&gt;merge
request&lt;/a&gt;
was merged, but to this date it&amp;#8217;s not shipped in a stable gst-plugins-rs release
yet. There&amp;#8217;s one more complication here, &lt;span class="caps"&gt;ABI&lt;/span&gt; broke between &lt;code&gt;dav1d&lt;/code&gt; 1.2 and 1.4
versions. The &lt;code&gt;dav1d-rs&lt;/code&gt; 0.10.3 release expects the latter. I&amp;#8217;m not sure how we
will cope with that in terms of gst-plugins-rs release&amp;nbsp;versioning&amp;#8230;&lt;/p&gt;
&lt;p&gt;Anyway, WebKit&amp;#8217;s runtime environment can be adapted to ship dav1d 1.4 and
development version of the &lt;code&gt;dav1ddec&lt;/code&gt; element, which is what was done in this
&lt;a href="https://github.com/WebKit/WebKit/pull/27218"&gt;pull request&lt;/a&gt;. The rabbit is
getting out of his&amp;nbsp;hole.&lt;/p&gt;
&lt;p&gt;The WebCodec &lt;span class="caps"&gt;AV1&lt;/span&gt; tests were finally fixed in WebKit, by this &lt;a href="https://github.com/WebKit/WebKit/pull/27230"&gt;pull
request&lt;/a&gt;. Beyond colorimetry
handling a few more fixes were needed, but luckily those didn&amp;#8217;t require any
fixes outside of&amp;nbsp;WebKit.&lt;/p&gt;
&lt;p&gt;Wrapping up, if you&amp;#8217;re still reading this post, I thank you for your patience.
Working on inter-connected projects can look a bit daunting at times, but
eventually the whole ecosystem benefits from cross-project collaborations like
this one. Thanks to Luca and Sebastian for the help and reviews in &lt;code&gt;dav1d-rs&lt;/code&gt;
and the &lt;code&gt;dav1ddec&lt;/code&gt; element. Thanks to my fellow &lt;a href="https://igalia.com"&gt;Igalia&lt;/a&gt;
colleagues for the WebKit&amp;nbsp;reviews.&lt;/p&gt;</content><category term="misc"></category><category term="Projects"></category><category term="WebKit"></category><category term="GStreamer"></category></entry><entry><title>WebRTC in WebKitGTK and WPE, status updates, part I</title><link href="https://base-art.net/Articles/webrtc-in-webkitgtk-and-wpe-status-updates-part-i/" rel="alternate"></link><published>2023-02-16T21:30:00+01:00</published><updated>2023-02-16T21:19:35+01:00</updated><author><name>Philippe Normand</name></author><id>tag:base-art.net,2023-02-16:/Articles/webrtc-in-webkitgtk-and-wpe-status-updates-part-i/</id><summary type="html">&lt;script type="module"&gt;
    import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
    mermaid.initialize({ startOnLoad: true });
&lt;/script&gt;

&lt;p&gt;Some time ago we at &lt;a href="https://igalia.com"&gt;Igalia&lt;/a&gt; embarked on the journey to ship
a &lt;a href="https://gstreamer.freedesktop.org"&gt;GStreamer&lt;/a&gt;-powered WebRTC backend. This is
a long journey, it is not over, but we made some progress …&lt;/p&gt;</summary><content type="html">&lt;script type="module"&gt;
    import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
    mermaid.initialize({ startOnLoad: true });
&lt;/script&gt;

&lt;p&gt;Some time ago we at &lt;a href="https://igalia.com"&gt;Igalia&lt;/a&gt; embarked on the journey to ship
a &lt;a href="https://gstreamer.freedesktop.org"&gt;GStreamer&lt;/a&gt;-powered WebRTC backend. This is
a long journey, it is not over, but we made some progress. This post is the
first of a series providing some insights of the challenges we are facing and
the plans for the next release&amp;nbsp;cycle(s).&lt;/p&gt;
&lt;p&gt;Most web-engines nowadays bundle a version of &lt;a href="https://webrtc.org/"&gt;LibWebRTC&lt;/a&gt;,
it is indeed a pragmatic approach. WebRTC is a huge spec, spanning across many
protocols, RFCs and codecs. LibWebRTC is in fact a multimedia framework on its
own, and it&amp;#8217;s a very big code-base. I still remember the suprised face of
&lt;a href="https://crisal.io/"&gt;Emilio&lt;/a&gt; at the &lt;a href="https://webengineshackfest.org/2022/"&gt;2022 WebEngines
conference&lt;/a&gt; when I told him we had unusual
plans regarding WebRTC support in GStreamer WebKit ports. There are several
reasons for this plan, explained in the &lt;a href="https://wpewebkit.org/about/faq.html"&gt;&lt;span class="caps"&gt;WPE&lt;/span&gt;
&lt;span class="caps"&gt;FAQ&lt;/span&gt;&lt;/a&gt;. We worked on a LibWebRTC backend for
the WebKit GStreamer ports, my colleague Thibault Saunier &lt;a href="https://blogs.gnome.org/tsaunier/2018/07/31/webkitgtk-and-wpe-gains-webrtc-support-back/"&gt;blogged about
it&lt;/a&gt;
but unfortunately this backend has remained disabled by default and not shipped
in the tarballs, for the reasons explained in the &lt;span class="caps"&gt;WPE&lt;/span&gt; &lt;span class="caps"&gt;FAQ&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The GStreamer project nowadays provides a library and a plugin allowing
applications to interact with third-party WebRTC actors. This is in my opinion a
paradigm shift, because it enables new ways of interoperability between the
so-called Web and traditional native applications. Since the GstWebRTC
announcement back in late 2017 I&amp;#8217;ve been experimenting with the idea of shipping
an alternative to LibWebRTC in WebKitGTK and &lt;span class="caps"&gt;WPE&lt;/span&gt;. The &lt;a href="https://github.com/WebKit/WebKit/commit/a530847a7ce739e1b8b7a55cf1f5ae41a0938a11"&gt;initial GstWebRTC WebKit
backend&lt;/a&gt;
was merged upstream on March 18,&amp;nbsp;2022.&lt;/p&gt;
&lt;p&gt;As you might already know, before any audio/video call, your browser might ask
permission to access your webcam/microphone and even during the call you can now
share your screen. From the WebKitGTK/&lt;span class="caps"&gt;WPE&lt;/span&gt; perspective the procedure is the same
of course. Let&amp;#8217;s dive&amp;nbsp;in.&lt;/p&gt;
&lt;h2&gt;WebCam/Microphone&amp;nbsp;capture&lt;/h2&gt;
&lt;p&gt;Back in 2018 for the LibWebRTC backend, Thibault added support for
GStreamer-powered media capture to WebKit, meaning that capture devices such as
microphones and webcams would be accessible from WebKit applications using the
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia"&gt;getUserMedia&lt;/a&gt;
spec. Under the hood, a GStreamer source element is created, using the
&lt;a href="https://gstreamer.freedesktop.org/documentation/gstreamer/gstdevice.html?gi-language=c"&gt;GstDevice&lt;/a&gt;
&lt;span class="caps"&gt;API&lt;/span&gt;. This implementation is now re-used for the GstWebRTC backend, it works
fine, still has room for improvements but that&amp;#8217;s a topic for a follow-up&amp;nbsp;post.&lt;/p&gt;
&lt;p&gt;A MediaStream can be rendered in a &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; element, through a
custom GStreamer source element that we also provide in WebKit, this is all
internally wired up so that the following &lt;span class="caps"&gt;JS&lt;/span&gt; code will trigger the WebView in
natively capturing and rendering a WebCam device using&amp;nbsp;GStreamer:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mediaDevices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getUserMedia&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;mediaStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;video&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;srcObject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mediaStream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onloadedmetadata&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;video&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When this WebPage is rendered and after the user has granted access to capture
devices, the GStreamer backends will create not one, but two&amp;nbsp;pipelines.&lt;/p&gt;
&lt;pre class="mermaid"&gt;
flowchart LR
    pipewiresrc--&gt;videoscale--&gt;videoconvert--&gt;videorate--&gt;valve--&gt;appsink
&lt;/pre&gt;

&lt;pre class="mermaid"&gt;
flowchart LR
    subgraph mediastreamsrc
    appsrc--&gt;srcghost[src]
    end
    subgraph playbin3
       subgraph decodebin3
       end
       subgraph webkitglsink
       end
       decodebin3--&gt;webkitglsink
    end
    srcghost--&gt;decodebin3
&lt;/pre&gt;

&lt;p&gt;The first pipeline routes video frames from the capture device using
&lt;code&gt;pipewiresrc&lt;/code&gt; to an &lt;code&gt;appsink&lt;/code&gt;. From the &lt;code&gt;appsink&lt;/code&gt; our capturer leveraging the
Observer design pattern notifies its observers. In this case there is only one
observer which is a GStreamer source element internal to WebKit called
&lt;code&gt;mediastreamsrc&lt;/code&gt;. The playback pipeline shown above is heavily simplified, in
reality more elements are involved, but what matters most is that thanks to the
flexibility of Gstreamer, we can leverage the existing MediaPlayer backend that
we at Igalia have been maintaining for more than 10 years, to render
MediaStreams. All we needed was a custom source element, the rest of our
MediaPlayer didn&amp;#8217;t need much changes to support this&amp;nbsp;use-case.&lt;/p&gt;
&lt;p&gt;One notable change we did since the initial implementation though is that for us
a MediaStream can be either raw, encoded or even encapsulated in a &lt;span class="caps"&gt;RTP&lt;/span&gt; payload. So
depending on which component is going to render the MediaStream, we have enough
flexibility to allow zero-copy, in most scenarios. In the example above,
typically the stream will be raw from source to renderer. However, some webcams
can provide encoded streams. &lt;span class="caps"&gt;WPE&lt;/span&gt; and WebKitGTK will be able to internally
leverage these and in some cases allow for direct streaming from hardware device
to outgoing PeerConnection without third-party&amp;nbsp;encoding.&lt;/p&gt;
&lt;h2&gt;Desktop&amp;nbsp;capture&lt;/h2&gt;
&lt;p&gt;There is another &lt;span class="caps"&gt;JS&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;, allowing to capture from your screen or a window,
called
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia"&gt;getDisplayMedia&lt;/a&gt;,
and yes, we also support it! Thanks to these recent years ground-breaking
progress of the Linux Desktop such as &lt;a href="https://pipewire.org"&gt;PipeWire&lt;/a&gt; and
&lt;a href="https://flatpak.github.io/xdg-desktop-portal/"&gt;xdg-desktop-portal&lt;/a&gt; we can now
stream your favorite desktop environment over WebRTC. Under the hood when the
WebView is granted access to the desktop capture through the portal, our backend
creates a &lt;code&gt;pipewiresrc&lt;/code&gt; GStreamer element, configured to source from the file
descriptor provided by the portal, and we have a healthy raw video&amp;nbsp;stream.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a &lt;a href="https://www.youtube.com/live/fAbbiyRnJ6I"&gt;demo&lt;/a&gt;:&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/fAbbiyRnJ6I" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen&gt;&lt;/iframe&gt;

&lt;h2&gt;WebAudio&amp;nbsp;capture&lt;/h2&gt;
&lt;p&gt;What more, yes you can also create a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamAudioDestinationNode"&gt;MediaStream from a WebAudio
node&lt;/a&gt;.
On the backend side, the
&lt;a href="https://github.com/WebKit/WebKit/blob/main/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceGStreamer.cpp"&gt;GStreamerMediaStreamAudioSource&lt;/a&gt;
fills GstBuffers from the audio bus channels and notifies third-parties
internally observing the MediaStream, such as outgoing media sources, or simply
an &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; element that was configured to source from the given MediaStream. I
have no demo for this, you&amp;#8217;ll have to take my&amp;nbsp;word.&lt;/p&gt;
&lt;h2&gt;Canvas&amp;nbsp;capture&lt;/h2&gt;
&lt;p&gt;But wait there is more. Did I hear canvas? Yes we can feed your favorite
&lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; to a MediaStream. The &lt;span class="caps"&gt;JS&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; is called
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/captureStream"&gt;captureStream&lt;/a&gt;,
&lt;a href="https://github.com/WebKit/WebKit/blob/main/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp"&gt;its code is actually
cross-platform&lt;/a&gt;
but defers to the &lt;code&gt;HTMLCanvasElement::toVideoFrame()&lt;/code&gt; method which has a
GStreamer implementation. The code is not the most optimal yet though due to
shortcomings of our current graphics pipeline implementation. Here is a &lt;a href="https://www.youtube.com/live/gW0OzeRpzeU"&gt;demo of
Canvas to WebRTC&lt;/a&gt; running in the
WebKitGTK&amp;nbsp;MiniBrowser:&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/gW0OzeRpzeU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen&gt;&lt;/iframe&gt;

&lt;h2&gt;Wrap-up&lt;/h2&gt;
&lt;p&gt;So we&amp;#8217;ve got MediaStream support covered. This is only one part of the puzzle
though. We are facing challenges now on the
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection"&gt;PeerConnection&lt;/a&gt;
implementation. MediaStreams are cool but it&amp;#8217;s even better when you can share
them with your friends on the fancy A/V conferencing websites, but we&amp;#8217;re not
entirely ready for this yet in WebKitGTK and &lt;span class="caps"&gt;WPE&lt;/span&gt;. For this reason, WebRTC is not
yet enabled by default in the upcoming WebKitGTK and &lt;span class="caps"&gt;WPE&lt;/span&gt; 2.40 releases. We&amp;#8217;re
just not there yet. In the next part of these series I&amp;#8217;ll tackle the
PeerConnection backend on which we&amp;#8217;re working hard on these days, both in WebKit
and in&amp;nbsp;GStreamer.&lt;/p&gt;
&lt;p&gt;Happy hacking and as always, all my gratitude goes to my fellow
&lt;a href="https://igalia.com"&gt;Igalia&lt;/a&gt; comrades for allowing me to keep working on these
domains and to Metrological for funding some of this work. Is your organization
or company interested in leveraging modern WebRTC APIs from WebKitGTK and/or
&lt;span class="caps"&gt;WPE&lt;/span&gt;? If so please &lt;a href="https://www.igalia.com/contact/"&gt;get in touch with us&lt;/a&gt; in
order to help us speed-up the implementation&amp;nbsp;work.&lt;/p&gt;</content><category term="misc"></category><category term="Projects"></category><category term="WebKit"></category><category term="GStreamer"></category></entry><entry><title>Catching up on WebKit GStreamer WebAudio backends maintenance</title><link href="https://base-art.net/Articles/catching-up-on-webkit-gstreamer-webaudio-backends-maintenance/" rel="alternate"></link><published>2020-11-29T13:45:00+01:00</published><updated>2020-11-29T13:45:00+01:00</updated><author><name>Philippe Normand</name></author><id>tag:base-art.net,2020-11-29:/Articles/catching-up-on-webkit-gstreamer-webaudio-backends-maintenance/</id><summary type="html">&lt;p&gt;Over the past few months the WebKit development team has been working on
modernizing support for the &lt;a class="reference external" href="https://www.w3.org/TR/webaudio/"&gt;WebAudio&lt;/a&gt; specification. This post highlights some
of the changes that were recently merged, focusing on the GStreamer&amp;nbsp;ports.&lt;/p&gt;
&lt;p&gt;My fellow WebKit colleague, Chris Dumez, has been very active lately, updating
the WebAudio implementation …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Over the past few months the WebKit development team has been working on
modernizing support for the &lt;a class="reference external" href="https://www.w3.org/TR/webaudio/"&gt;WebAudio&lt;/a&gt; specification. This post highlights some
of the changes that were recently merged, focusing on the GStreamer&amp;nbsp;ports.&lt;/p&gt;
&lt;p&gt;My fellow WebKit colleague, Chris Dumez, has been very active lately, updating
the WebAudio implementation for the mac ports in order to comply with the latest
changes of the specification. His contributions have been documented in the
Safari Technology Preview release notes for &lt;a class="reference external" href="https://webkit.org/blog/11294/release-notes-for-safari-technology-preview-113/"&gt;version 113&lt;/a&gt;, &lt;a class="reference external" href="https://webkit.org/blog/11294/release-notes-for-safari-technology-preview-114/"&gt;version 114&lt;/a&gt;,
&lt;a class="reference external" href="https://webkit.org/blog/11294/release-notes-for-safari-technology-preview-115/"&gt;version 115&lt;/a&gt; and &lt;a class="reference external" href="https://webkit.org/blog/11294/release-notes-for-safari-technology-preview-116/"&gt;version 116&lt;/a&gt;. This is great for the WebKit project! Since
the initial implementation landed around 2011, there wasn&amp;#8217;t much activity and
over the years our implementation started lagging behind other web engines in
terms of features and spec compliance. So, many thanks Chris, I think you&amp;#8217;re
making a lot of WebAudio web developers very happy these days&amp;nbsp;:)&lt;/p&gt;
&lt;p&gt;The flip side of the coin is that some of these changes broke the GStreamer
backends, as Chris is focusing mostly on the Apple ports, a few bugs slipped in,
noticed by the &lt;span class="caps"&gt;CI&lt;/span&gt; test bots and dutifully &lt;a class="reference external" href="https://trac.webkit.org/wiki/WebKitGTK/Gardening/Howto"&gt;gardened&lt;/a&gt; by our bots sheriffs. &lt;a class="reference external" href="https://base-art.net/Articles/1/"&gt;Those
backends were upstreamed in 2012&lt;/a&gt; and since then I didn&amp;#8217;t devote much time to
their maintenance, aside from casual&amp;nbsp;bug-fixing.&lt;/p&gt;
&lt;p&gt;One of the WebAudio features recently supported by WebKit is &lt;a class="reference external" href="https://webaudio.github.io/web-audio-api/#audioworklet"&gt;the Audio Worklet
interface&lt;/a&gt; which allows applications to perform audio processing in a dedicated
thread, thus relieving some pressure off the main thread and ensuring a
glitch-free WebAudio rendering. I added support for this feature in &lt;a class="reference external" href="https://trac.webkit.org/changeset/268579"&gt;r268579&lt;/a&gt;.
Folks eager to test this can try the &lt;span class="caps"&gt;GTK&lt;/span&gt; nightly MiniBrowser with the&amp;nbsp;demos:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ wget https://trac.webkit.org/export/270226/webkit/trunk/Tools/Scripts/webkit-flatpak-run-nightly
$ chmod +x webkit-flatpak-run-nightly
$ python3 webkit-flatpak-run-nightly --gtk MiniBrowser https://googlechromelabs.github.io/web-audio-samples/audio-worklet/
&lt;/pre&gt;
&lt;p&gt;For many years our AudioFileReader implementation was limited to mono and stereo
audio layouts. This limitation was lifted off in &lt;a class="reference external" href="https://trac.webkit.org/changeset/269104"&gt;r269104&lt;/a&gt; allowing for
processing of up to 5.1 surround audio files in the &lt;a class="reference external" href="https://www.w3.org/TR/webaudio/#AudioBufferSourceNode"&gt;AudioBufferSourceNode&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Our AudioDestination, used for audio playback, was only able to render stereo.
It is now able to probe the GStreamer platform audio sink for the maximum number
of channels it can handle, since &lt;a class="reference external" href="https://trac.webkit.org/changeset/268727"&gt;r268727&lt;/a&gt;. Support for &lt;a class="reference external" href="https://www.w3.org/TR/webaudio/#dom-audiocontext-getoutputtimestamp"&gt;AudioContext
getOutputTimestamp&lt;/a&gt; was hooked up in the GStreamer backend in &lt;a class="reference external" href="https://trac.webkit.org/changeset/266109"&gt;r266109&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The WebAudio spec has a &lt;a class="reference external" href="https://www.w3.org/TR/webaudio/#mediastreamaudiosourcenode"&gt;MediaStreamAudioDestinationNode&lt;/a&gt; for MediaStreams,
allowing to feed audio samples coming from the WebAudio pipeline to outgoing
WebRTC streams. Since &lt;a class="reference external" href="https://trac.webkit.org/changeset/269827"&gt;r269827&lt;/a&gt; the GStreamer ports now support this feature as
well! Similarly, incoming WebRTC streams or capture devices can stream their
audio samples to a WebAudio pipeline, this has been supported for a couple years
already, contributed by my colleague Thibault&amp;nbsp;Saunier.&lt;/p&gt;
&lt;p&gt;Our GStreamer FFTFrame implementation was broken for a few weeks, while Chris
was landing various improvements for the platform-agnostic and mac-specific
implementations. I finally fixed it in &lt;a class="reference external" href="https://trac.webkit.org/changeset/267471"&gt;r267471&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is only the tip of the iceberg. A few more patches were merged, including
some security-related bug-fixes. As the Web Platform keeps growing, supporting
more and more multimedia-related use-cases, we, at the &lt;a class="reference external" href="https://www.igalia.com/technology/multimedia"&gt;Igalia Multimedia team&lt;/a&gt;,
are committed to maintain our position as GStreamer experts in the WebKit&amp;nbsp;community.&lt;/p&gt;
</content><category term="misc"></category><category term="Projects"></category><category term="GStreamer"></category><category term="WebKit"></category></entry><entry><title>Web-augmented graphics overlay broadcasting with WPE and GStreamer</title><link href="https://base-art.net/Articles/web-augmented-graphics-overlay-broadcasting-with-wpe-and-gstreamer/" rel="alternate"></link><published>2020-07-02T15:00:00+02:00</published><updated>2020-07-02T15:00:00+02:00</updated><author><name>Philippe Normand</name></author><id>tag:base-art.net,2020-07-02:/Articles/web-augmented-graphics-overlay-broadcasting-with-wpe-and-gstreamer/</id><summary type="html">&lt;p&gt;Graphics overlays are everywhere nowadays in the live video broadcasting
industry. In this post I introduce a new demo relying on &lt;a class="reference external" href="https://gstreamer.freedesktop.org"&gt;GStreamer&lt;/a&gt; and
&lt;a class="reference external" href="https://wpewebkit.org"&gt;WPEWebKit&lt;/a&gt; to deliver low-latency web-augmented video&amp;nbsp;broadcasts.&lt;/p&gt;
&lt;p&gt;Readers of this blog might remember a few posts about &lt;a class="reference external" href="https://wpewebkit.org"&gt;WPEWebKit&lt;/a&gt; and a
&lt;a class="reference external" href="https://gstreamer.freedesktop.org"&gt;GStreamer&lt;/a&gt; element we at &lt;a class="reference external" href="https://igalia.com"&gt;Igalia&lt;/a&gt; worked on …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Graphics overlays are everywhere nowadays in the live video broadcasting
industry. In this post I introduce a new demo relying on &lt;a class="reference external" href="https://gstreamer.freedesktop.org"&gt;GStreamer&lt;/a&gt; and
&lt;a class="reference external" href="https://wpewebkit.org"&gt;WPEWebKit&lt;/a&gt; to deliver low-latency web-augmented video&amp;nbsp;broadcasts.&lt;/p&gt;
&lt;p&gt;Readers of this blog might remember a few posts about &lt;a class="reference external" href="https://wpewebkit.org"&gt;WPEWebKit&lt;/a&gt; and a
&lt;a class="reference external" href="https://gstreamer.freedesktop.org"&gt;GStreamer&lt;/a&gt; element we at &lt;a class="reference external" href="https://igalia.com"&gt;Igalia&lt;/a&gt; worked on. In december 2018 I &lt;a class="reference external" href="https://base-art.net/Articles/web-overlay-in-gstreamer-with-wpewebkit/"&gt;introduced
GstWPE&lt;/a&gt; and a few months later blogged about a &lt;a class="reference external" href="https://base-art.net/Articles/html-overlays-with-gstwpe-the-demo/"&gt;proof-of-concept application&lt;/a&gt;
I wrote for it. So, learning from this first iteration, I wrote another&amp;nbsp;demo!&lt;/p&gt;
&lt;p&gt;The first demo was already quite cool, but had a few&amp;nbsp;down-sides:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;It works only on desktop (running in a Wayland compositor). The Wayland
compositor dependency can be a burden in some cases. Ideally we could
imaginge GstWPE applications running &amp;#8220;in the cloud&amp;#8221;, on machines without &lt;span class="caps"&gt;GPU&lt;/span&gt;,
bare&amp;nbsp;metal.&lt;/li&gt;
&lt;li&gt;While it was cool to stream to Twitch, Youtube and the like, these platforms
currently can ingest only &lt;span class="caps"&gt;RTMP&lt;/span&gt; streams. That means the latency introduced can
be quite significant, depending on the network conditions of course, but even
in ideal conditions the latency was between one and 2 seconds. This is not
great, in the world we live&amp;nbsp;in.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To address the first point, &lt;span class="caps"&gt;WPE&lt;/span&gt; founding engineer, &lt;a class="reference external" href="https://blogs.igalia.com/zdobersek/"&gt;Žan Doberšek&lt;/a&gt; enabled
software rasterizing support in &lt;span class="caps"&gt;WPE&lt;/span&gt; and its &lt;a class="reference external" href="https://github.com/igalia/wpebackend-fdo"&gt;&lt;span class="caps"&gt;FDO&lt;/span&gt; backend&lt;/a&gt;. This is great because
it allows &lt;span class="caps"&gt;WPE&lt;/span&gt; to run on machines without &lt;span class="caps"&gt;GPU&lt;/span&gt; (like continuous integration
builders, test bots) but also &amp;#8220;in the cloud&amp;#8221; where machines with &lt;span class="caps"&gt;GPU&lt;/span&gt; are less
affordable than bare metal! Following up, I enabled this feature in GstWPE. The
source element caps template now has &lt;cite&gt;video/x-raw&lt;/cite&gt;, in addition to
&lt;cite&gt;video/x-raw(memory:GLMemory)&lt;/cite&gt;. To force swrast, you need to set the
&lt;cite&gt;LIBGL_ALWAYS_SOFTWARE=true&lt;/cite&gt; environment variable. The downside of swrast is
that you need a good &lt;span class="caps"&gt;CPU&lt;/span&gt;. Of course it depends on the video resolution and
framerate you want to&amp;nbsp;target.&lt;/p&gt;
&lt;p&gt;On the latency front, I decided to switch from &lt;span class="caps"&gt;RTMP&lt;/span&gt; to WebRTC! This &lt;span class="caps"&gt;W3C&lt;/span&gt; spec
isn&amp;#8217;t only about video chat! With WebRTC, sub-second live one-to-many
broadcasting can be achieved, without much efforts, given you have a good &lt;span class="caps"&gt;SFU&lt;/span&gt;.
For this demo I chose &lt;a class="reference external" href="https://janus.conf.meetecho.com"&gt;Janus&lt;/a&gt;, because its APIs are well documented, and it&amp;#8217;s a
cool project! I&amp;#8217;m not sure it would scale very well in large deployments, but
for my modest use-case, it fits very&amp;nbsp;well.&lt;/p&gt;
&lt;p&gt;Janus has a plugin called &lt;a class="reference external" href="https://janus.conf.meetecho.com/docs/videoroom.html"&gt;video-room&lt;/a&gt; which allows multiple participants to
chat. But then imagine a participant only publishing its video stream and
multiple &amp;#8220;clients&amp;#8221; connecting to that room, without sharing any video or audio
stream, one-to-many broadcasting. As it turns out, &lt;a class="reference external" href="https://gstreamer.freedesktop.org"&gt;GStreamer&lt;/a&gt; applications can
already connect to this video-room plugin using &lt;a class="reference external" href="https://gstreamer.freedesktop.org/documentation/webrtc/index.html?gi-language=c#webrtcbin-page"&gt;GstWebRTC&lt;/a&gt;! A demo was developed
by &lt;a class="reference external" href="https://github.com/tobiasfriden"&gt;tobiasfriden&lt;/a&gt; and &lt;a class="reference external" href="https://github.com/saket424"&gt;saket424&lt;/a&gt; in Python, it recently moved to the &lt;a class="reference external" href="https://gitlab.freedesktop.org/gstreamer/gst-examples"&gt;gst-examples&lt;/a&gt;
repository. As I kind of prefer to use Rust nowadays (whenever I can anyway) I
ported this demo to Rust, it was upstreamed in &lt;a class="reference external" href="https://gitlab.freedesktop.org/gstreamer/gst-examples"&gt;gst-examples&lt;/a&gt; as well. This
specific demo streams the video test pattern to a Janus&amp;nbsp;instance.&lt;/p&gt;
&lt;p&gt;Adapting this Janus demo was then quite trivial. By relying on a similar video
mixer approach I used for the first GstWPE demo, I had a GstWPE-powered WebView
streaming to&amp;nbsp;Janus.&lt;/p&gt;
&lt;p&gt;The next step was the actual graphics overlays infrastructure. In the first
GstWPE demo I had a basic &lt;span class="caps"&gt;GTK&lt;/span&gt; &lt;span class="caps"&gt;UI&lt;/span&gt; allowing to edit the overlays on-the-fly. This
can&amp;#8217;t be used for this new demo, because I wanted to use it headless. After
doing some research I found a really nice NodeJS app on Github, it was developed
by &lt;a class="reference external" href="https://github.com/moschopsuk"&gt;Luke Moscrop&lt;/a&gt;, who&amp;#8217;s actually one of the main developers of the &lt;a class="reference external" href="https://github.com/bbc/brave"&gt;Brave
&lt;span class="caps"&gt;BBC&lt;/span&gt;&lt;/a&gt; project. The &lt;a class="reference external" href="https://github.com/moschopsuk/Roses-2015-CasparCG-Graphics"&gt;Roses CasparCG Graphics&lt;/a&gt; was developed in the context of
the &lt;a class="reference external" href="https://www.la1tv.co.uk"&gt;Lancaster University Students&amp;#8217; Union &lt;span class="caps"&gt;TV&lt;/span&gt; Station&lt;/a&gt;, this app starts a
web-server on port 3000 with two main entry&amp;nbsp;points:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;An admin web-&lt;span class="caps"&gt;UI&lt;/span&gt; (in &lt;cite&gt;/admin/&lt;/cite&gt; allowing to create and manage overlays, like sports score
boards, info banners, and so&amp;nbsp;on.&lt;/li&gt;
&lt;li&gt;The target overlay page (in the root location of the server), which is a
web-page without predetermined background, displaying the overlays with &lt;span class="caps"&gt;HTML&lt;/span&gt;,
&lt;span class="caps"&gt;CSS&lt;/span&gt; and &lt;span class="caps"&gt;JS&lt;/span&gt;. This web-page is meant to be fed to &lt;a class="reference external" href="https://casparcg.com"&gt;CasparCG&lt;/a&gt; (or GstWPE&amp;nbsp;:))&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After making a few tweaks in this NodeJS app, I can&amp;nbsp;now:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Start the NodeJS app, load the admin &lt;span class="caps"&gt;UI&lt;/span&gt; in a browser and enable some&amp;nbsp;overlays&lt;/li&gt;
&lt;li&gt;Start my native Rust GStreamer/&lt;span class="caps"&gt;WPE&lt;/span&gt; application, which:&lt;ul&gt;
&lt;li&gt;connects to the overlay&amp;nbsp;web-server&lt;/li&gt;
&lt;li&gt;mixes a live video source (webcam for instances) with the &lt;span class="caps"&gt;WPE&lt;/span&gt;-powered&amp;nbsp;overlay&lt;/li&gt;
&lt;li&gt;encodes the video stream to H.264, &lt;span class="caps"&gt;VP8&lt;/span&gt; or &lt;span class="caps"&gt;VP9&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;sends the encoded &lt;span class="caps"&gt;RTP&lt;/span&gt; stream using WebRTC to a Janus&amp;nbsp;server&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Let &amp;#8220;consumer&amp;#8221; clients connect to Janus with their browser, in order to see
the resulting live&amp;nbsp;broadcast.&lt;/li&gt;
&lt;/ol&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/QNZJYOuVGiE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;&lt;p&gt;(If the video doesn&amp;#8217;t display, here is the &lt;a class="reference external" href="https://youtu.be/QNZJYOuVGiE"&gt;Youtube link&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;This is pretty cool and fun, as my colleague &lt;a class="reference external" href="https://bkardell.com"&gt;Brian Kardell&lt;/a&gt; mentions in the
video. Working on this new version gave me more ideas for the next one. And very
recently the &lt;a class="reference external" href="https://github.com/Igalia/WPEBackend-fdo/commit/fd14bac16e465083b755675c441e19cc60db04b3"&gt;audio rendering protocol&lt;/a&gt; was merged in WPEBackend-&lt;span class="caps"&gt;FDO&lt;/span&gt;! That
means even more use-cases are now unlocked for&amp;nbsp;GstWPE.&lt;/p&gt;
&lt;p&gt;This demo&amp;#8217;s source code is hosted on &lt;a class="reference external" href="https://github.com/Igalia/gst-wpe-webrtc-demo"&gt;Github&lt;/a&gt;. Feel free to open issues there, I
am always interested in getting feedback, good or&amp;nbsp;bad!&lt;/p&gt;
&lt;p&gt;GstWPE is maintained upstream in &lt;a class="reference external" href="https://gstreamer.freedesktop.org"&gt;GStreamer&lt;/a&gt; and relies heavily on &lt;a class="reference external" href="https://wpewebkit.org"&gt;WPEWebKit&lt;/a&gt; and
its &lt;a class="reference external" href="https://github.com/igalia/wpebackend-fdo"&gt;&lt;span class="caps"&gt;FDO&lt;/span&gt; backend&lt;/a&gt;. Don&amp;#8217;t hesitate to &lt;a class="reference external" href="https://www.igalia.com/contact/"&gt;contact us&lt;/a&gt; if you have specific
requirements or issues with these projects&amp;nbsp;:)&lt;/p&gt;
</content><category term="misc"></category><category term="Projects"></category><category term="GStreamer"></category><category term="WebKit"></category></entry><entry><title>GStreamer’s playbin3 overview for application developers</title><link href="https://base-art.net/Articles/gstreamers-playbin3-overview-for-application-developers/" rel="alternate"></link><published>2020-06-13T12:05:12+02:00</published><updated>2020-06-13T12:05:12+02:00</updated><author><name>Philippe Normand</name></author><id>tag:base-art.net,2020-06-13:/Articles/gstreamers-playbin3-overview-for-application-developers/</id><summary type="html">&lt;p&gt;Multimedia applications based on GStreamer usually handle playback with the
&lt;a class="reference external" href="https://gstreamer.freedesktop.org/documentation/tutorials/playback/playbin-usage.html"&gt;playbin&lt;/a&gt; element. I recently added support for &lt;a class="reference external" href="https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-playbin3.html"&gt;playbin3&lt;/a&gt; in WebKit. This post
aims to document the changes needed on application side to support this new
generation flavour of&amp;nbsp;playbin.&lt;/p&gt;
&lt;p&gt;So, first of, why is it named playbin3 anyway? The GStreamer …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Multimedia applications based on GStreamer usually handle playback with the
&lt;a class="reference external" href="https://gstreamer.freedesktop.org/documentation/tutorials/playback/playbin-usage.html"&gt;playbin&lt;/a&gt; element. I recently added support for &lt;a class="reference external" href="https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-playbin3.html"&gt;playbin3&lt;/a&gt; in WebKit. This post
aims to document the changes needed on application side to support this new
generation flavour of&amp;nbsp;playbin.&lt;/p&gt;
&lt;p&gt;So, first of, why is it named playbin3 anyway? The GStreamer 0.10.x series had a
playbin element but a first rewrite (playbin2) made it obsolete in the GStreamer
1.x series. So playbin2 was renamed to playbin. That&amp;#8217;s why a second rewrite is
nicknamed playbin3, I suppose&amp;nbsp;:)&lt;/p&gt;
&lt;p&gt;Why should you care about playbin3? Playbin3 (and the elements it&amp;#8217;s using
internally: parsebin, decodebin3, uridecodebin3 among others) is the result of a
deep re-design of playbin2 (along with decodebin2 and uridecodebin) to better&amp;nbsp;support:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;gapless&amp;nbsp;playback&lt;/li&gt;
&lt;li&gt;audio cross-fading support (not yet&amp;nbsp;implemented)&lt;/li&gt;
&lt;li&gt;adaptive&amp;nbsp;streaming&lt;/li&gt;
&lt;li&gt;reduced &lt;span class="caps"&gt;CPU&lt;/span&gt;, memory and I/O resource&amp;nbsp;usage&lt;/li&gt;
&lt;li&gt;faster stream switching and full control over the stream selection&amp;nbsp;process&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This work was carried on mostly by Edward Hervey, he presented his work in
detail at 3 GStreamer conferences. If you want to learn more about this and the
internals of playbin3 make sure to watch his awesome presentations at the &lt;a class="reference external" href="https://gstconf.ubicast.tv/videos/decodebin3-or-dealing-with-modern-playback-use-cases/"&gt;2015
gst-conf&lt;/a&gt;, &lt;a class="reference external" href="https://gstconf.ubicast.tv/videos/the-new-gststream-api-design-and-usage/"&gt;2016 gst-conf&lt;/a&gt; and &lt;a class="reference external" href="https://gstconf.ubicast.tv/videos/lightning-talks/#start=1418&amp;amp;autoplay&amp;amp;timeline"&gt;2017 gst-conf&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Playbin3 was added in GStreamer 1.10. It is still considered experimental but in
my experience it works already very well. Just keep in mind you should use at
least the latest GStreamer 1.12 (or even the upcoming 1.14) release before
reporting any issue in Bugzilla. Playbin3 is not a drop-in replacement for
playbin, both elements share only a sub-set of GObject properties and signals.
However, if you don&amp;#8217;t want to modify your application source code just yet, it&amp;#8217;s
very easy to try playbin3&amp;nbsp;anyway:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ USE_PLAYBIN3=1 my-playbin-based-app
&lt;/pre&gt;
&lt;p&gt;Setting the &lt;cite&gt;USE_PLAYBIN&lt;/cite&gt; environment variable enables a code path inside the
GStreamer playback plugin which swaps the playbin element for the playbin3
element. This trick provides a glance to the playbin3 element for the most lazy
people :) The problem is that depending on your use of playbin, you might get
runtime warnings, here&amp;#8217;s an example with the Totem&amp;nbsp;player:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ USE_PLAYBIN3=1 totem ~/Videos/Agent327.mp4
(totem:22617): GLib-GObject-WARNING **: ../../../../gobject/gsignal.c:2523: signal 'video-changed' is invalid for instance '0x556db67f3170' of type 'GstPlayBin3'

(totem:22617): GLib-GObject-WARNING **: ../../../../gobject/gsignal.c:2523: signal 'audio-changed' is invalid for instance '0x556db67f3170' of type 'GstPlayBin3'

(totem:22617): GLib-GObject-WARNING **: ../../../../gobject/gsignal.c:2523: signal 'text-changed' is invalid for instance '0x556db67f3170' of type 'GstPlayBin3'

(totem:22617): GLib-GObject-WARNING **: ../../../../gobject/gsignal.c:2523: signal 'video-tags-changed' is invalid for instance '0x556db67f3170' of type 'GstPlayBin3'

(totem:22617): GLib-GObject-WARNING **: ../../../../gobject/gsignal.c:2523: signal 'audio-tags-changed' is invalid for instance '0x556db67f3170' of type 'GstPlayBin3'

(totem:22617): GLib-GObject-WARNING **: ../../../../gobject/gsignal.c:2523: signal 'text-tags-changed' is invalid for instance '0x556db67f3170' of type 'GstPlayBin3'
sys:1: Warning: g_object_get_is_valid_property: object class 'GstPlayBin3' has no property named 'n-audio'
sys:1: Warning: g_object_get_is_valid_property: object class 'GstPlayBin3' has no property named 'n-text'
sys:1: Warning: ../../../../gobject/gsignal.c:3492: signal name 'get-video-pad' is invalid for instance '0x556db67f3170' of type 'GstPlayBin3'
&lt;/pre&gt;
&lt;p&gt;As mentioned previously, playbin and playbin3 don&amp;#8217;t share the same set of
GObject properties and signals, so some changes in your application are required
in order to use&amp;nbsp;playbin3.&lt;/p&gt;
&lt;p&gt;If your application is based on the &lt;a class="reference external" href="https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/GstPlayer.html"&gt;GstPlayer&lt;/a&gt; library then you should set the
&lt;cite&gt;GST_PLAYER_USE_PLAYBIN3&lt;/cite&gt; environment variable. GstPlayer already handles both
playbin and playbin3, so no changes needed in your application if you use&amp;nbsp;GstPlayer!&lt;/p&gt;
&lt;p&gt;Ok, so what if your application relies directly on playbin? Some
changes are needed! If you previously used playbin stream selection
properties and signals, you will now need to handle the GstStream and
GstStreamCollection APIs. Playbin3 will emit a &lt;a class="reference external" href="https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#GST-MESSAGE-STREAM-COLLECTION:CAPS"&gt;stream collection
message&lt;/a&gt; on the bus, this is very nice because the collection
includes information (metadata!) about the streams (or tracks) the
media asset contains. In playbin this was handled with a bunch of
signals (audio-tags-changed, audio-changed, etc), properties (n-audio,
n-video, etc) and action signals (get-audio-tags, get-audio-pad, etc).
The new &lt;a class="reference external" href="https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstStream.html"&gt;GstStream &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; provides a centralized and
non-playbin-specific access point for all these informations. To
select streams with playbin3 you now need to send a &lt;a class="reference external" href="https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstEvent.html#gst-event-new-select-streams"&gt;select_streams
event&lt;/a&gt; so that the demuxer can know exactly which streams should be
exposed to downstream elements. That means potentially improved
performance! Once playbin3 completed the stream selection it will emit
a &lt;a class="reference external" href="https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html#GST-MESSAGE-STREAMS-SELECTED:CAPS"&gt;streams selected message&lt;/a&gt;, the application should handle this
message and potentially update its internal state about the selected
streams. This is also the best moment to update your &lt;span class="caps"&gt;UI&lt;/span&gt; regarding the
selected streams (like audio track language, video track dimensions,&amp;nbsp;etc).&lt;/p&gt;
&lt;p&gt;Another small difference between playbin and playbin3 is about the source
element setup. In playbin there is a &lt;cite&gt;source&lt;/cite&gt; read-only GObject property and a
&lt;cite&gt;source-setup&lt;/cite&gt; GObject signal. In playbin3 only the latter is available, so your
application should rely on &lt;cite&gt;source-setup&lt;/cite&gt; instead of the &lt;cite&gt;notify::source&lt;/cite&gt;
GObject&amp;nbsp;signal.&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/tools/gst-play.c"&gt;gst-play-1.0&lt;/a&gt; playback utility program already supports playbin3 so it
provides a good source of inspiration if you consider porting your application
to playbin3. As mentioned at the beginning of this post, WebKit also now
supports playbin3, however it needs to be enabled at build time using the CMake
&lt;cite&gt;-DUSE_GSTREAMER_PLAYBIN3=&lt;span class="caps"&gt;ON&lt;/span&gt;&lt;/cite&gt; option. This feature is not part of the WebKitGTK+
2.20 series but should be shipped in 2.22. As a final note I wanted to
acknowledge my favorite worker-owned coop &lt;a class="reference external" href="https://igalia.com"&gt;Igalia&lt;/a&gt; for allowing me to work on
this WebKit feature and also our friends over at &lt;a class="reference external" href="https://centricular.com"&gt;Centricular&lt;/a&gt; for all the
quality work on&amp;nbsp;playbin3.&lt;/p&gt;
</content><category term="misc"></category><category term="Projects"></category><category term="GStreamer"></category></entry><entry><title>WebKitGTK and WPE now supporting videos in the img tag</title><link href="https://base-art.net/Articles/webkitgtk-and-wpe-now-supporting-videos-in-the-img-tag/" rel="alternate"></link><published>2020-06-09T18:00:00+02:00</published><updated>2020-06-10T09:00:00+02:00</updated><author><name>Philippe Normand</name></author><id>tag:base-art.net,2020-06-09:/Articles/webkitgtk-and-wpe-now-supporting-videos-in-the-img-tag/</id><summary type="html">&lt;p&gt;Using videos in the &lt;cite&gt;&amp;lt;img&amp;gt;&lt;/cite&gt; &lt;span class="caps"&gt;HTML&lt;/span&gt; tag can lead to more responsive web-page loads
in most cases. Colin Bendell blogged about this topic, make sure to read his
&lt;a class="reference external" href="https://cloudinary.com/blog/evolution_of_img_gif_without_the_gif"&gt;post on the cloudinary website&lt;/a&gt;. As it turns out, this feature has been
supported for more than 2 years in Safari, but …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Using videos in the &lt;cite&gt;&amp;lt;img&amp;gt;&lt;/cite&gt; &lt;span class="caps"&gt;HTML&lt;/span&gt; tag can lead to more responsive web-page loads
in most cases. Colin Bendell blogged about this topic, make sure to read his
&lt;a class="reference external" href="https://cloudinary.com/blog/evolution_of_img_gif_without_the_gif"&gt;post on the cloudinary website&lt;/a&gt;. As it turns out, this feature has been
supported for more than 2 years in Safari, but only recently the WebKitGTK and
WPEWebKit ports caught up. Read on for the crunchy details or skip to the end of
the post if you want to try this new&amp;nbsp;feature.&lt;/p&gt;
&lt;p&gt;As WebKitGTK and WPEWebKit already heavily use GStreamer for their multimedia
backends, it was natural for us to also use GStreamer to provide the video
ImageDecoder&amp;nbsp;implementation.&lt;/p&gt;
&lt;p&gt;The preliminary step is to hook our new decoder into the &lt;a class="reference external" href="https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/MIMETypeRegistry.cpp"&gt;MIMETypeRegistry&lt;/a&gt; and
into the &lt;a class="reference external" href="https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/graphics/ImageDecoder.cpp"&gt;ImageDecoder.cpp&lt;/a&gt; platform-agnostic module. This is where the main
decoder branches out to platform-specific backends. Then we need to add a new
class implementing WebKit&amp;#8217;s &lt;a class="reference external" href="https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/graphics/ImageDecoder.h"&gt;ImageDecoder&lt;/a&gt; virtual&amp;nbsp;interface.&lt;/p&gt;
&lt;p&gt;First you need to implement &lt;cite&gt;supportsMediaType()&lt;/cite&gt;. For this method we already
had all the code in place. WebKit scans the GStreamer plugin registry and
depending on the plugins available on the target platform, a mime-type cache is
built, by the &lt;a class="reference external" href="https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/graphics/gstreamer/GStreamerRegistryScanner.cpp"&gt;RegistryScanner&lt;/a&gt;. Our new image decoder just needs to hook into
this component (exposed as singleton) so that we can be sure that the decoder
will be used only for media types supported by&amp;nbsp;GStreamer.&lt;/p&gt;
&lt;p&gt;The second most important places of the decoder are its constructor and the
&lt;cite&gt;setData()&lt;/cite&gt; method. This is the place where the decoder receives encoded data,
as a SharedBuffer, and performs the decoding. Because this method is
synchronously called from a secondary thread, we run the GStreamer pipeline
there, until the video has been decoded entirely. Our pipeline relies on the
GStreamer decodebin element and WebKit&amp;#8217;s internal video sink. For the time being
hardware-accelerated decoding is not supported. We should soon be able to fix
this issue though. Once all samples have been received by the sink, the decoder
notifies its caller using a callback. The caller then knows it can request
decoded&amp;nbsp;frames.&lt;/p&gt;
&lt;p&gt;Last, the decoder needs to provide decoded frames! This is implemented using the
&lt;cite&gt;createFrameImageAtIndex()&lt;/cite&gt; method. Our decoder implementation keeps an internal
Map of the decoded samples. We sub-classed the &lt;a class="reference external" href="https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/graphics/gstreamer/MediaSampleGStreamer.h"&gt;MediaSampleGStreamer&lt;/a&gt; to provide
an &lt;cite&gt;image()&lt;/cite&gt; method, which returns the Cairo surface representing the decoded
frame. Again, here we don&amp;#8217;t support &lt;span class="caps"&gt;GL&lt;/span&gt; textures yet. Some more infrastructure
work is likely going to be needed in that area of our WebKit&amp;nbsp;ports.&lt;/p&gt;
&lt;p&gt;Our implementation of the video ImageDecoder lives in &lt;a class="reference external" href="https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/graphics/gstreamer/ImageDecoderGStreamer.cpp"&gt;ImageDecoderGStreamer&lt;/a&gt;
which will be shipped in WebKitGTK and WPEWebKit 2.30, around September/October.
But what if you want to try this already? Well, building WebKit can be a tedious
task. We&amp;#8217;ve been hard a work at &lt;a class="reference external" href="https://igalia.com"&gt;Igalia&lt;/a&gt; to make this a bit easier using a &lt;a class="reference external" href="https://base-art.net/Articles/introducing-the-webkit-flatpak-sdk/"&gt;new Flatpak &lt;span class="caps"&gt;SDK&lt;/span&gt;&lt;/a&gt;.
So, you can either try this feature in Epiphany Tech Preview or
(surprise!) with our new tooling allowing to download and run nightly binaries
from the upstream WebKit build&amp;nbsp;bots:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ wget https://raw.githubusercontent.com/WebKit/webkit/master/Tools/Scripts/webkit-flatpak-run-nightly
$ chmod +x webkit-flatpak-run-nightly
$ python3 webkit-flatpak-run-nightly MiniBrowser https://colinbendell.github.io/webperf/img-mp4/
&lt;/pre&gt;
&lt;img src="https://base-art.net/png/WebKitGTK-video-img-tag.png"/&gt;&lt;p&gt;This script locally installs our new Flatpak-based developer &lt;span class="caps"&gt;SDK&lt;/span&gt; in
&lt;cite&gt;~/.cache/wk-nightly&lt;/cite&gt; and then downloads a zip archive of the build artefacts
from servers recently brought up by my colleague &lt;a class="reference external" href="http://blog.neutrino.es/"&gt;Carlos Alberto Lopez Perez&lt;/a&gt;,
many thanks to him :). The downloaded zip file is unpacked in &lt;cite&gt;/tmp&lt;/cite&gt; and kept
around in case you want to run this again without re-downloading the build
archive. Flatpak is then used to run the binaries inside a sandbox! This is a
nice way to run the bleeding edge of the web-engine, without having to build it
or install any distro&amp;nbsp;package.&lt;/p&gt;
&lt;p&gt;Implementing new features in WebKit is one of the many expertize domains we are
involved in at &lt;a class="reference external" href="https://igalia.com"&gt;Igalia&lt;/a&gt;. &lt;a class="reference external" href="https://www.igalia.com/technology/multimedia"&gt;Our multimedia team&lt;/a&gt; is always on the lookout to help
folks in their projects involving either GStreamer or WebKit or both! Don&amp;#8217;t
hesitate to reach&amp;nbsp;out.&lt;/p&gt;
</content><category term="misc"></category><category term="Projects"></category><category term="WebKit"></category><category term="GStreamer"></category></entry><entry><title>HTML overlays with GstWPE, the demo</title><link href="https://base-art.net/Articles/html-overlays-with-gstwpe-the-demo/" rel="alternate"></link><published>2019-12-08T15:00:00+01:00</published><updated>2019-12-08T15:00:00+01:00</updated><author><name>Philippe Normand</name></author><id>tag:base-art.net,2019-12-08:/Articles/html-overlays-with-gstwpe-the-demo/</id><summary type="html">&lt;p&gt;Once again this year I attended the &lt;a class="reference external" href="https://gstreamer.freedesktop.org/conference/2019/"&gt;GStreamer conference&lt;/a&gt; and just before
that, &lt;a class="reference external" href="https://events19.linuxfoundation.org/events/embedded-linux-conference-europe-2019/"&gt;Embedded Linux conference Europe&lt;/a&gt; which took place in Lyon (France).
Both events were a good opportunity to demo one of the use-cases I have in mind
for &lt;a class="reference external" href="https://base-art.net/Articles/web-overlay-in-gstreamer-with-wpewebkit/"&gt;GstWPE&lt;/a&gt;, &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;overlays!&lt;/p&gt;
&lt;p&gt;As we, at &lt;a class="reference external" href="https://igalia.com"&gt;Igalia&lt;/a&gt;, usually have a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Once again this year I attended the &lt;a class="reference external" href="https://gstreamer.freedesktop.org/conference/2019/"&gt;GStreamer conference&lt;/a&gt; and just before
that, &lt;a class="reference external" href="https://events19.linuxfoundation.org/events/embedded-linux-conference-europe-2019/"&gt;Embedded Linux conference Europe&lt;/a&gt; which took place in Lyon (France).
Both events were a good opportunity to demo one of the use-cases I have in mind
for &lt;a class="reference external" href="https://base-art.net/Articles/web-overlay-in-gstreamer-with-wpewebkit/"&gt;GstWPE&lt;/a&gt;, &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;overlays!&lt;/p&gt;
&lt;p&gt;As we, at &lt;a class="reference external" href="https://igalia.com"&gt;Igalia&lt;/a&gt;, usually have a booth at &lt;span class="caps"&gt;ELC&lt;/span&gt;, I thought a GstWPE demo would be
nice to have so we can show it there. The demo is a rather simple &lt;span class="caps"&gt;GTK&lt;/span&gt;
application presenting a live preview of the webcam video capture with an &lt;span class="caps"&gt;HTML&lt;/span&gt;
overlay blended in. The &lt;span class="caps"&gt;HTML&lt;/span&gt; and &lt;span class="caps"&gt;CSS&lt;/span&gt; can be modified using the embedded text
editor and the overlay will be updated accordingly. The final video stream can
even be streamed over &lt;span class="caps"&gt;RTMP&lt;/span&gt; to the main streaming platforms (Twitch, Youtube,
Mixer)! Here is a&amp;nbsp;screenshot:&lt;/p&gt;
&lt;img src="https://base-art.net/png/gst-wpe-broadcast-demo-screenshot.png"/&gt;&lt;p&gt;The code of the demo is available on &lt;a class="reference external" href="https://github.com/Igalia/gst-wpe-broadcast-demo"&gt;Igalia&amp;#8217;s GitHub&lt;/a&gt;. Interested people
should be able to try it as well, the app is packaged as a Flatpak. See the
instructions in the GitHub repo for more&amp;nbsp;details.&lt;/p&gt;
&lt;p&gt;Having this demo running on our booth greatly helped us to explain GstWPE and
how it can be used in real-life &lt;a class="reference external" href="https://gstreamer.freedesktop.org/"&gt;GStreamer&lt;/a&gt; applications. Combining the
flexibility of the Multimedia framework with the wide (wild) features of the Web
Platform will for sure increase the synergy and foster&amp;nbsp;collaboration!&lt;/p&gt;
&lt;p&gt;As a reminder, GstWPE is available in &lt;a class="reference external" href="https://gstreamer.freedesktop.org/"&gt;GStreamer&lt;/a&gt; since the 1.16 version. On the
roadmap for the mid-term I plan to add Audio support, thus allowing even better
integration between WPEWebKit and GStreamer. Imagine injecting &lt;span class="caps"&gt;PCM&lt;/span&gt; audio coming
from WPEWebKit into an audio mixer in your GStreamer-based application! Stay&amp;nbsp;tuned.&lt;/p&gt;
</content><category term="misc"></category><category term="Projects"></category><category term="GStreamer"></category><category term="WebKit"></category></entry><entry><title>Review of the Igalia Multimedia team Activities (2019/H1)</title><link href="https://base-art.net/Articles/review-of-the-igalia-multimedia-team-activities-2019h1/" rel="alternate"></link><published>2019-08-05T15:30:00+02:00</published><updated>2019-08-05T15:30:00+02:00</updated><author><name>Philippe Normand</name></author><id>tag:base-art.net,2019-08-05:/Articles/review-of-the-igalia-multimedia-team-activities-2019h1/</id><summary type="html">&lt;p&gt;This blog post takes a look back at the various Multimedia-related tasks the
&lt;a class="reference external" href="https://www.igalia.com/technology/multimedia"&gt;Igalia Multimedia team&lt;/a&gt; was involved in during the first half of&amp;nbsp;2019.&lt;/p&gt;
&lt;div class="section" id="gstreamer-editing-services"&gt;
&lt;h2&gt;GStreamer Editing&amp;nbsp;Services&lt;/h2&gt;
&lt;p&gt;Thibault added support for the &lt;a class="reference external" href="https://github.com/PixarAnimationStudios/OpenTimelineIO"&gt;OpenTimelineIO&lt;/a&gt; open format for editorial
timeline information. Having many editorial timeline information formats
supported by OpenTimelineIO reduces …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;This blog post takes a look back at the various Multimedia-related tasks the
&lt;a class="reference external" href="https://www.igalia.com/technology/multimedia"&gt;Igalia Multimedia team&lt;/a&gt; was involved in during the first half of&amp;nbsp;2019.&lt;/p&gt;
&lt;div class="section" id="gstreamer-editing-services"&gt;
&lt;h2&gt;GStreamer Editing&amp;nbsp;Services&lt;/h2&gt;
&lt;p&gt;Thibault added support for the &lt;a class="reference external" href="https://github.com/PixarAnimationStudios/OpenTimelineIO"&gt;OpenTimelineIO&lt;/a&gt; open format for editorial
timeline information. Having many editorial timeline information formats
supported by OpenTimelineIO reduces vendor lock-in in the tools used by video artists in
post-production studios. For instance a movie project edited in Final Cut Pro
can now be easily reimported in the &lt;a class="reference external" href="https://pitivi.org"&gt;Pitivi&lt;/a&gt; free and open-source video editor.
This accomplishment was made possible by implementing an OpenTimelineIO &lt;span class="caps"&gt;GES&lt;/span&gt;
&lt;a class="reference external" href="https://github.com/PixarAnimationStudios/OpenTimelineIO/pull/412"&gt;adapter&lt;/a&gt; and &lt;a class="reference external" href="https://gitlab.freedesktop.org/gstreamer/gst-editing-services/merge_requests/67"&gt;formatter&lt;/a&gt;, both upstreamed respectively in OpenTimelineIO and &lt;span class="caps"&gt;GES&lt;/span&gt; by&amp;nbsp;Thibault.&lt;/p&gt;
&lt;img src="https://base-art.net/png/FcpAndPitivi.png"/&gt;&lt;p&gt;Another important feature for non-linear video editors is nested timeline
support. It allows teams to decouple big editing projects in smaller chunks that
can later on be assembled for the final product. Another use-case is about
pre-filling the timeline with boilerplate scenes, so that an initial version of
the movie can be assembled before all teams involved in the project have
provided the final content. To support this, Thibault implemented a &lt;a class="reference external" href="https://gitlab.freedesktop.org/gstreamer/gst-editing-services/blob/master/plugins/ges/gesdemux.c"&gt;&lt;span class="caps"&gt;GES&lt;/span&gt; demuxer&lt;/a&gt; which transparently enables
playback support for &lt;span class="caps"&gt;GES&lt;/span&gt; files (through &lt;a class="reference external" href="file://path/to/file.xges"&gt;file://path/to/file.xges&lt;/a&gt; URIs) in any GStreamer-based
media&amp;nbsp;player.&lt;/p&gt;
&lt;p&gt;As if this wasn&amp;#8217;t impressive enough yet, Thibault greatly improved the &lt;span class="caps"&gt;GES&lt;/span&gt;
unit-tests, fixing a lot of memory leaks, race conditions and generally
improving the reliability of the test suite. This is very important because the
Gitlab continuous integration now executes the tests harness for every submitted
merge&amp;nbsp;request.&lt;/p&gt;
&lt;p&gt;For more information about this, the curious readers can dive in &lt;a class="reference external" href="https://blogs.gnome.org/tsaunier/2019/04/22/gstreamer-editing-services-opentimelineio-support/"&gt;Thibault&amp;#8217;s blog post&lt;/a&gt;.
Thibault was invited to talk about these on-going efforts at &lt;a class="reference external" href="https://s2019.siggraph.org/"&gt;&lt;span class="caps"&gt;SIGGRAPH&lt;/span&gt;&lt;/a&gt; during
the &lt;a class="reference external" href="https://s2019.siggraph.org/presentation/?id=bof_124&amp;amp;sess=sess314"&gt;OpenTimelineIO &lt;span class="caps"&gt;BOF&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, Thibault is mentoring &lt;a class="reference external" href="https://swaynethoughts.wordpress.com/"&gt;Swayamjeet Swain&lt;/a&gt; as part of the &lt;a class="reference external" href="https://summerofcode.withgoogle.com/"&gt;GSoC&lt;/a&gt; program,
the project is about adding nested timeline support in &lt;a class="reference external" href="https://pitivi.org"&gt;Pitivi&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="gstreamer-va-api"&gt;
&lt;h2&gt;GStreamer &lt;span class="caps"&gt;VA&lt;/span&gt;-&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Víctor performed a good number of code reviews for GStreamer-&lt;span class="caps"&gt;VAAPI&lt;/span&gt; contributors,
he has also started investigating GStreamer-&lt;span class="caps"&gt;VAAPI&lt;/span&gt; bugs specific to the &lt;span class="caps"&gt;AMDGPU&lt;/span&gt;
Gallium driver, in order to improve the support of &lt;span class="caps"&gt;AMD&lt;/span&gt; hardware in multimedia&amp;nbsp;applications.&lt;/p&gt;
&lt;p&gt;As part of the on-going GStreamer community efforts to improve continuous
integration (&lt;span class="caps"&gt;CI&lt;/span&gt;) in the project, we purchased Intel and &lt;span class="caps"&gt;AMD&lt;/span&gt; powered devices
aimed to run validation tests. Running &lt;span class="caps"&gt;CI&lt;/span&gt; on real end-user hardware will help
ensure regressions remain under&amp;nbsp;control.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="servo-and-gstreamer-rs"&gt;
&lt;h2&gt;Servo and&amp;nbsp;GStreamer-rs&lt;/h2&gt;
&lt;p&gt;As part of our on-going involvement in the &lt;a class="reference external" href="https://servo.org/"&gt;Servo&lt;/a&gt; Mozilla project, &lt;a class="reference external" href="https://blogs.igalia.com/vjaquez"&gt;Víctor&lt;/a&gt; has
enabled zero-copy video rendering support in the GStreamer-based &lt;a class="reference external" href="https://github.com/servo/media"&gt;Servo-media&lt;/a&gt;
crate, along with &lt;a class="reference external" href="https://github.com/rust-windowing/glutin/pull/1082"&gt;bug fixes in Glutin&lt;/a&gt; and finally in &lt;a class="reference external" href="https://github.com/servo/servo/pull/23483"&gt;Servo itself&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A prior requirement for this major milestone was to enable gst-gl in the
GStreamer Rust bindings and after around 20 patches were merged in the
repository, we are pleased to announce Linux and Android platforms are
supported. Windows and macOS platforms will also be supported,&amp;nbsp;soon.&lt;/p&gt;
&lt;p&gt;The following screencast shows how hardware-accelerated video rendering performs
on Víctor&amp;#8217;s&amp;nbsp;laptop:&lt;/p&gt;
&lt;video controls src="https://s3.amazonaws.com/media-p.slid.es/videos/105177/rzteE40V/hwacceleration.mp4"/&gt;&lt;p&gt;Víctor also delivered a talk at the &lt;a class="reference external" href="https://www.meetup.com/MadRust/events/259059099/"&gt;MadRust&lt;/a&gt; meetup, about GStreamer-rs, the
&lt;a class="reference external" href="https://people.igalia.com/vjaquez/talks/madrust2019/"&gt;slides are available&lt;/a&gt; on his&amp;nbsp;website.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="webkit-s-media-source-extensions"&gt;
&lt;h2&gt;WebKit&amp;#8217;s Media Source&amp;nbsp;Extensions&lt;/h2&gt;
&lt;p&gt;As part of our on-going collaboration with various device manufacturers, &lt;a class="reference external" href="https://www.igalia.com/igalian/aboya"&gt;Alicia&lt;/a&gt;
and &lt;a class="reference external" href="https://www.igalia.com/igalian/eocanha"&gt;Enrique&lt;/a&gt; validated the &lt;a class="reference external" href="https://ytlr-cert.appspot.com/2019/main.html"&gt;Youtube &lt;span class="caps"&gt;TV&lt;/span&gt; &lt;span class="caps"&gt;MSE&lt;/span&gt; 2019 test suite&lt;/a&gt; in WPEWebKit-based&amp;nbsp;products.&lt;/p&gt;
&lt;p&gt;Alicia developed a new GstValidate plugin to improve GStreamer pipelines
testing, called &lt;a class="reference external" href="https://gstreamer.freedesktop.org/documentation/gst-devtools/plugins/validateflow.html?gi-language=c"&gt;validateflow&lt;/a&gt;. Make sure to read her &lt;a class="reference external" href="https://blogs.igalia.com/aboya/2019/05/14/validateflow-a-new-tool-to-test-gstreamer-pipelines/"&gt;blog post about it&lt;/a&gt;!.&lt;/p&gt;
&lt;p&gt;In her quest to further improve &lt;span class="caps"&gt;MSE&lt;/span&gt; support, especially seek support, Alicia
rewrote the GStreamer source element we use in WebKit for &lt;span class="caps"&gt;MSE&lt;/span&gt; playback. The code
&lt;a class="reference external" href="https://bugs.webkit.org/show_bug.cgi?id=199719"&gt;review is on-going in Bugzilla&lt;/a&gt; and on track for inclusion in WPEWebKit and
WebKitGTK 2.26. This new design of the &lt;span class="caps"&gt;MSE&lt;/span&gt; source element requires the playbin3
GStreamer element and at least GStreamer 1.16. Another feature we plan to work
on in the near future is multi-track support; stay&amp;nbsp;tuned!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="webkit-webrtc"&gt;
&lt;h2&gt;WebKit&amp;nbsp;WebRTC&lt;/h2&gt;
&lt;p&gt;We announced &lt;a class="reference external" href="https://blogs.gnome.org/tsaunier/2018/07/31/webkitgtk-and-wpe-gains-webrtc-support-back/"&gt;LibWebRTC support for WPEWebKit and WebKitGTK&lt;/a&gt; one year ago.
Since then, Thibault has been implementing new features and fixing bugs in the
backend. Bridging between the WebAudio and WebRTC backend was implemented,
allowing tight integration of WebAudio and WebRTC web apps. More WebKit WebRTC
layout tests were unskipped in the buildbots, allowing better tracking of&amp;nbsp;regressions.&lt;/p&gt;
&lt;p&gt;Thibault also fixed various performance issues on Raspberry Pi platforms during
&lt;a class="reference external" href="https://appr.tc/"&gt;apprtc&lt;/a&gt; video-calls. As part of this effort he upstreamed a
&lt;a class="reference external" href="https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/commit/ee108d0ed20c376b5871b40108ba1cd54156baf9"&gt;GstUVCH264DeviceProvider&lt;/a&gt; in GStreamer, allowing applications to use
already-encoded H264 streams from webcams that provide it, thus removing the
need for applications to encode raw video&amp;nbsp;streams.&lt;/p&gt;
&lt;p&gt;Additionally, Thibault upstreamed a &lt;a class="reference external" href="https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/commit/ac5d0f7da688c1010ab2656f32c40e854e5b8bf2"&gt;device provider for &lt;span class="caps"&gt;ALSA&lt;/span&gt;&lt;/a&gt; in GStreamer,
allowing applications to probe for Microphones and speakers supported through
the &lt;span class="caps"&gt;ALSA&lt;/span&gt; kernel&amp;nbsp;driver.&lt;/p&gt;
&lt;p&gt;Finally, Thibault tweaked the GStreamer encoders used by the WebKit LibWebRTC
backend, in order to match the behavior of the Apple implementation and also
fixing a few performance and rendering issues on the&amp;nbsp;way.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="webkit-gstreamer-multimedia-maintenance"&gt;
&lt;h2&gt;WebKit GStreamer Multimedia&amp;nbsp;maintenance&lt;/h2&gt;
&lt;p&gt;The whole team is always keeping an eye on WebKit&amp;#8217;s Bugzilla, watching out for
multimedia-related bugs reported by the community members. &lt;a class="reference external" href="https://www.igalia.com/igalian/cturner"&gt;Charlie&lt;/a&gt; recently
fixed a few annoying &lt;a class="reference external" href="https://bugs.webkit.org/show_bug.cgi?id=197358"&gt;volume&lt;/a&gt; &lt;a class="reference external" href="https://bugs.webkit.org/show_bug.cgi?id=199505"&gt;bugs&lt;/a&gt; along with an issue related with &lt;a class="reference external" href="https://bugs.webkit.org/show_bug.cgi?id=197355"&gt;youtube&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I rewrote the &lt;a class="reference external" href="https://trac.webkit.org/changeset/243058/webkit"&gt;WebKitWebSrc&lt;/a&gt; GStreamer source element we use in WebKit to
download &lt;span class="caps"&gt;HTTP&lt;/span&gt;(S) media resources and feed the data to the playback pipeline.
This new element is now based on the GStreamer pushsrc base class, instead of
appsrc. A few seek-related issues were fixed on the way but unfortunately some
regressions also slipped in; those should all be fixed by now and shipped in
WPEWebKit/WebKitGTK&amp;nbsp;2.26.&lt;/p&gt;
&lt;p&gt;An initial version of the &lt;a class="reference external" href="https://w3c.github.io/media-capabilities/"&gt;MediaCapabilities&lt;/a&gt; &lt;a class="reference external" href="https://bugs.webkit.org/show_bug.cgi?id=191191"&gt;backend&lt;/a&gt; was also upstreamed in
WebKit. It allows web-apps (such as Youtube &lt;span class="caps"&gt;TV&lt;/span&gt;) to probe the user-agent for
media decoding and encoding capabilities. The GStreamer backend relies on the
GStreamer plugin registry to provide accurate information about the supported
codecs and containers. &lt;a class="reference external" href="https://bugs.webkit.org/show_bug.cgi?id=198569"&gt;H264 &lt;span class="caps"&gt;AVC1&lt;/span&gt; profile and level&lt;/a&gt; information are also&amp;nbsp;probed.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="wpeqt"&gt;
&lt;h2&gt;WPEQt&lt;/h2&gt;
&lt;p&gt;Well, this isn&amp;#8217;t directly related with multimedia, but I finally announced the
initial release of &lt;a class="reference external" href="https://base-art.net/Articles/introducing-wpeqt-a-wpe-api-for-qt5/"&gt;WPEQt&lt;/a&gt;. Any feedback is welcome, QtWebKit has phased out and
if anyone out there relies on it for web-apps embedded in native &lt;span class="caps"&gt;QML&lt;/span&gt; apps, now
is the time to try&amp;nbsp;WPEQt!&lt;/p&gt;
&lt;/div&gt;
</content><category term="misc"></category><category term="Projects"></category><category term="WebKit"></category><category term="GStreamer"></category></entry><entry><title>Web overlay in GStreamer with WPEWebKit</title><link href="https://base-art.net/Articles/web-overlay-in-gstreamer-with-wpewebkit/" rel="alternate"></link><published>2018-12-08T15:09:36+01:00</published><updated>2018-12-08T15:09:36+01:00</updated><author><name>Philippe Normand</name></author><id>tag:base-art.net,2018-12-08:/Articles/web-overlay-in-gstreamer-with-wpewebkit/</id><summary type="html">&lt;p&gt;After a year or two of hiatus I attended the &lt;a class="reference external" href="https://gstreamer.freedesktop.org/conference/2018/"&gt;GStreamer conference&lt;/a&gt; which
happened in beautiful Edinburgh. It was great to meet the friends from the
community again and learn about what&amp;#8217;s going on in the multimedia world. The
quality of the talks was great, the videos are published …&lt;/p&gt;</summary><content type="html">&lt;p&gt;After a year or two of hiatus I attended the &lt;a class="reference external" href="https://gstreamer.freedesktop.org/conference/2018/"&gt;GStreamer conference&lt;/a&gt; which
happened in beautiful Edinburgh. It was great to meet the friends from the
community again and learn about what&amp;#8217;s going on in the multimedia world. The
quality of the talks was great, the videos are published online as usual in
&lt;a class="reference external" href="https://gstconf.ubicast.tv/channels/#gstreamer-conference-2018"&gt;Ubicast&lt;/a&gt;. I delivered a talk about the Multimedia support in &lt;a class="reference external" href="https://wpewebkit.org"&gt;WPEWebKit&lt;/a&gt;, you can
&lt;a class="reference external" href="https://gstconf.ubicast.tv/videos/multimedia-support-in-webkitgtk-and-wpe-current-status-and-plans/"&gt;watch it there&lt;/a&gt; and &lt;a class="reference external" href="https://gstreamer.freedesktop.org/data/events/gstreamer-conference/2018/Philippe%20Normand%20-%20Multimedia%20support%20in%20WebKitGTK%20and%20WPE,%20current%20status%20and%20plans.pdf"&gt;the slides are also available&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of the many interesting presentations was about &lt;a class="reference external" href="https://gstconf.ubicast.tv/videos/gstreamer-for-cloud-based-live-video-handling/"&gt;GStreamer for cloud-based
live video&lt;/a&gt;. Usually anything with the word cloud would tend to draw my
attention away but for some reason I attended this presentation, and didn&amp;#8217;t
regret it! The last demo presented by the &lt;span class="caps"&gt;BBC&lt;/span&gt; folks was about overlaying Web
content on native video streams. It&amp;#8217;s an interesting use-case for live &lt;span class="caps"&gt;TV&lt;/span&gt;
broadcasting for instance. A web page provides dynamic notifications popping up
and down, the web page is rendered with a transparent background and blended
over the live video stream. The &lt;span class="caps"&gt;BBC&lt;/span&gt; folks implemented a &lt;a class="reference external" href="https://github.com/bbc/brave/tree/master/gst-WebRenderSrc"&gt;GStreamer source
element relying on &lt;span class="caps"&gt;CEF&lt;/span&gt;&lt;/a&gt; for their Brave&amp;nbsp;project.&lt;/p&gt;
&lt;p&gt;So here you wonder, why am I talking about Chromium Embedded Framework (&lt;span class="caps"&gt;CEF&lt;/span&gt;)?
Isn&amp;#8217;t this post about &lt;a class="reference external" href="https://wpewebkit.org"&gt;WPEWebKit&lt;/a&gt;? After seeing the demo from the Brave
developers I immediately thought &lt;span class="caps"&gt;WPE&lt;/span&gt; could be a great fit for this &lt;span class="caps"&gt;HTML&lt;/span&gt; overlay
use-case too! So a few weeks after the conference I finally had the time to
start working on the &lt;a class="reference external" href="https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/tree/master/ext/wpe"&gt;&lt;span class="caps"&gt;WPE&lt;/span&gt; GStreamer plugin&lt;/a&gt;. My colleague &lt;a class="reference external" href="https://twitter.com/falconsigh"&gt;Žan Doberšek&lt;/a&gt;,
&lt;span class="caps"&gt;WPE&lt;/span&gt;&amp;#8217;s founder hacker, provided a nice solution for the initial rendering issues
of the prototype, many thanks to&amp;nbsp;him!&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a first example, a basic web-browser with&amp;nbsp;gst-play:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ gst-play-1.0 --videosink gtkglsink wpe://https://gnome.org
&lt;/pre&gt;
&lt;p&gt;A &lt;span class="caps"&gt;GTK&lt;/span&gt; window opens up and the &lt;span class="caps"&gt;GNOME&lt;/span&gt; homepage should load. You can click on links
too! To overlay a web page on top of a video you can use a pipeline like this&amp;nbsp;one:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ gst-launch-1.0 glvideomixer name=m sink_1::zorder=0 sink_0::height=818 sink_0::width=1920 ! gtkglsink \
 wpesrc location=&amp;quot;file:///home/phil/Downloads/plunk/index.html&amp;quot; draw-background=0 ! m. \
 uridecodebin uri=&amp;quot;http://192.168.1.44/Sintel.2010.1080p.mkv&amp;quot; name=d d. ! queue ! glupload \
  ! glcolorconvert ! m.
&lt;/pre&gt;
&lt;p&gt;which can be represented with this simplified&amp;nbsp;graph:&lt;/p&gt;
&lt;img src="https://base-art.net/svg/wpesrc.svg"/&gt;&lt;p&gt;The advantage of this approach is that many heavy-lifting tasks happen in the
&lt;span class="caps"&gt;GPU&lt;/span&gt;. &lt;span class="caps"&gt;WPE&lt;/span&gt; loads the page using its WPENetworkProcess external process, parses
everything (&lt;span class="caps"&gt;DOM&lt;/span&gt;, &lt;span class="caps"&gt;CSS&lt;/span&gt;, &lt;span class="caps"&gt;JS&lt;/span&gt;, &amp;#8230;) and renders it as a EGLImage, shared with the
UIProcess (the GStreamer application, gst-launch in this case). In most
situations &lt;cite&gt;decodebin&lt;/cite&gt; will use an hardware decoder. The decoded video frames are
uploaded to the &lt;span class="caps"&gt;GPU&lt;/span&gt; and composited with the EGLImages representing the web-page,
in a single OpenGL scene, using the &lt;cite&gt;glvideomixer&lt;/cite&gt; element.&lt;/p&gt;
&lt;p&gt;The initial version of the GstWPE plugin is now part of the gst-plugins-bad
staging area, where most new plugins are uploaded for further improvements later
on. Speaking of improvements, the following tasks have been&amp;nbsp;identified:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The wpesrc &lt;cite&gt;draw-background&lt;/cite&gt; property is not yet operational due to missing
WPEWebKit &lt;span class="caps"&gt;API&lt;/span&gt; for background-color configuration support. I expect to complete
this task very soon, interested people can follow &lt;a class="reference external" href="https://bugs.webkit.org/show_bug.cgi?id=192305"&gt;this bugzilla&amp;nbsp;ticket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Audio support, WPEWebKit currently provides only EGLImages to application
side. The audio session is rendered directly to GStreamer&amp;#8217;s &lt;cite&gt;autoaudiosink&lt;/cite&gt; in
WebKit, so there&amp;#8217;s currently no audio sharing support in&amp;nbsp;wpesrc.&lt;/li&gt;
&lt;li&gt;DMABuf support as an alternative to EGLImages. WPEWebKit internally leverages
linux-dmabuf support already but doesn&amp;#8217;t expose the file descriptors and plane&amp;nbsp;informations.&lt;/li&gt;
&lt;li&gt;Better navigation events support. GStreamer&amp;#8217;s navigation events &lt;span class="caps"&gt;API&lt;/span&gt; was
initially designed for &lt;span class="caps"&gt;DVD&lt;/span&gt; menus navigation uses-cases mostly, the exposed
input events informations are not a perfect match for WPEWebKit which expects
hardware-level informations from keyboard, mouse and touch&amp;nbsp;devices.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are more ways and use-cases related with &lt;span class="caps"&gt;WPE&lt;/span&gt;, I expect to unveil another
&lt;span class="caps"&gt;WPE&lt;/span&gt; embedding project very soon. Watch this space! As usual many thanks to my
&lt;a class="reference external" href="https://igalia.com"&gt;Igalia&lt;/a&gt; colleagues for sponsoring this work. We are always happy to hear what
others are doing with &lt;span class="caps"&gt;WPE&lt;/span&gt; and to help improving it, don&amp;#8217;t hesitate to get in&amp;nbsp;touch!&lt;/p&gt;
</content><category term="misc"></category><category term="Projects"></category><category term="GStreamer"></category><category term="WebKit"></category></entry></feed>