【问题标题】:Is it possible to remove start codes using NVENC?是否可以使用 NVENC 删除起始代码?
【发布时间】:2014-09-26 11:23:47
【问题描述】:

我正在使用NVENC SDK 编码 OpenGL 帧并通过 RTSP 流式传输它们。 NVENC 以几个 NAL 单元的形式给我编码数据。为了使用 Live555 流式传输它们,我需要找到 start code (0x00 0x00 0x01) 并将其删除。我想避免这个操作。

NVENC 有一个 sliceOffset 属性,我可以参考,但它表示切片,而不是 NAL 单元。它仅指向 SPS 和 PPS 标头的结尾,实际数据从这里开始。我知道切片不等于 NAL(如果我错了,请纠正我)。我已经对编码数据强制使用单个切片。

以下是否有可能?

  1. 强制 NVENC 对单个 NAL 单元进行编码
  2. 强制 NVENC 指示每个编码数据块中 NAL 单元的位置
  3. 让 Live555 接受流式传输的序列参数

【问题讨论】:

  • 我正在尝试做你已经实现的,使用 NVEnc 发送 OpenGL 帧。您使用的是 CUDA 互操作,还是有更好的方法?感谢您的任何指点!
  • 最好的方法是 CUDA 互操作,但我还没有这样做。我只是渲染到 FBO,将数据传递到 RAM,然后再传递到 NVENC 表面。在 CUDA 示例中应该有关于如何直接从 FBO 发送它们的资源。
  • 谢谢@chuckleplant,我去看看。到目前为止,我唯一拥有的就是在奥斯陆大学完成的这篇非常有趣的论文:heim.ifi.uio.no/paalh/students/MartinAlexanderWilhelmsen.pdf

标签: h.264 nvidia rtsp video-encoding live555


【解决方案1】:

似乎每个人都试图通过 RTSP/RTP 执行 H.264 归结为这个问题。那么这是我的两分钱:

1) 有一个访问单元的概念。访问单元是一组表示编码帧的 NAL 单元(也可能只有一个)。这是您应该工作的逻辑级别。如果您说您希望编码器为您提供单独的 NAL 单元,那么当编码过程从一个原始帧(例如 SPS + PPS + 编码图片)产生多个 NAL 单元时,您期望什么行为。话虽如此,有一些方法可以配置编码器以减少访问单元中 NAL 单元的数量(例如不包括 AUD NAL,不重复 SPS/PPS,不包括 SEI NAL)——有了这些知识,您实际上可以知道要做什么期望并强制编码器每帧为您提供单个 NAL(当然,这不适用于所有帧,但是根据您对解码器的了解,您可以处理它)。我不是 NVENC API 方面的专家,我也刚开始使用它,但至少对于 Intel Quick Sync,关闭 AUD、SEI 和禁用 PPS/SPS 的重复给了我大约 1 NAL 每帧帧 2...N。

2) 无法回答这个问题,因为正如我所提到的,我不熟悉 API,但我非常怀疑这一点。

3) SPS 和 PPS 应该在第一个访问单元(您从编码器获得的第一个比特流)中,您可以在比特流中找到正确的 NAL 并提取它们,或者可能有一个特殊的API 调用从编码器获取它们。

话虽如此,我认为实际运行比特流、解析起始代码并提取 NAL 单元并将它们一一提供给 Live555 并不难。当然,如果编码器提供以 AVCC 格式输出比特流(与起始码或附件 B 相比,它在 NAL 单元之间使用交错长度值,因此您可以直接跳转到下一个而不需要查找前缀)那么你应该使用它。当它只是 RTP 时,自己实现传输很容易,因为我运气不好 GStreamer 没有适当支持 FU-A 数据包化,在 RTSP 的情况下,传输基础设施的开销更大,而且使用像 Live555 这样的第三方库是合理的。

【讨论】:

  • 我最终通过了比特流,但我认为 (2) 对编码器来说是一件合理的事情,因为它对于流式传输会有所帮助。谢谢!
  • 好吧,AVCC 格式也提供了这一点,因此实际上不需要其他编码器特定的 API 来指定 NAL 单元的偏移量,可惜并非所有编码器都支持它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多