Qt Multimedia GStreamer 后端
本页介绍Qt Multimedia 的 GStreamer 后端(嵌入式 Linux 上的默认媒体后端)的限制和定制要点。
架构注意事项
GStreamer 之所以是嵌入式 Linux 的默认媒体后端,主要是因为大多数嵌入式板卡供应商都优先采用它来提供硬件加速媒体支持。FFmpeg 也适用于某些平台,因此我们鼓励用户尝试使用这两种媒体后端,以找出最适合自己的方式。
Qt Multimedia GStreamer不是通用的流媒体框架,也不一定是在Qt上使用GStreamer的最佳架构。如果开发人员需要对 GStreamer 管道进行高度控制,但又只想在 Qt 中显示视频输出,则可以考虑使用 GStreamer 的qml6glsink。
限制和已知问题
GStreamer 未与 Qt 捆绑,但通常与 Linux 发行版一起部署。
- 某些错误可能是由于使用的 GStreamer 版本造成的。我们建议在你的平台上使用最新的 GStreamer 错误修复版本。
- 某些错误也可能与 GStreamer 使用的库有关,如 Pulseaudio。最值得注意的是 Pulseaudio v16 有一个已知的 bug,会导致 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
- Raspberry Pi 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 问题后删除。
- 使用系统内存视频帧或软件转换进行视频回放或摄像机流媒体播放,可能会因 CPU 负载过重而导致丢帧和无响应。如果 GStreamer 解码器或摄像头设备以我们支持的像素格式之一输出 DMA-BUF 或 GLMemory 支持的视频帧,Qt 就能渲染它们,而无需额外的转换或复制。GStreamer 根据其流水线元素的能力选择格式和内存类型。自定义点中描述了控制哪些元素被添加到流水线的不同方法。另请参阅为 v4l2 摄像机指定 I/O 模式。
自定义点
Qt Multimedia 提供了某些自定义点,允许访问底层 GStreamer 管道。入口点是class QGStreamerPlatformSpecificInterface 。其他自定义功能可通过设置环境变量完成。
警告 此处列出的自定义点和 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 摄像头的 v4l2 捕捉设备时,底层 v4l2src GStreamer 元素的io-mode属性会影响它是否输出允许零拷贝渲染的 DMA-BUF 支持视频帧。在某些情况下,即使摄像机驱动程序支持 dmabuf 模式,默认自动模式也会选择 mmap 模式。可以通过下面的环境变量明确设置 io-mode 属性 int 值。下面的示例展示了如何使用枚举 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/private/qgstreamer_platformspecificinterface_p.h> [...] QMediaPlayer player; GstPipeline *pipeline = QGStreamerPlatformSpecificInterface::instance()->gstPipeline(&player); [...] QMediaCaptureSession session; GstPipeline *pipeline = QGStreamerPlatformSpecificInterface::instance()->gstPipeline(&session);
自定义 GStreamer 元素作为汇和源
可以从 GStreamer 管道描述中创建 GStreamer 元素,并将它们封装在QCamera 或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:自定义源
QMediaPlayer 接受 GStreamer 管道描述作为源 URI:
QMediaPlayer player; player.setSource(u"gstreamer-pipeline: videotestsrc name=testsrc"_s);
这将尝试编译管道描述作为QMediaPlayer 中的源,并自动连接到QMediaPlayer 的汇。
警告: Hic sunt dracones!自定义管道是一项试验性功能:自定义管道不能很好地映射到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.