确定RTP流中H.264 I帧的结尾

问题描述 投票:1回答:3

我处理来自IP摄像机的H.264 RTP流。我使用的摄像机将每个I帧拆分为几个NAL单元,每个I帧均拆分为RTP数据包(开始和结束标志确定每个单元的尺寸,而不是帧的尺寸)。

我怎么知道何时完成帧传输并且我有足够的数据来解压缩它?由于框架由几个单元组成-标记不能用于确定其结束。

[我工作的大多数摄像机都将每个帧分割为RTP数据包,其中标志确定帧的开始和结束。所以我从等待结束标志的数据包中解包数据-这是一个完整的帧。

我从这台摄像机获得的NAL单位顺序是:

[[NAL_UT_SPS]序列参数集+

[NAL_UT_PPS]图片参数集

[NAL_UT_SEI]补充增强信息

[NAL_UT_IDR_SLICE] I帧图像数据的第1部分

[NAL_UT_IDR_SLICE] I帧图像数据的第2部分

[NAL_UT_IDR_SLICE] I帧图像数据的第3部分

[NAL_UT_SLICE]第一个P帧

[NAL_UT_SLICE]第二个P帧

[NAL_UT_SLICE]第三个P帧

...

从此序列中,很明显,我可以将[NAL_UT_SPS] + [NAL_UT_PPS] + [NAL_UT_SEI] + 3 * [NAL_UT_IDR_SLICE]组合成一个I帧,然后我将其馈送到解码器。但是,如何确定多少个图片数据部分呢?我怎么知道我收到#X部分后,它不是序列中的最后一个?

有什么想法吗?

camera ip h.264 rtp compression
3个回答
2
投票

我解决了问题。

解决方案是:将所有非图片单元(在上面的示例中为NAL_UT_SPS,NAL_UT_PPS,NAL_UT_SEI)附加到帧的开头,对于包含图片的数据包(NAL_UT_IDR_SLICE,NAL_UT_SLICE),检查first_mb_in_slice字段(对于图片数据的第一个切片等于0,而对于第二个,第3个等于..]。

因此,如果first_mb_in_slice == 0并且缓冲区包含图片数据,则将其返回并将新的帧数据写入缓冲区,否则仅追加数据而不返回帧。这样,当我们开始接收帧2时,我们将返回帧1,并可以确定这是一个新帧,而不是上一个帧的一部分:

[[NAL_UT_SPS]帧#1(I)开始

[NAL_UT_PPS]框架#1继续

[[NAL_UT_SEI]帧#1继续

[[NAL_UT_IDR_SLICE]帧#1图片数据,第1部分:first_mb_in_slice == 0

[[NAL_UT_IDR_SLICE]帧#1图片数据,第2部分:first_mb_in_slice> 0

[[NAL_UT_IDR_SLICE]帧#1图片数据,第3部分:first_mb_in_slice> 0

[[NAL_UT_SLICE]帧#2(P)开始:first_mb_in_slice == 0

[[NAL_UT_SLICE]帧#3(P)开始:first_mb_in_slice == 0

[[NAL_UT_SLICE]帧#4(P)开始:first_mb_in_slice == 0

[[NAL_UT_SPS]帧#5(I)开始

...


0
投票

大多数H.264解码器接受输入流作为NAL。除非您有一个挑剔的解码器,否则我只会将NAL馈入解码器。通常,不能保证NAL:frame甚至slice之间的1:1关系。


0
投票

RTP定义了RPT报头中的标记位,该位向相同RTP时间戳的访问单元的结尾发出信号。如果标记位被设置,则它是此特定RTP时间戳的最后一个NALU。

如果使用标记位,则无需等待下一个访问单元到达,从而将等待时间降至最低。

您可以在5.1节中详细了解RFC for the H264 Payload中的Marker位。第9页。

© www.soinside.com 2019 - 2024. All rights reserved.