锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++开源 / VLC接口技术分析
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

VLC接口技术分析

前言

这里描述的是VLC的内部接口,外部接口可以参考一个nvlc.chm文件来进行。nvcl是vlc的C#封装,作者的研究非常深入。

3.1 VLC运行过程

通过对相关资料和自己的分析,VLC的运行过程如下:
ELF(Linux下可执行文件的格式)先被动态加载,然后主线程就变成了接口线程并且在src/interface/interface.c中开始。它执行下列步骤:
1.cpu探测:什么型号?所有能力(MMX,MMXEXT,3DNow,AltiVec等等)
2.消息接口初始化;
3.命令行选项解析组件
4.创建播放列表
5.仓库初始化
6.加载所有内置和动态组件
7.打开接口
8.安装信号处理器:SIGHUP,SIGINT和SIGQUIT(捕获一个,忽略后来的并退出)。
9.派生音频输出线程;
10.派生视频输出线程;
11.主循环:事件管理;
下图表示了这些步骤的执行过程:

VLC的运行过程图


VLC的运行过程图

3.2 消息接口

由于printf()函数不是线程安全的,因此在调用printf()函数时一个线程的执行将会受到干扰,当这个线程被另一个函数所调用时就会其状态被破坏而退出程序。所以VLC构造了自己的线程安全的消息接口。
VLC的线程安全的消息接口有两种实现方式:如果在config.h里定义了INTF_MSG_QUEUE的话,每一个类似printf()的函数 将会把排队的消息放到链表里,这个链表将会在事件循环中被线程接口用红色标记的方式打印出来。如果INTF_MSG_QUEUE没被定义的话,调用线程将 会获得一个print lock(用来防止在同一时刻有两个printf操作被执行)同时直接打印出消息(默认操作)。
以下为VLC线程安全消息的API:
QueueMsg:添加一条消息到消息队列,如果消息队列满了,先打印所有的消息;
FlushMsg:打印所有在消息队列里的消息,特别的,消息队列必须被提前加锁,因为该函数不检查锁。
PrintMsg:打印一条消息到stderr,可以打印彩色消息。

3.3 命令行选项

VLC用GNU的getopt解析命令行选项。Getopt结构定义在src\extras\getopt.h里。所有的配置也可以用环境变量改变:调用 函数main_Put*Variable和main_Get*Variable。所以,.\vlc--height=240和 .\vic_height=240./vlc(这种方式用于所有地方,包括插件)是一样的。但是为了线程安全的考虑,当第二个线程派生 了,main_Put*Variable便不能被使用了。

3.4 播放列表管理

当VLC得到输入媒体文件的时候播放列表被创建。一个合适的接口插件能够从这个播放列表添加和删除文件。在src/Playlist目录下的这些被使用的函数被描述。
播放列表既不是动态组件也不是内置组件,只是可以被外部调用的API:
Playlist_Create:初始化播放列表,派生两个线程。一个是播放列表主线程RunThread调用Input_CreateThread为每个被读的文件派生输入线程。一个是播放列表里的项目排队预解析线程RunPreparse。
Intf_playlistadd和intf_playlistdelete是两个典型的最常用的添加和删除播放列表的命令函数。此时接口主循环函数inif_manage将被启动同时在必要的时候终止输入的线程。

3.5 组建仓库

在启动的时候,VLC创建一个包含所有插件接口(.so和内置插件)的仓库,每一个插件都会被检查其实现的功能,这些功能如下:
MODULE_CAPABILITY_INTF:一个接口插件。
MODULE_CAPABILITY_ACCESS:A Sam- ism,目前还没有用到。
MODULE_CAPABILITY_PUT:一个输入插件比如说PS和DVD的播放要用到。
MODULE_CAPABILITY_DECAPS: A Sam-ism,unused at present。
MODULE_CAPABILITY_ADEC:音频解码器。
MODULE_CAPABILITY_VDEC:视频解码器。
MODULE_CAPABILITY_MOTION:视频解码器的补充动态组件。
MODULE_CAPABILITY_IDCT:视频解码器的IDCT组件。
MODULE_CAPABILITY_AOUT:一个音频输出组件。
MODULE_CAPABILITY_VOUT:一个视频输出组件。
MODULE_CAPABILITY_YUV:视频输出的YUV组件。
MODULE_CAPABILITY_AFX:音频输出的音频效果插件,目前还没实现。
MODULE_CAPABILITY_VFX:视频输出的音频效果插件,目前还没实现。
管理这些插件的API如下:
Module_InitBank:创建组件仓库,然后调用module_LoadMain将主程序信息导入组件银行。
Module_LoadMain:将主程序信息导入组件仓库。
Module_LoadBulltins:加载所有内置组件。
Module_Loadplugins:加载所有动态组件。
Module_EndBank:清空组件仓库。
Module_ReSetBank:通过卸载所有无用的动态(插件)组件,重置组件仓库。
Module_EndBank:卸载所有动态(插件)组件,清空模仓库。
Module_Need:得到能力最符合要求的组件。
Module_Unneed:减少一个组件的引用计数,必须被Module_Need的同一个线程调用。

3.6 接口主循环

这个接口线程首先选取合适的接口动态插件,然后和这个插件的pf_run()函数一起进入主接口循环。pf_run()函数将实行其该实现的功能并且每隔 100ms调用intf_Manage一次(典型的为用户图形界面的时间回调)。intf_Manage通过卸载不必要的组件来清空组件仓库,并且管理播 放列表和当消息队列正在用时对排队的消息进行红色标记。如果在linux下编译有图形界面,那么这个动态插件是modules\gui \wxwindows\xwindows.cpp。

3.7 接口动态组件

这两种组件都位于modules\目录,接口动态组件除了具有普通动态组件的定义外,还需要定义以下标准API:Run或者Runlntf:这个函数就是pf_run,履行接口动态组件的一切功能(等待用户输入并且显示信息)。

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内