【ACCESS精品源码栏目提醒】:网学会员--在 ACCESS精品源码编辑为广大网友搜集整理了:视频播放的基本原理 - 教育绩等信息,祝愿广大网友取得需要的信息,参考学习。
视频播放的基本原理当初看 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 协议的一部分,概括地说, 一 (节目)一个 programTS 通常是固定 188 字节的一个 packet,个 TS 流可以包含多个 program ,又可以包含多个视频、音频、和文字信息的 ES 流;每个 ES 流会有不同的 PID 标示。
而又为了可以分析这些 ES 流, 有一些固定的 PID 用来间隔发送 program 和 es 流信息的表格: TSPAT 和 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 的接口,会自动调用显卡的加速功能。
这样的功能分解使得模块化更容易一点,每个模块住需要专注于自己的事;从整体来说功能强大而且灵活。
但是事情总是不会那么简单。
就拿
access 来说,媒体的访问是分层的,如 RTSP 就涉及到 IPv4、TCP、UDP、RTCP、RTSP 等多个层次的协议。
有些视频格式包括了传输、封装格式和编辑码格式如 MPEG 系列,有些封装格式是独立的容器,但是很多人会误解它是编解码格式,如 mkv、avi 这些。
音频和视频在 demux 之后就是独立的,但是需要有一套机制把它们同步起来。
同时我们需要有一套机制来控制速度、暂停、停止、跳进,获取各种媒体信息,这些都是很复杂而又很重要的事情。
另外也许需要在某个地方插入一些修改,来实现某种效果。
如音频的 EQ,视频的亮度调整之类的,VLC 专门设计了
access_filter、audio_filter 和 video_filter 类型的模块来做这一类事情。
VLC 比较独特的地方是集成了原来的 VLS 的功能,这依赖于 VLC 中 stream_output 类型的模块,它们可以把正在播放的视频以某种方式重新转码和发送出去,如 http、UDP、文件等等。
MPlayer 的结构与此是类似的,如/stream 目录对应的是
access 的功能,/mpdemux 对应的 demux 功能,/libmpcodecs 是解码器,/libvo 和/libao2 分别是视频和音频的输出。
DirectShow 也是类似的,不过分类更多一些更复杂一点。
DirectShow 里面的模块叫做 ,filter 之间通过”pin”来连接。
access 的模块对应于 DirectShow 中的 Source FIlter,“filter”这一类 Filter 只有输出 pin 没有输入 pin。
demux 模块对应于 splitter filter,这种 filter 有一个输入 pin,多个输出 pin。
解码模块是一类 transform filter,有一个输入 pin、一个输出 pin,输出模块对应于 readering filter,有一个输入 pin,没有输出 pin。
当然 transform filter 不一定是解码器,也可能是某种其他的处理。