http://blog.csdn.net/tteaonly/article/details/7333162
前言:
所谓轻量,即代码小而少;所谓便携,即依赖第三方库少。
说明:
在我从事的开放项目中,常常需要在桌面、手机环境里运行播放器,播放的大都是流式媒体(即无法进行SEEK操作的数据流),目前主流的多媒体播放框架,都无法满足我的需求。在分析VLC代码的基础上,启动了一个发明轮子的项目,开发一个轻量、便携的多媒体框架,适用于定制开发一个feature player,以区别全功能播放器。
目前现有的媒体播放器实现大都是基于多媒体框架的,主流的框架包括有:
- DirectShow: 用户代码轻量,便携,只支持Windows
- GStreamer: 用户代码轻量,但不便携,大量依赖第三方库
- VLC: 提供libVLC作为用户开发库,开发简单且高效,但是代码过重,不便携,难定制。
- OpenMX: 不熟,需要付出学习成本,况且只支持Android跨OS差。
除了这些框架库的问题之外,从我的经验来看,目前这些框架普遍对“变帧率”的码流播放效果不够好。流媒体包括有 VOD/Live 两种视频形态,VOD通常是播放电影,播放上一般严格按照PTS顺序显示视频以及播放音频采样,网络不够好的情况下,最多就是暂停播放,不存在跳帧需求和延时概念。Live视频特别是监控视频和视频对话,视频多是变帧率的,对延时要求很高,在网络抖动(jitter)很大的时候,需要进行适当的跳帧以保证适当的延时。此外,feature player通常数据IO方式、媒体格式都是固定单一的,并且画面显示以及音频播放是需要定制的,这样一个重量级的外加一大堆插件的多媒体框架就不那么适合了。
以上就是为什么需要开一个适用于定制和二次修剪的面向feature player的多媒体框架的原因。
顶层设计:
按功能分,媒体播放器分为(按照VLC命名): Access, Stream, Demux, Decode, Video/Audio out, Player controller 6大部分。Access负责多媒体数据IO;Stream负责多媒体数据的流化;Demux负责将多媒体流拆解为Video/Audio 包;Decode模块负责将Video/Audio包,解压缩为图像和PCM数据;Video/Audio out负责显示图像以及播放PCM;Player controller负责用户接口,如快进/暂停等。
我所设计框架主要面向live stream media,因此可以去掉Stream模块,只有Access, Demux, Decode, AVout, Player 5个功能模块。其中每个模块对应输入/输出,数据流如下所示:
[Access] ---(raw data)--->[Demux]----(A/V packet)--->Decode----(Picture/PCM)---->AVout
每个模块对应一个线程,维护自己的数据输入和输出,输出的数据交给下给下一个模块进行释放,每个模块都事件回调和消息接收的形式交给Player对象控制.
总结如下:
- 系统由:Player, Access, Demux, Decode, AVOut组成
- 每个模块一个独立线程
- 每个模块输出数据交给下一个模块进行释放
- Access, Demux, Decode, AVOut 以事件回调和消息接收的形式交给Player对象控制
基础设施:
根据前面分析,这个播放器对多线程,消息以及回调非常依赖,因此考虑引入Message Queue和Signal/Slot机制作为代码核心基础设置。此外,为了做好跨系统,对 time, timer, list, fifo等做好封装,方便使用。比如以64bit作为计时类型,确保不出现翻转,利用STL提供的list管理各种指针列表,实现各种资源的显示管理。