有没有办法可以将视频帧从 GStreamer 转换为要在 Skia 中使用的 SkImage 实例?

问题描述

我目前正在使用 GStreamer 编写自己的游戏引擎,用于媒体和 Skia (Vulkan) 用于图形。有没有办法可以将视频帧从 GStreamer 转换为要在 Skia 中使用的 SkImage 实例?

我在网上搜索了文档和解决方案,但我发现我可以通过来自 GStreamer 的信号通过 GstBuffer 获得 fakesink。不确定这是否有帮助。

解决方法

您基本上需要 https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/tree/master/examples/src/bin 中的 app_sink.rsapp_src.rs 示例的组合。

第一个向您展示了如何从管道中获取(在本例中为音频)缓冲区。您将收到为每个到达的缓冲区调用的回调。然后你可以

  1. 从回调中提取它们并通过某种渠道将它们传递给您的skia代码
  2. 只需通知您的skia 代码缓冲区可用,然后从skia 代码中提取它
  3. 直接从skia代码中拉取:这将阻塞,直到缓冲区可用

第二部分向您展示了如何使用 gst_video::VideoFrame API 来映射 gst::Buffer 并访问原始视频数据。这应该允许你以某种方式将它传递给skia。我不知道skia是如何工作的,所以你必须自己弄清楚那部分。

您还需要确保 GStreamer 以正确的格式为您提供数据,例如RGB。 app_sink.rs 示例通过在 appsink 元素上设置上限来实现这一点,在您的情况下,您希望在那里设置相应的视频上限,以描述skia 想要的格式。

该目录中另一个可能有用的示例是 glupload.rs 示例。它使用 appsink 将 GStreamer 缓冲区作为 GL 纹理获取,然后通过 glutin 渲染它们。 Vulkan 也可以实现类似的功能,但目前 GStreamer Vulkan 库还不是绑定的一部分。