代码之家  ›  专栏  ›  技术社区  ›  Michael Brown

在C中通过RTP发出解码H264#

  •  0
  • Michael Brown  · 技术社区  · 5 年前

    我试图从MPEG2-TS流(通过HLS)中读取H264帧,在研究了这些帧之后,我被卡住了 RTP rfc 和ISO 13818-1(MPEG2-TS)。我已经解析了MPEG-TS流中的PES数据包,并试图读取RTP/H264有效载荷,但它似乎没有正确解码(我可能遗漏了一些东西)。第一个开始标记 00 00 00 01 与预期一样,但以下字节(0xE0)似乎无效。在188字节的数据包中,也有多个开始标记,后面紧跟着很少的数据:

    单个188字节数据包:

    47 41 00 30 07 50 00 00 FE 00 00 00 01 E0 00 80 05 21 00 01 00 03 00 00 00 01 09 F0 00 00 00 01 67 64 00 2A AC 2C 6A 81 E0 08 9F 97 01 6E 02 02 80 00 03 00 80 00 1E 42 00 00 00 01 68 EE 3C B0 00 00 00 01 06 E5 01 6C 80 00 00 00 01 65 B8 00 1C D9 C000 05 FF 6D 0B 52 D2 A2 D1 EF 11 EC FF C5 4A EC 63 C1 47 9F A7 78 36 7B 1F 30 0A 24 C8 0C 35 2D 96 BD BC 97 B5 E0 AA 40 A3 9F 3E 4A 42 C2 9B D0 43 63 6F 82 CD 94 2C 3C 7F A2 A4 29 DE 73 80 5E BF 1B E9 73 0B F5 FE BC 92 ED 11 67 8C 94 AB CE 40 4C 5C D2 68 DC 91 CE 19 2E BB 98

    我将起始标记(0xE0)后NAL单元头的第一个字节解码为:

    //  forbidden_zero_bit = 1 bit (for error checking, should be 0)
    //  ref_idc = 2 bits: is a reference field / frame / picture
    //  unit_type = 5 bits: Specifies the NAL payload type.
    var nalUnitHeader = 0xE0; // 1110 0000
    var forbidden_zero = nalUnitHeader.GetBits(1, 1); // 0000 0001, 1 bit (is invalid)
    var ref_idc = nalUnitHeader.GetBits(2, 2); // 0000 0011, next 2 bits
    var nalUnitType = nalUnitHeader.GetBits(5, 4); // 0000 0000, next 5 bits
    

    规范上说禁止的字段必须始终为0,所以看起来我遗漏了什么。在上面 GetBits() 是一个只计算遮罩和移位偏移的助手,我确认它是正确的,除非endianness是另一种方式,但我检查了其他人是如何做的,与他们的结果相比看起来是正确的。

    0 回复  |  直到 5 年前
        1
  •  0
  •   Michael Brown    5 年前

    事实证明,这是一个错误的 TsDecoder 我用来处理MPEG2-TS流中传输数据包的库没有正确处理自适应字段长度。它只关闭了1个字节,但最终给了我一个不正确的偏移量,我以为NAL单元的开头实际上是未处理的字节 00 以及Pes数据包头的开始 00 00 01 E0 .令人困惑,因为它看起来确实很像NAL单元启动标记 00 00 00 01 !