ts流中的时间概念: pcr,pts,dts 实例解说

ts流中的时间概念: pcr,pts,dts 实例解说
----------------------------------------
PCR OPCR
----------------------------------------
ts流包头4字节,第5字节为适配域长度,若不为0,第六字节为适配域标志.
适配域有5个标志,这里先说两个,节目参考时钟,原始节目参考时钟
所谓的时钟参考信息就是从适配域中获取的. 对dvb播放很重要. 调谐接受时钟用的
其它3个标志是什么?应该不重要,暂时也没有碰到.

PCR (Program Clock Reference) 节目参考时钟
PCR 占用42bit, 分两部分,33bit + 9 bits
program_clock_reference_base: 33bit , :后跟6bits 1,保留字段
program_clock_reference_extension: 9bit

时钟=base*300 + ext; //ext < 300, 就是这么怪,前面一个数顶300,后面一个顶1个

33bits 是90Khz时钟的计数值, 42bits 是27M时钟的计数值. 这就是300的来历(27M/90K=300).

内存存储方式: 占用6bytes


(gdb) x/7b adapt
  0x7ffff7c5ea29:    0x50    0x00    0x03    0x8e    0x8c    0x7e    0x00


第一个字节是适配域标志字节,后面跟6bytes PCR 字节

获取代码:
  if (adapt[0] & 0x10)  // We have a PCR
  {
    *got_pcr = TRUE;
    // The program_clock_reference_base
    // NB: Force the first byte to be unsigned 64 bit,
    *pcr = ((uint64_t)adapt[1] << 25) | (adapt[2] << 17) | (adapt[3] << 9) |
      (adapt[4] << 1) | (adapt[5] >> 7);
    // Plus the program clock reference extension
    *pcr = ((*pcr) * 300) + ((adapt[5] & 1) << 8) + adapt[6];
  }

pcr 是什么?
pcr是一个42bit表示的长整形,而且其数值是前33bit*300 + 后9bit(<300),

pcr时间单位是什么?  
答:不是us, PCR是针对27M时钟产生的,其时间单位是1/27M, 是小于1us的

pcr 表示的最大时间是多少?
由于pcr_low是被300求余的,则其最大值为299=0x12B,
那么pcr_va[0-5]数组的值分别为:0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2B
pcr = 0x1ffffffff*300+299
tms = pcr/27000000
用python 工具求其数值
>>> print ("%f"%((0x1ffffffff*300+299)/27000000))
95443.717689 (s)

可以算得pcr最大值为95443.717689/3600s = 26.5h ,一天多一点.

pcr 是干什么用的?
PCR用来同步头端和终端的27M时钟,并借此同步头端和终端的色度平衡和帧率。
从实现方式上,编码器内部维护一个PCR的计数器,以这个计数器为时间,DVB要求每40ms必须有一个PCR,所以要把PCR 发送到码流里
在数字电视终端设备上,都有一个压控振荡器和一个内部的计数器,这个内部的计数器会对本地压控振荡器的时钟进行计数,并且和TS流内部的PCR数字进行比较,
若本地计数器的变化率高于PCR的变化率,表征本地的27M时钟比头端27M时钟快,应该调整压控振荡器的电压,降低压控振荡器的频率;反之则提高本地振荡器的振荡频率。
ASI发出的时钟也是27M.
如果我没有调频头,只是ts文件或udp数据流, 那pcr 应该不用了??!!

OPCR.
不是输出参考时钟呢. 而是原始节目参考时钟 (Origin program clock reference),其作用及数值参考PCR

----------------------------------------
PES 及 pts dts
----------------------------------------
PES: 打包的es 主要是为了在es流中加入pts,dts时间戳信息,当然还要加别的信息.
pes 头部有6bytes, 分析一个具体的实例:


47 41 00 30 07 50 00 00 7B 0C 7E 00 00 00 01 E0
00 00 80 C0 0A 31 00 09 10 A1 11 00 07 D8 61 00
00 00 01 09 F0 00 00 00 01 06 05 FF ......

47 41 00 30: ts 头部,pid=0x100,有适配域,有负载
07: 适配域长度
50 00 00 7B 0C 7E 00:适配域 PCR , PCR用来调整接收端频率的,见pcr描述

pes 层大致为 pes_header(6b)+option_pes_header(3-259b)+Payload(最大65526)

00 00 01 : 固定pes头部
E0 00 00 : 流ID为E0,视频流,PES包长度0。 音频流ID范围从0xC0到0xDF,视频流ID范围从0xE0到0xEF。

80 C0 0A
80: '10'(固定位)+加扰控制(2)+优先级(1)+数据定位指示(1)+版权(1)+原始或复制(1)
c0: 七个标志, 先认识其中的一个,前2bits是PTS_DTS_FLAG, '11':都有,'10':仅有pts, 其它几个标志不重要也很少见.
0A: 后面数据长度

pts,dts 是如何存储的?
pts,dts 是33bits 数据,但占5bytes数据,其存储为:

PTS_DTS_flags == '11',同时有 DTS 和 PTS
    constvalue0(4bits):固定为 '0011'。
    PTS [32..30](3bits)
    constvalue1(1bit):固定为 '1'
    PTS [29..15](15bits)
    constvalue1(1bit):固定为 '1'
    PTS [14..0](15bits)
    constvalue1(1bit):固定为 '1'
    dts(33bits):为 0,封装格式与 pts 一致,除了开始的 4 bits 固定为 '0001'。

pts 代码获取:
  part1 = (data[0] & 0x0E) >> 1; //3bits
  part2 = (data[1] << 7) | ((data[2] & 0xFE) >> 1); //15bits
  part3 = (data3 << 7) | ((data4 & 0xFE) >> 1);    //15bits
  pts = (part1 << 30) | (part2 << 15) | part3;

pts,dts 是干什么用的?
PTS(presentation time)显示时间戳和DTS(decoding time stamp)解码时间戳,是用来音视频同步的,
DTS/PTS是相对SCR(系统参考)的时间戳,是以 90000为单位,
系统时钟频率为 90Khz,所以转换到秒为 PTS/90000。

31 00 09 10 A1: pts = 133200
11 00 07 D8 61: dts = 126000

剩余的为视频流负载.


参考: 1. tsreport.c 代码(ubuntu)
参考: 2. ISO/IEC 13818-1 标准
参考: 3. 网络

参考图片:ts包格式

参考图片: pes 包格式

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值