网络协议 14 - 流媒体协议:要说爱你不容易 (2)

    视频经过编码之后,生动活泼的一帧帧图像就变成了一串串让人看不懂的二进制。这个二进制可以放在一个文件里,然后按照一定的格式保存起来,这里的保存格式,就是系列名词一。

    编码后的二进制文件就可以通过某种网络协议进行封装,放在互联网上传输,这个时候就可以进行网络直播了。

    网络协议将编码好的视频流,从主播端推送到服务器,在服务器上有个运行了同样协议的服务端来接收这些网络数据包,从而得到里面的视频流,这个过程称为接流

    服务端接到视频流之后,可以滴视频流进行一定的处理,比如转码,也就是从一个编码格式转成另一种格式,这样才能适应各个观众使用的客户端,保证他们都能看到直播。

    流处理完毕后,就可以等待观众的客户端来请求这些视频流。观众的客户端请求视频流的过程称为拉流

    如果有非常多的观众同时看一个视频直播,都从一个服务器上拉流,压力就非常大,因此需要一个视频的分发网络,将视频预先加载到就近的边缘节点,这样大部分观众就能通过边缘节点拉取视频,降低服务器的压力。

    当观众将视频流拉下来后,就需要进行解码,也就是通过上述过程的逆过程,将一串串看不懂的二进制转变成一帧帧生动的图片,在客户端播放出来。

    整个直播过程,可以用下图来描述:

网络协议 14 - 流媒体协议:要说爱你不容易

    接下来,我们依次来看一下每个过程:

编码:将丰富多彩的图片变成二进制流

    虽然我们说视频是一张张图片的序列,但如果每张图片都完整,就太大了,因而会将视频序列分成三种帧:

I帧,也称关键帧。里面是完整的图片,只需要本帧数据,就可以完成解码。

P帧,前向预测编码帧。P 帧表示的是这一帧跟之前一个关键帧(或 P 帧)的差别,解码时需要用之前缓存的画面,叠加上和本帧定义的差别,生成最终画面。

B帧,双向预测内插编码帧。B 帧记录的是本帧与前后帧的差别。要解码 B 帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的数据与本帧数据的叠加,取得最终的画面。

    可以看出,I 帧最完整,B 帧压缩率最高,而压缩后帧的序列,应该是 IBBP 间隔出现。这就是通过时序进行编码

    在一帧中,分成多个片,每个片中分成多个宏块,每个宏块分成多个子块,这样将一张大图分解成一个个小块,可以方便进行空间上的编码。如下图:

网络协议 14 - 流媒体协议:要说爱你不容易

    尽管时空非常立体的组成了一个序列,但总归还是要压缩成一个二进制流。这个流是有结构的,是一个个的网络提取层单元(NALU,Network Abstraction Layer Unit)。变成这种格式就是为了传输,因为网络上的传输,默认的是一个个的包,因而这里也就分成了一个个的单元。

网络协议 14 - 流媒体协议:要说爱你不容易

    如上图,每个 NALU 首先是一个起始标识符,用于标识 NALU 之间的间隔。然后是 NALU 的头,里面主要配置了 NALU 的类型。最后的 Payload 里面是 NALU 承载的数据。

    在 NALU 头里面,主要的内容是类型 NAL Type,其中:

0x07 表示 SPS,是序列参数集,包括一个图像序列的所有信息,如图像尺寸、视频格式等。

0x08 表示 PPS,是图像参数集,包括一个图像的所有分片的所有相关信息,包括图像类型、序列号等。

    在传输视频流之前,剥削要传输者两类参数,不然就无法解码。为了保证容错性,每一个 I 帧之前,都会传一遍这两个参数集合。

    如果 NALU Header 里面的表示类型是 SPS 或 PPS,则 Payload 中就是真正的参数集的内容。

    如果类型是帧,则 Payload 中是真正的视频数据。当然也是一帧帧保存的。前面说了,一帧的内容还是挺多的,因而每一个 NALU 里面保存的是一片。对于每一片,到底是 I 帧,还是 P 帧,亦或是 B 帧,在片结构里面也有 Header,这里面有个类型用来标识帧的类型,然后是片的内容。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfppw.html