http://blog.csdn.net/tteaonly/article/details/7279130
0. 起因
VLC最近出了2.0版本,决定今年深入掌握之,从分析代码开始,以此为备忘。
1. 概述
VLC多媒体框架的优点是:1.系统更加紧凑、高效;2.跨平台支持好,特别是桌面平台(包括Windows、Mac);
3. 编译系统完善,很容易可以构造出支持Windows,Linux的版本;4. 社区活跃,长期技术更新支持有保证。
整个VLC是以libvlc和libvlccore以及第三方插件组成,前端是独立的。据悉VLC C源码是黑客级别,本人看了多
眼之后,深以为然,包括有:类对象架构,观察者模式,插件管理系统等值得学习的代码。另外一方面,整个代
码要消化和理解也是一件不容易的事情。而且由于历史原因,整个VLC代码到处充满了垃圾和无用的代码,估计
清理起来也非常麻烦。
2. 目录说明 ( 以 vlc-2.0.0 为准)
- include/ libvlccore 库的头文件,编写自己的插件也是需要包含这里
- include/vlc libVLC头文件,如果仅仅使用libvlc开发,需要包含这里
- bin vlc程序代码,即原生GUI前端程序代码
- lib libVLC接口实现代码
- compat 跨 OS 代码
- contrib 第三方库的针对VLC的patch以及编译脚本
- extras 一些不太常用的辅助工具以及脚本
- modules 将各种第三方库封装为VLC的插件,按目录区分功能,如demux,video_filter等等
- src libvlccore实现,是vlc架构最重要部分
主要需要重点学习和关注的是:lib src两个目录之下的代码,这个两个目录也是整个vlc项目的核心。
3. 核心对象
使用libVLC构建一个最简单的播放器只需要调用下面间的API
[cpp] view plain copy
- _vlcinstance = <strong>libvlc_new</strong>(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
- _mp = <strong>libvlc_media_player_new</strong> (_vlcinstance);
- libvlc_media_player_set_xwindow (_mp, windid );
- _msource = libvlc_media_new_location(_vlcinstance, "./demo.mp4");
- <strong>libvlc_media_player_set_media</strong> (_mp, _msource);
- <strong>ibvlc_media_player_play</strong> (_mp);
首先通过libvlc_new构造一个全局的instance对象,这个指针可以看作VLC context的handler. 整个VLC对象使用
XXX_new , XXX_release, XXX_retain 三个函数来管理对象的创建销毁以及引用,针对每个对象使用ref_count记录
指针引用次数,这样可以调用XXX_release函数多次,在最后一次进行真正的资源释放工作。 libvlc_instance_t 对
象组成如下,包括两个核心功能的顶层指针(核心对象一个是管理播放,一个是管理流媒体服务)。
libvlc_int_t *p_libvlc_int; |
---|
libvlc_vlm_t libvlc_vlm; |
unsigned ref_count; vlc_mutex_t instance_lock; |
为了完成播放人物还需libvlc_media_player_t 以及 libvlc_media_t 两个对象,这个两个对象都是从libvlc_instance对象
创建,其中libvlc_media_t封装了多媒体对象,可以是一个文件,一个URL或者一个媒介(如DVD)。 libvlc_media_player
对象则封装播放相管内容。
首先看看 libvlc_media_t 对象,主要组成如下:
//指向顶层指针 int i_refcount; libvlc_instance_t *p_libvlc_instance; |
---|
//播放对象描述 input_item_t *p_input_item; libvlc_media_list_t *p_subitems; void *p_user_data; |
//控制变量 libvlc_event_manager_t * p_event_manager; vlc_cond_t parsed_cond; vlc_mutex_t parsed_lock; |
//内置变量 bool is_parsed; bool has_asked_preparse; |
接下来就是最重要libvlc_player对象的组成了:
int i_refcount; libvlc_instance_t * p_libvlc_instance; vlc_mutex_t object_lock; |
libvlc_media_t * p_md; libvlc_event_manager_t * p_event_manager; |
struct { input_thread_t *p_thread; input_resource_t *p_resource; vlc_mutex_t lock; } input; |
其中最最重要的就是这个 struct input结构体,几乎所有重要的内容都在这个结构体内部,是理解整个VLC的核心,VLC内
主要的对象Access, Stream, Demuxer, Decoder, Vout, Aout全部都包含在input_thread, input_resource内。