1.TS协议简述
使用UE工具打开ts文件,ts协议都是以0x47作为开头,代表一个ts文件开始。0x47也是debug时,经常作为是否为ts包的判断依据。ts流应用场景除了前面HLS,还有广播电视,卫星直播。一般一个ts流由很多个频道组成,每个频道由不同pid区分。
除了使用ue工具,这里还推荐一个分析ts流的工具,它是EasyICE,对于分析ts,HLS,非常好用工具,建议下载。
下载地址:https://www.easyice.cn/archives/85
1.1 EasyICE主要功能介绍
唯一一款支持HLS协议的免费分析软件。通过HLS 缓冲分析模块,可以一目了然的看到播放器的缓冲状态。当你的节目出现卡顿,观察缓冲状态就可以知道是否数据到达太慢。HLS分析支持直播与点播业务。
TS切片质量报告,包含了通常人们关心的,以及Apple要求的切片需符合的技术参数,不管节目制作者还是检验人员,切片质量报告最有用不过了。当一个节目的播放效果出现问题,对于节目本身首先要关注的就是这些参数。
为数字电视行业TS OVER IP设计的直播分析功能,支持单播,广播,组播(IGMP_v2,IGMP_v3),可以检测TR101290,媒体信息,PID统计,以及PCR的精度,间隔,总抖动等内容,数据接收与检测采取异步方式,线程间共享缓冲使用无锁的设计,保证了分析结果的准确性。
支持TS包分类,头部字段解析,以及视频(MPEG2,H264)帧类型判断。支持查找,快速定位需要的TS包,便于分析原始数据。
不同于其他码流分析产品的TR101290,仅有事件统计,在EasyICE中,你可以根据某一错误事件定位到数据包视图的相应位置,看看那里出了问题。
直观的看到时间戳变化,时间戳差值变化(这个功能就非常好用),GOP帧数,GOP字节数,以及基于两PCR包间数据量计算出的码率变化。同样,点击图表中的每个采样点,可以定位到数据包视图的相应位置。另外,滚动鼠标可以缩放视图,甚至可以导出这些采样值原始数据。
比较快的分析速度,支持从cap,pcap格式的抓包文件导出TS流。把cap文件拖进去试试看~所有功能免费使用
解析音视频PID
视频pid与PCR的pid一样
在ts流中是间隔插入PAT和PMT,PAT和PMT是重复的,这样有助于快速搜索节目。如果不插入,可能在搜索节目,切换节目时,可能找不到对应的节目。
一般0.5s就插入一个PAT。如下图:
解析媒体信息
如下图EasyICE检测出的媒体信息。
解析视频帧
通过这个工具,还可以解析每组GOP的排布情况。这个功能也非常好用,瞬间爱上这个软件了。
更为直观的显示GOP。
码率波动图
可以实时观察码率波动的情况。
分析数据包
可以根据EasyICE提供的结果,去分析数据包,比如数据包是否连续。
2 .ts⽂件分层
ts ⽂件为传输流⽂件,视频编码主要格式为 H264/MPEG4,⾳频为 AAC/MP3。每一层都是使用header+payload形式打包,类似网络5层协议。
如果把ts文件传输比作一个快递运输的过程,那么es就是真实的包裹,如一件衣服。pes就是使用打包盒子装好,并贴好时间,顺序等标签信息。ts就是贴上发货地址,寄货地址等信息,运送出去。
ts ⽂件分为三层:
(1)ts层(Transport Stream),也称为传输流层,在pes 层的基础上加⼊数据流的识别(如0x47头部信息)和传输必须的信息。ts header字段,如下表格所示:
重点关注sync_byte和continuity_counter(循环计数器,音频,视频,字幕对应每一个PID都是独立,各自计数,相互不干扰),在解封装时,确保该信息正确,才能保证这个包是有效。
从这个软件分析的结果,也可以得出,音视频,PAT,PMT的pid都是独立。
第一、Ts Header
ts 层的内容是通过 PID 值来标识的,主要内容包括:PAT 表、PMT 表、⾳频流、视频流。解析 ts 流要先找到 PAT 表,只要找到 PAT 就可以找到 PMT,然后就可以找到⾳视频流了。PAT 表和 PMT 表需要定期插⼊ ts 流,因为⽤户随时可能加⼊ ts 流,这个间隔⽐较⼩,通常每隔⼏个视频帧就要加⼊ PAT和 PMT。PAT 和 PMT 表是必须的,还可以加⼊其它表如 SDT(业务描述表)等,不过 hls 流只要有PAT 和 PMT 就可以播放了。
如何区分哪些是音频数据,哪些是视频数据?
先弄清PAT和PMT关系。
PAT表:主要的作⽤就是指明了 PMT 表的 PID 值。能找到PAT。PAT的pid默认值是0。通过PAT能够解析出当前ts流包含的节目数量以及对应节目的PMT pid。
PMT表:主要作用就是指明了音视频流的PID值。通过PMT的PID值就可以区分那个包是视频数据,那个包是音频数据。
音频流:编码好的音频数据。
视频流:编码好的视频数据。
根据上面的流程,举个例子,如一个ts流可能有很多个节目,如CCTV-1,CCTV-2,CCTV-3等,如果寻找CCTV-1,先找到ts流的PAT表,然后PAT找CCTV-1的PMT表中的pid=100,解析PMT的pid=100,然后分析出音频的pid(如为101)、视频的pid(如为102),字幕pid(如为103)等,这些都是相互独立。根据音频、视频、字幕对应的pid,找到对应的pid的ts,并根据id放入不同的队列,然后解析出具体的音频,视频数据。注意:这里还涉及到ts->pes->es的解封装过程。
第二、adaptation field
adaptation field所包含的字段如下表格,这里重点关注PCR和错误指示符。
⾃适应区的⻓度要包含传输错误指示符标识的⼀个字节。PCR是节目时钟参考,也是一种音视频同步的时钟,pcr、dts、pts 都是对同⼀个系统时钟的采样值,pcr 是递增的,因此可以将其设置为 dts 值,⾳频数据不需要 pcr(PCR的pid,一般与视频的pid是同一个值)。
在测试的时候发现,如果没有字段,ipad 是可以播放的,但 vlc ⽆法播放。
打包 ts 流时 PAT 和 PMT 表(属于文本数据)是没有 adaptation field,不够的⻓度直接补 0xff 即可。视频流和⾳频流都需要加 adaptation field,即文本数据不需要adaptation field,音视频数据需要adaptation field。一般在⼀个帧的第⼀个 ts包和最后⼀个 ts 包⾥加adaptation field,中间的 ts 包不加adaptation field。所以adaptation field是灵活改变,如下图所示:
PAT 格式如下图所示:
PAT表所对应的字段如下表所示,重点关注表中红色框框部分,table_id就是PAT默认的pid,默认值为0。program_number表示当节目号为0x0001时,是PMT。PID对应的值就是去寻找PMT表的依据。CRC32,表示校验码,用于验证。
PMT表所对应的字段如下表所示:
PMT表的table_id与PAT表的pid,相关联。
PAT表中的PCR_PID表示所在TS分组的PID,一般为视频ID相关联。stream_type表示当前包是音频,视频还是字幕或其他数据。如h264编码对应的是0x1b,aac编码对应的0x0f,mp3编码对应0x03。elementary_PID表示音频、视频、字幕或其它数据对应的PID,通过elementary_PID就可以找到真正的数据,用于解码。CRC32同样也是用于数据验证。
注意:这里有一段数据是循环,从字段stream_type开始到ES_info_length结束,这是一段循环,一直在解析。
如果需要加密数据,一般是在ts层的payload部分。
(2)pes 层(Packet Elemental Stream),也称为打包层,在⾳视频数据上加了时间戳等对数据帧的说明信息。也就是说时间戳pts是存储在pes header里。在做音视频同步,就需要去关联这里的时间戳信息。
pes 层是在每⼀个视频/⾳频帧上加⼊了时间戳等信息,pes 包内容很多,这⾥只留下最常⽤的。如果需要更详细研究,就需要根据spec去学习。
当解析完ts层后,这里继续解析PES层,PES层格式如下:
PES Header一般为6Bytes,Option Pes Header为3Bytes-259Bytes,不是固定值,Payload最大值不超过65526Bytes。
PES层字段表如下图所示:
pes start code表示一个pes的起始。stream id表示音频,视频id,与PMT表的id,相关联。pes packet length表示pes包长度。第一个flag表示是否是加密包,真正加密是在ts的payload部分。第二个flag表示是否包含pts,dts等。pes data length表示pes payload数据长度。这些字段中最关键的就是pts和dts值。
pts 是显示时间戳、dts 是解码时间戳,视频数据两种时间戳都需要,如果音视频的pts和dts相同,就只需要pts即可。有 pts 和 dts 两种时间戳是 B 帧引起的,I 帧 和 P 帧的 pts 等于 dts。如果⼀个视频没有B 帧,则 pts 永远和 dts 相同。
从⽂件中顺序读取视频帧,取出的帧顺序和 dts 顺序相同。dts 算法⽐较简单,初始值 + 增量即可,pts 计算⽐较复杂,需要在 dts 的基础上加偏移量。
注意:⾳频的 pes 中只有 pts(同 dts,这也是为什么能够常使用audio master的原因之一),而视频的 I、P 帧两种时间戳都要有,视频 B 帧只要 pts(同 dts)。打包 pts 和 dts 就需要知道视频帧类型,但是通过容器格式我们是⽆法判断帧类型的,必须解析 h.264内容才可以获取帧类型,通过帧类型去加添加pts或dts。
B帧会增加缓存,解码一般是先解出P帧,再解出B帧,所以B帧会增加延时,显示一般就是B帧先显示,因为B帧的原因,就需要调整帧顺序,需要花时间。如下图所示:
计算点播视频dts公式:
视频dts计算公式为 dts = 初始值 + 90000 / video_frame_rate ,初始值可以随便指定,但是最好不要取 0,video_frame_rate 就是视频帧率,⽐如 20、30。
pts 和 dts 是 以 timestamp(时间戳) 为单位的,1s = 90000 time scale ,所以一帧的pts就是90000/video_frame_rate 个 timescale。
播放时长就是⽤⼀帧的 timescale 除以采样频率,可以转换为⼀帧的播放时⻓。
计算点播音频dts公式:
音频dts计算公式为dts =初 始 值 + (90000 * audio_samples_per_frame) /audio_sample_rate audio_samples_per_frame 这 个 值 与 编 解 码 相 关 ,一般 aac 取 值 1024 , mp3 取 值 1158
audio_sample_rate 是采样率,⽐如 24000、41000. AAC ⼀般解码出来是每声道 1024 个 sample,也就是说⼀帧的时⻓为 1024/sample_rate 秒。所以每⼀帧时间戳依次 0,1024/sample_rate, ...,1024*n/sample_rate 秒 。
十分注意:如果是直播场景,直播视频的 dts 和 pts 应该直接⽤直播数据流中的时间,不应该按公式计算。
(3)es 层(Elementary Stream),也称为原始流层,表示原始的音视频数据。
ts协议,三层数据结构图,如下:
ts层由ts Header(一般由4Bytes组成,第一个字节是固定0x47开头),adaption field(调整的字节,灵活改变),payload(是ts层负载,一般是184Bytes)组成。所以一般ts包是为188个字节,也有些大于188字节的。
ts层的payload主要由pes层数据组成。PES层主要由pes header(一般是6Bytes),option pes header(调整的字节,灵活改变),pes payload(不是固定值)组成。
pes层的payload主要是由es层数据组成,es层主要由视频的nal header(一般是4Bytes,一把是会有start code),nal type(一般是1Bytes),h264 data(不是固定值),音频的adts header(7Bytes),aac data(不是固定值)组成。
第一,h.264 视频
关于h264格式可以参考前面的文章,有助于你更好理解h264。
打包 h.264 数据时必须给视频数据加上⼀个 nalu(Network Abstraction Layer Unit),nalu 包括nalu header 和 nalu type,nalu header 固定为 0x00000001(帧开始)或 0x000001(帧中)。h.264 的数据是由 slice 组成的,slice 的内容包括:视频、sps、pps 等。nalu type 决定了后⾯的h.264 数据内容。其结构的spec表示如下:
F:1bit,forbidden_zero_bit,h.264 规定必须取 0。
NRI:2bits,nal_ref_idc,取值为 0~3,指示这个 nalu 的重要性,I 帧、sps、pps 通常取3,P 帧常取 2,B 帧通常取 0。
Type:5bits,取值如下表所示:
一般在工程项目中,IDR帧,SEI,SPS,PPS,这些都是常用分析的图像信息。
注意:打包 es 层数据时 pes 头和 es 数据之间要加⼊⼀个 type=9 的 nalu(分解符号),关键帧 slice 前必须要加⼊type=7 (sps)和 type=8 的 nalu(pps),⽽且是紧邻的。如下图所示:
第二,aac⾳频
打包aac⾳频必须加上⼀个adts(Audio Data Transport Stream)头,共7Byte,adts包括fixed_header和variable_header两部分,各28bit。spec如下图所示:
fixed_header如下图所示,如果需要手动添加头部,则需要参考如下字段。可以参考这2篇文章。
重点关注红色框框部分,id表示执行是MPEG-4还是MPEG-2标准。profile表示是什么编码方式,其中1表示aac。sampling_frequency_index表示支持的采样率。channel_configurati on表示通道配置,如左声道,右声道等。
variable_header如下图所示,
重点关注打红色框部分,aac_frame_length表示adts头在内的音视频数据长度。
3.总结
关于这篇文章,主要讲解的就是ts主要格式分析和非常好用的工具EasyICE介绍,这样会帮助你提高工作效率。
本篇文章就分析到这里,欢迎大家关注欢迎关注,点赞,转发,收藏,分享,评论区讨论。
后面关于项目知识,后期会更新。欢迎关注微信公众号"记录世界 from antonio"。