Skip to content

Hardware encoding for screencasts

From the main commit message:

Now that we have the pipeline fallback mechanism, we can add more
gstreamer pipelines, the generic preference goes like this:

1) Try h264 on hardware using VA-API, first using vapostproc to do
the color conversion using specialized hardware, then using the
color conversion shader. We're using the new va* instead of vaapi*
gst elements here, as those are maintained and should already be more
stable than the old ones.

2) Try h264 on hardware using nvenc for nvidia graphics cards, this
encoder should be quite stable, and the nvenc encoders are known to
work very well.

3) Try h264 on hardware using v4l2 for most ARM devices. This is using
the new v4l2sl (stateless) encoder, which is also actively maintained
and developed, and supporting all the modern devices.

4) Fall back to h264 software encoding using openh264. This is the least
problematic software encoder for h264, Fedora ships it in a
pre-installed repo and it can be enabled very easily. Most people should
have it enabled already to allow for decoding of h264 content. Unlike
vp8enc, this encoder is optimized for realtime and is really fast, it
outperforms the vp8 encoder by an order of magnitude and should allow
for smooth recordings even on older hardware.

5) Fall back to the two existing vp8 pipelines, these are the ones that
should work on all systems (including setups using software rendering
where no DMA buffers are available).

All the hardware encoder pipelines use capsfilters to enforce the use of
DMA buffers on the path from mutter to the color conversion, and from the
color conversion to the encoder. Using DMA buffers should ensure that
secondary GPUs are not used for the encoding when gnome-shell is running
on the primary GPU, potentially doing very slow copying of data. That's
only as long as mutter doesn't support explicit modifiers though, once
those are in, we need a different solution to make sure the internal GPU
is used.

The reason why mp4 was chosen as a container format over mkv is that mp4
can be played inside firefox and chromium, whereas mkv can't be played.
It's ensured that the mp4 file is still playable in case the recording
got cancelled by using the "first-moov-then-finalise" fragment-mode on
mp4mux.

This is a fairly conservative aproach, relying only on the h264 encoder.
Even though h264 is problematic from a patent perspective and often can't
be shipped by default, it still the best supported codec out there. The
software encoders and decoders are really fast, it's used everywhere on
the web, and it can be hardware decoded on almost any device out there.

Once AV1 is more popular and supported by more hardware, we should
probably move on to that, but for now h264 seems like the best tradeoff
in terms of stability, compatibility, and performance, even with the
patent issues around it. We're entering uncharted territories here
already, shipping hardware encoding on linux for a large range of
devices, so far this has only been done on tightly controlled embedded
platforms. We shouldn't make our lives even harder by shipping even more
rarely used encoders and formats.
Edited by Jonas Dreßler

Merge request reports