我有一个来自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 ProtocolRTSP。另外,在从视频流本身开始之前,摄像机会以两条消息发送SPSPPS

因此,我按以下顺序捕获消息:
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个完整视频帧后再次向我发送SPSPPS。 (同样在两个RTP帧中,如上例所示)。我知道,尤其是PPS可以在流之间进行更改,但这不是问题。

我的问题是:

1.我是否需要每8个视频帧写入一次SPS/PPS?

如果我的SPSPPS保持不变,那么只要在文件的开头写入它们就足够了,仅此而已?

2.如何区分SPS/PPS和普通RTP帧?

在解析传输数据的C++代码中,我需要在具有正常有效负载的RTP帧与携带SPS/PPS的RTP帧之间进行区别。我该如何区分它们?好了,SPS/PPS框架通常更小,但这并不是依赖的保存调用。因为如果我忽略它们,我需要知道可以丢弃哪些数据,或者如果我需要编写它们,则需要将00 00 01前缀放在它们前面。 ?还是每8个视频帧出现一次固定的规则?

最佳答案

  • 如果SPS和PPS保持不变,则可以忽略第一个参数。
  • 对于SPS,您需要解析每个NAL的nal_unit_type字段,nal_unit_type == 7;对于PPS,nal_unit_type == 8。

  • 我记得,nal_unit_type是帧的第一个字节的低5位。
    nal_unit_type = frame[0] & 0x1f;
    

    关于c++ - RTP上的H.264-识别SPS和PPS帧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9618369/

    10-09 06:59