我有一个原始H.264流从一个IP相机打包在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通信中从Session Description Protocol获得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的帧之间进行区别。我怎么才能区分他们?好的,SPS/PPS帧通常要小得多,但这不是一个可以依赖的保存调用。因为如果我忽略它们,我需要知道我可以丢弃哪些数据,或者如果我需要写它们,我需要将00 00 01前缀放在它们前面。?或者它们每8帧出现一次是一条固定的规则吗?
发布于 2012-03-08 13:33:42
我记得,nal_unit_type是帧的第一个字节的较低的5位。
nal_unit_type = frame[0] & 0x1f;发布于 2012-09-01 09:27:45
编辑:关于碎片单元的NAL单元构造的更多解释:
这是FU-A有效负载的前两个字节(就在rtp头之后):
| FU indicator | FU header |
+---------------+---------------+
|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|NRI| Type |S|E|R| Type |
+---------------+---------------+要构造NAL单元,应从"FU标头“取"Type”,从"FU指示器“取"F”和"NRI“。
这里是一个简单的实现
https://stackoverflow.com/questions/9618369
复制相似问题