【发布时间】:2020-12-10 22:33:28
【问题描述】:
在研究了RTP rfc 和 ISO 13818-1 (MPEG2-TS) 之后,我正在尝试从 MPEG2-TS 流中读取 H264 帧(通过 HLS)并卡住了。我已经从 MPEG-TS 流中解析了 PES 数据包,并试图读取 RTP/H264 有效负载,但它似乎没有正确解码(而且我可能遗漏了一些东西)。 00 00 00 01 的第一个开始标记符合预期,但后面的字节 (0xE0) 似乎无效。在 188 字节的数据包中还有多个起始标记,后面跟着非常少的数据:
单个 188 字节数据包:
47 41 00 30 07 50 00 00 00 00 FE 00 00 00 01 E0 00 00 80 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 02 80 00 00 03 00 80 00 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 00 1C D9 C0 00 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 C1 A4 29 C 1 BF 73 80 5E 1B E9 73 0B F5 FE FD BC 92 ED 11 67 8C 94 63 AB CE 40 4C 5C D2 68 DC 2D 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() 是一个只计算掩码和移位偏移量的助手,我确认它是正确的,除非字节序是另一种方式,但我检查了其他人是如何做到的,并且与他们的结果相比看起来是正确的。
【问题讨论】:
-
我认为我的问题可能与不正确的 PES 数据包解析有关。这似乎是 PES 数据包标头起始代码 (00 00 01 0E),不应成为有效负载的一部分。
标签: c# h.264 http-live-streaming rtp mpeg2-ts