paf*_*aft 1 compression ip camera rtp h.264
我处理来自 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 部分时,我如何知道它不是序列中的最后一个?
有任何想法吗?
我解决了这个问题。
解决方案是:将所有非图片单元(上例中的 NAL_UT_SPS、NAL_UT_PPS、NAL_UT_SEI)附加到帧的开头,并且对于包含图片的数据包(NAL_UT_IDR_SLICE、NAL_UT_SLICE)检查first_mb_in_slice 字段(对于图片数据的第一个切片与第二个、第三个不相等..)。
因此,如果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 帧
...