【问题标题】:How to convert H.264 UDP packets to playable media stream or file (defragmentation)如何将 H.264 UDP 数据包转换为可播放的媒体流或文件(碎片整理)
【发布时间】:2013-03-02 11:50:48
【问题描述】:

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

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

  1. How to process raw UDP packets so that they can be decoded by a decoder filter in a directshow source filter
  2. Problem to Decode H264 video over RTP with ffmpeg (libavcodec)

两者都有一些令人困惑的细微差别(见下文)。

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

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

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

第一个字节:[ 3 NAL UNIT BITS | 5 片段类型位]
第二个字节:[ 起始位 |结束位 |保留位 | 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 的不同之处在于,有效载荷标头的第二个字节也可能被放入已转换的数据包中。但我都尝试了,但仍然没有运气。

新构建的流中可能还缺少其他东西?还是我碎片整理有误?

【问题讨论】:

  • 原来组合帧的新payload header是错误的。我会检查那里可能有什么问题。
  • [3 NAL 单位位(从第一个字节开始)| 5 NAL UNIT BITS(从第二个字节开始)| 0x40] 可以解决问题。我还不知道为什么。

标签: java udp h.264 rtp sdp


【解决方案1】:

请参阅Problem to Decode H264 video over RTP with ffmpeg (libavcodec) 以获取答案。它有正确的实现!

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

【讨论】:

    【解决方案2】:

    托马斯,

    我正在尝试自己理解这一切。在我看来,通过阅读以下内容:How to process raw UDP packets so that they can be decoded by a decoder filter in a directshow source filter 您的“起始字节”减少了一个字节。我认为它是 3 个字节,而不是 4 个......如:00 00 01

    也许这就是它遇到问题的地方。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 2010-11-24
      • 1970-01-01
      相关资源
      最近更新 更多