Qt Multimedia GStreamer 后端
本页面介绍了Qt Multimedia 中 GStreamer 后端的限制和自定义要点,该后端是嵌入式 Linux 系统上的默认媒体后端。
架构考量
GStreamer 之所以成为嵌入式 Linux 上的默认媒体后端,主要是因为它是大多数嵌入式主板厂商在支持硬件加速媒体时优先考虑的框架。FFmpeg 在某些平台上也可能适用,因此建议用户尝试这两种媒体后端,以找出最适合自己的方案。
Qt Multimedia 并非通用流媒体框架,也未必是将 GStreamer 与 Qt 结合使用的最佳架构方案。对于需要高度控制 GStreamer 管道,但仅希望通过 Qt 显示视频输出的开发者,不妨考虑使用 GStreamer 的qml6glsink。
限制与已知问题
GStreamer 并未随 Qt 捆绑提供,但通常随 Linux 发行版一起部署。
- 某些错误可能源于所使用的 GStreamer 版本。我们建议在您的平台上使用最新的 GStreamer 错误修复版本。
- 某些错误也可能与 GStreamer 使用的库(如 Pulseaudio)有关。最值得注意的是,Pulseaudio v16 存在一个已知错误,会导致 GStreamer 管道卡死,需要回溯应用以下两个补丁:
- https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/745
- https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/764
该漏洞目前影响大多数主流 Linux 发行版,包括 Ubuntu 22.04、23.10 和 24.04,Debian 11 和 12,以及 Fedora 39 和 40。
- 录制过程中不支持切换摄像头设备或摄像头
- 快进/快退、播放速率、循环播放和切换输出设备均存在已知问题。
- 音频功能需要 PulseAudio。详情请参阅Linux 平台说明。
- 某些嵌入式开发板需要单独配置以解决管道协商/链接问题并提升性能。建议开发者在遇到此类问题时,尝试调整“自定义要点”部分列出的环境变量。Qt的Yocto元层文件中包含了针对特定开发板、BSP和Boot to Qt 版本组合的推荐配置。以下是开发分支版本的链接:
- NXP i.MX 6/8/9:https://code。qt.io/cgit/yocto/meta-boot2qt.git/tree/meta-boot2qt-distro/dynamic-layers/freescale-layer/recipes-qt/boot2qt-addons/default-qt-envs.bbappend?h=dev
- 树莓派 4/5:https://code。qt.io/cgit/yocto/meta-boot2qt.git/tree/meta-boot2qt-distro/dynamic-layers/raspberrypi/recipes-qt/boot2qt-addons/default-qt-envs.bbappend?h=dev
- 某些NXP i.MX开发板会暴露一个名为imx-capture的v4l2设备,若在GStreamer中与v4l2src配合使用,可能会导致错误。 为防止Qt Multimedia 将imx-capture添加到可用摄像头设备列表中,请将环境变量QT_GSTREAMER_SKIP_IMXCAPTURE设置为1。请注意,这被视为私有API,待NXP 修复imx-capture相关问题后,该API将被移除。
- 使用系统内存视频帧或软件转换进行视频播放或摄像头流传输时,可能会因 CPU 负载过重而导致丢帧和系统无响应。如果 GStreamer 解码器或摄像头设备输出的是由 DMA-BUF 或 GLMemory 支持的、符合我们支持的像素格式的视频帧,Qt 可以无需额外转换或复制即可直接渲染这些帧。 GStreamer 会根据其管道元素的能力来选择格式和内存类型。关于如何控制哪些元素被添加到管道中的不同方法,请参阅“自定义点”部分。另请参阅“为 v4l2 摄像头指定 I/O 模式”。
自定义点
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=identityGStreamer 还可以通过 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.