我有一个来自IP摄像机的原始H.264流,打包为RTP帧。我想将原始H.264数据保存到文件中,以便可以使用ffmpeg
进行转换。
因此,当我要将数据写入原始H.264文件时,我发现它必须看起来像这样:
00 00 01 [SPS]
00 00 01 [PPS]
00 00 01 [NALByte]
[PAYLOAD RTP Frame 1] // Payload always without the first 2 Bytes -> NAL
[PAYLOAD RTP Frame 2]
[... until PAYLOAD Frame with Mark Bit received] // From here its a new Video Frame
00 00 01 [NAL BYTE]
[PAYLOAD RTP Frame 1]
....
因此,我从先前的
SPS
通信中从PPS
中获取了Session Description Protocol
和RTSP
。另外,在从视频流本身开始之前,摄像机会以两条消息发送SPS
和PPS
。因此,我按以下顺序捕获消息:
1. Preceding RTSP Communication here ( including SDP with SPS and PPS )
2. RTP Frame with Payload: 67 42 80 28 DA 01 40 16 C4 // This is the SPS
3. RTP Frame with Payload: 68 CE 3C 80 // This is the PPS
4. RTP Frame with Payload: ... // Video Data
然后是一些带有有效负载的帧,在某个时候带有
Marker Bit = 1
的RTP帧。这意味着(如果我做对了)我有完整的视频帧。此后,我再次从有效负载中编写了前缀序列(00 00 01
)和NAL
,并继续相同的过程。现在,我的相机会在每完成8个完整视频帧后再次向我发送
SPS
和PPS
。 (同样在两个RTP帧中,如上例所示)。我知道,尤其是PPS
可以在流之间进行更改,但这不是问题。我的问题是:
1.我是否需要每8个视频帧写入一次SPS/PPS?
如果我的
SPS
和PPS
保持不变,那么只要在文件的开头写入它们就足够了,仅此而已?2.如何区分SPS/PPS和普通RTP帧?
在解析传输数据的C++代码中,我需要在具有正常有效负载的RTP帧与携带
SPS/PPS
的RTP帧之间进行区别。我该如何区分它们?好了,SPS/PPS
框架通常更小,但这并不是依赖的保存调用。因为如果我忽略它们,我需要知道可以丢弃哪些数据,或者如果我需要编写它们,则需要将00 00 01
前缀放在它们前面。 ?还是每8个视频帧出现一次固定的规则? 最佳答案
我记得,nal_unit_type是帧的第一个字节的低5位。
nal_unit_type = frame[0] & 0x1f;
关于c++ - RTP上的H.264-识别SPS和PPS帧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9618369/