当前位置:文档之家› VLC源代码分析

VLC源代码分析

VLC源代码分析
VLC源代码分析

VLC源代码分析

一、VLC简介

VLC的全名是Video Lan Client,是一个开源的、跨平台的视频播放器。VLC支持大量的音视频传输、封装和编码格式,完整的功能特性列表可以在这里获得https://www.doczj.com/doc/b65965231.html,/vlc/features.html,下面给出一个简要的不完整的列表:

操作系统:Windows、WinCE、Linux、MacOSX、BEOS、BSD

访问形式:文件、DVD/VCD/CD、http、ftp、mms、TCP、UDP、RTP、IP组播、IPv6、rtsp

编码格式:MPEG*、DIVX、WMV、MOV、3GP、FLV、H.263、H.264、FLAC

视频字幕:DVD、DVB、Text、Vobsub

视频输出:DirectX、X11、XVideo、SDL、FrameBuffer、ASCII

控制界面:WxWidgets、QT4、Web、Telnet、Command line

浏览器插件:ActiveX、Mozilla(firefox)

实际上为了更清晰一点,我们可以反过来说说VLC不支持哪些常见的。首先是RealVideo(Real的Audio部分支持),因为Real的Video加码器存在版权的问题。实际上VLC 0.9.0已经加入了RealVideo的支持,但是需要额外的解码器(类似MPlayer)。另外,VLC不支持3GP的音频格式AMR。

VLC原先是几个法国的大学生做的项目,后来他们把VLC作为了一个开源的项目,吸引了来自世界各国的很多优秀程序员来共同编写和维护VLC,才逐渐变成了现在这个样子。

至于为什么叫VideoLan Client,是因为以前还有一个VideoLan Server的项目(简称VLS),而目前VLS的功能已经合并到VLC中来,所以VLC不仅仅是一个视频播放器,它也可以作为小型的视频服务器,更可以一边播放一边转码,把视频流发送到网络上。VLC最为突出的就是网络流的播放功能,例如MPEG2的UDP TS流的播放和转发,几乎是无可替代的。

对普通用户来说,VLC还有一个好处是不影响Windows中的解码器。VLC通常不影响也不依赖于系统中自带的解码器(除了realvideo和quicktime的类型),很绿色很环保;更不用担心流氓软件、广告插件之类的恶心的玩意儿。

从程序结构来看,VLC的可扩展性是相当优秀的。VLC绝大部分用高效的C代码来编写(少量的C++和汇编),但是实现了完全动态的模块化,所有功能包括程序框架本身都是module,可以在运行时载入,这使得VLC可以轻易的扩展多种功能并且容易维护。它的架构有一点类似于DirectShow的技术。

VLC也很注重版权方面的问题,你可以放心的自由的使用而不需要为版权的问题担心——VLC只包括免费的、自由的库。VLC基于GPL,因此也可以用于商业应用,只需要保留GPL,以及公开源代码,如果你修改了VLC的话。

下面是VLC相关的一些链接

VLC官方网站:https://www.doczj.com/doc/b65965231.html,/

VLC下载页面:https://www.doczj.com/doc/b65965231.html,/vlc/

VLC下载目录(源码和安装包):https://www.doczj.com/doc/b65965231.html,/pub/videolan/vlc/

VLC Nightly Builds:https://www.doczj.com/doc/b65965231.html,/

VLC 开发Wiki:https://www.doczj.com/doc/b65965231.html,/Developers_Corner

VLC Win32第三方库预编译包下载目录:https://www.doczj.com/doc/b65965231.html,/pub/testing/win32/

VLC 官方论坛:https://www.doczj.com/doc/b65965231.html,/

VLC 邮件列表:https://www.doczj.com/doc/b65965231.html,/developers/lists.html

二、Windows平台编译

第一步,要创建编译VLC的环境。VLC在Windows下可以用Msys+MingW 或者Cygwin的方式来编译,二者大同小异,这里主要介绍Cygwin。

Cygwin是一个在Windows下面模拟Linux环境的东西。它提供了很多库和应用程序,让你可以像在Linux上一样来使用Windows。你需要在https://www.doczj.com/doc/b65965231.html,/ 下载一个cygwin的安装程序setup.exe。然后选择一个cygwin的源来下载所需要的库,国内的话到ftp://https://www.doczj.com/doc/b65965231.html,/cygwin/和https://www.doczj.com/doc/b65965231.html,/pub 相对来说会快一点。第一次安装,除了默认的库以外,我们还需要加入一些库来支持VLC的编译,包括

Archive (目录)

unzip

zip

Devel

autoconf

automake

binutils

cvs

expat

gcc

gcc-core

gcc-g++

gcc-mingw

gcc-mingw-core

gcc-mingw-g++

gdb (如果你需要调试的话)

gettext

gettext-devel

git (不一定需要)

ibiconv

ibtool

make

mingw-runtime

nasm

patchutils

pkg-config

subversion

Editor

vim (有了它方便点)

Libs

libgcrypt

Web //这两个可以不要,如果你不想编译第三方库

curl (optional: for building extras/contrib)

wget (optional: for building extras/contrib)

然后是下载所需要版本的VLC的源代码。对于Release版本,可以从这里下载:https://www.doczj.com/doc/b65965231.html,/pub/videolan/vlc/,如果你需要下载实时最新的库,就要从VLC的源码库上取下来了。现在VLC改用git了,使用命令:git clone git://https://www.doczj.com/doc/b65965231.html,/vlc.git

VLC还需要很多第三方的库,你可以取得源码来编译,这部分可以参考Linux上的VLC编译的文章。在Windows上VLC做了一个编译好的win32第三方库的包,可以从https://www.doczj.com/doc/b65965231.html,/pub/testing/win32/ 下载。包需要解压到根目录‘/’,事实上这些库都位于’/usr/win32-branch’里边。

在cygwin中进入vlc的主目录,运行bootstrap,’./bootstrap’。在等待它结束之前,我们先来看一下如何配置VLC的编译。运行‘./configure -h >cfg_opt.txt’就可以把配置的选项信息都输出到cfg_opt.txt中,然后慢慢来研究。里面大多是启用、禁用某些特性和功能模块,或者配置某些模块需要的库的路径等信息。为了方便可以写一个简单的脚本来做这件事,当然这个不是必需的。

PATH=/usr/win32-branch/bin:$PATH \

PKG_CONFIG_PATH=/usr/win32-branch/lib/pkgconfig \

CPPFLAGS=”-I/usr/win32-branch/include -I/usr/win32-branch/include/ebml” \

LDFLAGS=-L/usr/win32-branch/lib \

CC=”gcc -mno-cygwin” CXX=”g++ -mno-cygwin” \

./configure \

–host=i686-pc-mingw32 \

–disable-gtk \

–enable-nls –enable-sdl –with-sdl-config-path=/usr/win32-branch/bin \

–enable-ffmpeg –with-ffmpeg-mp3lame –with-ffmpeg-faac \

–with-ffmpeg-zlib –enable-faad –enable-flac –enable-theora \

–with-wx-config-path=/usr/win32-branch/bin \

–with-freetype-config-path=/usr/win32-branch/bin \

–with-fribidi-config-path=/usr/win32-branch/bin \

–enable-live555 –with-live555-tree=/usr/win32-branch/https://www.doczj.com/doc/b65965231.html, \

–enable-caca –with-caca-config-path=/usr/win32-branch/bin \

–with-xml2-config-path=/usr/win32-branch/bin \

–with-dvdnav-config-path=/usr/win32-branch/bin \

–disable-cddax –disable-vcdx –enable-goom \

–enable-twolame –enable-dvdread \

–enable-release –enable-dca \

–enable-mkv \

–enable-quicktime –enable-mozilla \

–with-mozilla-sdk-path=/usr/win32-branch/gecko-sdk \

–enable-mostly-builtin \

&& make

例如把这个文件保存为‘mybuild’,等bootstrp运行结束之后,我们只需要运行一下mybuild就会开始配置和编译了。这通常需要挺长的时间,如果运气好,在漫长的等待之后make运行成功,vlc就编译好了。直接双击主目录里边的vlc.exe应该就可以运行了。

为了方便可以把它打包,最简单的是‘make package-win32-base’,它将创建一个子目录来存放所有运行所需的东西,这个目录就是一个绿色版的VLC啦。

当然如果你运气没那么棒,可能会碰到各种各样的错误,例如在boottrap或者configure中出错,通常是因为没安装某个库或者库的版本不合适;也可能碰到编译的错误,尝试去google一下。

本文参考https://www.doczj.com/doc/b65965231.html,/Win32CompileCygwinNew

三、Linux平台编译

先下载源代码,把源代码解压之后也是先运行一下bootstrap,看看缺什么工具没有,例如gcc、make、libtool、automake、autoconfig等是否有合适的版本。如果不合适的话就用你喜欢的方式去升级或者安装。

下面最麻烦的一步来了。VLC在Linux上没有给出和Windows上类似的第三方库的预编译包,你必须去自己获得并编译这些库。这些库的数量取决于你的配置选项。VLC给出了一个自动化的解决方案,关注一下主目录\extras\contrib,里边有一些工具来帮助你自动下载、patch和编译所有可能用到的第三方库。先运行一下那个目录下的bootstrap,如果缺少***.mak的话可以到VLC的代码库中找一下,是一个系统相关的文件,然后简单的一句make就可以了。如果你对这些库比较熟悉的话最好先手动筛选一下,有一些可能不是你所需要的,而下载他们可能需要很长的时间。

在漫长的等待之后,如果一切顺利(我几乎不相信会这样),这一步就算完成了。可能遇到的问题有:下载实在太慢,可以用其他下载工具把库的代码包下下来放到\extras\contrib\src里边;如果下载一半断掉,可以把那个不完整的文件删掉重新再运行make。

这一步做完之后和windows上的编译就几乎一样了。写一个配置脚本然后运行它。例如一个配置脚本:

./configure \

–enable-release \

–disable-skins2 \

–disable-wxwidgets \

–enable-mozilla \

–with-mozilla-sdk-path=./gecko-sdk \

–disable-sout \

–disable-httpd \

–enable-live555 \

–disable-dvdnav \

–disable-libcdio \

–disable-libcddb \

–disable-cdda \

–disable-vcd \

–disable-dvdread \

–disable-smb \

–disable-cmml \

–disable-alsa \

–disable-opengl \

–disable-png \

–disable-screen \

–disable-mkv \

–disable-mod \

–disable-mpc \

–disable-libtar \

–disable-speex \

–disable-visual \

–disable-daap \

–disable-bonjour \

–disable-gnutls \

–enable-faad \

–enable-mostly-builtin

配置完之后再运行make就可以了。

参考:https://www.doczj.com/doc/b65965231.html,/UnixCompile

四、VLC使用

VLC的功能很强大,它不仅仅是一个视频播放器,也可作为小型的视频服务器,更可以一边播放一边转码,把视频流发送到网络上。

最简单的,从界面打开一个文件播放,也可以在命令行下使用,如C:\Program Files\VideoLAN\VLC>vlc.exe test.ts

获取内置的帮助,会写到vlc-help.txt:C:\Program Files\VideoLAN\VLC>vlc.exe -h

获取更详细的帮助,有大量的选项介绍:C:\Program Files\VideoLAN\VLC>vlc.exe -H

在线使用帮助

https://www.doczj.com/doc/b65965231.html,/doc/play-howto/en/play-howto-en.html

https://www.doczj.com/doc/b65965231.html,/doc/streaming-howto/en/streaming-howto-en.html

搜索并显示可用的模块列表:C:\Program Files\VideoLAN\VLC>vlc.exe -l

Windows下,默认情况,VLC的配置文件在%APPDATA%\vlc\vlcrc,%APPDATA%在XP下通常是C:\Documents and Settings\用户名\Application Data

Linux下,在用户home目录的/.vlc/中

vlc的选项完全可以通过修改vlcrc来设置,界面只是略微方便一点

重置所有选项到默认状态:C:\Program Files\VideoLAN\VLC>vlc.exe –reset-config

VLC从vlcrc中指定的plugin-path,以及当前目录的modules和plugins目录来递归查找plugin,VLC的大部分功能都是通过plugin来实现的。VLC 默认有大量的动态插件,为了加快启动速度,vlc会在%APPDATA%\vlc\cache中缓存plugin的列表,选项plugins-cache=0可以禁止缓存plugin

打开一个UDP组播流,组播组239.255.1.1,端口4567,默认端口1234,对于rtp协议,VLC会自动识别,写udp还是rtp都没问题

C:\Program Files\VideoLAN\VLC>vlc.exe udp://@239.255.1.1:4567

在本地UDP端口888 接收流, “@”表示绑定一个地址,而不是连接该地址

C:\Program Files\VideoLAN\VLC>vlc.exe udp://@888

串流输出,就是在播放的时候,以某种方式向外传送视频,在打开界面的串流/保存中设置会比较方便。

例如,循环播放test.ts,以rtp方式传送到224.1.1.1端口1234, 同时显示视频

vlc.exe test.ts –loop :sout=#duplicate{dst=std{access=rtp,mux=ts,dst=224.1.1.1:1234},dst=display}

例如,接收UDP端口888,数据全部保存到C:\dump.ts

vlc.exe udp://@888 :demux=dump :demuxdump-file=”C:\dump.ts”

关于Windows下视频输出模块

Direct3D :效果比DirectX差一点,但是方便截图,也可以在图像上实现alpha

DirectX:效果最好,利用DirectX的显示加速

OpenGL:在不同的硬件上表现不太一样

WinGDI:最慢的一种,不需要显卡加速

caca:用彩色的Assic字符来显示

临时启用某个视频输出,可以这样:C:\Program Files\VideoLAN\VLC-0.8.6e>vlc test.ts –vout=caca

ActiveX控件

官方发布的VLC自带ActiveX控件axvlc.dll,注册之后可以方便的在应用程序和网页中使用VLC,注册的办法是

C:\Program Files\VideoLAN\VLC-0.8.6e>regsvr32 axvlc.dll

ActiveX VLC的使用方法可以参考源代码中ActiveX目录的README.TXT和test.html,ActiveX控件的接口有第一版和第二版,第一版简单,功能少,已经不再维护建议用第二版本,功能多一点

Mozilla Plugin

你还可以在Windows和Linux的Firefox中使用VLC。Windows下可以在安装VLC的时候选上Mozilla plugin,事实上它做的就是在

HKLM_Software_MozillaPlugin键下添加一个VLC的子键。Linux下可以把libvlcplugin.so(或者叫npvlc.so)和插件目录放到Firefox的plugins目录,来使之生效。

同样这适用于基于Xulrunner的应用程序,事实上像Miro、SongBird等xul应用都是用的这个插件。与ActiveX类似的,VLC的Mozilla Plugin也有两套接口,建议用新的第二版。

注册表

在Windows下VLC只使用很少量的注册表的信息,最重要的一条是HKLM_Software_VLC键下的InstallDir项,VLC的Mozilla Plugin和ActiveX控件通过这一项来定位其插件的目录。Telnet、Http控制对VLC来说,控制界面都是Interface类的模块,你可以使用各种控制模块。Windows下默认使用的是wxwidgets图形界面,还可以使用http、telnet等界面,来远程控制VLC,如果用VLC在服务器上专门作视频流转发一类的事情,这种远程界面可以帮上大忙。

视频过滤器

0.8系列中有多达13种视频过滤器,为视频添加各种效果和特殊处理。

Skin2界面

一个漂亮一点的,可以换肤的界面。

其他的

播放DVD、VCD光盘,打开DirectShow设备,播放当前屏幕…

一些问题

目前的VLC无法播放Real视频,如rm、rmvb。其实从0.9版本的VLC开始可以依赖其他解码器播放。但就目前测试的情况来看,顺序播放没问题,但是拖动则效果很差。RTSP的播放,拖动有问题,在获取播放位置时有缺陷。例如和达尔文服务器的配合。

五、视频播放的基本原理

几乎所有的视频播放器,如VLC、MPlayer、Xine,包括DirectShow,在播放视频的原理和架构上都是非常相似的,理解这个对理解VLC的源码会有事半功倍的效果。

大致的来说,播放一个视频分为4个步骤:

1. acess 访问,或者理解为接收、获取、得到

2. demux 解复用,就是把通常合在一起的音频和视频分离(还有可能的字幕)

3. decode 解码,包括音频和视频的解码

4. output 输出,也分为音频和视频的输出(aout和vout)

拿播放一个UDP组播的MPEG TS流来说吧,access部分负责从网络接收组播流,放到VLC的内存缓冲区中,access模块关注IP协议,如是否IPv6、组播地址、组播协议、端口等信息;如果检测出来是RTP协议(RTP协议在UDP头部简单得加上了固定12个字节的信息),还要分析RTP头部信息。这部分可以参看VLC源码/modules/access/udp.c。在同目录下还可以看到大量的access模块,如file、http、dvd、ftp、smb、tcp、dshow、mms、v4l…等等

而demux部分首先要解析TS流的信息。TS格式是MPEG2协议的一部分,概括地说,TS通常是固定188字节的一个packet,一个TS流可以包含多个program(节目),一个program又可以包含多个视频、音频、和文字信息的ES流;每个ES流会有不同的PID标示。而又为了可以分析这些ES流,TS有一些固定的PID用来间隔发送program和es流信息的表格:PAT和PMT表。关于TS格式的详细信息可以去google一下。VLC专门做了一个独立的库libdvbpsi 来解析和编码TS流,而调用它的代码可以参见VLC源码/modules/demux/ts.c。

其实之所以需要demux,是因为音视频在制作的时候实际上都是独立编码的,得到的是分开的数据,为了传输方便必须要用某种方式合起来,这就有了各种封装格式也就有了demux。demux分解出来的音频和视频流分别送往音频解码器和视频解码器。因为原始的音视频都是占用大量空间,而且冗余度较高的数据,通常在制作的时候就会进行某种压缩。这就是我们熟知的音视频编码格式,包括MPEG1(VCD)、MPEG2(DVD)、MPEG4、H.264、rmvb等等。音视频解码器的作用就是把这些压缩了的数据还原成原始的音视频数据。VLC解码MPEG2使用了一个独立的库libmpeg2,调用它的源文件是

/modules/codec/libmpeg2.c。VLC关于编解码的模块都放在/modules/codec目录下,其中包括著名的庞大的ffmpeg。

解码器,例如视频解码器输出的是一张一张的类似位图格式的图像,但是要让人从屏幕看得到,还需要一个视频输出的模块。当然可以像一个Win32窗口程序那样直接把图像画到窗口DC上——VLC的一个输出模块WinGDI就是这么干的,但是通常这太慢了,而且消耗大量的CPU。在Windows下比较好的办法是用DirectX的接口,会自动调用显卡的加速功能。

这样的功能分解使得模块化更容易一点,每个模块住需要专注于自己的事;从整体来说功能强大而且灵活。

但是事情总是不会那么简单。就拿access来说,媒体的访问是分层的,如RTSP就涉及到IPv4、TCP、UDP、RTCP、RTSP等多个层次的协议。有些视频格式包括了传输、封装格式和编辑码格式如MPEG系列,有些封装格式是独立的容器,但是很多人会误解它是编解码格式,如mkv、avi这些。

音频和视频在demux之后就是独立的,但是需要有一套机制把它们同步起来。同时我们需要有一套机制来控制速度、暂停、停止、跳进,获取各种媒体信息,这些都是很复杂而又很重要的事情。

另外也许需要在某个地方插入一些修改,来实现某种效果。如音频的EQ,视频的亮度调整之类的,VLC专门设计了access_filter、audio_filter和video_filter 类型的模块来做这一类事情。

VLC比较独特的地方是集成了原来的VLS的功能,这依赖于VLC中stream_output类型的模块,它们可以把正在播放的视频以某种方式重新转码和发送出去,如http、UDP、文件等等。

MPlayer的结构与此是类似的,如/stream目录对应的是access的功能,/mpdemux对应的demux功能,/libmpcodecs是解码器,/libvo和/libao2分别是视频和音频的输出。

DirectShow也是类似的,不过分类更多一些更复杂一点。DirectShow里面的模块叫做“filter”,filter之间通过”pin”来连接。access的模块对应于DirectShow中的SourceFIlter,这一类Filter只有输出pin没有输入pin。demux模块对应于splitter filter,这种filter有一个输入pin,多个输出pin。解码模块是一类transform filter,有一个输入pin、一个输出pin,输出模块对应于readering filter,有一个输入pin,没有输出pin。当然transform filter 不一定是解码器,也可能是某种其他的处理。

另外给出一个VLC的API Document,参见:https://www.doczj.com/doc/b65965231.html,/doc/vlcapi.htm

六、代码精简

VLC默认包含了大量的功能,超过2百个插件;Windows下安装包大小接近10MB,安装之后超过35MB。有时候如果我们只需要部分的功能,应该如何精简它呢?

精简VLC的第一步是重新配置编译选项,将不需要的功能去掉。一个精简配置脚本如下:

PATH=/usr/win32-branch/bin:$PATH \

PKG_CONFIG_PATH=/usr/win32-branch/lib/pkgconfig \

CPPFLAGS=”-I/usr/win32-branch/include -I/usr/win32-branch/include/ebml” \

LDFLAGS=-L/usr/win32-branch/lib \

CC=”gcc -mno-cygwin” CXX=”g++ -mno-cygwin” \

./configure \

–with-freetype-config-path=/usr/win32-branch/bin \

–with-fribidi-config-path=/usr/win32-branch/bin \

–disable-ffmpeg \

–disable-live555 \

–disable-cddax \

–disable-vcdx \

–disable-skins2 \

–disable-wxwidgets \

–disable-mozilla \

–disable-httpd \

–disable-dvdnav \

–disable-libcdio \

–disable-libcddb \

–disable-cdda \

–disable-sdl \

–disable-sdl-image \

–disable-vcd \

–disable-dvdread \

–disable-smb \

–disable-cmml \

–disable-alsa \

–disable-opengl \

–disable-png \

–disable-screen \

–disable-mkv \

–disable-mod \

–disable-mpc \

–disable-libtar \

–disable-speex \

–disable-visual \

–disable-daap \

–disable-bonjour \

–disable-gnutls \

–disable-vorbis \

–disable-real \

–disable-xml \

–disable-x264 \

–enable-sout \

–enable-activex \

–enable-release

从这个脚本可见,主要是禁用了大量的功能。运行 ./configure -h 可以显示每一个配置项的意义;如果还不清楚可以再去搜一下选项对应的库的位置。ffmpeg是一个庞大的编解码库,但是MPEG2的解码可以利用另一个库libmpeg2,所以在这里不需要它。

注意make完之后要用make package-win32-base来打一下包,打包时会用strip工具来压缩每一个可执行文件。

但是这样还没有结束。配置项并不是很全面的,而且还会有一些小问题,例如xml禁用了还会有。。。于是还需要手动的清理一下plugins目录里面的插件,挑出没有用处的,这也需要对VLC模块的熟悉。或者使用Roger的笨方法,一个一个试,对功能没有影响的就拿掉。SImpleTV0.4所使用的plugin如以下所示:

liba52sys_plugin.dll liba52 用于AC3格式的音频解码,CCTV高清频道需要

liba52tofloat32_plugin.dll

liba52tospdif_plugin.dll

liba52_plugin.dll

libaccess_file_plugin.dll 文件访问,播放文件需要

libaccess_http_plugin.dll HTTP访问模块

libaccess_output_file_plugin.dll sout的文件模块,用于录制libaccess_udp_plugin.dll UDP访问模块

libaout_directx_plugin.dllDirectX的声音输出,默认的声音输出模块libdeinterlace_plugin.dll 解交错的vout-filter模块

libdirect3d_plugin.dll Direct3D视频输出模块,在上面可以半透明。。。libfixed32tofloat32_plugin.dll一些数据转换模块

libfixed32tos16_plugin.dll

libfloat32tos16_plugin.dll

libfloat32tos8_plugin.dll

libfloat32tou16_plugin.dll

libfloat32tou8_plugin.dll

libfloat32_mixer_plugin.dll

libglwin32_plugin.dll OpenGL视频输出模块

libi420_ymga_plugin.dll

libi422_yuy2_plugin.dll

libipv4_plugin.dllIPv4网络模块

libipv6_plugin.dllIPv6网络模块

liblibmpeg2_plugin.dlllibmpeg2,解码全靠它

liblogger_plugin.dll 日志模块,调试必备

libmemcpy_plugin.dll 好像是利用各种CPU指令加速内存拷贝的libmpeg_audio_plugin.dll MPEG音频的解码模块

libmpgatofixed32_plugin.dll

libmpga_plugin.dll

libmux_dummy_plugin.dll

libpacketizer_mpegvideo_plugin.dll

libs16tofixed32_plugin.dll

libs16tofloat32swab_plugin.dll

libs16tofloat32_plugin.dll

libs8tofloat32_plugin.dll

libsimple_channel_mixer_plugin.dll

libstream_out_display_plugin.dll sout的模块。。。

libstream_out_duplicate_plugin.dll

libstream_out_standard_plugin.dll

libtrivial_channel_mixer_plugin.dll

libtrivial_mixer_plugin.dll

libtrivial_resampler_plugin.dll

libts_plugin.dll TS流的解复用模块

libu8tofixed32_plugin.dll

libu8tofloat32_plugin.dll

libugly_resampler_plugin.dll

libvout_directx_plugin.dllDirectX视频输出模块

libwingdi_plugin.dll GDI视频输出模块

作为ActiveX控件的VLC,只需要这些模块和axvlc.dll就足够了。当然如果使用了libvlc.dll还要带上。

VLC 0.9.2 正式发布&& VLC播放Rm Rmvb的插件

新的VLC加入了RealVideo的demux和codec module,已经可以播放rm、rmvb格式的real视频,但是需要下载以下两个附件:

pncrt.dll 拷贝到C:\Program Files\VideoLAN\VLC\

drv43260.dll 拷贝到C:\Program Files\VideoLAN\VLC\plugins\

这两个文件也可以从MPlayer的win32 codec中拷贝出来。从测试的情况来看,顺序播放没有什么问题,但是跳转的时候比较慢,图像不太稳定

这里有对VLC新特性的介绍https://www.doczj.com/doc/b65965231.html,/What_is_cool_in_0.9

Release Note:https://www.doczj.com/doc/b65965231.html,/developers/vlc/NEWS

下载目录:https://www.doczj.com/doc/b65965231.html,/pub/vlc/0.9.2/win32/

下载链接(exe):https://www.doczj.com/doc/b65965231.html,/pub/vlc/0.9.2/win32/vlc-0.9.2-win32.exe

七、将VLC嵌入自己的应用

总的来说把VLC内嵌入自己的应用有4种途径:

?1、直接调用VLC进程

?2、VLC的plugin for Mozilla

?3、VLC的ActiveX插件

?4、调用libvlc

当然,理论上也可以把VLC的源码直接扣出一部分来放到自己的程序中,不过这种方法难度太大没多大意义。

先说第一种办法,别怀疑,这是非常有用的一种解决方案,特别是对于转码、流转发等应用,通常直接调用VLC就可以了。VLC有HTTP和Telnet的Interface 模块(就是和用户交互的界面),也很方便和远程交互。而且跨平台应用也非常方便,只需要安装不同平台的VLC就行了。直接调用VLC的话最重要的就是参数,可以从vlc.exe -H 中获取比较详细的命令行参数介绍。对于转码、转发的,命令行参数会比较复杂,可以用GUI先试一下,然后把界面上的Generated stream output string拷下来。

VLC的Mozilla plugin除了用于Firefox的web页之外,还可以用于任何XUL-base的应用,这种应用通常使用xulrunner来启动。XUL是一种用XML 来写界面的语言,有点像HTML而且也兼容大部分HTML标记,Firefox就是用XUL来写的。VLC的Mozilla插件通常用Javascript来控制,详细的接口文档可以参考这里:https://www.doczj.com/doc/b65965231.html,/doc/play-howto/en/ch04.html#id310965 这个接口有比较老的第一版和比较新的第二版,建议用新的,功能多一些。用VLC的Mozilla插件的应用并不少,例如比较出名的Miro、Songbird。因为这个好处是显而易见的:跨平台、可控性强、使用简单;限制也很明显:专为Mozilla设计,应用的范围很窄。

VLC的ActiveX插件只能用于Windows平台,当然这是因为ActiveX只是微软的东西。但是不得不说这个还是很好用的。无论是C++、C#、VB还是网页,都可以轻松地将这个ActiveX利用起来。关于这个的VLC官方文档在这里https://www.doczj.com/doc/b65965231.html,/ActiveX_Controls 开发、使用之前别忘了先要注册ActiveX控件,方法是运行regsvr32 axvlc.dll。Roger 之前写的SimpleTV 就是调用了VLC的ActiveX控件,所以这也可以作为一个示例的代码,可以主要看看怎么调用这个控件来做串流的代码:

//Create Option for the plugin

bool bIPv6 = false;

if (strstr (szMRL, “::”))

{

bIPv6 = true;

}

tagVARIANT opt,var,ip6;

CString sout, ipv6 = “ipv6=1″;

SAFEARRAY *psa;

long index;

SAFEARRAYBOUND bound[1] = {0};

bound[0].cElements = bIPv6 ? 2 : 1;

if (m_cfg.bDisplayWhenRecording)

{

sout.Format(”sout=#duplicate{dst=display,dst=std{access=file,mux=ts,dst=\”%s\”}}”,

strName);

}

else

{

sout.Format(”sout=#duplicate{dst=std{access=file,mux=ts,dst=\”%s\”}}”, strName);

}

var.vt = VT_BSTR;

var.bstrVal = sout.AllocSysString();

psa = SafeArrayCreate (VT_VARIANT, 1, bound);

index = 0;

SafeArrayPutElement (psa, &index, &var);

if (bIPv6)

{

ip6.vt = VT_BSTR;

ip6.bstrVal = ipv6.AllocSysString();

index = 1;

SafeArrayPutElement (psa, &index, &ip6);

}

opt.vt = VT_ARRAY | VT_BSTR;

opt.parray = psa;

tagVARIANT nul;

nul.vt = VT_NULL;

m_vlc.GetPlaylist ().add (szMRL, nul, opt);

m_vlc.GetPlaylist ().next ();

m_vlc.GetPlaylist ().play ();

很多人调用VLC的ActiveX控件都会遇到一个问提就是,播放没有反应。大部分的原因都是因为plugins的问题。VLC作为exe运行时会递归搜索当前目录下的modules和plugins目录来寻找plugin,但是当以ActiveX控件运行时,默认只会检查注册表的HKLM_Software_VideoLan_VLC_InstallDir,并添上plugins作为模块搜索路径,如果这个路径没有设置或者设置不对,VLC将找不到大部分的模块,导致大部分功能缺失而无法运行。如果需要修改这一特性可以修改\activex\plugin.cpp (0.8.6i)中的VLCPlugin::getVLC函数。在SimpleTV中,Roger修改的一个片段是

char p_pluginpath[MAX_PATH+1];

int iTmp = 0;

/* 得到SimpleTV.exe的全路径*/

DWORD dwLen = GetModuleFileNameA (NULL, p_pluginpath, MAX_PATH);

for (iTmp = strlen(p_pluginpath) – 1; iTmp >= 0; — iTmp)

{

if (p_pluginpath[iTmp] == ‘\\’)

{

p_pluginpath[iTmp] = 0;

break;

}

}

/* 将模块路径设为SimpleTV下的player\modules */

strcat (p_pluginpath, “\\player\\modules“);

ppsz_argv[ppsz_argc++] = “–plugin-path”;

ppsz_argv[ppsz_argc++] = p_pluginpath;

还有一点是配置文件vlcrc的路径,如果需要修改的话,可以修改src/misc/configuration.c 中的GetDir 函数,在Windows下这个目录默认返回%APPDATA% ,以上两步做好的话其实就可以做出一个Portable的绿色版VLC了。

和其他ActiveX的播放器,例如WMP、QuickTime、RealPlayer相比,VLC的优点也很明显:自带所需解码器、开源、功能强大。

当然ActiveX方式和Mozilla 插件的方式也是有局限性的,这样的方式功能还不够强大,例如没有截屏的接口…如果需要更多完整的功能,可以考虑直接调用libvlc的接口,

VLC官方提供了一些文档和例子https://www.doczj.com/doc/b65965231.html,/Libvlc。这里还有一个用C#调用libvlc的例子

https://www.doczj.com/doc/b65965231.html,/539865/116981

在Windows下libvlc可能默认是不编译的(0.8.6i),可以在configure中开启这一选项–enable-shared-libvlc

完整的VLC体积还是不小的,如果只需要VLC一部分功能的话,可以最后做一下精简。

八、代码功能分析

VLC媒体播放器的核心是libvlc ,它提供了界面,应用处理功能,如播放列表管理,音频和视频解码和输出,线程系统。所有libvlc源文件设在的/src目录及其子目录:

# config/ :从命令行和配置文件加载配置,提供功能模块的读取和写入配置

# control/: 提供动作控制功能,如播放/暂停,音量管理,全屏,日志等。

# extras/: 大多是平台的特殊代码

# modules/: 模块管理

# network/: 提供网络接口(socket管理,网络错误等)

# osd/: 显示屏幕上的操作

# test/: libvlc测试模块

# text/: 字符集

# interface/ : 提供代码中可以调用的接口中,如按键后硬件作出反应。

# playlist/: 管理播放功能,如停止,播放,下一首,随机播放等

# input/: 建立并读取一个输入流,并且分离其中的音频和视频,然后把分离好的音频流和视频流发送给解码器.

# video_output/ : 初始化视频播放器,把从解码器得到的视频画面转化格式(从YUV 转为RGB)然后播放它们

# audio_output/ : 初始化音频混合器,即设置正确的同步频率,并对从解码器传来的音频流重新取样

# stream_output/: 输出音频流和视频流到网络

# misc/: libvlc使用的其他部分功能,如线程系统,消息队列,CPU的检测,对象查找系统,或平台的特定代码。

九、代码模块分析

VLC媒体播放器的模块部份,在/modules的子目录下(详细说明可以参考其下的List文件),这些模块只在程序载入它们时有效.每一个模块,可提供不同的功能,它们会适合的特定文件或某一特定的环境.此外,audio_output/video_output/interface 模块都写成了可跨平台的代码,方便支持新的平台(如beos或服务Mac OS X )。

插件模块可以在src/modules.c 和include/vlc_modules*.h 提供函数中,动态加载和卸载

LibVLC可以将模块直接插入到应用程序中,例如不支持动态加载代码的操作系统.模块静态插入到应用程序叫内建.

1、vlc.c 入口程序

2、Libvlc.c 各个模块的结合点,主要是接口编程

?Vlc_Create(): 两个重要的数据结构:libvlc_t & vlc_t , 所有的参数传递都在这里面

?Vlc_Init(): 初始化参数,module_bank

?Vlc_AddInf(): 添加module

3、./src/misc/configure.c 命令行参数和参数文件分析

参数文件是~/.vnc/vlcrc。其中可以设置log文件的位置

4、./include/ 所有头文件的集合

5、./src/interface/Interface.h 所有module的集合

6、./src/misc/Modules.c

其中module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,

const char *psz_name, vlc_bool_t b_strict ) 方法是寻找合适的interface

如果找到合适的,就调用AllocatePlugin()动态的分配一个。

7、how to link to different modules without OOP

对VLC源代码阅读的计划是从其程序的框架开始,先对其主要的文件进行整理:

1.include/main.h 文件:access to all program variables,主要定义了2个结构体:libvlc_t,vlc_t。

a. struct libvlc_t 根据程序注释:该结构体只有一个实例,在main函数中被分配,而且只能在main中访问。它用来存储一些只能初始化一次的数据,比如

说cpu容量或者global lock.

b. struct vlc_t 注释称:This structure is a LibVLC instance

libvlc_t,vlc_t在VLC_COMMON_MEMBERS宏中出现,分别定义了libvlc_t * p_libvlc; vlc_t * p_vlc; 对象,注释称为root of the evil,可见其结构体的重要性.所有的参数传递都在这里面(具体尚不清楚)。

2.include/Vlc_common.h 文件:common definitions,Collection of useful common types and macros definitions,通用类型和宏定义的集合

主要作用是为了将不同的操作系统中的变量定义统一起来,比如说根据将unit_8来统一代表unsiged char类型.

该文件中还定义了VLC_COMMON_MEMBERS宏,该宏中包括了所有VLC基本对象的通用成员变量:these members are common for all vlc objects。

定义导出函数

#ifndef __PLUGIN__

# define VLC_EXPORT( type, name, args ) type name args

#else

# define VLC_EXPORT( type, name, args ) struct _u_n_u_s_e_d_

extern module_symbols_t* p_symbols;

#endif

定义回调函数

typedef int ( * vlc_callback_t ) ( vlc_object_t *, /* variable's object */

char const *,/* variable name */

vlc_value_t, /* old value */

vlc_value_t,/* new value */

void * ); /* callback data */

3.include/vlc_objects.h 文件:vlc_object_t definition and manipulation methods,vlc_object_t的定义和处理函数

struct vlc_object_t

{

VLC_COMMON_MEMBERS

}; //定义一个结构来使用宏定义的公共成员

8、VLC中vlm介绍

代码从两大部分入手,一个telnet 的deamon。还有就是rtsp的实现部分。结果发现,他们通过了一个桥梁vlm的media进行沟通。

?当受到new MEDIANAME vod enabled 就建立一个media。

?如果受到setup MEDIANAME input filename.mpg 就读入流准备分析,建立input流

?当受到rtsp的请求后,就建立这个output流

这样,vod就和别的模块一致了。rtsp只是一种output流的module。

代码分析

1. /modules/control/telnet.c

/*****************************************************************************

* Run: main loop

*****************************************************************************/ static void Run( intf_thread_t *p_intf ){

vlm_ExecuteCommand( p_sys->mediatheque, cl->buffer_read,

&message );

}

2. /src/Misc/vlm.c

/***************************************************************************** * vlm_ExecuteCommand:

*****************************************************************************/ int vlm_ExecuteCommand( vlm_t *p_vlm, const char *psz_command,

vlm_message_t **pp_message)

{

}

vlm_MediaNew( vlm_t *vlm, const char *psz_name, int i_type ){

vlm_media_t *media = malloc( sizeof( vlm_media_t ) );

}

*****************************************************

struct vlm_t

{

VLC_COMMON_MEMBERS

vlc_mutex_t lock;

inti_media;

vlm_media_t**media;

inti_vod;

vod_t *vod;

inti_schedule;

vlm_schedule_t **schedule;

};

*****************************************************

int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd, const char *psz_value ){

if( (p_input = input_CreateThread2( vlm, &media->item, psz_header

) ) )

{

while( !p_input->b_eof && !p_input->b_error ) msleep( 100000 );

input_StopThread( p_input );

input_DestroyThread( p_input );

vlc_object_detach( p_input );

vlc_object_destroy( p_input );

}

}

3. /src/Input/input.c

input_thread_t *__input_CreateThread2( vlc_object_t *p_parent,

input_item_t *p_item,

char *psz_header )

{

input_thread_t *p_input = NULL; /* thread descriptor */

p_input = Create( p_parent, p_item, psz_header, VLC_FALSE );

/* Now we can attach our new input */

vlc_object_attach( p_input, p_parent );

/* Create thread and wait for its readiness. */

if( vlc_thread_create( p_input, "input", Run,

VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )

{

msg_Err( p_input, "cannot create input thread" );

vlc_object_detach( p_input );

vlc_object_destroy( p_input );

return NULL;

}

}

static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,

char *psz_header, vlc_bool_t b_quick )

{

}

/*****************************************************************************

* Run: main thread loop

* This is the "normal" thread that spawns the input processing chain,

* reads the stream, cleans up and waits

*****************************************************************************/

static int Run( input_thread_t *p_input )

{

}

===================================================================================== 4. \modules\misc\rtsp.c

static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name,

input_item_t *p_item )

{

vod_sys_t *p_sys = p_vod->p_sys;

vod_media_t *p_media = malloc( sizeof(vod_media_t) );

int i;

if( !p_media )

{

msg_Err( p_vod, "not enough memory" );

return NULL;

}

memset( p_media, 0, sizeof(vod_media_t) );

p_media->es = 0;

p_media->psz_mux = 0;

p_media->rtsp = 0;

p_media->b_raw = VLC_FALSE;

asprintf( &p_media->psz_rtsp_path, "%s%s", p_sys->psz_path, psz_name ); p_media->p_rtsp_url =

httpd_UrlNewUnique( p_sys->p_rtsp_host, p_media->psz_rtsp_path, NULL, NULL, NULL );

if( !p_media->p_rtsp_url )

{

msg_Err( p_vod, "cannot create RTSP url (%s)", p_media->psz_rtsp_path); free( p_media->psz_rtsp_path );

free( p_media );

return NULL;

}

msg_Dbg( p_vod, "created RTSP url: %s", p_media->psz_rtsp_path ); asprintf( &p_media->psz_rtsp_control_v4,

"a=control:rtsp://%%s:%d%s/trackID=%%d\r\n",

p_sys->i_port, p_media->psz_rtsp_path );

asprintf( &p_media->psz_rtsp_control_v6,

"a=control:rtsp://[%%s]:%d%s/trackID=%%d\r\n",

p_sys->i_port, p_media->psz_rtsp_path );

httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_SETUP, RtspCallback, (void*)p_media );

httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_DESCRIBE, RtspCallback, (void*)p_media );

httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_PLAY, RtspCallback, (void*)p_media );

httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_PAUSE, RtspCallback, (void*)p_media );

httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_TEARDOWN, RtspCallback, (void*)p_media );

}

static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, httpd_message_t *answer, httpd_message_t *query )

{

switch( query->i_type )

{

case HTTPD_MSG_SETUP:

{

}

case HTTPD_MSG_PLAY:

{

p_rtsp = RtspClientGet( p_media, psz_session );

vod_MediaControl( p_vod, p_media, psz_session, VOD_MEDIA_PLAY,

psz_output );

}

}

}

5. vlc_vod.h

static inline int vod_MediaControl( vod_t *p_vod, vod_media_t *p_media,

char *psz_id, int i_query, ... )

{

i_result = p_vod->pf_media_control( p_vod->p_data, p_media, psz_id,

i_query, args );

}

十、libvlc外部api的简单整理

1、libvlc.h

定义了libvlc的外部api,引用这个头文件就可以把VLC嵌入到我们的程序里面了。libvlc的对象必须先被初始化之后才能被使用。

2、libvlc core

libvlc_new() 用于初始化一个libvlc的实例,argc表示参数的个数,argv表示参数,返回创建的实例若当发生错误时返回NULL

libvlc_release()用于销毁一个libvlc的实例

3、libvlc error handling

libvlc_errmsg()返回的是在idaoyong线程中产生的最新的libvlc错误,这个错误信息至少在另外一个错误发生之前(至少再调用一次libvlc)都是有效的,当没有任何错误的时候返回的是NULL

libvlc_clearerr()用于清除当前线程的libvlc的错误状态.此操作是可选的,默认情况下,错误状态是会在新的错误发生时被覆盖.

libvlc_vprinterr()用于设置当前线程的libvlc的错误状态和消息.无论何时都返回一个nul字符

libvlc_printerr() /源码里的注释和上一个一模一样

libvlc_retain()增加libvlc的引用计数,任何新的libvlc实例的引用计数为1

libvlc_add_intf():尝试启动libvlc实例的用户接口,p_instance表示要启动的实例,name为接口名,NULL表示默认,返回0表示成功-1表示发生错误

libvlc_set_exits_handler():此函数用于为一个已存在的libvlc事件注册一个回调.此方法在你用libvlc_add_intf()开启了至少一个接口时非常有用.典型的,这个函数将唤醒你的程序主循环(从其他线程).参数p_instance 表示libvlc实例,cb表示当libvlc要退出时要调用的回调.opaque表示回调的数据指针.警告:此函数不能同libvlc_wait()同时调用.

libvlc_wait():等待到有一个接口引发实例的推出动作.必须先用libvlc_add_intf()开启至少一个接口.

libvlc_set_user_agent(): 设置应用程序名,当有协议要求的时候,libvlc将把这个名字作为用户代理串传递给它.参数name应该是一个可读的应用程序名,例如"FooBar player 1.2.3",http参数为HTTP User Agent。例如"FooBar/1.2.3 Python/2.6.0。

libvlc_get_Version():返回libvlc的版本号

libvlc_get_compiler():返回编译libvlc的编译器的版本。

libvlc_get_changeset() :返回libvlc的changeset?

4、libvlc asynchronous events

libvlc 发出不同步事件

许多libvlc对象,如libvlc_instance_t libvlc_media_player_t不同步的产生时间,它们中的每一个都提供了libvlc_event_manager_t事件管理器。你可以通过libvlc_event_attach()来订阅这些事件以及用libvlc_event_detach()来退订事件。

libvlc_event_manager_t是属于libvlc对象的事件管理器

libvlc_event_type_t:表示libvlc的事件

libvlc_callback_t():回调函数通知(call back function notification翻译不准确),参数p_event为触发回调的时间.

libvlc_event_attach():注册一个event notification。参数p_event_manager 想要绑定的事件管理器.通常来说它是由vlc_my_object_event_manager()处获得的,此处的my_object是你想要监听的对象,i_event_type是想要监听的事件,f_callback是当i_event_type发生时要调用的函数。user_data是用户提供的伴随事件而传递的数据。成功时此函数返回0,发生错误时返回ENOMEM

libvlc_event_detach()退订一个event notification

libvlc_event_type_name():获得一个事件的类型名

5、libvlc_log LibVLC logging

libvlc_log系列函数提供了访问libvlc消息日志的方法.这些函数仅用于高级用户或调试之用.

libvlc_get_log_verbosity():获得VLC消息的详细级别

libvlc_set_log_verbosity():设置VLC消息的详细级别

libvlc_log_open():开启VLC消息日志实例(从一个libvlc实例中获得其消息日志实例)

libvlc_log_close():关闭VLC消息日志实例

libvlc_log_count():返回日志中消息条数

libvlc_log_clear():清除日志实例.将把实例中的所有消息删除,为了防止消息阻塞,应该经常清除.

libvlc_log_get_iterator():定位并返回一个日志中记录的iterator

libvlc_log_iterator_free():释放一个先前定位好的iterator

libvlc_log_iterator_next():返回下一条日志消息,当接下来为空的时候返回NULL,否则返回下一个消息对象

6、libvlc_media.h

libvlc_media_t是一个可播放的媒体的抽象表达.它包含了这个媒体的位置以及各种可选的元数据.

libvlc_state_t:此枚举类型的循序必须严格保证和源码一致,同时可参考mediacontrol_PlayerStatus,input_state_e枚举类型以及VideoLan.LibVLC.State (在bindings/cil/src/media.cs)

libvlc_media_stats_t:Libvlc的媒体统计信息

libvlc_media_track_info_t:没有注释,主要是fourcc和docec的其他信息。

libvlc_media_new_location():使用一个给定的媒体资源路径来建立一个libvlc_media对象.参数psz_mrl为要读取的MRL(Media Resource Location).此函数返回新建的对象或NULL.

libvlc_media_new_path():从本地文件系统路径新建,其他参照上一条

libvlc_media_new_as_node():使用给定的名称创建一个libvlc_media_t并将其作为一个空的节点

libvlc_media_add_option():添加一个选项到已有的libvlc_media_t,这个选项将被用于决定media_player如何读取媒体。这样一来就可以在每个媒体上指定各自的VLC的高级reading/streaming选项。

libvlc_media_add_option_flag():减价一个带有可配置标记的选贤到已有的libvlc_media_t.其他同上一条.

libvlc_media_retain():保留一个引用到一个媒体描述对象(libvlc_media_t.使用libvlc_media_release()来减少一个媒体描述对象的引用计数

libvlc_media_release():减少一个libvlc_media_t的引用计数,如果减少到0时,此此函数将释放此对象(销毁).它将发送一个libvlc_MediaFreed事件到所有的监听者那里。如果一个libvlc_media_t被释放了,它就再也不能使用了。

libvlc_media_get_mrl():从一个媒体描述对象处获得它的mrl

libvlc_media_duplicate():镜像一份媒体描述对象

libvlc_media_get_meta():读取媒体的元数据。如果媒体还没被解析,则返回NULL,这个方法会自动调用libvlc_media_parse_async(),因此,在调用此方法以后,你可以接收到一个libvlc_MediaMetaChanged事件。如果你希望使用一个同步的版本,请确保你在调用get_meta()之前调用了

libvlc_media_parse();

libvlc_media_set_meta():设置媒体的元数据,此方法不会保存数据,还需要调用libvlc_media_save_meta()来保存.

libvlc_media_get_state():获取当前媒体描述对象的状态.可能的状态被定义在livblc_structures.c中.

libvlc_media_subitems():获得一个媒体描述对象的子项目.此方法将增加媒体描述对象的引用计数,使用libvlc_media_list_release()减少引用计数.

libvlc_media_event_manager():获得一个媒体描述对象的事件管理器.

libvlc_media_get_duration():获得一个媒体描述对象的持续时间.发生错误时返回-1.

libvlc_media_parse():解析一个本地媒体的元数据和轨道信息,此方法是同步的.

libvlc_media_parse_async():同上,此方法不同步,你可以监听libvlc_MediaParsedChanged事件来追踪他,如果已经被解析过了则此事件不会被触发。

libvlc_media_is_parsed():获得一个媒体描述对象的分析状态。当分析过了返回true。

libvlc_media_set_user_data():设置媒体描述符的用户数据,此数据仅被host程序访问,VLC.framework将它作为一个指向一个引用了一个libvlc_media_t 指针的本地对象的指针来使用

libvle_media_get_tracks_info():获得媒体描述符的基本流信息.注意你必须使用--sout="#description"播放媒体恰好一次,否则将得到一个空的数组。而多次播放则会导致多个重复数据。

VLC API集合:https://www.doczj.com/doc/b65965231.html,/developers/vlc/doc/doxygen/html/group__libvlc.html#_details

十一、VLC问题及解决

编译VLC 1.1.4 出现一大堆libtool的错误,类似如下的:

../libtool: line 2253: X-g: command not found

../libtool: line 2253: X-O2: command not found

解决方法:./myvlc.sh 后cp /usr/bin/libtool ./

在windows xp下编译ffmpeg

Android源码编译

Android源码编译 开发工具:Ubuntu10.04 在Ubuntu下使用root用户登录,注意root一开始是锁定的,使用如下命令解锁:sudopasswd root 按回车铵,提示输入当前密码,在提示输入二次密码。输入完成切换用户使用root用户登录。 Android源码结构 Makefile (全局的Makefile) bionic (Bionic含义为仿生,这里面是一些基础的库的源代码) bootloader(引导加载器) build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具) dalvik (JAVA虚拟机) development(程序开发所需要的模板和工具) external (目标机器使用的一些库) frameworks (应用程序的框架层) hardware (与硬件相关的库) kernel (Linux2.6的源代码) packages (Android的各种应用程序) prebuil (Android在各种平台下编译的预置脚本) recovery (与目标的恢复功能相关) system (Android的底层的一些库) Out (编译好的文件) 编译Android源码必需的安装的软件包 g++库文件有可能Ubuntu自带,使用g++ -v命令查找是否安装,如果没有自带请手动安装,使用如下命令,sudo apt-get-install g++-4.4. 注意:g++分很多版本,如果使用了最新版本4.6将没办法编译,建议安装4.4版本 Gcc库文件有可能Ubuntu自带,使用gcc–v命令查找是否安装,如果没有自带使用如下命令手动安装,sudo apt-get-install gcc-4.4. 注意:gcc分很多版本,如果使用了最新版本4.6将没办法编译,建议安装4.4版本 不过还有一些应该是linux系统自带的,如果缺少就按照提示install一下sudo apt-get install build-essential sudo apt-get install make sudo apt-get install libc6-dev sudo apt-get install patch sudo apt-get install texinfo sudo apt-get install libncurses-dev

android源代码下载和编译教程

Android源代码由两部分组成,其一是Android系统应用部分的代码,其次是Android 所使用的内核代码,如果针对Google Nexus S来开发ROM,就需要下载三星的内核代码Android 系统应用代码: https://https://www.doczj.com/doc/b65965231.html,/platform/manifest Android内核代码: https://https://www.doczj.com/doc/b65965231.html,/kernel/samsung.git 准备阶段:设置Linux编译环境(本人是Ubuntu 11.10 ,32位系统),一般你需要以下配置: Python 2.5 -- 2.7. GNU Make 3.81 -- 3.82,, JDK 6 (for Gingerbread or newer); JDK 5( for Froyo or older). Git 1.7 or newer. 1、安装一些必备的包。 Git是Linux Torvalds为了帮助管理Linux内核而开发的一个开放源码的分布式版本控制系统软件,它不同于SVN,CVS这样集中式的版本控制系统。在集中式版本控制系统中只有一个仓库(repository),许多个工作目录,而git这样的分布式控制系统中,每一个工作目录都包含一个完整仓库,它们支持离线工作,本地提交可以稍后提交到服务器上。分布式系统理论上也比集中式的单服务器系统更健壮,单服务器系统一旦服务器出现问题整个系统就不能运行了,分布式系统通常不会因为一两个节点而收到影响? 因为Android是由kernel,Dalvik,Bionic,prebuild,build等多个Git项目组成, 所以Android项目编写了一个名为repo的python的脚本来统一管理这些项目的仓库,使得Git的使用更加简单。 $ sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs \ x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev \ libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown \ libxml2-utils xsltproc $ sudo apt-get install libx11-dev:i386 2、创建源代码目录 首先确保在当前用户的主目录下创建一个/bin目录(如果没有的话),然后把它加到PATH 环境变量中: $ mkdir ~/bin $ PATH=~/bin:$PATH 或者$export PATH=$PATH:~/bin 3、用curl下载repo脚本,并保存在~/bin/repo文件中: $ curl https://https://www.doczj.com/doc/b65965231.html,/dl/googlesource/git-repo/repo > ~/bin/repo 为repo加上执行权限 $ chmod a+x ~/bin/repo 4、初始化版本库 首先建立一个目录,用来存放下载下来的东西 $mkdir MyAndroid $cd MyAndroid 以后,执行如下命令 $ repo init -u https://https://www.doczj.com/doc/b65965231.html,/platform/manifest -b android-2.3.7_r1 我这里下载的是android2.3.7版本的,所用的参数是android-2.3.7_r1。由于最新的是android-4.0.3_r1,所以使用上面即可下载2.3.7的源代码 注意:如果要是把所有的版本都下载下来,那时间是需要很久很久的,需要耐心等待,但是如果仅仅是下载某一个版本的话,还是很快就可以了。 最后,如果看到repo initialized in /MyAnroid的提示,说明本地的版本库已经初始化成功了(期间需要你填写姓名和Gmail地址)。

Android_4.2_源码下载和编译环境安装及Android_4.2_源码编译

Android 4.2源码的下载和编译环境的安装及源码的编译Google于2012.11.14发布了Android4.2的源码,下面把本人在ubuntu10.04 的64位 系统上下载源码,和编译源码做个记录备份,也供有需要的人参考,若是在下载编译安装Android源代码遇到问题,可加QQ群交流: 217706590,难免有错,敬请见谅,还忘勿吝啬指出。 源代码下载、编译环境安装、源代码编译和运行模拟器的可能出现的一些错误在本文最后一章节,若出现类似错误,可以参考。 1、源码的下载 源代码的下载,首先需要安装以下软件:curl 和git-core 1.1安装curl: 在终端中执行:sudo apt-get install curl 1.2安装git-core 1.2.1在用户目录下新建bin文件 在终端中执行:mkdir ~/bin 将~/bin添加环境变量,作用是:要将git软件下载安装在此目录,在别的目录运行可能会找不到此软件,所以要添加到环境变量中 在终端中执行:PA TH=~/bin:$PATH 1.2.2安装git-core 在终端中执行:curl https://https://www.doczj.com/doc/b65965231.html,/dl/googlesource/git-repo/repo§> ~/bin/repo 给repo执行权限:chmod a+x ~/bin/repo 1.3 下载源代码 1.3.1进入要源代码将要保存的目录 如我的源代码保存在:、/opt/android/src 在终端中执行:cd /opt/android/src 进入到src目录中 1.3.2 获取repo最新的配置 repo init -u https://https://www.doczj.com/doc/b65965231.html,/platform/manifest§ 若是执行错误则用以下命令: ~/bin/repo init -u https://https://www.doczj.com/doc/b65965231.html,/platform/manifest§ 1.3.3 下载源代码 对于下载不同版本的android,指定一个manifest分支(即只指明android对应的版

hadoop3.0.0源码编译

1. 2.编译步骤 (1)jdk安装和部署 1.安装jdk cd /home/lly/下载/hadoop/ rpm –ivhjdk-8u101-linux-x64.rpm 2.添加环境变量 $sudo vim /etc/profile 3.加入如下内容 export JAVA_HOME=/usr/java/jdk1.8.0_101 export JRE_HOME=$JAVA_HOME/jre export CLASSPATH=.:$JAVA_HOME/lib:$JER_HOME/lib:$CLASSPATH export PATH=$JAVA_HOME/bin:$JER_HOME/bin:$PATH 按”esc” :w :q 4.立刻应用改变 $sudo source /etc/profile 5.测试 java –version java version "1.8.0_101" Java(TM) SE Runtime Environment (build 1.8.0_101-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode) (2)maven安装和部署 1.解压 cd /home/lly/下载/hadoop/ tarzxvfapache-maven-3.3.9-bin.tar.gz -C /usr/soft 2.添加环境变量 $sudo vim /etc/profile

3.加入如下内容 export MAVEN_HOME=/usr/soft/apache-maven-3.3.3 export PATH=.:$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin 按”esc” :w :q 4.立刻应用改变 $sudo source /etc/profile 5.测试 mvn -version Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00) Maven home: /usr/soft/apache-maven-3.3.9 Java version: 1.8.0_101, vendor: Oracle Corporation Java home: /usr/java/jdk1.8.0_101/jre (3)依赖安装 1.输入命令 $sudoyum install g++ autoconfautomakelibtoolcmakezlib1g-dev pkg-configlibssl-de (4)安装cmake 1.解压 cd /home/lly/下载/hadoop/ tarzxvfcmake-3.6.2.tar.gz -C /usr/soft 2.安装 cd/usr/soft/cmake-3.6.2 ./bootstrap make make install 3.测试 cmake–version (5)安装protobuf 1.解压 cd /home/lly/下载/hadoop/ tarzxvfprotobuf-2.5.0.tar.gz -C /usr/soft 2.安装 cd/usr/soft/protobuf-2.5.0 ./configure --prefix=/usr/soft/protobuf-2.5.0 make

Ubuntu下编译Android源码全过程

Ubuntu下编译Android源码全过程(转) 源码, 编译, Ubuntu, Android 一、获取Android源代码 Git是LinuxTorvalds(Linux之父)为了帮助管理Linux内核开发而开发的一个开放源码的分布式版本控制软件,它不同于Subversion、CVS这样的集中式版本控制系统。在集中式版本控制系统中只有一个仓库(Repository),许多个工作目录(WorkingCopy),而在Git这样的分布式版本控制系统中(其他主要的分布式版本控制系统还有BitKeeper、Mercurial、GNUArch、Bazaar、Darcs、SVK、Monotone等),每一个工作目录都包含一个完整仓库,它们支持离线工作,本地提交可以稍后提交到服务器上。 因为Android是由Kernel、Dalvik、Bionic、Prebuilt、build等多个项目组成,如果我们分别使用Git来逐个获取显得很麻烦,所以Android项目编写了一个名为Repo的Python 的脚本来统一管理这些项目的仓库,使得项目的获取更加简单。 在Ubuntu 8.04上安装Git只需要设定正确的更新源,然后使用apt-get就可以了,apt-get 是一条Linux命令,主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或 操作系统。 apt-get命令一般需要root权限执行,所以一般跟着sudo命令。 sudo apt-get install git-core curl 这条命令会从互联网的软件仓库中安装git-core和curl。 其中curl是一个利用URL语法在命令行方式下工作的文件传输工具,它支持很多协议,包括FTP、FTPS、HTTP、HTTPS、TELENT等,我们需要安装它从网络上获取Repo脚本文件。 curl https://www.doczj.com/doc/b65965231.html,/repo >~/bin/repo 这句命令会下载repo脚本文件到当前主目录的/bin目录下,并保存在文件repo中。 最后我们需要给repo文件可执行权限

CEGUI0.7.6源码配置编译详细过程

CEGUI 0.7.6 源码配置编译详细过程 (YangJing@南京20120314) 1.我的开发环境 操作系统:Vista Ultimate 32bit中文 编译环境:VS2010旗舰版中文 DXSDK: Microsoft DirectX SDK (June 2010) OGRE版本:1.7.4,直接用的二进制版本 2.下载CEGUI及依赖包源码 下载源码分为2部分,一部分是CEGUI本身的源码,另一部分是编译源码需要的依赖项dependencies。依赖项和源码版本有大致的对应关系,如CEGUI-DEPS-0.7.x-r3-vc10,表示该依赖项包适合于CEGUI 0.7.x(当然也适合于CEGUI0.7.6),vc10编译器,r3是依赖项资源包的版本。下载地址自己找吧。 下载后这个样子: 然后解压,源码解压后,是这个样子: 那个dependencies目录是加了依赖包后才出现的。依赖包解压后的样子: 把这里的dependencies目录拷贝到上面源码包内就可以了。注意相对位置别弄错了。 3.配置过程

目录下有个build_vs2008.bat文件,该文件运行后可以生成CEGUI.sln。还有其它版本的VS2003,VD2005,但是没有VS2010的。我的做法是来个VS2008,然后用VS2010打开,会有个自动升级的过程,就得到2010版的.sln了。 在cmd命令下,目录切换到premake目录,然后运行build_vs2008.bat,就得到CEGUI.sln了。这样,打开解决方案后,发现没有CEGUIOgreRenderer工程,而我要在OGRE应用中使用CEGUI(CEGUIOgreRenderer.lib和CEGUIOgreRenderer.dll),所以这样还不行。 打开build_vs2008.bat,看到: premake --file cegui.lua --target vs2008 说明用了cegui.lua。打开cegui.lua,看到: dofile("config.lua") 等等,莫非有什么配置项在config.lua内,打开config.lua 看到: 红色箭头这一项,本来是false,默认不生成CEGUIOgreRenderer工程,我该为true,然后再运行build_vs2008.bat,在新生成的CEGUI.sln中看到CEGUIOgreRenderer工程了。其它的Renderers也可以在这里找到。我又要了个CEGUIDirect3D10Renderer模块。 然后我就编译整个CEGUI解决方案。发现很多问题:

Ubuntu下Android源码修改、编译及运行、launcher定制

环境 Linux版本: Ubuntu 11.04(可由 10.10的版本进行升级)64位系统 GCC版本: gcc version 4.5.2 Java版本: java version " 1.6.0_26" 下载android源码前注意: 1、保证Ubuntu系统中的容量在80G左右,以保证足够的空间来存放android源码以及编译后的相关文件。 联网方法: 采用拨号进行连接。相关操作步骤如下所示: 1、虚拟机设置硬件网络适配器网络连接桥接 2、启动Ubuntu系统,打开终端(在普通用户下),输入相关命令如下: $ pppoeconf//打开后输入上网账号跟密码,确认保存 $ sudo pon dsl-provider//上网连接命令

经过这两个步骤后就可以进行上网了。 Android源码编译所依赖的tools 01.$ sudo apt-get update 02.$ sudo apt-get -y install git-core 03.$ sudo apt-get -y install gnupg 04.$ sudo apt-get -y install sun-java6-jdk flex 05.$ sudo apt-get -y install bison 06.$ sudo apt-get -y install gperf 07.$ sudo apt-get -y install libsdl-dev 08.$ sudo apt-get -y install libesd0-dev 09.$ sudo apt-get -y install libwxgtk 2.6-dev 10.$ sudo apt-get -y install build-essential 11.$ sudo apt-get -y install zip 12.$ sudo apt-get -y install curl 13.$ sudo apt-get -y install libncurses5-dev 14.$ sudo apt-get -y install zlib1g-dev 15.$ sudo apt-get -y install valgrind 注意: (如果是32bit的系统的话,则要更改几个Android.mk文件)01./external/clearsilver/cgi/Android.mk

Android 源码编译 流程

Android 源码编译调试流程 by mengke 1 编译流程 sudo apt-get install build-essential sudo apt-get install make sudo apt-get install gcc sudo apt-get install g++ sudo apt-get install libc6-dev sudo apt-get install patch sudo apt-get install texinfo sudo apt-get install libncurses-dev sudo apt-get install git-core gnupg sudo apt-get install flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl sudo apt-get install ncurses-dev sudo apt-get install zlib1g-dev sudo apt-get install valgrind sudo apt-get install python2.5 安装java环境 sudo apt-get install sun-java6-jre sun-java6-plugin sun-java6-fonts sun-java6-jdk sudo apt-get install sun-java5-jdk (ubuntu 910 估计会有一些问题) (注:官方文档说如果用sun-java6-jdk可出问题,得要用sun-java5-jdk。经测试发现,如果仅仅make(make不包括make sdk),用sun-java6-jdk是没有问题的。而make sdk,就会有问题,严格来说是在make doc出问题,它需要的javadoc版本为1.5。 因此,我们安装完sun-java6-jdk后最好再安装sun-java5-jdk,或者只安装sun-java5-jdk。这里sun-java6-jdk和sun-java5-jdk都安装,并只修改javadoc.1.gz和javadoc。因为只有这两个是make sdk用到的。这样的话,除了javadoc工具是用1.5版本,其它均用1.6版本: sudo apt-get install sun-java5-jdk) cd /etc/alternatives sudo rm javadoc.1.gz sudo ln -s /usr/lib/jvm/java-1.5.0-sun/man/man1/javadoc.1.gz javadoc.1.gz sudo rm javadoc sudo ln -s /usr/lib/jvm/java-1.5.0-sun/bin/javadoc javadoc 假设源代码的目录为mydroid root@mk-desktop:~/mydroid# ls Makefile build development frameworks out sdk bionic cts device hardware packages system bootable dalvik external ndk prebuilt vendor

安卓系统源码编译

安卓源码编译 1、编译环境的搭建 操作系统推荐安装64位的ubuntu10.04,其他版本的ubuntu也可以安装,但是可能出现一些莫名其妙的Bug。 系统安装结束之后,还需要安装一些编译源码需要的工具和依赖包。具体内容如下:确认下列软件安装成功并且版本号正确: 1.1 gcc4.4,而不是gcc4.6,如果是4.6,需要安装gcc4.4,命令如下: sudo apt-get install gcc-4.4 sudo apt-get install g++-4.4 cd /usr/bin ls -l gcc* sudo mv gcc gcc.bak sudo ln -s gcc-4.4 gcc ls -l g++* sudo mv g++ g++.bak sudo ln -s g++-4.4 g++ gcc -v g++ -v 1.2 python 2.5-2.7,ubuntu10.04版本,默认的python版本是2.6。 1.3 JDK版本是1.6.0,而不是openJDK, 1.4 安装git sudo apt-get install git-core gnupg 1.5 一些依赖包的安装: Ubuntu系统版本不同,所需要安装的依赖包也不同,具体情况如下所述: u buntu 10.04(64位) $ sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs \ x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev \ libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown \ libxml2-utils xsltproc ubuntu 11.10(64位)

Android_SDK编译,带自己api的android.jar编译

Android SDK编译 ——如何将自己源代码加入android.jar 在Android源码编译成功的基础上重新编译带自己API的android.jar需要进行以下几步操作。 1 添加自己源代码,在Android源码frameworks/base目录下新建一个文件夹保存代码,如tv,以包的形式命名添加的文件所在的路径,如/tv/java/android/tv,添加的java文件开头定义的包即是编译成功的class文件所在的包。 2 修改makefile文件 2.1 修改build/core/pathmap.mk文件 在FRAMEWORKS_ BASE_ SUBDIRS变量后添加tv\,代码如下(makefile 文件中的语句以Tab键空格开头) FRAMEWORKS_BASE_SUBDIRS := \ $(addsuffix /java, \ core \ graphics \ location \ media \ opengl \ sax \ telephony \ wifi \ vpn \ keystore \ tv \ ) 2.2修改frameworks/base/Android.mk 文件 在packages_to_ document变量后添加自己源代码的包名称,如android/tv,结果如下(makefile文件中的语句以Tab键空格开头) packages_to_document := \ android \ javax/microedition/khronos android/tv 3 在ubuntu命令行终端使用如下命令进行编译: make clean make update-api make PRODUCT-sdk-sdk 最后一行也可以用如下两个命令代替: make –j4 make sdk 4 编译结果 4.1 android.jar文件所在的目录为 /out/target/common/obj/PACKAGING/android_jar_intermediates/android.jar 并在/out/target/common/obj/JA V A_LIBRARIES/android_stubs_current_interme diates/src目录下重新以package形式组织所有生成到android.jar中的源代码。 4.2 SDK所在目录为

编译原理(PL0编译程序源代码)

/*PL/0编译程序(C语言版) *编译和运行环境: *Visual C++6.0 *WinXP/7 *使用方法: *运行后输入PL/0源程序文件名 *回答是否将虚拟机代码写入文件 *回答是否将符号表写入文件 *执行成功会产生四个文件(词法分析结果.txt符号表.txt虚拟代码.txt源程序和地址.txt)*/ #include #include"pl0.h" #include"string" #define stacksize 500//解释执行时使用的栈 int main(){ bool nxtlev[symnum]; printf("请输入源程序文件名:"); scanf("%s",fname); fin=fopen(fname,"r");//以只读方式打开pl0源程序文件 cifa=fopen("词法分析结果.txt","w"); fa1=fopen("源程序和地址.txt","w");//输出源文件及各行对应的首地址 fprintf(fa1,"输入pl0源程序文件名:"); fprintf(fa1,"%s\n",fname); if(fin){ printf("是否将虚拟机代码写入文件?(Y/N)");//是否输出虚拟机代码 scanf("%s",fname); listswitch=(fname[0]=='y'||fname[0]=='Y'); printf("是否将符号表写入文件?(Y/N)");//是否输出符号表 scanf("%s",fname); tableswitch=(fname[0]=='y'||fname[0]=='Y'); init();//初始化 err=0; cc=cx=ll=0; ch=' '; if(-1!=getsym()){ fa=fopen("虚拟代码.txt","w"); fas=fopen("符号表.txt","w"); addset(nxtlev,declbegsys,statbegsys,symnum); nxtlev[period]=true; if(-1==block(0,0,nxtlev)){//调用编译程序 fclose(fa); fclose(fa1); fclose(fas); fclose(fin); return 0; }

如何单独编译Android源代码中的模块

如何单独编译Android源代码中的模块第一次下载好Android源代码工程后,我们通常是在Android源代码工程目录下执行make命令,经过漫长的等待之后,就可以得到Android系统镜像system.img了。以后如果我们修改了Android 源代码中的某个模块或者在Android源代码工程新增一个自己的模块,是不是还是执行make命令呢?答案是否定的,Google为我们准备了另外的命令来支持编译单独的模块,以及重新打包system.img 的命令。在继续学习Android源代码之前,就让我们先来看看这个命令吧。 一. 首先在Android源代码目录下的build目录下,有个脚本文件envsetup.sh,执行这个脚本文件后,就可以获得一些有用的工具: USER-NAME@MACHINE-NAME:~/Android$ . ./build/envsetup.sh 注意,这是一个source命令,执行之后,就会有一些额外的命令可以使用: - croot: Changes directory to the top of the tree. - m: Makes from the top of the tree. - mm: Builds all of the modules in the current directory. - mmm: Builds all of the modules in the supplied directories. - cgrep: Greps on all local C/C++ files. - jgrep: Greps on all local Java files. - resgrep: Greps on all local res/*.xml files. - godir: Go to the directory containing a file. 这些命令的具体用法,可以在命令的后面加-help来查看,这里我们只关注mmm命令,也就是可以用它来编译指定目录的所有模块,通常这个目录只包含一个模块。 二. 使用mmm命令来编译指定的模块,例如Email应用程序: USER-NAME@MACHINE-NAME:~/Android$ mmm packages/apps/Email/ 编译完成之后,就可以在out/target/product/generic/system/app目录下看到 Email.apk文件了。Android系统自带的App都放在这具目录下。另外,Android系统的一些可执行文件,例如C编译的可执行文件,放在out/target/product/generic/system/bin目录下,动态链接库文件放在out/target/product/generic/system/lib目录下, out/target/product/generic/system/lib/hw目录存放的是硬件抽象层(HAL)接口文件,后面的文章里面,我们会陆续提及到,敬请关注。 三. 编译好模块后,还要重新打包一下system.img文件,这样我们把system.img运行在模拟器上时,就可以看到我们的程序了。 USER-NAME@MACHINE-NAME:~/Android$ make snod 四. 参照Ubuntu上下载、编译和安装Android最新源代码一文介绍的方法运行模拟器: USER-NAME@MACHINE-NAME:~/Android$ emulator 这样一切就搞定了。

Ubuntu下QT源码编译详细过程

10 .QT 10.1 qt的源码编译 安装编译源码的所需工具和库 X11: 1. apt-get install libX11-dev libXext-dev libXtst-dev 2. apt-get install xorg-dev 3. apt-get install libtool 4. apt-get install autoconf 5. apt-get install g++ ARM: 1 apt-get install qt3-dev-tools apt-get install qt4-qmake 2 安装触屏支持库tslib-1.4 tar -zxvf tslib-1.4.tar.gz cd tslib进入tslib目录下,目录内容如图10-1所示: 图10-1 tslib ./autogen.sh 该shell脚本的正确的执行过程如图10-2所示:

图10-2 autogen.sh执行过程 设置环境变量 CC=arm-linux-gcc 讲ac_cv_func_malloc_0_nonnull=yes重定向输入到arm-linux.cache echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache 执行configure文件 ./configure --prefix=/opt/ts/ --host=arm-linux --cache-file=arm-linux.cache 执行make编译 make 执行make install安装 make install 检验是否安装成功,在/opt/ts/下面存在的四个文件夹,则安装成功,如图10-3所示: 图10-3 ts安装目录 X11版本编译安装过程: 第一步:解压 工程路径:/home/lizhangjie/install 目标文件:qt-everywhere-opensource-src-4.6.3.tar.gz 通过tar命令将目标文件解压到工程路径下: tar –zxvf qt-everywhere-opensource-src-4.6.3.tar.gz 注意:tar.bz2结尾的压缩文件才会用到-jxvf 参数。 解压之后会得到文件夹qt-everywhere-opensource-src-4.6.3,编译该源码得到的最终是X11版本的,我们后面还要编译ARM版本。 第二步:执行configure文件 我们首先的通过执行configure文件,让系统按照configure文件生成各级Makefile。cd qt-everywhere-opensource-src-4.6.3,qt-everywhere-opensource-src-4.6.3文件夹下的内容,如图10-3所示:

android源码的下载和编译方法

Android4.0源码下载编译方法 第一步:初始化编译环境 To build the Android source files, you will need to use Linux or Mac OS. Building under Windows is not currently supported 大概意思就是指要编译Android源代码文件,你需要使用Linux或者Mac OS系统,在Windows 下编译当前不是被支持的,所以,得安个Linux,我目前用的是装在虚拟机的Ubuntu,当然其它的也可以的。 强烈建议: 虚拟机的RAM>=4G, DISK >= 40G 1.安装虚拟机, 我从360上边下载了VMwareworkstation8.0.4版本; 2.安装ubuntu系统, 使用了ubuntu11.04, 现在最新的版本是ubuntu 11.10, 这里我推荐使 用11.04版本, 原因后边有讲到; 在home界面选中”Create a New Virtual Machine” 选择”Typical”, 然后”next”

选中”Installer disc image file(iso):”, 在Browser中选中需要安装的镜像文件.

然后”next”, “next”, 修改Maximum disk size(GB) 40, 选中”Store virtual disk as a single file”;

然后”next”, 在如下界面点击完成(注意这里的Memory是1G, 4G的内存要求,我们可以通过增加SWAP空间来解决, 文档最后又说明)

Linux下源码编译安装详解

前言 源码要运行,必须先转成二进制的机器码。这是编译器的任务。比如,下面这段源码(假定文件名叫做test.c)。 #include int main(void) { fputs("Hello, world!\n", stdout); return 0; } 要先用编译器处理一下,才能运行。 $ gcc test.c $ ./a.out Hello, world! 对于复杂的项目,编译过程还必须分成三步。 $ ./configure $ make $ make install 编译过程流程图:

一.编译的具体过程 1. 配置(configure) 编译器在开始工作之前,需要知道当前的系统环境,比如标准库在哪里、软件的安装位置在哪里、需要 装哪些组件等等。这是因为不同计算机的系统环境不一样,通过指定编译参数,编译器就可以灵活适应环境,编译出各种环境都能运行的机器码。这个确定编译参数的步骤,就叫做"配置"(configure)。 这些配置信息保存在一个配置文件之中,约定俗成是一个叫做configure的脚本文件。通常它是由autocon 工具生成的。编译器通过运行这个脚本,获知编译参数。 configure脚本已经尽量考虑到不同系统的差异,并且对各种编译参数给出了默认值。如果用户的系统环 比较特别,或者有一些特定的需求,就需要手动向configure脚本提供编译参数。 $ ./configure --prefix=/www --with-mysql 上面代码是php源码的一种编译配置,用户指定安装后的文件保存在www目录,并且编译时加入mysq 模块的支持。 2. 确定标准库和头文件的位置 源码肯定会用到标准库函数(standard library)和头文件(header)。它们可以存放在系统的任意目录中,编译器实际上没办法自动检测它们的位置,只有通过配置文件才能知道。 编译的第二步,就是从配置文件中知道标准库和头文件的位置。一般来说,配置文件会给出一个清单,列出几个具体的目录。等到编译时,编译器就按顺序到这几个目录中,寻找目标。 对于大型项目来说,源码文件之间往往存在依赖关系,编译器需要确定编译的先后顺序。假定A文件依赖于B文件,编译器应该保证做到下面两点。 (1)只有在B文件编译完成后,才开始编译A文件。 (2)当B文件发生变化时,A文件会被重新编译。 编译顺序保存在一个叫做makefile的文件中,里面列出哪个文件先编译,哪个文件后编译。而makefile文件由configure脚本运行生成,这就是为什么编译时configure必须首先运行的原因。 在确定依赖关系的同时,编译器也确定了,编译时会用到哪些头文件。 不同的源码文件,可能引用同一个头文件(比如stdio.h)。编译的时候,头文件也必须一起编译。为了节省时间,编译器会在编译源码之前,先编译头文件。这保证了头文件只需编译一次,不必每次用到的时候,都重新编译了。 不过,并不是头文件的所有内容,都会被预编译。用来声明宏的#define命令,就不会被预编译。

Linux如何编译安装源码包软件

一、什么是源码包软件; 顾名思义,源码包就是源代码的可见的软件包,基于Linux和BSD系统的软件最常见;在国内源可见的软件几乎绝迹;大多开源软件都是国外出品;在国内较为出名的开源软件有fcitx;lumaqq;Lumaqq及scim等; 但软件的源代码可见并不等于软件是开源的,我们还要以软件的许可为准;比如有些软件是源码可见的,但他约定用户只能按他约定的内容来修改;比如vbb论坛程序;所以一个软件是否是开源软件,得具备两个条件;一是源代码可见;二是要有宽松的许可证书,比如GPL 证书等; 在GNU Linux或BSD社区中,开发人员在放出软件的二进制软件包的同时,也会为我们提供源代码软件包; 二、源代码有何用? 一个软件的如果有源码,是任何人都能看到他是怎么开发而来的,就像一个瓶子,比如瓶子制作的模具是什么;需要什么材料;具体的用途以及瓶子的详细说明书等等。软件的开放源码就是类似,开发者在给我们软件的同时,也会告诉我们软件是怎么开发出来的;只要我们的水平足够的高,所有的代码都在那里,我们就可以修改和定制软件,以适合我们的需要;如果Windows开放源代码,并以GPL发布,一样是有人能造出来N多的Windows发行版;遗憾的是Windows并不是开源系统; 所以软件的源代码的用处无非是以下两点; 1、软件根据用户的需要加以定制; 2、二次开发;注:要根据软件的许可证书约定为准,开发者许可二次开发才行; 三、怎样安装以源码包打包的软件; 1、源码包的打包格式; 源代码一般以file.tar.gz file.tar.bz2或file.src.rpm 打包;file.tar.gz和 file.tar.bz2格式的解包命令如下; [root@localhostbeinan]# tarjxvf file.tar.bz2 [root@localhostbeinan]# tar zxvf file.tar.gz

相关主题
文本预览
相关文档 最新文档