资源描述
HLS,Http Live Streaming 是由Apple公司定义用于实时流传播合同,HLS基于HTTP合同实现,传播内容涉及两某些,一是M3U8描述文献,二是TS媒体文献。
1、M3U8文献
用文本方式对媒体文献进行描述,由一系列标签构成。
#EXTM3U
#EXT-X-TARGETDURATION:5
#EXTINF:5,
./0.ts
#EXTINF:5,
./1.ts
#EXTM3U:每个M3U8文献第一行必要是这个tag。
#EXT-X-TARGETDURATION:指定最大媒体段时间长度(秒),#EXTINF中指定期间长度必要不大于或等于这个最大值。该值只能浮现一次。
#EXTINF:描述单个媒体文献长度。背面为媒体文献,如./0.ts
2、ts文献
ts文献为传播流文献,视频编码重要格式h264/mpeg4,音频为acc/MP3。
ts文献分为三层:ts层Transport Stream、pes层 Packet Elemental Stream、es层 Elementary Stream. es层就是音视频数据,pes层是在音视频数据上加了时间戳等对数据帧阐明信息,ts层就是在pes层加入数据流辨认和传播必要信息
注: 详解如下
(1)ts层 ts包大小固定为188字节,ts层分为三个某些:ts header、adaptation field、payload。ts header固定4个字节;adaptation field也许存在也也许不存在,重要作用是给局限性188字节数据做填充;payload是pes数据。
ts header
sync_byte
8b
同步字节,固定为0x47
transport_error_indicator
1b
传播错误批示符,表白在ts头adapt域后由一种无用字节,普通都为0,这个字节算在adapt域长度内
payload_unit_start_indicator
1b
负载单元起始标示符,一种完整数据包开始时标记为1
transport_priority
1b
传播优先级,0为低优先级,1为高优先级,普通取0
pid
13b
pid值
transport_scrambling_control
2b
传播加扰控制,00表达未加密
adaptation_field_control
2b
与否包括自适应区,‘00’保存;‘01’为无自适应域,仅具有效负载;‘10’为仅含自适应域,无有效负载;‘11’为同步带有自适应域和有效负载。
continuity_counter
4b
递增计数器,从0-f,起始值不一定取0,但必要是持续
ts层内容是通过PID值来标记,重要内容涉及:PAT表、PMT表、音频流、视频流。解析ts流要先找到PAT表,只要找到PAT就可以找到PMT,然后就可以找到音视频流了。PAT表PID值固定为0。PAT表和PMT表需要定期插入ts流,由于顾客随时也许加入ts流,这个间隔比较小,普通每隔几种视频帧就要加入PAT和PMT。PAT和PMT表是必要,还可以加入其他表如SDT(业务描述表)等,但是hls流只要有PAT和PMT就可以播放了。
·
PAT表:她重要作用就是指明了PMT表PID值。
·
·
PMT表:她重要作用就是指明了音视频流PID值。
·
·
音频流/视频流:承载音视频内容。
·
adaption
adaptation_field_length
1B
自适应域长度,背面字节数
flag
1B
取0x50表达包括PCR或0x40表达不包括PCR
PCR
5B
Program Clock Reference,节目时钟参照,用于恢复出与编码端一致系统时序时钟STC(System Time Clock)。
stuffing_bytes
xB
填充字节,取值0xff
自适应区长度要包括传播错误批示符标记一种字节。pcr是节目时钟参照,pcr、dts、pts都是对同一种系统时钟采样值,pcr是递增,因而可以将其设立为dts值,音频数据不需要pcr。如果没有字段,ipad是可以播放,但vlc无法播放。打包ts流时PAT和PMT表是没有adaptation field,不够长度直接补0xff即可。视频流和音频流都需要加adaptation field,普通加在一种帧第一种ts包和最后一种ts包里,中间ts包不加。
PAT格式
table_id
8b
PAT表固定为0x00
section_syntax_indicator
1b
固定为1
zero
1b
固定为0
reserved
2b
固定为11
section_length
12b
背面数据长度
transport_stream_id
16b
传播流ID,固定为0x0001
reserved
2b
固定为11
version_number
5b
版本号,固定为00000,如果PAT有变化则版本号加1
current_next_indicator
1b
固定为1,表达这个PAT表可以用,如果为0则要等待下一种PAT表
section_number
8b
固定为0x00
last_section_number
8b
固定为0x00
开始循环
program_number
16b
节目号为0x0000时表达这是NIT,节目号为0x0001时,表达这是PMT
reserved
3b
固定为111
PID
13b
节目号相应内容PID值
结束循环
CRC32
32b
前面数据CRC32校验码
PMT格式
table_id
8b
PMT表取值随意,0x02
section_syntax_indicator
1b
固定为1
zero
1b
固定为0
reserved
2b
固定为11
section_length
12b
背面数据长度
program_number
16b
频道号码,表达当前PMT关联到频道,取值0x0001
reserved
2b
固定为11
version_number
5b
版本号,固定为00000,如果PAT有变化则版本号加1
current_next_indicator
1b
固定为1
section_number
8b
固定为0x00
last_section_number
8b
固定为0x00
reserved
3b
固定为111
PCR_PID
13b
PCR(节目参照时钟)所在TS分组PID,指定为视频PID
reserved
4b
固定为1111
program_info_length
12b
节目描述信息,指定为0x000表达没有
开始循环
stream_type
8b
流类型,标志是Video还是Audio还是其她数据,h.264编码相应0x1b,aac编码相应0x0f,mp3编码相应0x03
reserved
3b
固定为111
elementary_PID
13b
与stream_type相应PID
reserved
4b
固定为1111
ES_info_length
12b
描述信息,指定为0x000表达没有
结束循环
CRC32
32b
前面数据CRC32校验码
(2)pes层
pes层是在每一种视频/音频帧上加入了时间戳等信息,pes包内容诸多,咱们只留下最惯用。
pes start code
3B
开始码,固定为0x000001
stream id
1B
音频取值(0xc0-0xdf),普通为0xc0
视频取值(0xe0-0xef),普通为0xe0
pes packet length
2B
背面pes数据长度,0表达长度不限制,
只有视频数据长度会超过0xffff
flag
1B
普通取值0x80,表达数据不加密、无优先级、备份数据
flag
1B
取值0x80表达只具有pts,取值0xc0表达具有pts和dts
pes data length
1B
背面数据长度,取值5或10
pts
5B
33bit值
dts
5B
33bit值
pts是显示时间戳、dts是解码时间戳,视频数据两种时间戳都需要,音频数据pts和dts相似,因此只需要pts。有pts和dts两种时间戳是B帧引起,I帧和P帧pts等于dts。如果一种视频没有B帧,则pts永远和dts相似。从文献中顺序读取视频帧,取出帧顺序和dts顺序相似。dts算法比较简朴,初始值 + 增量即可,pts计算比较复杂,需要在dts基本上加偏移量。
音频pes中只有pts(同dts),视频I、P帧两种时间戳都要有,视频B帧只要pts(同dts)。打包pts和dts就需要懂得视频帧类型,但是通过容器格式咱们是无法判断帧类型,必要解析h.264内容才可以获取帧类型。
举例阐明:
I P B B B P
读取顺序: 1 2 3 4 5 6
dts顺序: 1 2 3 4 5 6
pts顺序: 1 5 3 2 4 6
点播视频dts算法:
dts = 初始值 + 90000 / video_frame_rate,初始值可以随便指定,但是最佳不要取0,video_frame_rate就是帧率,例如23、30。
pts和dts是以timescale为单位,1s = 90000 time scale ,一帧就应当是90000/video_frame_rate 个timescale。
用一帧timescale除以采样频率就可以转换为一帧播放时长
点播音频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层
es层指就是音视频数据,咱们只简介h.264视频和aac音频。
h.264视频:
打包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数据内容。
F
1b
forbidden_zero_bit,h.264规定必要取0
NRI
2b
nal_ref_idc,取值0~3,批示这个nalu重要性,I帧、sps、pps普通取3,P帧普通取2,B帧普通取0
Type
5b
参照下表
nal_unit_type
阐明
0
未使用
1
非IDR图像片,IDR指核心帧
2
片分区A
3
片分区B
4
片分区C
5
IDR图像片,即核心帧
6
补充增强信息单元(SEI)
7
SPS序列参数集
8
PPS图像参数集
9
分解符
10
序列结束
11
码流结束
12
填充
13~23
保存
24~31
未使用
红色字体显示内容是最惯用,打包es层数据时pes头和es数据之间要加入一种type=9nalu,核心帧slice前必要要加入type=7和type=8nalu,并且是紧邻。
一、背景简介
之前我做了一种项目,规定写一种TS流解析模块,因而看了ISOIEC 13818-1文档,外加诸多人博客来协助理解,来理解TS流格式是个什么东西,收货颇多。因而我觉得是时候发点干货回馈社会了。
二,TS流背景简介
在简介详细字段,参数这些头疼,烦人东西之前,我觉得有必要先简介下TS流应用背景,有了这个概念,再去进一步学习,将如虎添翼。TS流最典型应用就是咱们平时生活中数字高清电视。咱们看电视码流就是TS封装格式码流,电视码流发送过来后,就会由咱们机顶盒进行解封装,解码,然后传给电视机进行播放。这里就有一种问题,咱们看电视,有诸多频道,节目,相应码流是怎么区别呢?(TIPS,频道和节目关系,例如咱们有央视综合频道,下属CCTV-1~CCTV14这些节目)TS流引入了PAT和PMT两张表格概念来解决这个问题。
三,PAT和PMT
TS流是以每188字节为一包,咱们可以称为ts packet。这个ts packet有也许是音视频数据,也有也许是表格。举例阐明,TS流包顺序为:
PAT,PMT,DATA,DATA,,,,,,PAT,PMT,DATA,DATA,,,,,,
每隔一段时间,发送一张PAT表,紧接着发送一张PMT表,接着发送DATA(音视频)数据。
那么你也许要问了,有了这2张表格怎么区别频道,节目呢?PAT表格里面包括所有PMT表格信息,一种PMT表格相应一种频道,例如央视综合频道。而一种PMT里面包括所有节目信息,例如CCTV1~CCTV14。在实际状况中咱们是有诸多频道,因此PMT表格可不止一张,有也许是PAT,PMT,PMT,PMT,,,DATA,DATA,,,,PAT,PMT,PMT,,,DATA,DATA这样形式。除了这个设定外,每个频道或节目均有自己标记符(PID),这样当咱们拿到一种DATA,解析出里面PID,就懂得是什么节目,并且也懂得所属频道是什么了。咱们看电视时候,会收到所有节目DATA,当咱们正在看某个节目时候,机顶盒会把这个节目DATA单独过滤出来,其他舍弃。
四,ts packet格式解说
ts packet咱们懂得一包是188字节,它分为ts header和ts body。其中ts header里面会有个PID字段标记着当前ts body类型。ts body有也许是表格,也有也许是DATA,表格没什么好说,咱们说下DATA构造。DATA包
其实就是PES包,而PES包是对ES封装,PES包分为PES头加ES。这里ES是原始流,是指通过压缩后H264,aac等格式音视频数据。那么帧数据,PES包,ts packet包相应关系是什么样呢?一帧数据封装成一种PES包(含PES头和ES),这个PES包如果不大于188字节,那么一种ts packet就可以放下了。最后ts packet一包格式就是ts header+填充字节+PES包(PES头+ES)。填充字节意思是如果ts header加上PES包不满188字节,这个时候必定要填充下使其凑满188字节发送。是不是很简朴?那么咱们懂得视频帧是很大,往往不不大于188字节,这个时候怎么存储呢?还是把一种视频帧放入一种PES包。然后分别放在几种ts packet包即可。构造如下:
第一种ts packet:ts header+PES头+某些ES
第二个ts packet:ts header+某些ES
...
最后一种ts packet:ts header+填充字节+某些ES
PES头加上这些某些ES,就是一种PES包。
五,详细字段解析
详细字段请参照ISOIEC 13818-1.pdf文档,看起来应当没什么困难,这里不再累述。
传送门:
但是其中ts header里payload_unit_start_indicator和pes header里PES_packet_length这两个字段,在解析ts流时候至关重要,新手也许比较困惑,不懂其意,我得好好讲讲。
payload_unit_start_indicator有两个值,0或1,详细意思咱们来举个例子。假设有两个视频帧,每个视频帧假设都需要3个ts packet包来存储一种PES包。那么一共有6个ts packet,它们payload_unit_start_indicator值为1,0,0,1,0,0,值为1代表一种帧开始,下一种1就是新一帧开始了。
PES_packet_length顾名思义就是PES包长度,但是注意,它是2个字节存储,这意味着,最大只能表达65535,一旦视频帧很大,超过这个长度,怎么办,就把PES_packet_length置为0,这是ISO原则规定。因此在解析时候,不能以PES_packet_length为准,要参照payload_unit_start_indicator。
展开阅读全文