简要

ts是一种封装格式,全名为MPEG-TS,文件分为三层:ts层(Transport Stream)、pes层(Packet Elemental Stream)、es层(Elementary Stream)。es层就是音视频数据,pes层是在音视频数据上加了时间戳等对数据帧的说明信息,ts层是在pes层上加入了数据流识别和传输的必要信息(header)。

相关概念

PAT:Program Association Table,节目关联表

PMT:Program Map Table,节目映射表

ES流(Elementary Stream):基本码流,不分段的音频、视频或其他信息的连续码流。

PES流:把基本流ES分割成段,在每一个视频/音频帧上加入了时间戳等信息。

PS流(Program Stream):节目流,将具有共同时间基准的一个或多个PES组合(复合)而成的单一数据流(用于播放或编辑系统,如m2p)。

TS流(Transport Stream):传输流,将具有共同时间基准或独立时间基准的一个或多个PES组合(复合)而成的单一数据流(用于数据传输)

ES你可以理解为一段音频或者视频的数据,ES流可能会很大,所以要拆分成PES包,PES包的长度是有限制的,64KB。所以并不是一个ES对应一个PES。

TS:ts_header(0x47开头)+payload(负载)-------188个字节

PES:pes_header( 0x000001开头)+ES(包含时间戳)------64K

ES:NAL(0x0001开头(3或者4个字节),SPS(0x67),PPS(0x68),I帧(0x65),I帧(0x65))+编码data-----不限制大小,比如I帧可能有好几百K

scrambling (system): 加扰,以改变视频,音频或编码数据流的特性,防止以明文形式传输,使未经授权者接收明文数据。

PCR (system): Program Clock Reference

PTS(system):presentation time-stamp 显示时间戳,可能存在于PES包头中的字段,用于指示在系统目标解码器中显示帧数据的时间。

DTS(system):decoding time-stamp 解码时间戳,可能存在于PES包头中的字段,用于指示在系统目标解码器中解码访问帧数据的时间。

CRC:Cyclic Redundancy Check 循环冗余检查,以验证数据的正确性。

PSI:Program Specific Information 程序特定信息,提供了单个TS流的信息,使接收方能够对单个TS流中的不同节目进行解码,这些信息都存在用表的形式提供给,如PAT、PMT、CAT等。但它无法提供多个TS流的相关业务,也不能提供节目的类型、节目名称、开始时间、节目简介等信息。

SI:Specific Information 特定信息,PSI中无法提供的相关信息,SI定义了NIT、SDT、EIT和TDT等9张表,方便用户查看多种信息。

结构图

通过av_read_frame获取到原始的es数据流对比可以看出.和ts原始数据缺少了ts和pes的头.左边为.ts文件,右边为.264文件。

流程图

编码过程

TS解析图

这个图主要解析的是流的基本信息:format,filesize,duration,bitrate以及音视频的Count

PAT和PMT的相关基本信息

下面图是多音轨的TS

各种流的PID,索引及数量占的百分比,可以看到PAT和PMT是一一对应的,同时对应多个音频或者视频数据

分析

TS层的packet都是固定等长的188字节包,由ts header、adaptation field、payload组成,其中ts header固定4个字节(32位);adaptation field可能存在也可能不存在,主要作用是给不足188字节的数据做填充;payload是pes数据。结构图如下

Ts header部分

这里我们分析一段TS流其中一个Packet的Packet Data部分:
        首先给出一个数据包,其数据如下:

Packet Header

Packet Data

0x47 0x40 0x00 0x10

0000 b0 11 00 01 c1 00 00 00 00 e0 1f 00 01 e1 00 24 ac48 84 ff ff…… ff ff

分析Packet Header如下表所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

Packet(十六进制)

4

7

4

0

0

0

1

0

Packet(二进制)

0

1

0

0

0

1

1

1

0

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

Packet Header Bits

1 sync_byte=0x47

2

3

4

5 PID=0x0000

6

7

8

根据包头数据格式,我们可以知晓整个数据包的属性,列表如下:

sync_byte

0x47

固定同步字节

transport_error_indicator

“0”

没有传输错误

payload_unit_start_indicator

“1”

在前4个字节后会有一个调整字节。所以实际数据应该为去除第一个字节后的数据。即上面数据中红色部分不属于有效数据包。

transport_priority

“0”

传输优先级低

PID

0x0000

PID=0x0000说明数据包是PAT表信息

transport_scrambling_control

“00”

未加密

adaptation_field_control

“01”

附加区域控制

continuity_counte

“0000”

包递增计数器

如上表所示,我们可以知道,首先Packet的Packet Data是PAT信息表,因为其PID为0x0000,并且在包头后需要除去一个字节才是有效数据(payload_unit_start_indicator="1"),即上面数据中红色部分不属于有效数据包。这样,Packet Data就应该是“ 00 b0 11 00 01 c1 00 00 00 00 e0 1f 00 01 e1 00 24 ac48 84 ff ff …… ff ff ”。

Packet Data分析

第n个字节

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Packet Data(除去开头的0x00)

00

b0

11

00

01

c1

00

00

00

00

e0

1f

00

01

e1

00

24

ac

48

84

字段名

具体值

次序

说明

table_id

8

0000

第1个字节 0000 0000B(0x00)

PAT的table_id只能是0x00

section_syntax_indicator

1

1

第2、3个字节

1011 0000 0001 0001B(0xb0 11)

段语法标志位,固定为1

zero

1

0

reserved

2

11

section_length

12

0000 0001 0001B=0x011=17

段长度为17字节

transport_stream_id

16

0x0001

第4、5个字节 0x00 0x01

reserved

2

11

第6个字节 1100 0001B(0xc1)

version_number

5

00000

一旦PAT有变化,版本号加1

current_next_indicator

1

1

当前传送的PAT表可以使用,若为0则要等待下一个表

section_number

8

0x00

第7个字节0x00

last_section_number

8

0x00

第8个字节 0x00

开始循环

program_number

16

0x0000-第一次

2个字节(0x00 00)

节目号

reserved

3

111

2个字节

1110 0000 0001 1111B(0xe0 1f)

network_id(节目号为0时)

program_map_PID(节目号为其他时)

13

0 0000 0001 1111B=31

-第一次

节目号为0x0000时,表示这是NIT,PID=0x001f,即31

节目号为0x0001时,表示这是PMT,PID=0x100,即256

结束循环

CRC_32

32

--

4个字节

PID

PID是TS流中唯一识别标志,Packet Data是什么内容就是由PID决定的。如果一个TS流中的一个Packet的Packet Header中的PID是0x0000,那么这个Packet的Packet Data就是DVB的PAT表而非其他类型数据(如Video、Audio或其他业务信息)。

从这两个图,可以看出,PAT的PID是0。 下表给出了一些表的PID值,这些值是固定的,不允许用于更改。

PAT

PAT表(Program Association Table,节目关联表) ,PAT的PID为0x0000,它的主要作用是针对复用的每一路传输流,提供传输流中包含哪些节目、节目的编号以及对应节目的节目映射表(PMT)的位置,即PMT的TS包的包标识符(PID)的值,同时还提供网络信息表(NIT)的位置,即NIT的TS包的包标识符(PID)的值。

  • table_id: 标识一个TS PSI 分段的内容是节目关联分段,条件访问分段还是节目映射分段。对于PAT,置为0x00。
  • section_syntax_indicator: 对于PAT,置为0x01。
  • section_length: 分段长度字段,其值为从section_length(包括在内)到CRC_32字段的字节数,其值不超过1021。
  • transport_stream_id: 区别与其他复用流的标识。
  • version_number: PAT的版本号,如果PAT有变,则版本号加1。
  • current_next_indicator:置0时,表明该传送的表分段不能使用,下一个表分段才有效。
  • section_number: 表明该TS包属于该PAT的第几个分段,分段号从0开始。
  • last_section_number: 表明最后一个分段号,同时表明该PAT的最大分段数目。一般,一个PAT表由一个TS包传送。
  • program_number: 节目的编号。
  • network_PID: NIT表的PID值。
  • program_map_PID: PMT表的PID值。
  • CRC_32: CRC校验。
typedef struct TS_PAT
{  unsigned table_id                     : 8; //固定为0x00 ,标志是该表是PAT表  unsigned section_syntax_indicator     : 1; //段语法标志位,固定为1  unsigned zero                         : 1; //0  unsigned reserved_1                   : 2; // 保留位  unsigned section_length               : 12; //表示从下一个字段开始到CRC32(含)之间有用的字节数  unsigned transport_stream_id          : 16; //该传输流的ID,区别于一个网络中其它多路复用的流  unsigned reserved_2                   : 2;// 保留位  unsigned version_number               : 5; //范围0-31,表示PAT的版本号  unsigned current_next_indicator       : 1; //发送的PAT是当前有效还是下一个PAT有效  unsigned section_number               : 8; //分段的号码。PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段  unsigned last_section_number          : 8;  //最后一个分段的号码  std::vector<TS_PAT_Program> program;  unsigned reserved_3                    : 3; // 保留位  unsigned network_PID                    : 13; //网络信息表(NIT)的PID,节目号为0时对应的PID为network_PID  unsigned CRC_32                        : 32;  //CRC32校验码
} TS_PAT;   

从图中可以看到,这个TS里有一个节目,而PMT_PID=0x1000(4096)

PMT

PMT表(Program Map Table,节目映射表)

指明该节目包含的内容,即该节目由哪些流组成,这些流的类型(音频、视频、数据),以及组成该节目的流的位置,即对应的TS包的PID值,每路节目的节目时钟参考(PCR)字段的位置。

PMT表中包含的数据如下:

  • 当前节目中所有Video ES流的PID
  • 当前节目所有Audio ES流的PID
  • 当前节目PCR的PID等。

从图中可以看到这个TS包含一个program,program里包含一路视频和四路音频

主要的字段解析如下:

  • table_id: 标识一个TS PSI 分段的内容是节目关联分段,条件访问分段还是节目映射分段。对于PMT,置为0x02。
  • section_syntax_indicator: 对于PMT,置为0x01。
  • section_length: 分段长度字段,其值为从section_length(包括在内)到CRC_32字段的字节数,其值不超过1021。
  • program_number: 表明一共有多少个节目。
  • version_number: PMT的版本号,如果字段中有关信息有变,则版本号以32为模加1。版本号是对一个节目的定义。
  • current_next_indicator:置0时,表明该传送的表分段不能使用,下一个表分段才有效。
  • section_number: 总为0x00。
  • last_section_number: 总为0x00。
  • PCR_PID: 指示含有该节目的PCR字段的TS包的PID。
  • program_info_length: 表明跟随其后的对节目信息描述的字节数,也就是第一个N loop descriptors的字节数。
  • stream_type: 表明PES流的类型。譬如,0x01表明是MPEG-1视频,0X03表明是MPEG-1音频。
  • elementary_PID: 表明该负载有该PES流的TS包的PID值。
  • ES_info_length: 表明跟随其后的描述相关节目元素的字节数,也就是第二个N loop descriptors的字节数。
  • CRC_32: 在CEDARX代码中仅对DVB的场景下作校验。

typedef struct TS_PMT_Stream
{  unsigned stream_type                       : 8; //指示特定PID的节目元素包的类型。该处PID由elementary PID指定  unsigned elementary_PID                    : 13; //该域指示TS包的PID值。这些TS包含有相关的节目元素  unsigned ES_info_length                    : 12; //前两位bit为00。该域指示跟随其后的描述相关节目元素的byte数  unsigned descriptor;
}TS_PMT_Stream;//PMT 表结构体
typedef struct TS_PMT
{unsigned table_id                        : 8; //固定为0x02, 表示PMT表unsigned section_syntax_indicator        : 1; //固定为0x01unsigned zero                            : 1; //0x01unsigned reserved_1                      : 2; //0x03unsigned section_length                  : 12;//首先两位bit置为00,它指示段的byte数,由段长度域开始,包含CRC。unsigned program_number                    : 16;// 指出该节目对应于可应用的Program map PIDunsigned reserved_2                        : 2; //0x03unsigned version_number                    : 5; //指出TS流中Program map section的版本号unsigned current_next_indicator            : 1; //当该位置1时,当前传送的Program map section可用;//当该位置0时,指示当前传送的Program map section不可用,下一个TS流的Program map section有效。unsigned section_number                    : 8; //固定为0x00unsigned last_section_number            : 8; //固定为0x00unsigned reserved_3                        : 3; //0x07unsigned PCR_PID                        : 13; //指明TS包的PID值,该TS包含有PCR域,//该PCR值对应于由节目号指定的对应节目。//如果对于私有数据流的节目定义与PCR无关,这个域的值将为0x1FFF。unsigned reserved_4                        : 4; //预留为0x0Funsigned program_info_length            : 12; //前两位bit为00。该域指出跟随其后对节目信息的描述的byte数。std::vector<TS_PMT_Stream> PMT_Stream;  //每个元素包含8位, 指示特定PID的节目元素包的类型。该处PID由elementary PID指定unsigned reserved_5                        : 3; //0x07unsigned reserved_6                        : 4; //0x0Funsigned CRC_32                            : 32;
} TS_PMT;

PAT与PMT两张表帮助我们找到该传送流中的所有节目与流,PAT告诉我们,该TS流由哪些节目组成,每个节目的节目映射表PMT的PID是什么,而PMT告诉我们,该节目由哪些流组成,每一路流的类型与PID是什么。

TS流的形成过程:

  • 将原始音视频数据压缩之后,压缩结果组成一个基本码流(ES)。
  • 对ES(基本码流)进行打包形成PES。
  • 在PES包中加入时间戳信息(PTS/DTS)。
  • 将PES包内容分配到一系列固定长度的传输包(TS Packet)中。
  • 在传输包中加入定时信息(PCR)。
  • 在传输包中加入节目专用信息(PSI) 。
  • 连续输出传输包形成具有恒定比特率的MPEG-TS流。

TS流的解析过程:

  • 从复用的MPEG-TS流中解析出TS包;
  • 从TS包中获取PAT及对应的PMT(PSI中的表格);
  • 从而获取特定节目的音视频PID;
  • 通过PID筛选出特定音视频相关的TS包,并解析出PES;
  • 从PES中读取到PTS/DTS,并从PES中解析出基本码流ES;
  • 将ES交给解码器,获得压缩前的原始音视频数据

分析TS解析过程

ffmpeg对mpeg2-TS详细解析_ChenYuanshen的博客-CSDN博客_ffmpeg mpeg2

FFMpeg对MPEG2 TS流解码的流程分析

FFMpeg对MPEG2 TS流解码的流程分析_iteye_4476的博客-CSDN博客

FFMpeg对MPEG2 TS流解码的流程分析[2]

FFMpeg对MPEG2 TS流解码的流程分析[2] - it610.com

TS流PAT/PMT详解

TS流PAT/PMT详解_rolandz_的博客-CSDN博客_pat pmt

TS 流解析流程

  • 复用的MPEG-TS流中解析出TS包;
  • 从TS包中获取PAT及对应的PMT;
  • 从而获取特定节目的音视频PID;
  • 通过PID筛选出特定音视频相关的TS包,并解析出PES;
  • 从PES中读取到PTS/DTS,并从PES中解析出基本码流ES;
  • 将ES交给解码器,获得压缩前的原始音视频数据。

总下简单的说就是,解析ts的过程就是通过找到PAT表,从PAT表中找出对应存在的节目的id,按照这些id找到这些节目的PMT表,从中获到这些节目总的相对的媒体数据id,然后通过这些id,再从ts文件中找到这些文件的es数据,来完成解码或者别的什么操作。

TS流PAT/PMT详解 - rlandj - 博客园

TS文件格式详解及解封装过程相关推荐

  1. 详解数据包封装解封装过程

    基本概念 IP地址:指互联网协议地址,用于在整个互联网中标识设备的存在位置(私有地址除外). MAC地址:为局域网地址,用于在一个局域网内确定主机的位置,这也说明了MAC只能在局部传递. 一:当互访者 ...

  2. Ffmpeg快速命令使用 Ffmpeg选项详解 Ffmepg格式详解 常见视频文件格式详解

    http://www.ffmpeg.com.cn/index.php/%E9%A6%96%E9%A1%B5 Ffmpeg快速命令使用 From Ffmpeg工程组 Jump to: navigatio ...

  3. MP4文件格式详解——文件类型ftyp

    原谅地址:http://blog.csdn.net/pirateleo/article/details/7583321 文件类型ftyp(ISO-14496-12) Author:Pirate Leo ...

  4. MP4文件格式详解——文件类型ftyp(转)

    文件类型ftyp(ISO-14496-12) Author:Pirate Leo Email:codeevoship@gmail.com ISO 14496 - 12 定义了一种封装媒体数据的基础文件 ...

  5. 多媒体 MP4文件格式详解——文件类型ftyp

    ISO 14496 - 12 定义了一种封装媒体数据的基础文件格式,mp4.3gp.ismv等我们常见媒体封装格式都是以这种基础文件格式为基础衍生的. 如果从全局角度了解基础文件格式,请看我之前的博文 ...

  6. MP4文件格式详解——元数据moov(二)tkhd box

    ISO 14496 - 12 定义了一种封装媒体数据的基础文件格式,mp4.3gp.ismv等我们常见媒体封装格式都是以这种基础文件格式为基础衍生的. 如果从全局角度了解基础文件格式,请看我之前的博文 ...

  7. 刻录启动镜像之一:镜像文件格式详解

    刻录启动镜像之一:镜像文件格式详解 Disk Image CD/DVD Live CD .iso .bin / .raw / .img .cue .dmg .nrg Disk Image 磁盘映像是包 ...

  8. 音视频入门-11-PNG文件格式详解

    音视频入门文章目录 PNG 文件格式解析 PNG 图像格式文件由一个 8 字节的 PNG 文件署名域和 3 个以上的后续数据块(IHDR.IDAT.IEND)组成. PNG 文件包括 8 字节文件署名 ...

  9. 【破解教程】PE文件格式详解(上)

    PE文件格式详解(上) 摘要 Windows NT 3.1引入了一种名为PE文件格式的新可执行文件格式.PE文件格式的规范包含在了MSDN的CD中(Specs and Strategy, Specif ...

  10. ZIP(32位)文件格式详解

    ZIP(32位)文件格式详解 为什么要去了解ZIP文件格式 最近有个需求,需要加载jar包中的jar包中的class,此时有两种方式: 1.将jar解压缩,然后将解压缩后的路径添加到class pat ...

最新文章

  1. 201807 相关性度量的几种方法-卡方检验、相关系数、信息增益...
  2. MySQL errno: 145 错误修复
  3. r语言和metawin_Windows下使用Rtools编译R语言包
  4. php 半角全角,PHP 全角转半角实现代码
  5. kernel 中标准的 ir 模块的 时间的定义_Linux开机流程详解:BIOSgt;MBRgt;GRUBgt;Kernel...
  6. [MyBatisPlus]乐观锁和悲观锁
  7. 洛谷P1014 [NOIP1999 普及组] Cantor 表
  8. 格雷码 matlab,基于格雷码的结构光重建代码(MATLAB版本)
  9. R之Excel文件读取与程序包的安装调用
  10. 如何能自动上传公众号文章到网站里面!
  11. win32 API 调用方法
  12. Minecraft在安卓手机上搭建java服务器
  13. 认知电子战 (1.3):认知电子战概述
  14. 语音合成——闽南语合成(1)
  15. Kinect for Windows SDK v2.0 开发笔记 (十二) 高清面部帧(3) 面部模型(2D)
  16. PL/SQL 入门学习(一)
  17. Pascal VOC2012数据集下载
  18. 金刚经 原文及受持要领
  19. 提交AppStore审核总有意外出现?美团被下架
  20. 怎样解决 crx扩展无法离线安装,本地插件crx不能安装 的问题?

热门文章

  1. 【SSDP 协议介绍】
  2. Angular端口4200被占用后如何处理
  3. 最近抖音,小红书上面有个很火的天气推送的公众号,可以给自己爱的人进行定时推送. 效果如下,结合亲生经历给大家讲述一下操作流程。整个项目代码目前十分规整,项目代码整体400多行 ,就直接分享出来吧.
  4. php 怎么把数组按拼音,php实现数组按拼音顺序排序的方法
  5. H5打开APP技术总结
  6. 106.比特率和波特率
  7. h3c交换机配置nat_H3C NAT配置实例
  8. [GIS原理] 10.2 空间插值
  9. 实验1:局域网的组建与配置
  10. Android开发视频教程汇总