• 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 包格式

  • 相关阅读:
    java计算机毕业设计海康物流MyBatis+系统+LW文档+源码+调试部署
    [附源码]计算机毕业设计JAVAjsp校园志愿者服务管理系统
    三栏布局,中间自适应
    ERR_PNPM_LINKING_FAILED Error: EPERM: operation not permitted, rename
    多线程事物造成死锁全面分析
    如何快速选购腾讯云NVIDIA GPU云服务器实例?
    Linux 6种日志查看方法
    VSCODE调试控制台的使用——以pytorch下神经网络的加载模型前向传播为例
    Apollo配置中心-手把手教你搭建Apollo配置中心运行环境
    小程序固定头部实现:van-nav-bar插件
  • 原文地址:https://blog.csdn.net/hejinjing_tom_com/article/details/127096094