本页内容

Qt Multimedia GStreamer 后端

本页面介绍了Qt Multimedia 中 GStreamer 后端的限制和自定义要点,该后端是嵌入式 Linux 系统上的默认媒体后端。

架构考量

GStreamer 之所以成为嵌入式 Linux 上的默认媒体后端,主要是因为它是大多数嵌入式主板厂商在支持硬件加速媒体时优先考虑的框架。FFmpeg 在某些平台上也可能适用,因此建议用户尝试这两种媒体后端,以找出最适合自己的方案。

Qt Multimedia 并非通用流媒体框架,也未必是将 GStreamer 与 Qt 结合使用的最佳架构方案。对于需要高度控制 GStreamer 管道,但仅希望通过 Qt 显示视频输出的开发者,不妨考虑使用 GStreamer 的qml6glsink。

限制与已知问题

GStreamer 并未随 Qt 捆绑提供,但通常随 Linux 发行版一起部署。

自定义点

Qt Multimedia 提供了某些自定义点,以便访问底层的 GStreamer 管道。入口点为QGStreamerInterface 。还可以通过设置环境变量进行其他自定义。

警告: 此处列出的自定义点 和 Qt 特定的环境变量被视为私有 API,可能会发生变更。请注意,环境变量默认会被子进程继承,这可能会导致意想不到的后果。

外部 OpenGL 纹理渲染

Qt 通过将底层缓冲区绑定为 EGL 图像,并将其作为 OpenGL 纹理暴露给着色器,将基于 DMA-BUF 的视频帧导入 OpenGL 图形管道。默认情况下,Qt 使用 GL_TEXTURE_2D 纹理目标和标准着色器代码对这些纹理进行采样。 某些嵌入式主板在配合专用片段着色器并使用 GL_TEXTURE_EXTERNAL_OES 纹理目标时,性能表现更佳。可通过设置以下环境变量来启用此行为:

QT_MULTIMEDIA_FORCE_GL_TEXTURE_EXTERNAL_OES=1

为 v4l2 摄像头指定 I/O 模式

当在QCamera 或QML Camera中使用v4l2捕获设备时,底层v4l2src GStreamer元素的io-mode属性将决定其是否输出基于DMA-BUF的视频帧,从而支持零拷贝渲染。 在某些情况下,即使摄像头驱动程序支持 dmabuf 模式,默认的自动模式也会选择 mmap 模式。可以通过以下环境变量显式设置 io-mode 属性的整数值。以下示例演示了如何使用枚举 GST_V4L2_IO_DMABUF 将 io-mode 设置为 dmabuf:

QT_GSTREAMER_V4L2SRC_IOMODE=4

选择特定的 GStreamer 元素

一个 GStreamer 发行版可能包含多个不同的插件,它们在媒体管道中可能执行相同任务。GStreamer 会根据其功能优先级自动选择解码器和解复用器等元素,但可以通过 GStreamer 环境变量覆盖该选择。 以下示例将 v4l2h264dec 硬件解码器的优先级设置为高于任何 H.264 软件解码器,同时确保不会选择 aiurdemux 解复用器:

GST_PLUGIN_FEATURE_RANK=v4l2h264dec:MAX,aiurdemux:NONE

要检查运行时创建了哪些元素,请为 GstElementFactory 启用 4 级调试日志:

GST_DEBUG=GST_ELEMENT_FACTORY:4

此外,您可以通过指定一个文件夹来存储.dot 图文件(这些文件会在各种事件发生时被导出,例如播放状态发生变化时),从而直观地检查整个GStreamer管道:

GST_DEBUG_DUMP_DOT_DIR=/root/graphs

有关这些环境变量的更多信息,请参阅 GStreamer 文档:

指定硬件转换组件

如果 GStreamer 管道的媒体源无法提供符合 `Qt Multimedia` 支持的像素格式的视频缓冲区,则该管道将使用软件转换,除非其中包含合适的硬件加速视频转换元素。要指定要使用的硬件转换元素,请将其作为GStreamer 管道描述设置到以下环境变量中:

QT_GSTREAMER_OVERRIDE_VIDEO_CONVERSION_ELEMENT

如果可用,某些供应商专有的转换元素(如 imxvideoconvert_g2d、nvvidconv)会默认添加到管道中。如果不需要这些元素,可能会导致不必要的转换,可以通过使用同一环境变量指定 GStreamer身份元素来禁用它们:

QT_GSTREAMER_OVERRIDE_VIDEO_CONVERSION_ELEMENT=identity

GStreamer 还可以通过 OpenGL 组件执行格式转换,为 Qt 提供基于 GLMemory 的视频帧:

QT_GSTREAMER_OVERRIDE_VIDEO_CONVERSION_ELEMENT=glupload ! glcolorconvert

原始管道访问

可以访问支撑QMediaPlayer 和QMediaCaptureSession 的底层GstPipeline 。

警告:这是一个 不安全的 API,因为管道仍由 Qt 实现进行管理。使用此 API 时需格外谨慎。

#include <QtMultimedia/spi/qgstreamerinterface.h>

[...]
QMediaPlayer player;
GstPipeline *pipeline = QGStreamerInterface::instance()->gstPipeline(&player);
[...]
QMediaCaptureSession session;
GstPipeline *pipeline = QGStreamerInterface::instance()->gstPipeline(&session);

将自定义 GStreamer 元素用作接收端和源

可以根据 GStreamer 管道描述创建 GStreamer 元素,并将其封装在QGStreamerVideoSource 或QAudioDevice 中:

#include <QtMultimedia/spi/qgstreamerinterface.h>
#include <QtMultimedia/spi/qgstreamervideosource.h>

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

QGStreamerVideoSource videoSource(QStringLiteral("videotestsrc is-live=true ! gamma gamma=2.0"));
session.setNativeVideoSource(&videoSource);
videoSource.start();

QMediaPlayer:自定义源

QMediaPlayer 接受 GStreamer 管道描述作为源 URI:

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

这将尝试编译该管道描述以作为QMediaPlayer 的源,并自动连接到QMediaPlayer 的接收端。

警告:此处 有龙!自定义管道是一项实验性功能:自定义管道与QMediaPlayer 的API映射并不理想,最明显的是媒体状态、元数据API以及传输状态。大多数调用将直接映射到GStreamer管道,这可能会根据管道的不同导致未定义的行为。 在大多数情况下,gstreamer-pipeline: 可能并非应用程序代码的理想选择:对于任意视频源,建议优先使用配备自定义摄像头的QMediaCaptureSession (参见上文)。对于仅需将内容渲染到 Qt/Qml GUI 中的任意复杂管道,GStreamer 的qml6glsink (参见下文)可能是更稳健的选择。

© 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.