我需要在Rust中生成一个实时叠加层,用作GStreamer源。
我有一些可变变量;需要在1080p60视频流上叠加的字符串数组和一些传感器数据。
最先生成原始流,还是先编码到MJPG?什么方法在Rust应用程序和GStreamer之间的总开销最小?
答案 0 :(得分:2)
这里有多种选择,具体取决于您希望如何生成叠加层。我不建议通过MJPEG或其他任何东西,但只是在原始视频上工作。使用Rust GStreamer绑定非常方便,并且基本上具有最低的开销。
1)生成叠加原始视频流,每个帧都是完全透明的,没有叠加。这可以类似于Rust GStreamer绑定here
中的appsrc示例然后,您可以将其传递给compositor元素(或使用某些硬件API的glvideomixer或其他混音器元素),这可以合成您的普通视频流和叠加流。
为了生成叠加层,您可以使用任何可以在ARGB(或任何其他原始视频格式)上呈现文本等的API。一种选择是Cairo,它也有Rust绑定。
与下一个解决方案相比,它必须生成完整的视频帧,合成器必须为每个帧生成另一个视频帧。必须进行大量的复制。
2)您可以在Rust中编写GStreamer元素,充当视频过滤器并在视频帧上绘制叠加层。有一个示例视频过滤器here,我写了一篇文章解释每个部分here
您不必在src / lib.rs中执行所有插件初始化工作,但可能只有应用程序内部RGB2Gray转换器的源文件等效,并在代码开头的某处调用寄存器函数
视频滤波器本身也会更简单,因为输入和输出格式是相同的。
为了生成叠加层,您可以使用任何可以在ARGB(或任何其他原始视频格式)上呈现文本等的API。一种选择是Cairo,它也有Rust绑定。
除了可能需要的视频格式转换(如果输入视频的格式与您支持的格式不同),这将是最有效的方法。
3)使用cairooverlay GStreamer元素。它基本上像2)一样工作,并直接为您提供开罗上下文,然后您可以使用它来在视频帧上绘制任何您想要的内容。对于通过元素的每一帧,您都会获得一个带有Cairo上下文的信号(“绘制”信号)。
但是你必须使用Cairo API,你可能需要为Rust Cairo绑定添加一些API扩展。我不是百分百确定是否已经有了所需的一切。