I、P、B 帧
- I 帧 (Intra coded frames):I 帧图像采纳帧内编码方式,即只利用了单帧图像内的空间相关性,而没有利用工夫相关性。I 帧应用帧内压缩,不应用静止弥补,因为 I 帧不依赖其它帧,所以是随机存取的入点,同时是解码的基准帧。I 帧次要用于接收机的初始化和信道的获取,以及节目的切换和插入,I 帧图像的压缩倍数绝对较低。I 帧图像是周期性呈现在图像序列中的,呈现频率可由编码器抉择。
- P 帧 (Predicted frames):P 帧和 B 帧图像采纳帧间编码方式,即同时利用了空间和工夫上的相关性。P 帧图像只采纳前向工夫预测,能够进步压缩效率和图像品质。P 帧图像中能够蕴含帧内编码的局部,即 P 帧中的每一个宏块能够是前向预测,也能够是帧内编码。
- B 帧 (Bi-directional predicted frames):B 帧图像采纳双向工夫预测,能够大大提高压缩倍数。值得注意的是,因为 B 帧图像采纳了将来帧作为参考,因而 MPEG-2 编码码流中图像帧的传输程序和显示程序是不同的。
通过上述根本能够阐明如果有 B frame 存在的状况下一个 GOP 的最初一个 frame 肯定是 P。
这就带来一个问题:在视频流中,先到来的 B 帧无奈立刻解码,须要期待它依赖的前面的 I、P 帧先解码实现,这样一来播放工夫与解码工夫不统一了,程序打乱了,那这些帧该如何播放呢?这时就须要咱们来理解另外两个概念:DTS 和 PTS。
DTS、PTS
- DTS(Decoding Time Stamp):即解码工夫戳,这个工夫戳的意义在于通知播放器该在什么时候解码这一帧的数据。
- PTS(Presentation Time Stamp):即显示工夫戳,这个工夫戳用来通知播放器该在什么时候显示这一帧的数据。
尽管 DTS、PTS 是用于领导播放端的行为,但它们是在编码的时候由编码器生成的。
当视频流中没有 B 帧时,通常 DTS 和 PTS 的程序是统一的。但如果有 B 帧时,就回到了咱们后面说的问题:解码程序和播放程序不统一了。
比方一个视频中,帧的显示程序是:I B B P,当初咱们须要在解码 B 帧时晓得 P 帧中信息,因而这几帧在视频流中的程序可能是:I P B B,这时候就体现出每帧都有 DTS 和 PTS 的作用了。DTS 通知咱们该按什么程序解码这几帧图像,PTS 通知咱们该按什么程序显示这几帧图像。程序大略如下:
PTS: 480 640 560 520 600 800 720 680 760 960 ...
DTS: 400 440 480 520 560 600 640 680 720 760 ...
Stream: I P B B B P B B B P ...
播放序:1 5 3 2 4 9 7 6 8 10 ...
PTS >= DTS
音视频的同步
下面说了视频帧、DTS、PTS 相干的概念。咱们都晓得在一个媒体流中,除了视频以外,通常还包含音频。音频的播放,也有 DTS、PTS 的概念,然而音频没有相似视频中 B 帧,不须要双向预测,所以音频帧的 DTS、PTS 程序是统一的。
音频视频混合在一起播放,就出现了咱们经常看到的狭义的视频。在音视频一起播放的时候,咱们通常须要面临一个问题:怎么去同步它们,免得呈现画不对声的状况。
要实现音视频同步,通常须要抉择一个参考时钟,参考时钟上的工夫是线性递增的,编码音视频流时根据参考时钟上的工夫给每帧数据打上工夫戳。在播放时,读取数据帧上的工夫戳,同时参考以后参考时钟上的工夫来安顿播放。这里的说的工夫戳就是咱们后面说的 PTS。实际中,咱们能够抉择:同步视频到音频、同步音频到视频、同步音频和视频到内部时钟。
PTS 和 DTS 的工夫基
工夫基是 FFmpeg 中的概念,也就是 time_base。它也是用来度量工夫的。time_base 是工夫的根底刻度。例如,time_base={1,25} 示意把 1 秒分为 25 等份,每一份就是 1 /25 秒,即 time_base=1/25 秒。pts 或者 dts 的值指的是占多少个这样的工夫刻度 time_base。
所以,pts*time_base 就是帧的显示工夫,dts*time_base 就是帧的解码工夫。
不同的封装格局,timebase 是不一样的。常见的有:
flv:{1, 1000}
ts:{1, 90000}
mp4 视频:{1, 25}、{1, 24}、{1,, 1000} 等
mp4 音频:{1, 44100}、{1, 48000} 等
mkv:{1, 1000} 等