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

时间:2013-02-22 22:51:39

标签: camera ip h.264 rtp compression

我处理来自IP摄像机的H.264 RTP流。我使用的相机将每个I帧分成几个NAL单元,每个单元被分成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]第3个P帧

...

从这个序列可以看出,我可以将[NAL_UT_SPS] + [NAL_UT_PPS] + [NAL_UT_SEI] + 3 * [NAL_UT_IDR_SLICE]组合成一个I帧,我最近将其提供给解码器。但是如何确定图片数据部分的数量呢?我怎么知道我什么时候收到#X部分,它不是序列中的最后一部分?

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

我解决了这个问题。

解决方案是:将所有非图片单元(上例中的NAL_UT_SPS,NAL_UT_PPS,NAL_UT_SEI)和包含图片的数据包(NAL_UT_IDR_SLICE,NAL_UT_SLICE)附加到帧的开头,检查 first_mb_in_slice字段(对于第一片图片数据,它等于0,对于第二片,第三片不等于...)。

因此,如果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< - 此时我们将返回第1帧

[NAL_UT_SLICE]帧#3(P)开始:first_mb_in_slice == 0< - 返回第2帧

[NAL_UT_SLICE]帧#4(P)开始:first_mb_in_slice == 0< - 返回第3帧

[NAL_UT_SPS]帧#5(I)开始< - 返回第4帧

...

答案 1 :(得分:0)

大多数H.264解码器接受输入流作为NAL。除非你有一个挑剔的解码器 - 我只是将NAL送入解码器。 通常,不保证NAL:帧或甚至切片之间的1:1关系。

答案 2 :(得分:0)

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

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

您可以在第5.1节的RFC for the H264 Payload中阅读有关Marker位的更多信息。第9页。