MPEG2演示时间戳(PTS)计算

8

我有一个MPEG2 TS文件,现在我想从每个图像帧中提取PTS信息。我知道PTS用33位描述,包括3个标记位。但是我不知道如何将这个位字段转换为更易于理解的形式(秒,毫秒)。请问有谁可以帮助我吗?

2个回答

19

MPEG2传输流时钟(PCR、PTS、DTS)的时间单位均为1/90000秒。PTS和DTS各有三个标记位需要跳过。该模式始终为(从最高有效位到最低有效位)3个位、标记位、15个位、标记位、15个位、标记位。标记位必须等于1。在C语言中,去除标记的方法如下:

uint64_t v; // this is a 64bit integer, lowest 36 bits contain a timestamp with markers
uint64_t pts = 0;
pts |= (v >> 3) & (0x0007 << 30); // top 3 bits, shifted left by 3, other bits zeroed out
pts |= (v >> 2) & (0x7fff << 15); // middle 15 bits
pts |= (v >> 1) & (0x7fff <<  0); // bottom 15 bits
// pts now has correct timestamp without markers in lowest 33 bits 

它们还有一个9位扩展字段,形成一个42位整数,其中扩展是最不显著的位。基础时间加上扩展的单位为1/27000000秒。许多实现将扩展设置为全零。


嗨,Alex, 这可能是一个冒险提问,你知道为什么数据以这种方式存储吗?我已经找了很多地方,但没有找到答案。 - jpihl
1
@jpihl 我怀疑标记的存在有两个原因:(1)捕捉所有零时间戳作为无效,(2)在按位读取或解码比特流时,当存在比特偏移时捕捉为无效。90000的单位被选择为30 fps和29.97 fps都是精确分数。 - Alex I
我明白了,这两点都很好,非常感谢!对我来说,它似乎只是为了没有好的理由使规范更加复杂。 - jpihl
1
实际上,27MHz的扩展只有PCR。PTS和DTS仅以90KHz为单位。注意:扩展的9位仅使用[0,299]值(而不是完整范围[0,511])。 - SergA

8

每天24小时 * 每小时60分钟 * 每分钟60秒 * 90k/秒(时钟)= 7962624000,需要33位才能表示;您可以使用此信息从时钟中提取时间;


不错的评论。我认为“k”代表1e3(而不是“K”)。因此,7776000000仍然是33位。 - code7amza
这是否意味着我可以从PTS获取编码器端的绝对时间?只使用00:00:00作为基准? - wick
3
抱歉,它并不意味着那样。PTS从一个任意值开始,标准中没有指定具体数值。大多数生成传输流的程序/设备都会在每个流的开头从0开始。虽然它们可以根据PTS表示的时间开始,但实际上没有这样做的。 - Alex I
PTS 可以与 PCR 结合,以在编码器端获得实际时钟,但不能保证与挂钟有任何关系 :)。 - weaknespase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接