Skip to content

Commit fead41f

Browse files
committed
update
1 parent 02d97cc commit fead41f

File tree

4 files changed

+152
-7
lines changed

4 files changed

+152
-7
lines changed

VideoDevelopment/关键帧.md

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,42 @@
11
关键帧
22
===
33

4-
**编码器将多张图像进行编码后生产成一段一段的 GOP ( Group of Pictures ) , 解码器在播放时则是读取一段一段的 GOP 进行解码后读取画面再渲染显示。**GOP ( Group of Pictures) 是一组连续的画面,由一张 I 帧和数张 B / P 帧组成,是视频图像编码器和解码器存取的基本单位,它的排列顺序将会一直重复到影像结束。I 帧是内部编码帧(也称为关键帧),P帧是前向预测帧(前向参考帧),B 帧是双向内插帧(双向参考帧)。简单地讲,I 帧是一个完整的画面,而 P 帧和 B 帧记录的是相对于 I 帧的变化。如果没有 I 帧,P 帧和 B 帧就无法解码。
54

6-
在H.264压缩标准中I帧、P帧、B帧用于表示传输的视频画面。
5+
6+
### I、P、B帧
7+
8+
在H.264协议中定义了3中帧,完整编码的帧叫I帧、参考之前的I帧生成的只对差异部分进行编码的帧叫P帧、还有一种参考前后的帧进行编码的帧叫B帧。
79

810
- I帧(Intra coded picture):帧内编码图像帧简称关键帧,这一帧画面的完整保留,解码时只需要本帧数据就可以完成.I帧通常是每个GOP(MPEG所使用的一种视频压缩技术)的第一个,GOP就是指两个I帧之间的距离。
911

1012
我们在做直播的时候,想要能达到秒开的效果,因为I帧是能不依赖其他帧独立完成解码的,这就意味着当播放器接收到I帧就能立马渲染出来,而接收到P、B帧则需要等待依赖的帧而不能立马完成解码和渲染,这个期间就会黑屏,所以可以在服务端通过缓存GOP,保证播放端在接入直播时能先获取到I帧马上渲染出画面,从而提高起播速度。在直播服务器中,支持设置一个cache,用于存放GOP,直播服务器缓存了当前的GOP序列,当播放端请求数据的时候,CDN会从I帧返回给客户端,从而保证客户端可以快速进行播放。当然由于缓存的是之前的视频信息,当音频数据到达播放端后,为了音视频同步播放器会进行视频的快进处理。
1113

1214
- P帧(Predictive coded picture):预测编码图像帧简称差别帧,这一帧跟之前的一个关键帧或P帧的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终的画面。也就是说P帧没有完整的画面数据,只有与前一帧的画面差别的数据。
15+
1316
- B帧(Bidirectionally predicted picture):双向预测编码图像帧简称双向差别帧,也就是B帧记录的是本帧与前后帧的差别。也就是要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面与本帧数据的叠加来获取最终的画面。B帧压缩率高,但是解码时会更耗CPU。
14-
- GOP(Group of Pictures)是一组连续的画面,由一张I帧和数张B/P帧组成,是视频图像编码器和解码器存取的基本单位,它的排列顺序将会一直重复到影像结束。
15-
编码器将多张图像进行编码后生产成一段一段的 GOP ,解码器在播放时则是读取一段一段的GOP进行解码后读取画面再渲染显示。
17+
18+
19+
20+
### GOP
21+
22+
这3中帧用于表示传输的视频画面。在H.264中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流,以I帧开始,到下一个I帧结束,中间部分也被称为一个GOP。
23+
24+
GOP(Group of Pictures)是一组连续的画面,由一张I帧和数张B/P帧组成,是视频图像编码器和解码器存取的基本单位,它的排列顺序将会一直重复到影像结束。
25+
编码器将多张图像进行编码后生产成一段一段的 GOP ,解码器在播放时则是读取一段一段的GOP进行解码后读取画面再渲染显示。
26+
27+
**编码器将多张图像进行编码后生产成一段一段的 GOP ( Group of Pictures ) , 解码器在播放时则是读取一段一段的 GOP 进行解码后读取画面再渲染显示。**GOP ( Group of Pictures) 是一组连续的画面,由一张 I 帧和数张 B / P 帧组成,是视频图像编码器和解码器存取的基本单位,它的排列顺序将会一直重复到影像结束。I 帧是内部编码帧(也称为关键帧),P帧是前向预测帧(前向参考帧),B 帧是双向内插帧(双向参考帧)。简单地讲,I 帧是一个完整的画面,而 P 帧和 B 帧记录的是相对于 I 帧的变化。如果没有 I 帧,P 帧和 B 帧就无法解码。
28+
29+
### IDR
30+
31+
一个序列(GOP)的第一个图像叫做IDR图像(立即刷新图像),IDR图像都是I帧图像。H.264引入IDR图像是为了解码的重新同步,当解码器解码到IDR图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找下一个参考集,开始解码一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像数据来解码。一个序列就是一段内容差异不太大的图像编码后生成的一串数据流。当运动变化比较少时,一个序列可以很长,因为运动变化少就代表图像画面的内容变动很小,所以就可以是一个I帧,然后一直是P帧、B帧。当运动变化多时,一个序列可能会比较短,比如只包含一个I帧和几个P帧、B帧。
1632

1733
- IDR(Instantaneous Decoding Refresh)--即时解码刷新。
1834
I帧:帧内编码帧是一种自带全部信息的独立帧,无需参考其它图像便可独立进行解码,视频序列中的第一个帧始终都是I帧。
35+
36+
那么IDR帧与I帧的区别是什 么呢?因为H264采用了多帧预测,所以I帧之后的P帧有可能会参考I 帧之前的帧,这就使得在随机访问的时候不能以找到I帧作为参考条 件,因为即使找到I帧,I帧之后的帧还是有可能解析不出来,而IDR帧 就是一种特殊的I帧,即这一帧之后的所有参考帧只会参考到这个IDR 帧,而不会再参考前面的帧。在解码器中,一旦收到一个IDR帧,就会 立即清理参考帧缓冲区,并将IDR帧作为被参考的帧。
37+
38+
39+
1940
I和IDR帧都是使用帧内预测的。它们都是同一个东西而已,在编码和解码中为了方便,要首个I帧和其他I帧区别开,所以才把第一个首个I帧叫IDR,这样就方便控制编码和解码流程。 IDR帧的作用是立刻刷新,使错误不致传播,从IDR帧开始,重新算一个新的序列开始编码。而I帧不具有随机访问的能力,这个功能是由IDR承担。 IDR会导致DPB(DecodedPictureBuffer 参考帧列表——这是关键所在)清空,而I不会。IDR图像一定是I图像,但I图像不一定是IDR图像。一个序列中可以有很多的I图像,I图像之后的图像可以引用I图像之间的图像做运动参考。一个序列中可以有很多的I图像,I图像之后的图象可以引用I图像之间的图像做运动参考。
2041
对于IDR帧来说,在IDR帧之后的所有帧都不能引用任何IDR帧之前的帧的内容,与此相反,对于普通的I-帧来说,位于其之后的B-和P-帧可以引用位于普通I-帧之前的I-帧。从随机存取的视频流中,播放器永远可以从一个IDR帧播放,因为在它之后没有任何帧引用之前的帧。但是,不能在一个没有IDR帧的视频中从任意点开始播放,因为后面的帧总是会引用前面的帧 。
2142
收到 IDR 帧时,解码器另外需要做的工作就是:把所有的 PPS 和 SPS 参数进行更新。
@@ -36,11 +57,11 @@ P帧和B帧极大的节省了数据量,节省出来的空间可以用来多保
3657

3758

3859

39-
60+
### PTS和DTS
4061

4162
【为什么会有PTS和DTS的概念】
4263

43-
通过上面的描述可以看出:P帧需要参考前面的I帧或P帧才可以生成一张完整的图片,而B帧则需要参考前面I帧或P帧及其后面的一个P帧才可以生成一张完整的图片。这样就带来了一个问题:在视频流中,先到来的 B 帧无法立即解码,需要等待它依赖的后面的 I、P 帧先解码完成,这样一来播放时间与解码时间不一致了,顺序打乱了,那这些帧该如何播放呢?这时就引入了另外两个概念:DTS 和 PTS。
64+
通过上面的描述可以看出:P帧需要参考前面的I帧或P帧才可以生成一张完整的图片,而B帧则需要参考前面I帧或P帧及其后面的一个P帧才可以生成一张完整的图片。这样就带来了一个问题:在视频流中,先到来的 B 帧无法立即解码,需要等待它依赖的后面的 I、P 帧先解码完成,这样一来播放时间与解码时间不一致了,顺序打乱了,那这些帧该如何播放呢?这时就引入了另外两个概念:DTS 和 PTS。在没有B帧的情况下,DTS和PTS的输出顺序是一样的。因为B 帧打乱了解码和显示的顺序,所以一旦存在B帧,PTS与DTS势必就会 不同。
4465

4566
【PTS和DTS】
4667

VideoDevelopment/播放器性能优化.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@
6666

6767
空间换时间。双播放器方案原理比较简单,就是在当前视频起播之后,预准备下一个视频的播放器,两个播放器循环使用。下一个视频的播放器一旦准备好,加上视频流已加载到本地,则起播非常快,几乎是视频直出的效果。但由于播放器准备更耗时,用户滑到下一个视频时,并不能百分百保证此视频的播放器已准备好。
6868

69+
### 预取策略
70+
71+
1,修改AndroidVideoCache进行预加载
72+
2,线程池并发缓存并控制视频缓存优先级(线程池线程数为3,先加入的先缓存),一次预加载8个视频,item创建时开始预加载,item销毁时,取消预加载
73+
3,等待下页第一个视频预加载完成,才会进入下一页视频,保证滑到的视频都是可以立马观看的。(一页视频为8个)
74+
4,当前视频开始播放之后才会进行预加载
75+
5,区分快滑慢滑两种模式,快滑时取消当前所有预加载,慢滑不取消,因为快滑大概率滑到一个未预加载的视频,慢滑大概率滑到一个已经预加载的视频,保证滑到视频尽快播放。
76+
6,当视频播放后,根据滑动方向,会将取消的预加载进行恢复,正向滑动就恢复当前之后之后的预加载任务,反选滑动就恢复当前视频之前的预加载任务。
77+
7,限制网速,当时视频还没播放的时候,会限制预下载的网速(慢滑不会取消预加载),通过让下载线程sleep来限制网速。
78+
8,ijkplayer起播参数配置。
79+
9,视频压缩和处理(让视频参数都位于视频首部)。
80+
81+
82+
6983
#### MOOV后置
7084

7185
很多手机为了偷懒,录制完视频后才知道视频信息,所以把moov放到末尾。对于moov放到视频最后的情况下,就要多一次seek,当从头开始解析的时候如果发现未找到moov信息,需要将其seek到尾部再去寻找,这样会导致起播慢。

VideoDevelopment/视频封装格式/TS.md

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,125 @@ TS
33

44

55

6-
TODO
6+
TS的全称为MPEG2-TS,TS即Transport Stream的缩写。它是分包发送的,每一个包长188字节(还有192和204字节的包)。包的结构为,包头4字节(第一个字节为0x47),负载为184字节。
77

8+
VD的音视频格式为MPEG2-PS,全称是Program Stream。而TS的全称则是Transport Stream。MPEG2-PS主要应用于存储的具有固定时长的节目,如DVD电影,而MPEG-TS则主要应用于实时传送的节目,比如实时广播的电视节目。这两种格式的主要区别是什么呢?简单地打个比喻说,你将DVD上的VOB文件的前面一截cut掉(或者干脆就是数据损坏),那么就会导致整个文件无法解码了,而电视节目是你任何时候打开电视机都能解码(收看)的。在TS流里可以填入很多类型的数据,如视频、音频、自定义信息等。所以,MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的。
89

10+
我们可以看出,TS格式是主要用于直播的码流结构,具有很好的容错能力。通常TS流的后缀是.ts、.mpg或者.mpeg,多数播放器直接支持这种格式的播放。TS流中不包含快速seek的机制,只能通过协议层实现seek。HLS协议基于TS流实现的。
911

1012

1113

14+
## TS格式详解
1215

16+
TS文件(流)可以分为三层:TS层(Transport Stream)、PES层(Packet Elemental Stream)、ES层(Elementary Stream)。
1317

18+
ES层就是音视频数据,PES层是在音视频数据上加了时间戳等对数据帧的说明信息,TS层是在PES层上加入了数据流识别和传输的必要信息。TS文件(码流)由多个TS Packet组成的。
1419

1520

1621

22+
![image-20210309114928103](https://raw.githubusercontent.com/CharonChui/Pictures/master/ts_archi.png?raw=true)
1723

1824

1925

26+
### TS层
2027

28+
TS包大小固定为188字节,TS层分为三个部分:TS Header、Adaptation Field、Payload。
2129

30+
TS Header固定4个字节;Adaptation Field可能存在也可能不存在,主要作用是给不足188字节的数据做填充;Payload是PES数据。
2231

32+
#### 1. TS Header
33+
34+
TS包的包头提供关于传输方面的信息。
35+
36+
TS包的包头长度不固定,前4个字节是固定的,后面可能跟有自适应字段(适配域)。4个字节是最小包头。
37+
38+
包头的结构体字段如下:
39+
40+
- sync_byte(同步字节):固定为0x47;该字节由解码器识别,使包头和有效负载可相互分离。
41+
- transport_error_indicator(传输错误标志):‘1’表示在相关的传输包中至少有一个不可纠正的错误位。当被置1后,在错误被纠正之前不能重置为0。
42+
- payload_unit_start_indicator(负载起始标志):为1时,表示当前TS包的有效载荷中包含PES或者PSI的起始位置;在前4个字节之后会有一个调整字节,其的数值为后面调整字段的长度length。因此有效载荷开始的位置应再偏移1+[length]个字节。
43+
- transport_priority(传输优先级标志):‘1’表明当前TS包的优先级比其他具有相同PID, 但此位没有被置‘1’的TS包高。
44+
- PID:指示存储与分组有效负载中数据的类型。
45+
- transport_scrambling_control(加扰控制标志):表示TS流分组有效负载的加密模式。空包为‘00’,如果传输包包头中包括调整字段,不应被加密。其他取值含义是用户自定义的。
46+
- adaptation_field_control(适配域控制标志):表示包头是否有调整字段或有效负载。‘00’为ISO/IEC未来使用保留;‘01’仅含有效载荷,无调整字段;‘10’ 无有效载荷,仅含调整字段;‘11’ 调整字段后为有效载荷,调整字段中的前一个字节表示调整字段的长度length,有效载荷开始的位置应再偏移[length]个字节。空包应为‘10’。
47+
- continuity_counter(连续性计数器):随着每一个具有相同PID的TS流分组而增加,当它达到最大值后又回复到0。范围为0~15。
48+
49+
#### 2. TS Adaptation Field
50+
51+
Adaptation Field的长度要包含传输错误指示符标识的一个字节。
52+
53+
PCR是节目时钟参考,PCR、DTS、PTS都是对同一个系统时钟的采样值,PCR是递增的,因此可以将其设置为DTS值,音频数据不需要PCR。
54+
55+
打包TS流时PAT和PMT表是没有Adaptation Field的,不够的长度直接补0xff即可。
56+
57+
视频流和音频流都需要加adaptation field,通常加在一个帧的第一个ts包和最后一个ts包里,中间的ts包不加。
58+
59+
#### 3. TS Payload
60+
61+
TS包中Payload所传输的信息包括两种类型:视频、音频的PES包以及辅助数据;节目专用信息PSI。
62+
63+
TS包也可以是空包。空包用来填充TS流,可能在重新进行多路复用时被插入或删除。
64+
65+
视频、音频的ES流需进行打包形成视频、音频的 PES流。辅助数据(如图文电视信息)不需要打成PES包。
66+
67+
### PES层 & ES 层
68+
69+
#### PES层
70+
71+
PES结构如图:
72+
73+
![pes](https://raw.githubusercontent.com/CharonChui/Pictures/master/pes.png?raw=true)
74+
75+
从上面的结构图可以看出,PES层是在每一个视频/音频帧上加入了时间戳等信息,PES包内容很多,下面我们说明一下最常用的字段:
76+
77+
- pes start code:开始码,固定为0x000001。
78+
- stream id:音频取值(0xc0-0xdf),通常为0xc0;视频取值(0xe0-0xef),通常为0xe0。
79+
- pes packet length:后面pes数据的长度,0表示长度不限制,只有视频数据长度会超过0xffff。
80+
- pes data length:后面数据的长度,取值5或10。
81+
- pts:33bit值
82+
- dts:33bit值
83+
84+
关于时间戳PTS和DTS的说明:
85+
86+
1. PTS是显示时间戳、DTS是解码时间戳。
87+
2. 视频数据两种时间戳都需要,音频数据的PTS和DTS相同,所以只需要PTS。
88+
89+
有PTS和DTS两种时间戳是B帧引起的,I帧和P帧的PTS等于DTS。如果一个视频没有B帧,则PTS永远和DTS相同。
90+
91+
从文件中顺序读取视频帧,取出的帧顺序和DTS顺序相同。DTS算法比较简单,初始值 + 增量即可,PTS计算比较复杂,需要在DTS的基础上加偏移量。
92+
93+
音频的PES中只有PTS(同DTS),视频的I、P帧两种时间戳都要有,视频B帧只要PTS(同DTS)。
94+
95+
#### ES 层
96+
97+
ES层指的就是音视频数据。
98+
99+
一般的,视频为H.264视频,音频为AAC音频。
100+
101+
102+
103+
104+
105+
## TS流生成及解析流程
106+
107+
### TS 流生成流程
108+
109+
- 将原始音视频数据压缩之后,压缩结果组成一个基本码流(ES)。
110+
- 对ES(基本码流)进行打包形成PES。
111+
- 在PES包中加入时间戳信息(PTS/DTS)。
112+
- 将PES包内容分配到一系列固定长度的传输包(TS Packet)中。
113+
- 在传输包中加入定时信息(PCR)。
114+
- 在传输包中加入节目专用信息(PSI) 。
115+
- 连续输出传输包形成具有恒定比特率的MPEG-TS流。
116+
117+
### TS 流解析流程
118+
119+
- 复用的MPEG-TS流中解析出TS包;
120+
- 从TS包中获取PAT及对应的PMT;
121+
- 从而获取特定节目的音视频PID;
122+
- 通过PID筛选出特定音视频相关的TS包,并解析出PES;
123+
- 从PES中读取到PTS/DTS,并从PES中解析出基本码流ES;
124+
- 将ES交给解码器,获得压缩前的原始音视频数据。
23125

24126

25127

VideoDevelopment/视频封装格式/视频封装格式.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88

99

1010

11+
封装,也叫多路复用(mux)。封装的目的一般为了在一个文件(流)中能同时存储视频(video)、音频(audio)、字幕(subtitle)等内容——这也正是“复用”的含义所在(分时复用)。封装还有另一个作用是在网络环境下确保数据的可靠快速传输。
12+
13+
编码的目的是为了压缩媒体数据。有别于通用文件数据的压缩,在图像或音频压缩的时候,可以借助图像特性(如前后关联、相邻图块关联)或声音特性(听觉模型)进行压缩,可以达到比通用压缩技术更高的压缩比。
14+
15+
16+
17+
18+
1119

1220
## 音频编码格式
1321

0 commit comments

Comments
 (0)