您的位置:首页 > 编程语言

VLC功能模块编程指南

2012-01-06 09:22 148 查看

功能模块编程指南

VLC建立在很多独立的功能模块上面的,象很多媒体播放器系统框架一样,每个模块实现一个新的功能。在阅读本文之前,必须先行阅读“VLC运行核及功能模块”和“VLC如何装载功能模块”章节。本文叙述如何为VLC编写一个新的功能模块。

Git与资源库操作

Git

如果你打算将你的工作上传到VLC,首先请阅读”git简介”一节,除此以外,还要检查”发送补丁”页里面的内容。

编译模块

Modules.am

首先在modules目录下,找到正确的存放代码的位置。

如果只是增加单文件模块到资源库,只需要添加该文件到moduels.am所在的目录。

如果需要添加比较大的模块到资源库:

创建一个新目录

在新目录下面创建一个新的Modules.am.

在configure.ac文件末尾添加对应的一行语句,用于m akefile。

例如, modules/video_filter/Modules.am文件告诉编译系统哪些源代码将加入videofilter模块。

注意: modules.am里面的缩进使用tab键(ASCII0x09),不是空隔键。

configure.ac

为了使模块可以编译,还需要在configure.ac添加VLC_ADD_PLUGIN
或PKG_ENABLE_MODULES_VLC语句,以新模块的名称作为参数。还要参照其它模块编译和链结所需要的参数,进行相应的添加。

当修改configure.ac以后,必须重新运行./bootstrap&& ./configure

装载模块

VLC 保留模块的缓冲区,用户不应该清除,但是,可以使用vlc–reset-plugins-cache来强行重启。

然后使用

vlc -vvv --color --list

检查插件是否可见。 也可以在QT开发的图形界面下查看。

一个空模块的例子

下面是一个很小的例子,有助于更好的理解。

/*****************************************************************************
* Preamble
*****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include <vlc_plugin.h>

/*****************************************************************************
* Local prototypes.
*****************************************************************************/

static int  Open           ( vlc_object_t * );
static void Close          ( vlc_object_t * );

/*****************************************************************************
* Module descriptor
*****************************************************************************/

vlc_module_begin()
set_shortname( _("testmodule") )
set_description( _("testmodle plug-in") )
set_capability( "testing", 0 )
set_callbacks( Open, Close )
set_category( CAT_INTERFACE ) /* 定义模块分类,默认的一些类别在vlc/include/vlc_configuration.h 中定义*/

add_integer( "test-angle", 1, "DVD Angle", "Default DVD Angle", false)
vlc_module_end ()

/*****************************************************************************
* Open: 初始化接口
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
}

/*****************************************************************************
* Close: 销毁接口
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
}

编写模块

模块描述表

VLC播放器模块必须包含一个自身的描述表,以及它可以接受的参数。

模块描述表使用vlc_module_begin()开始。

然后设置基本的信息:

set_shortname( _("DVD without menus") );
set_description( _("DVDRead Input") );
set_category( CAT_INPUT );
set_subcategory( SUBCAT_INPUT_ACCESS );

注意: _("")可以用来创建需要翻译的字符串。

能力和匹配分数

能力是模块可以装载的关键 。它定义模块的类型,即是否是数据读取模块,解复模块,还是其它类型的模块。VLC如何装载以及VLC能力的主要类型详情,请参考”VLC如何装载功能模块”一文。

如果VLC装载具体模块名称,直接打开。

如果VLC需要装载某一类型的功能模块(如解码器),VLC将装载所有的具有该能力的模块,按照匹配分数降序排列,然后调用Open()函数,如果返回VLC_SUCCESS,结束。

分数是一个整数,是一个与同一类功能模块的相对值。分数为0的时候,一种特例。下面是一个定义实例:

set_capability( "testing", 10 )

该语句定义testing能力为10.

分类和子类的配置

使用其中一个预定义的分类进行配置。分类和子类的配置决定功能模块的优先顺序。

配置分类包括:

CAT_INTERFACE

CAT_AUDIO

CAT_VIDEO

CAT_INPUT

CAT_SOUT

CAT_ADVANCED

CAT_PLAYLIST

同时,也应该使用某一个子类进行配置。所有的配置分类和子类的定义,参考include/vlc_configuration.h

配置和参数选项

如果需要给模块添加新的选项,按照下面的语句进行:

add_integer(name, value, text, longtext, advanced)


name是参数的标识,在命令行控制台里面可以用来设置参数的值

value参数的默认值。

text参数的简单描述,使用
_("")创建需要翻译的字符串。

longtext完整的参数描述,使用_("")可以创建需要翻译的文本。

advanced布尔值,如果为TRUE,对应的参数仅仅在—advanced选项的时候显示。

你可以添加下面的选项或参数到模块里面:

add_integer,

add_string,

add_float,

add_bool,

add_key,

add_file,

add_directory,

完整定义,请参看 include/vlc_plugin.h。

回调

模块打开和关闭的函数(随后详细介绍)需要在模块描述表里面定义,这样VLC才可以与模块进行交互。

set_callbacks()宏可以定义两个参数:第一个参数是pf_activate回调函数,第二个是pf_deactivate回调函数。VLC当需要一个插件实例提供正确接口的时候,调用pf_activate回调函数,
像宏里面set_capability()制定的一样。

Open(vlc_object_t*)

最重要的模块函数是打开函数:

static int  Open ( vlc_object_t * );

VLC运行核尝试打开模块的时候,将调用该函数,进行模块装载。

在Open函数里面,设置各种结构,设备或I/O。可以正常打开的函数将返回VLC_SUCCESS。否则,将认为装载失败。

Open函数里面还进行私有数据的分配(如有),对私有结构进行设置。如果打开失败,需要用户自己清理结构里面的资源。

Close(vlc_object_t*)

第二个最重要的函数是关闭函数,其声明如下:

static int  Close ( vlc_object_t * );

VLC运行核尝试关闭或卸载模块的时候,调用Close函数。

在关闭函数里面,将清理一些数据结构,I/O或设备。同时,关闭函数也释放一些私有数据。

子模块

子模块,如使用add_submodule()语句进行添加

与模块工作原理一样,这写模块对父模块非常有用,可以在模块之间代码公用。子模块在缓冲区分开存放,装载方式与模块一样。

模块类型

根据模块的能力的类别不同,需要实现的函数或方法也不一样,用户可以在相应的模块分类里面找到更多的信息。下面是一些主要的模块类别清单:

Access/获取

Demux/解复

Access_Demux /
获取并解复

Decoder/解码

Interface/用户界面

Videofilter /
视频滤波

Audiofilter /音频滤波

Audio output /语音输出

模块装载时的常见问题

有些时候,模块可能不正常工作,这时,需要转入到VLC源代码树的顶层目录,做下面的一些工作。这里假设使用bashshell.

保险方法 (先试)

编译文件和环境准备

find . -name .deps -exec rm -rf \{\} \;
./bootstrap
./configure

rm-rf选项具有递归功能,删除在源代码树里面的依赖缓冲区。它可以保证编译器自动查找新的文件。

编译

./compile


最后运行:

./vlc --reset-plugins-cache

省事方法

有时候,重设config.status里面的.deps缓冲区就可以了:

find . -name .deps -exec rm -rf \{\} \;
./config.status
./compile
./vlc --reset-plugins-cache

如果仅仅上面的几行不能凑效,请按照保险方法进行。

终极方法

当上面的方法还不能解决问题,可以按照下面的方法进行:

find . -name .deps -exec rm -rf \{\} \;
find . -name .libs -exec rm -rf \{\} \;
./bootstrap
./configure
./compile
./vlc --reset-plugins-cache

上面的过程同样删除库缓冲。在这个过程中必须运行configure,而不是config.status,后者在--no-create模式下运行configure,不会重新创建.lib缓冲。

独立的模块编译

为了能够避免编译整个的VLC源代码,可以单独对一些功能模块进行编译。这样在有些情况下非常有用的。例如新的模块由于只是版权问题不能随VLC一起发布。单独编译可以降低VLC的依赖,增加模块的独立性。

国际化

独立的模块不能使用VLC的主国际化域。需要添加自己的域。声明如下:

#define DOMAIN  "vlc-myplugin"
#define _(str)  dgettext(DOMAIN, str)
#define N_(str) (str)

/* ... */

vlc_module_begin()
set_text_domain (DOMAIN)
set_description (N_("My plugin"))
/* ... */
vlc_module_end()

或者完全禁止国际化:

#define _(str)  (str)
#define N_(str) (str)

关键字

为了保证VLC能装载模块,需要定义
__PLUGIN__关键字.这个可以使输出的符号类似下面的几行:(该处译者不甚明白,请参照原文。)

EXPORTS
vlc_entry__1_1_0g
vlc_entry_license__1_1_0g

同样,还可以定义__LIBVLC__关键字。

编译

使用简单makefile

下面的Makefile是VLC的X264模块的例子。

libdir = $(shell pkg-config --variable=libdir vlc-plugin )
vlclibdir = $(libdir)/vlc

all: libx264_plugin.so

libx264_plugin.so: libx264_plugin.o
gcc -shared -std=gnu99 $< `pkg-config  --libs vlc-plugin x264`  -Wl,-soname -Wl,$@ -o $@

libx264_plugin.o: x264.c
gcc -c -std=gnu99  $< `pkg-config  --cflags vlc-plugin x264` -D__PLUGIN__  -DMODULE_STRING=\"x264\" -o $@

clean:
rm -f libx264_plugin.o libx264_plugin.so

install: all
mkdir -p $(DESTDIR)$(vlclibdir)/
install -m 0755 libx264_plugin.so $(DESTDIR)$(vlclibdir)/

install-strip: all
mkdir -p $(DESTDIR)$(vlclibdir)/
install -s -m 0755 libx264_plugin.so $(DESTDIR)$(vlclibdir)/

uninstall:
rm -f -- $(DESTDIR)$(vlclibdir)/libx264_plugin.so

.PHONY: all clean install uninstall

使用自动工具

如果使用automake和libtool,按照下面Makefile.am例子进行:

vlclibdir = $(libdir)/vlc

vlclib_libx264_plugin_la_SOURCES = x264.c
vlclib_libx264_plugin_la_CFLAGS = $(VLC_PLUGIN_CFLAGS) $(X264_CFLAGS) \
-D__PLUGIN__ -DMODULE_STRING=\"x264\"
vlclib_libx264_plugin_la_LIBADD = $(VLC_PLUGIN_LIBS) $(X264_LIBS)
vlclib_libx264_plugin_la_LDFLAGS = \
-avoid-version -module -export-symbol-regex ^vlc_entry


专注领域:
机器视觉,智能监控,网络视频。
应用平台:WINDOWS,LINUX,
EMBEDDED
合作网站: http:// www.hdy.net.cn 怡心小院 http:// www.m20.com.cn 麦子频道
QQ:
494761986 EMAIL:buffi@qq.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐