TS封装格式小白入门分析总结

       TS全称transport stream,是基于MPEG-2的封装格式(所以也叫MPEG-TS),通常后缀为.ts,.mpg,.mpeg。TS封装格式如今广泛应用于数字电视,在即时通讯传输业务上大方光彩,本文将详细介绍TS文件的生成过程,以及对其数据结构的详细分析。

        关于视音频的基础知识可以参考雷神的博客:https://blog.csdn.net/leixiaohua1020/article/details/18893769                                   抓包工具和相关素材的下载:https://download.csdn.net/download/qq_41786131/11191889                                                          使用工具抓包分析TS的各种packet_type请参考我的另一篇文章:TS封装格式小白入门分析总结之抓包分析

   (一)TS文件生成过程和分层结构

         因TS是对基本码流的封装,所以TS也应是分层结构。TS主要分为三层:TS层(Transport Stream),PES层(Packet Element Stream),ES层(Element Stream),ES层就是压缩编码(视频采用H264,音频采用acc)后的基本的音视频码流,PES在ES层的基础上加入了时间戳(PTS/DTS)等信息,而TS层就是在PES层加入了定时信息(PCR)和节目专用信息(PSI)进而形成我们所需的稳定MPEG-TS码流。这就是ts文件生成的基本过程,其中的名词稍后会继续介绍。汇总为结构图如下所示:

   (二)TS层的结构分析

        观察图1,TS每个包大小固定188字节,其中TS Heather固定4个字节,adaptation field为自适应区, payload为有效负载,两者共计184个字节。TS Header结构以及相关作用如下所示:

typedef struct Transport_Packet{
    unsigned Sync_byte                       :8 //同步标志。值固定0x47
    unsigned Transport_error_indicator       :1 //传输错误指示符。为1时代表出错
    unsigned Payload_unit_start_indicator    :1 //有效负载起始指示符。为1时代表是一帧的开始
    unsigned Transport_priority              :1 //传输优先级,为1代表优先级高于相同PID的字段
    unsigned PID                             :13 //重点,稍后详解
    unsigned Transport_scrambling_control    :2 //加扰方式。00未加扰,其他值用户填写
    unsigned Adapaction_field_control        :2 //当前包是否有调整字段或者有效负载。00保留,01无调整字段有有效负载,10有调整字段无有效负载,11两者都有
    unsigned Continuity_counter              :4 //从0到15连续循环递增,代表连续的包,不一定从0开始
}
    

         可以看出,TS Header里主要是一些控制操作,它也是每个TS包的起始位置,我们之后抓包分析TS数据都要从这里开始。adapation field(调整字段)句法以及要点概括如下所示(牢记各个字段占位大小,有利于以后对数据包的分析):

Adaptation_field_length  8b其数值指示的是之后数据长度
Discontinuity_indicator  1b1代表当前TS包不连续状态为真
Random_access_indicator  1b为1时表明下一个相同PID的包应该含有PTS和原始访问点
Elementary_stream_priority_indicator  1b为1时表明比相同PID包的优先级高
PCR_flag  1b为1时代表调整字段中含有PCR(节目时钟参考,用于恢复与编码端一致的时钟顺序),其结构尚未列出(下同)
OPCR_flag  1b为1时代表调整字段中含有OPCR。
Splicling_point_flag  1b为1时代表调整字段中存在拼接点splice_countdown
Transport_private_data_flag  1b为1时代表调整字段中存在至少一个私有数据
Adapatation_filed_extension_flag  1b为1时代表存在调整字段的扩展

         然后就是有效负载payload部分,它的数据类型并不一定是PES结构,也可能包含PAT,PMT等,那这到底由谁决定呢?就是我们之前在TS Header里看到的PID(包指示符:packet identifiter)!不同的PID值指示了不同的payload的数据类型。 (打包ts流时PAT和PMT表是没有调整字段的,不够的长度直接补0xff即可。视频流和音频流都需要加adaptation field,通常加在一个帧的第一个ts包和最后一个ts包里,中间的ts包不加。调整字段的最后也是用0xff填充字节,所以抓包的数据“FF”数据一般在中部。)           我用EasyICE抓包了一段ts文件,常见的PID取值如下:

        可见payload承载的信息一般是包含着音视频数据的pes层或者空包,PID与包类型的对应关系请看我的另一篇博客: TS封装格式小白入门分析总结之抓包分析

   (三)PES层介绍

        有必要说一点,PES层是将ES层(一个片)加入了PES头部,一般ES层的数据是很大的(由PES包长度这个字段指出),所以加入PES头时必须将ES分割,我们只在第一个分割后的ES上加PES,所以就形成了这种情况(即很多TS包并不包含PES头部,直接是裸ES数据,稍后结合工具分析详解):

        PES层主要分为三个部分PES header(固定6个字节),optional header(可选),和pes payload(也就是ES层了)。PES的字段比较多,在此只列出它的句法结构图和几个比较重要的字段(摘自:https://blog.csdn.net/cabbage2008/article/details/49612011):

         可见每个PES包固定了三个字段:起始码流(packet_start_code_prefix,24b),流id(stream id,8b),包长度(PES_packet_length,16b)。这三个字段占据了6个字节,是我们分析PES包的起始标志,请牢记。然后是pes optional header(里面包含了很多字段),最后是pes payload。在此仅介绍几个比较重要的字段(标志flag对应了任选字段的内容是否存在)。

               起始码流(packet_start_code_prefix) 24b固定为00 00 01,借此可判断出PES包起始位置
流id(stream id) 8b用来指示pes包的数据类型。表示音频通常取值0xc0,表示视频通常取值0xe0
包长度(PES_packet_length)16b用来指示接下来数据类型的大小,一般不会超过0xffff,除非包含的是视频数据
            PES加扰控制(PES_scrambling_control) 2b

与TS包头加扰控制一致,00不加扰,其他值用户自定义

PES优先级(PES_priority) 1b置为1时代表比其他置为0的有效负载拥有更高的优先级
版权(copyright) 1b1代表此有效负载被版权保护,0代表不确定
        原始的或复制的            (original_or_copy) 1b1代表原始的,0代表复制的
显示解码时间戳标识符(PTS_DTS_flags) 2b两个位分别代表是否有PTS(显示时间戳)或者DTS(解码时间戳)。此flag占据两个位,后面还有6个flag用来指示相应字段,这也是为什么上图7个flag占据8个位的原因。
PES头数据长度(PES_header_data_length)8b此指示符的数值代表的是填充字段和任选字段数值的大小
PTS DTS33b各33b,
ES速率(ES Rate)22b由前面的flag指定是否存在,用来指定系统解码器解码PES包的速率,以50B/s为基本单位,这个速率会持续到新的ES Rate出现。
特技方式(trick_mode_control)3b由前面的相应flag指定是否存在。其中000快进,001慢动作,010冻结帧,011快速反向,100慢反向,其他值保留。
填充字节(stuffing_byte)8b 一般为11111111,由编码器插入,由解码器丢弃
覆盖字节(padding_byte)8b一般为11111111,由解码器丢弃。

      pes层中很多字段都是有它前面的flag指定,一般情况下很多字段是不存在的,最常见的是PTS/DTS.对PES各个字段更加详细的介绍请看相关的介绍文档:https://blog.csdn.net/cabbage2008/article/details/49848937

  (四)ES层介绍

       Element Stream,即最基本的视音频数据了,在Ts封装格式中,视频使用H264压缩编码的,音频则是ACC压缩编码。

       h264视频:

       对h264编码格式的详细介绍我们留在下一篇博客:。现在我们需要知道要传输h264视频必须在前面加上一个NALU(network abstract layout uint)头部,这个NALU头部格式如下图所示:

     

F(frobiden) 1b禁止位,发生语法错误时此为为1
NRI 2b参考级别,值越大,此NAL越重要
NAL_TYPE 5b指明了此NAL单元的类型,常见的取值如下图
nal_unit_type说明
0未使用
1非IDR图像片,IDR指关键帧
2片分区A
3片分区B
4片分区C
5IDR图像片,即关键帧
6补充增强信息单元(SEI)
7SPS序列参数集
8PPS图像参数集
9分解符
10序列结束
11码流结束
12填充
13~23保留
24~31未使用

      牢记关键帧非关键帧,SEI,SPS,PPS的对应取值。对h264编码的详细介绍请看另一篇博客:

       

  • 8
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值