我们经常接触到创建 DEMUX,注册 Filter 过滤数据, 通过回调过滤出 section 数据,然后我们对 section 数据做具体的解析或者其他操作。 我们这里说的 section 就是段的概念,一个 section 可能包含一个或者多个TS 包,我们可以这样理解,TS 是对数据内容发封装,属于传输层的格式,规定了传输数据的格式,它以 188 字节为单位组成一个 TS 包,在这一层,它不管封装的内容是什么,就是在传输的内容前加 上 4 个字节的头信息组成包。而我们 filter 过滤出来的 section 数据是去掉了 TS 包头的的有 效数据,可能是多个 TS 包组成起来的有效数据,我们解复用 DEMUX 中也包括对接收到的 TS 包数据,根据不同的 PID 来过滤出相应的 TS 包,然后去掉包头,把相关的多个 TS 包有 效数据组织起来形成 section 数据返回给应用开发者调用。 下图是我自己做的关于表,段,TS 包的结构关系:

  

  一个表由一个或多个段构成 (具有相同的 table_id 和 table_id_extension, 不同 section_number 来区分,并且由 last_section_number 确定该表的最大 section 的数目) ;每个段由一个或多个 TS 数 据 包 的 数 据 组 成 , 比 如 一 个 新 的 section 数 据 , 那 么 第 一 个 TS 包 的 payload_unit_start_indicator 一般为 1,后续该 section 的 TS 包的 payload_unit_start_indicator 为 0,直到另外的 section 数据到来时候 TS 包的 payload_unit_start_indicator 才变为 1(同时 也说明该 section 数据结束, section 数据的开始) 而 continuity_counter 随着具有相同 PID 新 , 的 TS 包的增加而增加,这样我们就可以方便我们组织各个 TS 包来获取 section 数据。同时 我们的 section 数据就是去掉各个 TS 包头后组织起来的有效载荷数据, 我们可以对比码流分 析仪来分析。

  一般一个 section 的长度是 1024,而 TS 包是 188,所以一般都是一个 section 是由多个 TS 包组成,当然也有可能一个 section 就是由一个 TS 的有效载荷数据组成(向 PAT 表一般都是这样)

  表是组成 SI 信息的一种数据结构。在 TS 中有很多不同节目的数据包,解码器如何确定 哪个数据包属于某个节目?其答案就是在 TS 中的 PSI 和 SI 信息里, 这些信息精确地指引出 获得某节目与该节目数据包的 PID 之间的关系。

  由 MPEG-2 定义的 TS 里面,数据包携带了两类信息:一是音、视频等素材的数据,二是 PSI 表。具有给定 PID 的数据包的有序排列就形成了 TS 流。PSI 表里的承载的内容主要是 TS(本节目流)的描述参数。由 MPEG-2 定义的 PSI 主要包含有三个表:PAT、PMT、CAT。 每个表都可作为一个或多个 TS 包的净荷插入 TS 中传送。

  

  一个 TS 数据包的净荷为 188 个字节,当一个 PSI/SI 表的字节长度大于 184 字节时,就要 对这个表进行分割,形成段(section)来传送。分段机制主要是将一个数据表分割成多个数 据段。在 PSI/SI 表到 TS 包的转换过程中,段起到了中介的作用。由于一个数据包只有 188 字节,而段的长度是可变的,EIT 表的段限长 4096 字节,其余 PSI/SI 表的段限长为 1024 字 节。因此,一个段要分成几部分插入到 TS 包的净荷中。

  PSI/SI 表的构成是:一个表由一个或多个子表构成,表用 table_id 来标识;不同的子表由 table_id 和 table_id_extension 来区分(具有相同的 table_id 和不同的 table_id_extension) ;一 个子表由一个或多个段构成 (具有相同的 table_id 和 table_id_extension, 不同 section_number 来区分) ;每个段由多个 TS数据包的数据组成,是 TS 数据包的数据,去掉了各个 TS 包的 包头后的有效数据组成,然后会形成对应的表格式,然后我们可以通过 filter 过滤出来的 section 数据参考表格式对 section 数据来解析。比如 PAT 的 section 表格式如下:

  

  每个段具有一个完整的数据结构,表的重要参数----描述符在段里传送。图 3 所示是 SDT 表 的结构。

  

  

  

  子表大于 1024 时,可把子表分割成两个或更多个段,并通过 section_number 来区分,如图 3-1 所示。

  不同的信息表在 TS 中通过 PID 来区分,具有相同 PID 的不同表由 table_id(table_id 是表 标识) 来区分, 属于同一个 table_id 的不同子表由 table_id_extension、 版本号(version_number) 进行区分, 属于同一个子表的不同段由 section_number 区分。 表的扩展标识符有: network_id、 oringinal_network_id、boquet_id、 tansport_stream_id、service_id 等。

  对于 NIT 表的子表具有相同的 table_id、network_id 和 version_number。

  对于 BAT 表的子表具有相同的 table_id、bouquet_id 和 version_number。

  对于 SDT 表的子表具有相同的 table_id、oringinal_network_id、tansport_stream _id 和 version_number。

  对于 EIT 表的子表具有相同的 table_id、oringinal_network_id、tansport_stream _id、 service_id 和 version_number。

  

PAT的定义:
  Table_id:为8bit字段,该字段标识节目关联分段,对于PAT,置为0x00。

  Section_syntax_indicator:1bit字段,对于PAT,置为0x01。

  Reserved:2bit保留字段,用于将来扩展,置为11。

  Section_length:12bit字段,指示当前section的长度,计数值从分段长度下一个字节开始,包括CRC校验的4个字节,开头两位置为00,因此其大小不超过1021。

  Transport_stream_id:16bit字段,当前TS流的ID,与网络中其他TS流相区别,由运营商指定。

  Reserved:2bit保留字段,用于将来扩展,置为11。

  Version_number:5bit字段,指出PAT表的版本号,一旦PAT表有变化,其版本号增1,当增至31时,恢复至0。

  Current_next_indicator:1bit,置为1时,表示传送的PAT当前有效,置为0表示PAT下一次有效。

  Section_number:8bit字段,表示section的数目,从0x00开始。

  Last_section_number:8bit字段,指出最后一个section号,即PAT表section的最大数目。

  Program_number:16bit字段,指出了节目对于哪一个PMT PID是可用的,当为0x00时,后面的PID对应于NIT。

  Reserved:3bit保留字段,用于将来扩展,置为111。

  Network_id:13bit字段,NIT PID。

  Program_map_PID:13bit字段,对应于program_number所指定的节目的program_map_section的PID,从上面可看出:一个program用4字节来表示(包括16bit的program_number与13bit的PID)。

  CRC:用来证实数据正确性的循环冗余校验码。

  (section_number和 last_section_number的功能是当PAT内容>184字节时,PAT表会分成多个段(sections),解复用程序必须在全部接收完成后再进行PAT的分析)

PMT定义如下:

  各字段含义如下:
  table_id:8bits的ID,应该是0x02
  section_syntax_indicator:1bit的段语法标志,应该是''1'' ''0'':固定是''0'',如果不是说明数据有错.
  reserved:2bits保留位,应该是''00''
  section_length:16bits段长度,从program_number开始,到CRC_32(包含)的字节总数.
  program_number:16bits的频道号码,表示当前的PMT关联到的频道.换句话就是说,当前描述的是program_number频道的信息.
  reserved:2bits保留位,应该是''00''
  version_number:版本号码,如果PMT内容有更新,则version_number会递增1通知解复用程序需要重新接收节目信息,否则version_number是固定不变的.
  current_next_indicator:当前未来标志符,一般是0
  section_number:当前段号码
  last_section_number:最后段号码,含义和PAT中的对应字段相同,请参考PAT部分.
  reserved:3bits保留位,一般是''000''.
  PCR_PID:13bits的PCR PID,具体请参考ISO13818-1,解复用程序不使用该参数.
  reserved:4bits保留位,一般是''0000''
  program_info_length:节目信息长度(之后的是N个描述符结构,一般可以忽略掉,这个字段就代表描述符总的长度,单位是Bytes) 紧接着就是频道内部包含的节目类型和对应的PID号码了.
  stream_type:8bits流类型,标志是Video还是Audio还是其他数据.
  reserved:3 bits保留位.
  elementary_PID:13bits对应的数据PID号码(如果stream_type是Video,那么这个PID就是Video PID,如果stream_type标志是Audio,那么这个PID就是Audio PID)
  reserved:4 bits保留位.
  ES_info_length:和program_info_length类似的信息长度(其后是N2个描述符号)
  CRC_32:32bits段末尾是本段的CRC校验值

SDT的定义
  DVB系统提出了一个SDT表格,该表格标志一个节目的名称,并且能和 PMT中的PID联系起来,这样用户就可以通过直接选择节目名称来选择节目了. SDT, Service description section,服务描述段 SDT可以提供的信息包括: (1) 该节目是否在播放中 (2) 该节目是否被加密 (3) 该节目的名称
  SDT定义如下: 各字段定义如下:
    table_id:8bits的ID,可以是0x42,表示描述的是当前流的信息,也可以是0x46,表示是其他流的信息(EPG使用此参数)
    section_syntax_indicator:段语法标志,一般是''1''
    reserved_future_used:2bits保留未来使用
    reserved:1bit保留位,防止控制字冲突,一般是''0'',也有可能是''1''
    section_length:12bits的段长度,单位是Bytes,从transport_stream_id开始,到CRC_32结束(包含)
    transport_stream_id:16bits当前描述的流ID
    reserved:2bits保留位
    version_number:5bits的版本号码,如果数据更新则此字段递增1
    current_next_indicator:当前未来标志,一般是''0'',表示当前马上使用.
    original_netword_id:16bits的原始网络ID号
    reserved_future_use:8bits保留未来使用位
  接下来是N个节目信息的循环:
    service_id:16 bits的服务器ID,实际上就是PMT段中的program_number.
    reserved_future_used:6bits保留未来使用位
    EIT_schedule_flag:1bit的EIT信息,1表示当前流实现了该节目的EIT传送
    EIT_present_following_flag:1bits的EIT信息,1表示当前流实现了该节目的EIT传送
    running_status:3bits的运行状态信息:1-还未播放 2-几分钟后马上开始,3-被暂停播出,4-正在播放,其他---保留
    free_CA_mode:1bits的加密信息,''1''表示该节目被加密. 紧 接着的是描述符,一般是Service descriptor,分析此描述符可以获取servive_id指定的节目的节目名称.具体格式请参考 EN300468中的Service descriptor部分.

ts包、表、子表、section的关系的更多相关文章

  1. CRM 2016 子表单中N:1关系 字段要求与新建时的关系

    父表单在新建子表单项时弹出的窗口和 子表单的N:1关系是有关系的.说白了就是子表单窗体上的父表单字段是不是必填项. 关系如下: 1 非必填项 点击子表单的"+"号时,会出现look ...

  2. 最简单删除SQL Server中所有数据的方法(不用考虑表之间的约束条件,即主表与子表的关系)

    其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入死循环,二是这里使用了微软未正式公开的sp_MSF ...

  3. Maximo子表中增加附件功能

    附件功能的实现(详见ewell.webclient.beans.warranty.WarrantysDateBean ,ewell.webclient.beans.doclinks.custom.Ad ...

  4. 010杰信-创建购销合同Excel报表系列-3-新增合同货物:这里涉及到子表的新增(合同货物表是购销合同表的子表)

    效果说明: 前面分析过购销合同的Excel报表需要四张表,这篇讲的是合同货物表. 这个合同货物表是购销合同的子表,是一个购销合同有多个合同货物的关系.在合同货物表中有购销合同的主键作为外键.所以这张表 ...

  5. mysql中相关,无关子查询,表与表之间的关系以及编码和乱码的解决

    ※MySQL中的字符编码(注意,utf8中没有'-',跟Java中不一样)SHOW VARIABLES; //查看系统变量//查询字符编码相关的系统变量SHOW VARIABLES WHERE var ...

  6. Day055--MySQL--外键的变种,表与表的关系,单表查询,多表查询, 内连接,左右连接,全外连接

    表和表的关系 ---- 外键的变种 * 一对多或多对一 多对多 一对一 参考 https://www.cnblogs.com/majj/p/9169416.html 如何找出两张表之间的关系 分析步骤 ...

  7. MySQL表与表之间的关系详解

    外键 说到表与表之间的关系就不得不说到一个关键词:外键 MySQ中的外键是什么,和表与表之间有什么关联? 外键(foreign key)又叫外连接, 在数据库中发挥着重要的作用 尤其是对于表和表之间的 ...

  8. hive中创建子表并插入数据过程初始化MR报错解决方法

    本文继成上一篇通过hive分析nginx日志文章,详情参考下面链接: http://www.cnblogs.com/wcwen1990/p/7066230.html 接着来: 创建业务子表: drop ...

  9. [django]主次表如何取出对方数据[主表obj.子表__set()]

    [sql]mysql管理手头手册,多对多sql逻辑 国家--城市例子 class Country(models.Model): name = models.CharField(max_length=3 ...

随机推荐

  1. mysql导入大量数据时报MySQL server has gone away错误的解决办法

    https://blog.csdn.net/eric520zenobia/article/details/77619469

  2. C#实现文件异步上传

    //前台方法,包含弹出框确认以及文件选择<input type="button" id="importxlsx" name="importxls ...

  3. linux虚拟机最优测试环境搭建

    目标:创建一个最优的linux虚拟机环境 环境:vmware12.0 系统:centos6.5 (* 以下配置是建立在配置完成基础网络环境后创建的,用static静态IP地址) 1.关闭selinux ...

  4. 改写python round()函数,解决四舍五入问题 round(1.365,2)=1.36

    round()函数四舍五入存在一个问题,遇到5不一定进一.如下图所示: print(round(1.365,2)) #1.36 没进一 print('%.2f'%1.365) print(round( ...

  5. SSD 从形式到实质之改变

    SSD 从形式到实质之改变  作者:廖恒          SSD的物理尺寸之混战正在进行其中. 数据中心的硬件架构师由于要规划下一代server的机械设计.还要制定JBOD的设计规范,想必面临不少困 ...

  6. table自适应

    当table大于屏幕时,table可以左右滑动 //给table的父元素设置样式 .edit_table{ width:100%; overflow: auto; }

  7. HttpHandler使用Session

    继承自IHttpHandler的类要实现两个接口:ProcessRequest和IsReusable但还不能使用Session,要使用Session需要下面的步骤处理: 1.先引用System.Web ...

  8. o'Reill的SVG精髓(第二版)学习笔记——第四章

    第四章:基本形状 4.1线段 SVG可以使用<line>元素画出一条直线段.使用时只需要指定线段起止点的x和y坐标即可.指定坐标时可以不带单位,此时会使用用户坐标,也可以带上单位,如em. ...

  9. LinkedList---链表各种方法的实现

    public class ListExer2 { public static void main(String[] args) { LinkList list = new LinkList(); li ...

  10. 18年selenium3+python3+unittest自动化测试教程(上)

    第一章 自动化测试课程介绍和课程大纲 1.自动化测试课程介绍 简介:讲解什么是自动化测试和课程大纲讲解,课程需要的基础和学后的水平 python3.7+selenium3 pycharm 第二章自动化 ...