Nvidia Jetson TX2平台无X11下基于eglfs运行Qt的录屏问题
无X11环境下eglfs_kms_egldevice模式的屏幕录制适配方案
现有方案失效的核心原因
ximagesrc插件依赖X11服务提供的窗口合成层数据源,无X11环境下不存在可对接的抓取目标,天然无法工作- 抓取
fb0帧缓冲的方式,读取的是内核控制台绑定的独立内存节点,eglfs模式下Qt应用的渲染输出是通过KMS/EGL直接写入硬件显示控制器的独立内存页,和fb0节点完全隔离,因此只能捕获到控制台内容,无法获取上层Qt窗口的渲染结果
可落地方案选型
基于GStreamer KMS源的原生捕获(适配现有技术栈的优先选择)
这类方案完全匹配此前使用GStreamer的开发习惯,不需要更换整体技术框架:
- 核心原理:绕开X11服务和fb设备,直接对接KMS显示管道,抓取硬件输出控制器当前绑定的扫描帧缓存,和eglfs_kms_egldevice的渲染输出路径完全一致,不存在内存隔离问题
- 插件组合逻辑:以
kmssrc作为采集端,搭配Jetson平台专属的硬件加速插件完成转码和封装 - 基础实现命令:
gst-launch-1.0 kmssrc device=/dev/dri/card0 ! video/x-raw,format=BGRA ! nvvidconv ! nvv4l2h264enc ! h264parse ! mp4mux ! filesink location=screen_record.mp4 - 关键配置注意:
kmssrc的设备路径需要指定为实际承载eglfs渲染输出的DRM主显示节点,通常Jetson平台对应/dev/dri/card0,不要使用渲染节点/dev/dri/renderD128,否则无法抓取到实际输出的屏幕内容- 运行采集进程的用户需要加入
video用户组,否则会因为权限不足无法访问DRM节点 - 可根据实际屏幕分辨率调整
kmssrc的采集分辨率参数,避免无效的缩放开销
Qt应用内嵌式录屏实现
如果录屏功能需要直接集成在现有Qt应用内部,不需要独立的后台采集进程,可采用这类方案:
- 核心逻辑:eglfs平台插件原生提供了渲染surface的帧访问接口,不需要跨进程抓取屏幕内容
- 实现路径:在Qt窗口的最终绘制完成回调中,通过EGL接口直接拷贝当前绑定的渲染surface帧,送入编码管线完成录制
- 优势:无跨进程拷贝开销,捕获内容和应用实际渲染结果100%同步,还可以灵活实现单窗口内容捕获,不受其他显示输出的干扰
基于DRM API的自定义采集实现
如果需要更灵活的采集逻辑(比如自定义裁剪区域、动态调整采集帧率),可直接基于DRM接口开发采集模块:
- 操作逻辑:通过DRM模式设置相关的IO接口,获取当前显示控制器绑定的帧缓冲物理地址,通过内存映射方式直接读取帧内容
- 避坑提醒:Jetson平台的eglfs默认启用三重缓冲机制,需要实时跟踪当前实际用于扫描输出的缓冲索引,否则会抓取到上一帧甚至未完成渲染的空白内容
适配过程常见问题
- 无X11环境下不要尝试强行启用
ximagesrc的依赖,即使插件编译安装成功,也因为不存在X11服务而无法获取有效帧 - 不要混用fb设备和DRM的采集路径,eglfs模式下fb驱动的节点会被KMS驱动抢占绑定,读取的内容和实际屏幕显示结果完全不同步
- 录制出现花屏时,优先检查采集管线的像素格式是否和eglfs配置的渲染格式对齐,Jetson平台上eglfs默认的渲染格式通常为BGRA
- 不要在录制管线中使用x264这类软件编码插件,Jetson平台需要替换为V4L2接口的硬件编码插件,否则录制帧率会远低于屏幕实际刷新率
内容的提问来源于stack exchange,提问作者Ammar Zafar
相关产品推荐
相关产品推荐

