如何从 Hex 中的 PCR 生成时间戳

How to generate timestamps from PCR in Hex

使用 tsduck 检查传输流时,我可以看到一些数据包包含十六进制的 PCR 值。我不确定如何将这些转换成时间戳。

例如下面的数据包中PCR值为0x000002014CE

* Packet 179
  ---- TS Header ----
  PID: 481 (0x01E1), header size: 25, sync: 0x47
  Error: 0, unit start: 1, priority: 0
  Scrambling: 0, continuity counter: 4
  Adaptation field: yes (21 bytes), payload: yes (163 bytes)
  Discontinuity: 0, random access: 0, ES priority: 0
  PCR: 0x000002014CE
  ---- PES Header ----
  Stream id: 0xE0 (Video 0)
  PES packet length: 0 (unbounded)
  ---- Full TS Packet Content ----
  47 41 E1 34 14 12 00 00 0D B0 7E 4E 0C 02 0A 22 8E 00 00 D1 2D 03 64 00
  29 00 00 01 E0 00 00 84 C0 0A 31 00 07 44 B7 11 00 05 D4 37 00 00 00 01
  09 30 00 00 01 06 01 03 03 84 19 80 00 00 01 41 9A 84 93 D1 13 7F F0 28
  2C 26 B5 35 90 10 B7 32 8C FF 00 D3 47 BE 4C 9A 83 AE CD B8 9C 09 5A 60
  07 BE C4 F2 2C 5D D3 24 6C 7F A0 E1 C4 7B BC FA 37 CA C5 C0 B0 C4 2C 91
  96 09 07 22 C4 A8 55 FF C2 BF 0E 7E 10 74 6D 84 F2 08 9D D0 29 52 7F 2B
  F6 3E C8 23 1F BC 4E 80 C3 AE FD AC F4 96 08 E5 13 C8 A7 41 20 B4 F6 F8
  E1 14 4A 03 4C 8E 98 00 04 73 2D AE 83 31 0B C8 61 03 3A A1

我尝试的是查看其中包含 PCR 值的数据包的前几个实例,然后将它们转换为十进制,然后除以 90,000,这是 PCR 时钟的时钟速率(即时基)。

但是看最后一栏,好像不太对。似乎间隔太高了。我以为 PCR 必须至少每 100ms 左右插入 PCR 标记,但这似乎太罕见了....

您使用的时基不正确。如果您查看您发布的示例,tsduck 将 PCR 显示为 0x000002014CE 但是该十六进制值根本不会显示在该数据包中。原因是 PCR 不仅仅是一个时间戳,它有 2 个时间戳。十六进制的PCR其实就是00 00 0D B0 7E 4E那么我们怎么从0xDB07E4E0x2014CE呢?我们通过将 0xDB07E4E 右移 15 位来提取 90 kHz 分量,然后通过屏蔽掉前 39 位来提取 27MHz 分量。然后将 90kHz 分量乘以 300 转换为 27MHz (300=27000000/90000) 并将两个值相加:

300*(0xDB07E4E>>15) + (0xDB07E4E&0x1ffff) = 0x2014CE

我们现在有了 27MHz 时间戳。要将其转换为秒,请除以 27000000

0x2014CE/27000000=0.0779

因此:

0x58e54 = 0.0135
0x78707 = 0.0183

TLDR:时基是 27000000,而不是 90000