crowinHELL
记录一点一滴

导航

 

vlc 调试记录
1)启动main函数,在vlc.c中
main函数中有一系列的初始化工作,主要工作是环境设置和消息通道等初始化
根据不同的操作系统得到或设置一系列的环境参数?

然后用liblvc_new初始化对libvlc的调用

仔细研究libvlc

 libvlc_set_exit_handler (vlc, vlc_kill, &self);
 libvlc_set_user_agent (vlc,"VLCmediaplayer","VLC/"PACKAGE_VERSION);

这两句暂时没弄懂什么意思

然后初始化playlist,初始化模块,初始化线程池,初始化界面
进入sigwait,等待消息参数

实际上,main里的过程相当于mfc的初始化界面和等待响应消息,只是vlc用自己的代码和数据结构写了一个mfc的框架和消息响应机制。由于不同的线程有不同的响应机制,先从access中的file.c入手,可以看看一个文件是怎么被打开的

界面应该是qt写的

2)access,文件读入过程分析

最顶层,libvlcapi  libvlc_media_library_load (include/vlc/libvlc_media_library.h)传入参数 libvlc_media_library_t ,没有找到libvlc_media_library_t的定义
我日,在lib/media_library里找到了定义,难道是因为定义只会在头文件里去找?
是用正则表达式找到的

struct libvlc_media_library_t
{
    libvlc_event_manager_t * p_event_manager;
    libvlc_instance_t *      p_libvlc_instance;
    int                      i_refcount;
    libvlc_media_list_t *    p_mlist;
};

可以看出里面有一个media_list,一个libvlc实例
对libvlc_media_library_load() 的分析可以看出,传入参数media_library和psz_uri(应该是媒体文件的地址),如果media_list存在则释放,并用libvlc_instance重新创建一个,然后调用libvlc_media_list_add_file_content加入播放列表
PS。vlc对于媒体文件的操作都是以media_list来操作的

从该函数中调用的一个函数

libvlc_media_list_add_file_content( libvlc_media_list_t * p_mlist,
                                    const char * psz_uri )

定位到其定义,可以看源代码

在这里,先用input_item_NewExt(),从传入的地址读取input_item_t
再用libvlc_media_new_from_input_item()从input_item转为libvlc_media,应该是libvlc其他函数可以调用的媒体格式
最后把转成libvlc_media的利用libvlc_media_list_add_media()添加到播放列表里去。
然后用input_Read读取这个media文件。


继续跟进input_Read()的源代码,可以看到VLC是如何调用module的。
传入时候的参数是这样
input_Read( p_mlist->p_libvlc_instance->p_libvlc_int, p_input_item );
本来定义是这样
int input_Read( vlc_object_t *p_parent, input_item_t *p_item )
说明文档如下
/**
 * Initialize an input thread and run it until it stops by itself.
 *
 * \param p_parent a vlc_object
 * \param p_item an input item
 * \return an error code, VLC_SUCCESS on success
 */

看出input_read会独立开辟一个线程用来读取数据,传入参数是p_item
此函数会先用create创造一个线程,然后对线程进行初始化,如果初始化成功,这个线程被传入到线程池里一直执行,直到自己结束。

跟进初始化代码Init(p_input),p_input是input_thread_t,也就是处理输入的专用线程

Init里代码比较复杂,先跳过。
直接看InputSourceInit()里的代码,大概了解一下vlc是怎么调用模块的
用modules.c里有很多调用方法,比如直接按名字调用,按need_modules调用,按shortcut调用,按capbility调用,等等。。。


在inputsourceInit里,先把传入的地址(可能是本地也可能是网络uri)分离成各个部分可以用到的信息,比如access用的地址,文件头anchor用来判断需要用什么access module读入。
尝试在input_SplitMRL设置断点,传入本地播放文件,只有psz_access 和 psz_path,psz_dup 有值,可能demux和anchor是播放网络流媒体才会用到的。


在初始化界面,添加播放列表和播放的时候都会执行一次inputsource()函数,区别在前两次不检索播放文件,在播放本地文件的时候b_preaparse会变成flase,函数体中会先尝试access_demux来读入文件(本地测试时候没有成功过),然后再用access_NEW来找到需要的模块,返回access指针,在access_NEW()函数体中用module_need传入所需的capbility来查找模块。

p_access返回的指针被stream_AccessNew调用,目的是通过access读入视频流?根据名字分析貌似是这样。

posted on 2013-06-24 15:36  谢葛格  阅读(568)  评论(0)    收藏  举报