播放器解决了视频播放的问题。通常来说,解决问题最好的办好就是大而化小,小而化无。因为整个播放过程是一个复杂的过程,所以播放器
也采用分而治之的办法。
简单来说,这个大问题可以分解为四个小问题。
1,数据接收;2,数据解析;3,数据解码;4,数据输出。
我会对mplayer和vlc这两个开源播放器的代码结构来说明这四个问题。
一,数据接收(access)
自然,我们不能无中生有,要处理数据,总要有数据来源才行。但是数据来源的渠道有很多种。
可能是硬盘文件,可能是dvd光盘,也可能是http/httplive数据包,也可能是rtp数据包(vod),或者ftp,广播电视的ts流等等。
所以第一步我们要处理的问题就是如何把不同的数据来源统一一个接口。这需要不同数据包解析器,也就是实现不同的协议来满足这个需求。
对于mplayer,相关的代码在strearm,
对于vlc,相关的代码在/modules/access
查看代码目录,里面文件名可以和我们前面说的一些数据来源一一对应。所以如果我们需要实现某种协议,大抵是可以从这里获取一些实现思
路的。
二,数据解析(demux)
有了数据了,我们还要解析这些数据。
为了方便媒体文件的传输,我们要把音频,图像,同步信息等等一堆信息放到一起(就是上一篇说的容器),这个过程就是mux(multiplex)。
但是为了方便媒体文件的处理,我们又需要解复用demux(Demultiplexer)
container是为了解决的传输而诞生的,demux就是为了解析而诞生的。
不同的容器需要不同的解析器,就是不同的demux接口,为了方便编程,我们同样需要统一接口。我们来看看mplayer和vlc是如何做的。
mplayer把相关代码放在了libmpdemux里面。
vlc把相关代码放在/modules/demux里面。
这两个代码统一各种容器的解析方式(就是我们常见的avi,ts,mkv的解析)。
不过需要注意的是,这些代码很大一部分都是warp的ffmpeg/libavformat里面的代码。
三,解码(decode)
上面那个过程把音视频数据分离,我们得到的数据可能是mpeg-2/h.264压缩的视频,也可能是mp3/aac/ac-3等音频数据。
但是这些数据都是压缩过的,我们知道,屏幕是由一个一个的点结成的,这一个一个点又是由rgb来描述的,声卡是处理一个一个音频帧的。
这个过程我们要解决的问题就是把压缩过的数据还原出来。如何还原?没错,靠我们的解码器。
上一篇说了不同的解码标准,现实中的情况是,我们有了一个标准,但是我们可能根据这个标准来实现不同的解码器。就像我们有一张桌子的
草图,但是我们做的桌子却有不同的颜色一个。标准有了,实现可以不同。
mplayer把这块代码放到libmpcodecs里
vlc把这块代码放到/modules/codec里。
不过要指出的是,这两块代码同样大部分是在warp ffmpeg/libavcodec。
ffmpeg真是做为神一样库而存在啊。
四,数据输出(render)
准备好了解码后的数据,就差最好一步输出了。
视频通常会解码为yuv数据,音频通常会解码为pcm数据。然后我们把这些数据分别放到屏幕和声卡里,播放过程就算完成了。
同样,数据输出也有很多渠道,也需要统一。
图像可能会输出到sdl,x11或者framebuffer,或者directfb,也可能是wingdi。
音频可能会出到oss,alsa,等等。
为了统一这些,vlc和mplayer同样warp了一些库,
mplayer放到libvo与libao
vlc放到/modules/audio_out与/modules/video_out。