如何将RTP/H264流写入文件



我找不到上一个问题的解决方案,所以我决定一步一步地尝试。

我现在想做的事情是将RTP/H264流存储为一个文件。

到目前为止,我发现了以下内容:

(首先,我的RTP/H264是FU-A,它是的形式)

| RTP HEADER 12bytes long | FU INDICATOR 1byte | FU HEADER 1byte | FU payload |

正如我所理解的RFC 6184文档,我用在FU标头的第一位具有"1"的数据包启动NAL,并附加在第一位设置"0"的后续数据包,直到最后一个在FU标题的第二位具有"0"。

我认为这就是如何在FU-a分组之前获得一个完整的NAL,我还发现我需要将"起始位"(0x00000001)放在每个完整NAL的前面。

但到目前为止运气不佳。以下是日志的一部分

 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ...
 ========= adding the next NAL as 716
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]7C/1111100 [5]85/10000101 [6]B8/10111000 [7]40/1000000 ...
 ========= a NAL is summed up as 4866
 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= adding the next NAL as 139
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E2/11100010 [7]20/100000 ...
 ========= a NAL is summed up as 7061
 ========= the new NAL is as 1377
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]41/1000001 [5]E4/11100100 [6]40/1000000 [7]1A/11010 ...
 ========= a NAL is summed up as 1369
 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E6/11100110 [7]60/1100000 ...
 ========= adding the next NAL as 94
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]E6/11100110 [7]60/1100000 ...
 ========= a NAL is summed up as 1472
 ========= the new NAL is as 447
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]41/1000001 [5]E8/11101000 [6]80/10000000 [7]16/10110 ...
 ========= a NAL is summed up as 439
 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EA/11101010 [7]A0/10100000  ...
 ========= adding the next NAL as 1174
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EA/11101010 [7]A0/10100000 ...
 ========= a NAL is summed up as 2552
 ========= the new NAL is as 1400
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EC/11101100 [7]C0/11000000 ...
 ========= adding the next NAL as 1364
 [0]0/0 [1]0/0 [2]0/0 [3]1/1 [4]5C/1011100 [5]81/10000001 [6]EC/11101100 [7]C0/11000000 ...
 ========= a NAL is summed up as 2742
 ========= the new NAL is as 1400
 ...

我的问题是,

  1. 如果我可以通过FU-A从碎片数据包中获得完整的NAL,我如何将其作为一个可以由VLC或其他播放器运行的文件?

  2. 我仍然很困惑是否必须保留FU指示器和FU标题。有人说我只需要把它们带到第一个数据包(从FU头的"1"开始)

任何建议都将不胜感激。

谢谢。

FU、STAP和MTAP NAL单元仅专用于RTP分组,因为它们旨在促进网络传输。换句话说,不要指望解码器正确地解析它们。最终,您需要像FU数据包那样重新组装NAL单元,或者像STAP/MTAP那样将它们分解为多个NAL单元。

一旦你有了NAL单元(包括PPS、SPS、SEI、切片分区和1-23范围内的所有其他类型),那么你就可以根据H.264附件B将"0001"起始码写入磁盘。

可以使用各种命令行工具将H.264附件B流放入MPEG-4之类的容器中(我非常确信ffmpeg可以做到)。

  1. 一种选择是将数据多路复用为mp4或avi等文件格式,以便能够使用VLC播放。AFAIR avi不太适合H.264(记不清原因了)。有免费的库,比如libmp4,或者如果你在使用DirectShow的窗口上,Geraint的mp4mux

另一种选择是使用ffmpeg将.264文件转换为mp4

ffmpeg -i test.264 test.mp4

这假设.264文件包含由起始代码分隔的NAL单元。

  1. 来自RFC6184

FU有效载荷由碎片的有效载荷的碎片组成NAL单元,使得如果分段单元的有效载荷连续FU按顺序串联,即分段NAL的有效载荷可以重建单元。分段的NAL单元类型八位字节NAL单元不包括在分段单元有效载荷中,而是NAL单元类型八位字节的信息分段NAL单元在FU的F和NRI字段中传输分段单元的指示符八位字节,并且在的类型字段中FU报头。FU有效载荷可以具有任意数量的八位字节,并且可以是空的。

如果您采用1中概述的第二种方法,那么在将原始NAL单元写入.264文件之前,您将需要重建它。

最新更新