On this page

Qt Multimedia GStreamer backend

This page covers limitations and customization points of the GStreamer backend of Qt Multimedia, the default media backend on embedded Linux.

Architectural Considerations

GStreamer is the default media backend on embedded Linux mainly because it is the framework most embedded board vendors prioritize for hardware accelerated media support. FFmpeg may also be suitable on some platforms, so users are encouraged to experiment with both media backends to find out which works best for them.

Qt Multimedia is not a general purpose streaming framework and not necessarily the architecturally best way to use GStreamer with Qt. Developers, who need a high degree of control over the GStreamer pipeline, but only want to show the video output Qt, may want to consider using GStreamer's qml6glsink.

Limitations and Known Issues

GStreamer is not bundled with Qt, but it is typically deployed with the Linux distribution.

Customization points

Qt Multimedia provides certain customization points to allow access to the underlying GStreamer pipeline. The entry point is class QGStreamerPlatformSpecificInterface. Additional customizations can be done by setting environment variables.

Warning: The customization points and Qt specific environment variables listed here, are considered as private APIs and may be subject to change. Be aware that environment variables are by default inherited by child processes and can have unintended consequences.

External OpenGL texture rendering

Qt imports DMA-BUF-backed video frames into the OpenGL graphics pipeline by binding the underlying buffer as an EGL image and exposing it to shaders as an OpenGL texture. By default, Qt samples these textures using the GL_TEXTURE_2D texture target and standard shader code. Some embedded boards performs better with the GL_TEXTURE_EXTERNAL_OES texture target instead, together with a dedicated fragment shader. This behavior can be enabled by setting the following environment variable:

QT_MULTIMEDIA_FORCE_GL_TEXTURE_EXTERNAL_OES=1

Selecting specific GStreamer elements

A GStreamer distribution can include multiple different plugins that can potentially perform the same task in the media pipeline. GStreamer automatically selects elements like decoders and demuxers based on their feature rank, which can be overridden via a GStreamer environment variable. Here's an example that ranks the v4l2h264dec hardware decoder higher than any H.264 software decoder, while also making sure the aiurdemux demuxer isn't selected:

GST_PLUGIN_FEATURE_RANK=v4l2h264dec:MAX,aiurdemux:NONE

To inspect which elements are being created during runtime, enable debug logging level 4 for GstElementFactory:

GST_DEBUG=GST_ELEMENT_FACTORY:4

Furthermore, you can visually inspect the whole GStreamer pipeline by specifying a folder for .dot graph files that will be dumped at various events, for example, changes in playback state:

GST_DEBUG_DUMP_DOT_DIR=/root/graphs

Read more about these environment variables in the GStreamer documentation:

Specifying hardware conversion elements

If the media source of a GStreamer pipeline cannot provide video buffers in a pixel format supported by Qt Multimedia, the pipeline will use software conversion unless it contains a suitable hardware accelerated video conversion element. To specify a hardware conversion element to be used, set it as a GStreamer pipeline description to the following environment variable:

QT_GSTREAMER_OVERRIDE_VIDEO_CONVERSION_ELEMENT

Some vendor specific conversion elements (imxvideoconvert_g2d, nvvidconv) are added to the pipeline by default if available. This can cause unnecessary conversion if they aren't needed, and can be disabled by specifying a GStreamer identity element using the same environment variable:

QT_GSTREAMER_OVERRIDE_VIDEO_CONVERSION_ELEMENT=identity

GStreamer can also perform format conversion with OpenGL elements, providing Qt with GLMemory-backed video frames:

QT_GSTREAMER_OVERRIDE_VIDEO_CONVERSION_ELEMENT=glupload ! glcolorconvert

Raw pipeline access

The GstPipeline underlying the QMediaPlayer and QMediaCaptureSession can be accessed.

Warning: This is an unsafe API, as the pipeline is still managed by the Qt implementation. Great care is required when using this API.

#include <QtMultimedia/private/qgstreamer_platformspecificinterface_p.h>

[...]
QMediaMediaPlayer player;
GstPipeline *pipeline = QGStreamerPlatformSpecificInterface::instance()->gstPipeline(&player);
[...]
QMediaCaptureSession session;
GstPipeline *pipeline = QGSreamerPlatformSpecificInterface::instance()->gstPipeline(&session);

Custom GStreamer elements as sinks and sources

It is possible to create GStreamer elements from a GStreamer pipeline decription and wrap them inside a QCamera or QAudioDevice:

#include <QtMultimedia/private/qgstreamer_platformspecificinterface_p.h>

[...]
QByteArray pipelineString = "videotestsrc is-live=true ! gamma gamma=2.0";

QMediaCaptureSession session;
session.setVideoSink(wid.videoSink());

QCamera *cam = QGStreamerPlatformSpecificInterface::instance()->makeCustomGStreamerCamera(
         pipelineString, &session);
session.setCamera(cam);

QMediaPlayer: custom sources

The QMediaPlayer accepts a GStreamer pipeline decription as source URI:

QMediaPlayer player;
player.setSource(u"gstreamer-pipeline: videotestsrc name=testsrc"_s);

This will try to compile the pipeline description to use as source in the QMediaPlayer and will be automatically connected to the sinks of the QMediaPlayer.

Warning: Hic sunt dracones! Custom pipelines are an experimental feature: the custom pipelines do not map well to QMediaPlayer APIs, most notably the media status, metadata APIs, and transport state. Most calls will directly map to the GStreamer pipeline, which can lead to undefined behavior depending on the pipeline. In most cases, the gstreamer-pipeline: may not be the right choice for application code: for arbitrary video sources, the QMediaCaptureSession with a custom camera (see above) is the preferred choice. For arbitrarily complex pipelines that only want to draw into a Qt/QML GUI, GStreamer's qml6glsink (see below) may be a more robust choice.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.