2024年5月1日发(作者:)

视频播放的基本原理

当初看VLC代码花了不少时间,其中很大的原因是不太了解视频播放的基本原理。现

在看来,几乎所有的视频播放器,如VLC、MPlayer、Xine,包括DirectShow,在播放

视频的原理和架构上都是非常相似的,理解这个对理解VLC的源码会有事半功倍的效果。

大致的来说,播放一个视频分为4个步骤:

1. acess 访问,或者理解为接收、获取、得到

2. demux 解复用,就是把通常合在一起的音频和视频分离(还有可能的字幕)

3. decode 解码,包括音频和视频的解码

4. output 输出,也分为音频和视频的输出(aout和vout)

拿播放一个UDP组播的MPEG TS流来说吧,access部分负责从网络接收组播流,

放到VLC的内存缓冲区中,access模块关注IP协议,如是否IPv6、组播地址、组播协议、

端口等信息;如果检测出来是RTP协议(RTP协议在UDP头部简单得加上了固定12个字

节的信息),还要分析RTP头部信息。这部分可以参看VLC源码

/modules/access/udp.c 。在同目录下还可以看到大量的access模块,如file、http、

dvd、ftp、smb、tcp、dshow、mms、v4l…等等

而demux部分首先要解析TS流的信息。TS格式是MPEG2协议的一部分,概括地

说,TS通常是固定188字节的一个packet,一个TS流可以包含多个program(节目),

一个program又可以包含多个视频、音频、和文字信息的ES流;每个ES流会有不同的

PID标示。而又为了可以分析这些ES流,TS有一些固定的PID用来间隔发送program

和es流信息的表格:PAT和PMT表。关于TS格式的详细信息可以去google一下。

VLC专门做了一个独立的库libdvbpsi来解析和编码TS流,而调用它的代码可以参见

VLC源码 /modules/demux/ts.c。

其实之所以需要demux,是因为音视频在制作的时候实际上都是独立编码的,得到的

是分开的数据,为了传输方便必须要用某种方式合起来,这就有了各种封装格式也就有了

demux。

demux分解出来的音频和视频流分别送往音频解码器和视频解码器。因为原始的音视

频都是占用大量空间,而且冗余度较高的数据,通常在制作的时候就会进行某种压缩。这

就是我们熟知的音视频编码格式,包括MPEG1(VCD)、MPEG2(DVD)、MPEG4、H.264、

rmvb等等。音视频解码器的作用就是把这些压缩了的数据还原成原始的音视频数据。VLC

解码MPEG2使用了一个独立的库libmpeg2,调用它的源文件是

/modules/codec/libmpeg2.c。VLC关于编解码的模块都放在/modules/codec目录下,

其中包括著名的庞大的ffmpeg。

解码器,例如视频解码器输出的是一张一张的类似位图格式的图像,但是要让人从屏

幕看得到,还需要一个视频输出的模块。当然可以像一个Win32窗口程序那样直接把图像

画到窗口DC上——VLC的一个输出模块WinGDI就是这么干的,但是通常这太慢了,而

且消耗大量的CPU。在Windows下比较好的办法是用DirectX的接口,会自动调用显卡

的加速功能。