在 GStreamer 中指定接收器的显示

Specify a display for a sink in GStreamer

我正在尝试在特定屏幕上显示视频流。 现在我使用具有 displayfullscreen 属性的 waylandsink,所以我有:

gst-launch-1.0 videotestsrc ! waylandsink display=wayland-0 fullscreen=TRUE

它工作正常。 然后我使用 xrandr --listmonitors 检查我的显示列表,我得到:

Monitors: 2 
  +*XWAYLAND0 1920/508x1080/286+0+0  XWAYLAND0
  +XWAYLAND1 1920/508x1080/286+1920+0  XWAYLAND1

所以我尝试用 wayland-1 替换 wayland-0 但管道停止了。 我不确定我的显示名称是否正确或我应该如何获得它(至于现在我使用了 wayland-0 并简单地增加了它)。或者如果可以使用 waylandsink

编辑: 我做了更多的研究(但还不够)。首先,我意识到 waylandsink 可能不是我要找的东西。其次是Linux中的how rendering works没看懂(现在还是不太明白)

但我发现:

我会继续寻找...

终于找到了!这是 kmssink 但我会解释更多原因。

首先我谈到了waylandsink。问题是我不知道 wayland 是一种协议,它似乎只适用于在桌面环境 (DE) 中显示内容。所以我想你可以为每个显示器创建 windows,然后 link 你的接收器到那些 windows。但我一直在寻找一种无需任何 DE 即可显示的方法,因此 waylandsink 不是一个选项。

对于glimagesink,根据我的尝试,它也在 DE 中,所以我没有进一步探索它。

然后是使用 fbdevsink 的帧缓冲区。它可以在没有 DE 的情况下工作,但有局限性...... /dev/fb0 中似乎只有一个帧缓冲区,无论显示分辨率如何,我们在其中绘制的内容都会显示在每个屏幕上。因此,如果我们有 2 个不同分辨率的显示器,我们不能在不对其中一个进行裁剪的情况下进行全屏显示。另外,我们不能在每个屏幕上显示不同的视频,因为帧缓冲区是重复的。最后,在我对其进行测试时,我发现有一段时间有帧被同时绘制到帧缓冲区中,因此这导致视频出现一些奇怪的视觉效果。 也许我列出的问题可以通过某种方式解决,但问题太多所以我放弃了这个选项

当我查看 kmssink 的文档时,它说我感兴趣的主要参数有 2 个:

  • bus-id
  • connector-id

通过指定 bus-id 我虽然可以在特定屏幕上显示。但是所有显示都使用相同的 bus-id: 0000:00:02.0 所以它不是指定显示的参数。

然后是connector-id。它是一个整数,可用于指定显示。在我的例子中,HDMI-A-177HDMI-A-292

如何获得 connector-id?嗯,这并不简单... 存在获取它们的命令,它称为 modetest。问题是它似乎只包含在某些嵌入式设备中。我发现该命令包含在包 libdrm 中,但在我的情况下安装它并没有让我访问该命令... 我将 GStreamer 与 Rust 结合使用,因此通过导入 drm package I was able to get a list of connector-id 和大量关于显示的数据。

所以最后我能做到:

gst-launch-1.0 videotestsrc ! kmssink connector-id=77

或:

gst-launch-1.0 videotestsrc ! kmssink connector-id=92

显示在我想要的屏幕上。 最后一件事:kmssink 需要以 root 身份执行才能工作