如何将RTP/H264流写为文件

Jun*_*Jun 10 streaming ffmpeg rtp h.264

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

我现在要做的是将RTP/H264流存储为文件.

到目前为止我发现的是以下内容:

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

| RTP HEADER 12bytes long | FU INDICATOR 1byte | FU HEADER 1byte | FU payload |
Run Code Online (Sandbox Code Playgroud)

据我了解RFC 6184文档,我正在使用一个数据包启动一个NAL,该数据包在FU Header的第一位有'1',并追加在第一位设置'0'的数据包,直到最后一个数据包为'1'在FU Header的第二位.

我认为这是如何在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
 ...
Run Code Online (Sandbox Code Playgroud)

我的问题是,

  1. 如果我可以通过FU-A从分段数据包中获取完整的NAL,我怎样才能将其作为能够由VLC或其他播放器运行的文件?

  2. 如果我必须保留FU指示器和FU标头,我仍然感到困惑.有人说我只需要将它们用于第一个数据包(在FU标题处以'1'开头)

任何建议将非常感激.

谢谢.

小智 6

FU,STAP和MTAP NAL单元仅特定于RTP分组化,因为它们旨在促进网络传输.换句话说,不要指望正确解析它们的解码器.最终,您需要像FU数据包一样重新组合NAL单元,或者在STAP/MTAP的情况下将它们分解为多个NAL单元.

一旦你有一个NAL单元(这包括PPS,SPS,SEI,切片分区和1-23范围内的所有其他类型),那么你可以写入磁盘以及每个H.264的'0001'起始代码附件B.

将H.264附件B流放入诸如MPEG-4的容器中可以使用各种命令行工具完成(我很确定ffmpeg可以做到这一点).


Ral*_*alf 5

  1. 一种选择是将数据复用为文件格式,如mp4或avi,以便能够与VLC一起播放.AFAIR avi不适合H.264(不记得手头的原因).有免费的库,比如libmp4,如果你在Windows上使用DirectShow,那就是Geraint的mp4mux.

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

    ffmpeg -i test.264 test.mp4

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

  2. 来自RFC6184

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

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