【问题标题】:Encode OpenGL texture using GStreamer & NVENC?使用 GStreamer 和 NVENC 编码 OpenGL 纹理?
【发布时间】:2020-01-24 19:39:42
【问题描述】:

我有一个将数据渲染成 rgba 纹理的 openGL 应用程序。我想使用 gstreamer 框架对其进行编码和流式传输(使用 nvenc 插件进行 h264 编码)。

我正在查看文档以解决这些问题:

  1. 如何将应用的现有 openGL 上下文导出到 nvenc 元素。
  2. 如何将纹理 ID 传递给来源?
  3. 同步将如何工作。即 nvenc 必须等待渲染完成,同样应用程序必须等待 nvenc 完成从纹理中读取。我假设它会涉及使用同步栅栏或 glMemoryBarriers。

任何示例代码都会非常有帮助。

我确实想避免将任何纹理复制到 cpu 内存。 Nvidia 的 NVENC sdk 提到它使用 CUDA 上下文进行调用,并且可以使用 cudaGraphicsGLRegisterImage 调用将 openGL 纹理导入到 CUDA 上下文中。所以我的期望是,从app到视频的编码帧可以不用任何副本就可以完成。

【问题讨论】:

    标签: c++ opengl gstreamer nvenc


    【解决方案1】:

    我知道这是一个老问题,但以防万一其他人遇到这个问题......

    1. 如果您的 NVENC 调用和 OpenGL 应用程序在同一个线程中,则无需对上下文执行任何操作。

      如果没有,您可能应该创建两个 OpenGL 上下文,一个用于渲染,一个用于编码。这两个上下文应该共享对象,如https://www.khronos.org/opengl/wiki/OpenGL_Context 中所述。

      您也可以只创建一个上下文并在线程之间传输上下文,方法是将其设置为“当前”到访问 OpenGL 对象的线程,但我发现这两个上下文更容易。

    2. Texture id 是一个整数,直接传过去就行了。

    3. NvEncMapInputResource“提供同步保证,在输入缓冲区用于编码之前,提交的任何图形或计算工作都已完成”。 NvEncEncodePicture 具有“同步编码模式”。

    4. 截至今天,NVENC 在 linux 上支持 OpenGL 编码设备,因此您不必在 CUDA 中注册 OpenGL 纹理。 NVENC可以直接访问OpenGL纹理,所以客户端没有内存拷贝。

      如果你在 windows 上工作,我相信你可以创建一个 CUDA 编码设备,然后从 OpenGL 纹理中获取一个 CUarray,NVENC 可以访问 CUarray。

    OpenGL 和 CUDA 编码设备的示例代码可以在 NVENC SDK 示例中找到。

    编辑:

    NvEncMapInputResource 的同步保证似乎只适用于单线程情况(或在相同的 GL 上下文中?)。如果渲染和编码发生在不同的线程和上下文中,则必须在映射之前添加同步对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-07
      • 2015-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      相关资源
      最近更新 更多