5

在将 SDP 会话的 UDP 流转换为可解码的 H.264 流时,我缺少一些基本的东西。我正在使用支持 H.264 的相机进行测试,并且可以直接使用播放器播放流。当我尝试播放翻译后的流时,播放器将无法识别它(缺少标题错误)。但是,我必须对 UDP 流进行解码,以便能够将其集成到 Java 应用程序中,该应用程序周围有一些解码器。

我已经看到以下问题的非常好的答案:

  1. 如何处理原始 UDP 数据包,以便它们可以被 directshow 源过滤器中的解码器过滤器解码
  2. 使用 ffmpeg (libavcodec) 通过 RTP 解码 H264 视频的问题

两者都有一些令人困惑的小差异(见下文)。

但首先让我们看一下简单的部分。正如我从相机看到的,发送了 SPS 和 PPS 数据包。所有剩余的数据包都是索引或不索引的分段帧。

对于所有没有帧的数据包(在我的情况下只有 NALUnitType 7 和 8),我去掉 RTP 标头(12 字节)并在前面添加起始字节 3 x 0 字节和 1 x 1(00 00 00 01)。

对于所有分段的帧数据包,我根据答案 1 的描述重建它们。所以详细地说,这意味着: RTP 标头的剥离(仅用于数据验证)。然后从有效载荷中解码片段信息:

第一个字节:[ 3 NAL UNIT BITS | 5 FRAGMENT TYPE BITS]
第二个字节:[ START BIT | 结束位 | 保留位 | 5 NAL 单位位]

如果设置了起始位,则会有一个新的有效载荷头构造如下:[3 NAL UNIT BITS(从第一个字节)| 5 NAL UNIT BITS(从第二个字节开始)]
这为我们提供了 NALUnitType 1 用于非 idr 切片或 5 用于 idr 切片。这是根据规范。

我采用这个新的有效负载标头(1 个字节)并将没有 2 个字节标头的有效负载附加到一个新包中。所有连续的片段都以相同的方式添加(12 字节 RTP 标头条,2 字节单元类型信息条),直到看到结束位信息。当看到结束时,我将开始字节(00 00 00 01)放在这个数据包的前面,并将它写到流中。

问题是由于未知原因无法解码。我读过的答案的答案 2 的不同之处在于,有效载荷标头的第二个字节也可能被放入转换后的数据包中。但我都尝试了,但仍然没有运气。

新建的流中可能还缺少其他东西吗?还是我在碎片整理中犯了错误?

4

2 回答 2

2

托马斯,

我试图自己理解这一切。在我看来,从阅读以下内容:如何处理原始 UDP 数据包,以便它们可以被直接显示源过滤器中的解码器过滤器解码,您的“起始字节”关闭了一个字节。我认为它是 3 个字节,而不是 4 个......如:00 00 01

也许这就是它遇到麻烦的地方。

于 2014-10-10T20:22:38.677 回答
1

有关答案,请参阅使用 ffmpeg (libavcodec) 通过 RTP 解码 H264 视频的问题。它有正确的实现!

@Thomas,是的,如果存在 SPS、PPS 或 SEI NAL,它确实有 4 个。

于 2014-11-14T19:00:33.203 回答