我使用NVENC SDK对OpenGL帧进行编码并通过RTSP对其进行流式处理。 NVENC以几个NAL单元的形式给出编码数据。为了使用Live555对它们进行流式传输,我需要找到start code(0x00 0x00 0x01)并将其删除。我想避免这种操作。
NVENC有一个sliceOffset属性,我可以参考,但它表示切片,而不是NAL单位。它仅指向实际数据开始的SPS和PPS标头的结尾。我知道切片不等于NAL(如果我错了,请纠正我)。我已经强制编码数据的单个切片。
以下任何一种可能吗?
答案 0 :(得分:1)
似乎每个人都试图通过RTSP / RTP进行H.264的问题归结为这个问题。那么这是我的两分钱:
1)存在访问单元的概念。访问单元是表示编码帧的一组NAL单元(也可以是仅一个)。这是你应该工作的逻辑层次。如果您希望编码器为您提供单独的NAL单元,那么当编码过程从一个原始帧(例如SPS + PPS +编码图像)产生多个NAL单元时,您会期望什么行为。话虽这么说,有办法配置编码器,以减少访问单元中的NAL单元数量(如不包括AUD NAL,不重复SPS / PPS,排除SEI NAL) - 有了这些知识,你实际上可以知道什么期望和强制编码器每帧给你一个NAL(当然这对所有帧都不起作用,但是你对解码器有了解,你可以处理它)。我不是NVENC API的专家,我也刚刚开始使用它,但至少对于英特尔快速同步,关闭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这样的第三方库。