admin 管理员组

文章数量: 887021


2024年2月23日发(作者:navigator属性)

VLC源代码分析

一、 VLC简介

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

操作系统: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官方网站:/

VLC下载页面:/vlc/

VLC下载目录(源码和安装包):/pub/videolan/vlc/

VLC Nightly Builds: /

VLC 开发Wiki:/Developers_Corner

VLC Win32第三方库预编译包下载目录:/pub/testing/win32/

VLC 官方论坛:/

VLC 邮件列表:/developers/

二、 Windows平台编译

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

Cygwin是一个在Windows下面模拟Linux环境的东西。它提供了很多库和应用程序,让你可以像在Linux上一样来使用Windows。你需要在/ 下载一个cygwin的安装程序。然后选择一个cygwin的源来下载所需要的库,国内的话到 ftp:///cygwin/和 /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版本,可以从这里下载:/pub/videolan/vlc/,如果你需要下载实时最新的库,就要从VLC的源码库上取下来了。现在VLC改用git了,使用命令: git clone git:///

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

在cygwin中进入vlc的主目录,运行bootstrap,’./bootstrap’。在等待它结束之前,我们先来看一下如何配置VLC的编译。运行 ‘./configure

-h >cfg_’就可以把配置的选项信息都输出到 cfg_中,然后慢慢来研究。里面大多是启用、禁用某些特性和功能模块,或者配置某些模块需要的库的路径等信息。为了方便可以写一个简单的脚本来做这件事,当然这个不是必需的。

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/

–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就编译好了。直接双击主目录里边的应该就可以运行了。

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

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

本文参考 /Win32CompileCygwinNew

三、 Linux平台编译

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

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

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

参考:/UnixCompile

四、 VLC使用

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

最简单的,从界面打开一个文件播放,也可以在命令行下使用,如C:Program FilesVideoLANVLC>

获取内置的帮助,会写到:C:Program FilesVideoLANVLC> -h

获取更详细的帮助,有大量的选项介绍:C:Program FilesVideoLANVLC> -H

在线使用帮助

/doc/play-howto/en/

/doc/streaming-howto/en/

搜索并显示可用的模块列表:C:Program FilesVideoLANVLC> -l

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

Data

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

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

重置所有选项到默认状态:C:Program FilesVideoLANVLC> –reset-config

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

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

C:Program FilesVideoLANVLC> udp://@239.255.1.1:4567

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

C:Program FilesVideoLANVLC> udp://@888

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

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

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

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

udp://@888 :demux=dump :demuxdump-file=”C:”

关于Windows下视频输出模块

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

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

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

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

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

临时启用某个视频输出,可以这样:C:Program FilesVideoLANVLC-0.8.6e>vlc –vout=caca

ActiveX控件

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

C:Program FilesVideoLANVLC-0.8.6e>regsvr32

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

Mozilla Plugin

你还可以在Windows和Linux的Firefox中使用VLC。Windows下可以在安装VLC的时候选上Mozilla plugin,事实上它做的就是在HKLM_Software_MozillaPlugin键下添加一个VLC的子键。Linux下可以把(或者叫)和插件目录放到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,参见:/doc/

六、 代码精简

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_ liba52 用于AC3格式的音频解码,CCTV高清频道需要

liba52tofloat32_

liba52tospdif_

liba52_

libaccess_file_ 文件访问,播放文件需要

libaccess_http_ HTTP访问模块

libaccess_output_file_ sout的文件模块,用于录制

libaccess_udp_ UDP访问模块

libaout_directx_ectX的声音输出,默认的声音输出模块

libdeinterlace_ 解交错的vout-filter模块

libdirect3d_ Direct3D视频输出模块,在上面可以半透明。。。

libfixed32tofloat32_一些数据转换模块

libfixed32tos16_

libfloat32tos16_

libfloat32tos8_

libfloat32tou16_

libfloat32tou8_

libfloat32_mixer_

libglwin32_ OpenGL视频输出模块

libi420_ymga_

libi422_yuy2_

libipv4_4网络模块

libipv6_6网络模块

liblibmpeg2_mpeg2,解码全靠它

liblogger_ 日志模块,调试必备

libmemcpy_ 好像是利用各种CPU指令加速内存拷贝的

libmpeg_audio_ MPEG音频的解码模块

libmpgatofixed32_

libmpga_

libmux_dummy_

libpacketizer_mpegvideo_

libs16tofixed32_

libs16tofloat32swab_

libs16tofloat32_

libs8tofloat32_

libsimple_channel_mixer_

libstream_out_display_ sout的模块 。。。

libstream_out_duplicate_

libstream_out_standard_

libtrivial_channel_mixer_

libtrivial_mixer_

libtrivial_resampler_

libts_ TS流的解复用模块

libu8tofixed32_

libu8tofloat32_

libugly_resampler_

libvout_directx_ectX视频输出模块

libwingdi_ GDI视频输出模块

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

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

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

拷贝到 C:Program FilesVideoLANVLC

拷贝到 C:Program FilesVideoLANVLCplugins

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

这里有对VLC新特性的介绍 /What_is_cool_in_0.9

Release Note:/developers/vlc/NEWS

下载目录:/pub/vlc/0.9.2/win32/

下载链接(exe):/pub/vlc/0.9.2/win32/

七、 将VLC嵌入自己的应用

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

•1、直接调用VLC进程

•2、VLC的plugin for Mozilla

•3、VLC的ActiveX插件

•4、调用libvlc

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

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

stream output string拷下来。

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

VLC的ActiveX插件只能用于Windows平台,当然这是因为ActiveX只是微软的东西。但是不得不说这个还是很好用的。无论是C++、C#、VB还是网页,都可以轻松地将这个ActiveX利用起来。关于这个的VLC官方文档在这里/ActiveX_Controls 开发、使用之前别忘了先要注册ActiveX控件,方法是运行 regsvr32 。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_ayWhenRecording)

{

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

strName);

}

else

{

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

}

= VT_BSTR;

l = ysString();

psa = SafeArrayCreate (VT_VARIANT, 1, bound);

index = 0;

SafeArrayPutElement (psa, &index, &var);

if (bIPv6)

{

= VT_BSTR;

l = ysString();

index = 1;

SafeArrayPutElement (psa, &index, &ip6);

}

= VT_ARRAY | VT_BSTR;

= psa;

tagVARIANT nul;

= VT_NULL;

m_ylist ().add (szMRL, nul, opt);

m_ylist ().next ();

m_ylist ().play ();

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

char p_pluginpath[MAX_PATH+1];

int iTmp = 0;

/* 得到的全路径 */

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下的 playermodules */

strcat (p_pluginpath, “playermodules“);

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官方提供了一些文档和例子 /Libvlc。这里还有一个用C#调用libvlc的例子/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源代码阅读的计划是从其程序的框架开始,先对其主要的文件进行整理:

e/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,可见其结构体的重要性.所有的参数传递都在这里面(具体尚不清楚)。

e/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 */

e/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 就读入流准备分析,建立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. modulesmiscrtsp.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=%%drn",

p_sys->i_port, p_media->psz_rtsp_path );

asprintf( &p_media->psz_rtsp_control_v6,

"a=control:rtsp://[%%s]:%d%s/trackID=%%drn",

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枚举类型以及(在bindings/cil/src/)

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程序访问,ork将它作为一个指向一个引用了一个libvlc_media_t指针的本地对象的指针来使用

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

VLC API集合:/developers/vlc/doc/doxygen/html/group__#_details

十一、 VLC问题及解决

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

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

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

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

在windows xp下编译ffmpeg

1、 安装MSys

到/project/?group_id=2435下载文件:

2

2

2下載鏈接:/project/?group_id=2435&use_mirror=nchc&filename=2&2下載鏈接:/project/?group_id=2435&use_mirror=nchc&filename=2&93684193

解压2,比如解压到D:msys(以下内容都使用该路径描述)。

解压2,产生一个名为bash-3.1的目录,在该目录下有一个子目录名为bin,其 他 的目录不需要关心。复制bin目录中的所有文件到D:msysbin,提示是否要覆盖的时候,选择是。

到“D:msyspostinstall”目录下执行,在出现的提示中输入n回车后,按任意键退出即可。 如果你不输入N的话就输入两次Y,最后把c:msysmingw 输入即可 。如果输入N的话,要打开D:把它重命名为fstab 并用nodepad打开编辑,把c:mingw mingw 改成d:msysmingw即可。最后配置PATH,在系统的环境配置中添加d:msysbin。

2、 安装MinGW

到/project/?group_id=2435下载文件:

gcc-g++-

把它们全部解压到D:msysmingw。或者直接下载文件 下载好按步骤安装,选择安装的组件最好都选上啦。不过安装目录一定要选择d:msysmingw 别的路径它找不到。

3、 修改“”

用文本编辑器打开D:, 安装微软的Visual Studio或是Visual C++。把下面一行加到的最前面,把路径替换成机器上实际存在的路径,比如我的在“c:Program FilesMicrosoft Visual Studio .NET 2005Vcbin”,于是就添加:call "c:Program FilesMicrosoft

Visual Studio .NET "

4、 svn

/downloads下载TortoiseSVN,安装好之后,在d:ffmpeg右击,选择SVN check out,

第一行目录选择svn:///ffmpeg/trunk 然后确定。这样就得到最新的SVN。

但由于SVN只针对UNIX系统做的。所以无法GCC对最新的SVN编译。会报错:192 PR command not found.

解决方法一:不用最新的SVN版本。因为即使用了最新的还是有这样的错误。 windows下还是无法编译最新的SVN代码。我这有07年3月的版本是可以用的。需要的可以索要。

解决方法二:下载

2 Mirror

并且解压缩出来,把bin下的内容拷贝到MSYS下,因为MSYS缺少COREUTILS所以报错 PR command not found。

改完后你会发现可以编译了,但是make的时候又出错了。怎么办呢?去sourceforge网站上下载2,替换掉原来的文件即可 (搜索了一天时间,提供出来免得大家走歪路!)

这样就可以用最新的SVN版本来进行编译了。

5、 测试

打开,输入cd空格/d/ffmpeg,路径变化后,然后输入./configure空格--enable-memalign-hack,回车!

如果不报错,那么再输入make.

6、 第三方插件

根据以上5个步骤就已经可以得到了,但没有加入声音,以及对其他格式支持的也不够好。

现在开始加入lame,就是声音。到/下载已经编译的mp3lame库(可以向我索要),解压出来后分别拷贝到你安装好的mingw目录下的相对目录里。在传递配置参数时要加入“--enable-libmp3lame” ,即使用以下命令配置:

./configure --enable-static --disable-shared --enable-memalign-hack --enable-libmp3lame

然后加入mp4的格式的支持:

然后加入3GP的支持:

编译的时候加上--enable-amr_nb --enable-amr_wb参数就行,根据编译系统的提示,所以我们得下载一

些编译3gp所需得文件。

/ftp/Specs/archive/26_series/26.204/

解压以后把里面的文件都拷贝到libavcodec/amrwb_float

/ftp/Specs/archive/26_series/26.104/

解压以后把里面的文件都拷贝到libavcodec/amr_float

十二、 附录

海狗哥的“MinGW下简单编译FFmpeg”:/539865/126804

FFMPEG工程组--在Windows下编译ffmpeg完全手册:/?tid=1897&extra=page%3D1

十三、 windows平台下vlc编译

Jeremiah刚刚工作几个月,参与的第一个项目是与视频监控有关,分配给我的任务就是用开源的vlc做一个自己的播放器。

对于开源项目来说,搭建起编译环境是第一步也是最重要的一步。Jeremiah在历经5天的痛苦折磨,google出了n多网页,其中还包括一个德语的网页和韩语的网页,终于编译通过了vlc0.8.6d。百度到的ChinaUnix的一个网页上面说:编译vlc感觉就像被...,Jeremiah深有体会啊。不过编译成功,还是小兴奋了一下。啊哈哈~!有些自虐倾向。

在网上查到一个vlc的qq群:49846130。里面人快满了,不知道什么时候开个二群。有兴趣的可以加一下,大家共同交流。

废话不多说了,步入正题。

在windows下编译vlc需要使用仿真Linux环境Cygwin或者Msys+MingW,据说差不多。但是Jeremiah没有用过后者,所以在这只介绍Cygwin环境。

编译之前的说明:由于最近Cygwin更新了库文件,导致出现了一些新的无法通过编译的错误。Jeremiah将自己的应用的Cygwin-old的库文件在我的公共邮箱提供了下载,具体下载方式为:

1). 登录

2). 用户名:jeremiah_vlc

3). 密码:发邮件给我(**********************),我会告知。

4). 在“我的文件夹”的“Jeremiah_VLC相关资源”有所有资料的超大附件连接。

编译第一步:去下载Cygwin。给个网址:[url]/[/url](用我上面提供的,选择从本地安装)

编译第二步:安装Cygwin。Cygwin需要安装到某个盘的根路径。然后要找个源下载相应的库,[url]/pub[/url]相对比较快,[url]ftp:///cygwin/[/url]作为参考。(如果用的本地的库文件,就不用写这一项)然后就需要安装其他库来支持vlc的编译了。目录如下:

Archive

unzip (5.52-2)

zip (2.32-2)

Devel

autoconf (4-1 2.13-3 2.61-1)

automake (2-1 1.10-1 1.4p6-4 1.5-2 1.63-3 1.7.9-3 1.8.5-3 1.9.6-2)

binutils (20080624)

cvs (1.11.22-1)

gcc (3.4.4-3)

gcc-core (3.4.4-3)

gcc-g++ (3.4.4-3)

gcc-mingw (20040810-1)

gcc-mingw-core (20050522-1)

gcc-mingw-g++ (20050522-1)

gdb (6.8-2)

gettext (0.15-1)

gettext-devel (0.15-1)

git (1.6.0.2-1)

libiconv (1.11-1)

libgcrypt-devel (1.41-4)

libtool (1.5.27a-1)

make (3.81-2)

mingw-runtime (3.15.1-1)

nasm (2.02-1)

patchutils (0.2.31-2)

pkg-config (0.23a-2)

subversion (1.5.2-1)

Editor

vim (7.2-3)

Libs

expat (2.0.1-1)

libgcrypt (1.4.1-4)

Web

curl (optional: for building extras/contrib) (7.16.3-1)

wget (optional: for building extras/contrib) (1.11.3-1)

经过比较漫长的下载过程,Cygwin就算安装好了。建议将下载下来的文件(位于安装文件同目录)保留下来,下次安装的时候直接从文件安装就不用到网上下载了。

第一次运行Cygwin,如果没有产生下列代码:

Copying skeleton files.

These files are for the user to personalise

their cygwin experience.

These will never be overwritten.

`./.bashrc' -> `/home/wangwei1//.bashrc'

`./.bash_profile' -> `/home/wangwei1//.bash_profile'

`./.inputrc' -> `/home/wangwei1//.inputrc'

则表示windows用户没有添加到Cygwin中,运行以下两条命令添加用户:

mkpasswd -l [-d] > /etc/passwd

mkgroup -l [-d] > /etc/group

其中-d可选,如果你在域中,需要用加入'-d 域名'。

重新开启Cygwin,在根目录'/'下就会生成/home/yourname的文件夹。

编译第三步:下载源码及第三方库。vlc的所有的源码(*.,*.2)及编译好的绿色版(win32/*.zip),安装版(win32/*.exe)都可以在这里下载:[url]/pub/videolan/vlc/[/url]。Cygwin下编译vlc最关键的就是源码和第三方库要相匹配,Jeremiah之所以编译了5天,经历了n多痛苦的过程,就是因为没有匹配好源码和第三方库,导致了大量的错误。上面网址里面的vlc的版本很多,相对稳定的是vlc-0.8.6*版本,推荐0.8.6i,匹配的contrib为:[url]/pub/testing/win32/2[/url]。Jeremiah写这篇博客的时候最新的发行版是vlc-0.9.6,其实1.0.0已经在测试了,只是没有正式发布而已([url]/[/url]),vlc各个版本的更新日志参考:[url]/developers/vlc/NEWS[/url]。但是Jeremiah没有编译成功vlc-0.9.6,0.9.*版本推荐0.9.4,匹配的contib为:2。

Jeremiah将在未来几篇博客中详细介绍编译0.8.6i和0.9.4。

windows平台下vlc编译之二:vlc-0.8.6i的编译

如果按照上一篇博客《windows平台下vlc编译之一:编译环境构建》安装好了Cygwin,下载了源码和第三方库之后,我们就可以编译vlc了。这篇博客先讲如何编译vlc-0.8.6i.

步骤一:解压源码和第三方库。

源文件:/pub/videolan/vlc/0.8.6i/

库:/pub/testing/win32/2

将和2拷贝到/home/username/下面(username为登陆的用户目录),运行以下命令解压:

tar xjvf 2 -C /

tar xzvf

做一点点清理工作

rm -rf /usr/win32/bin/moc

rm -rf /usr/win32/bin/rcc

rm -rf /usr/win32/bin/uic

步骤二:Bootstrap

cd vlc-0.8.6i

./bootstrap

可能出现的错误:

+ aclocal-1.9 -I m4

/usr/bin/m4::4643: cannot create temporary file for diversion: Permission denied

autom4te-2.61: /usr/bin/m4 failed with exit status: 1

aclocal-1.9: autom4te failed with exit status: 1

分析:杀毒软件有关系,比如Jeremiah用的Mcafee就会出这样的错误。

解决方法:关闭杀毒软件重新运行./bootstrap。

步骤三:编辑vlc脚本

在vic-0.8.6i下新建文本文件""(见附件),内容如下:

PKG_CONFIG_PATH=/usr/win32/lib/pkgconfig

CPPFLAGS="-I/usr/win32/include -I/usr/win32/include/ebml"

LDFLAGS=-L/usr/win32/lib

CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin"

./configure

--disable-gtk

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

--enable-ffmpeg --with-ffmpeg-mp3lame --with-ffmpeg-faac

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

--with-wx-config-path=/usr/win32/bin

--with-freetype-config-path=/usr/win32/bin

--with-fribidi-config-path=/usr/win32/bin

--enable-live555 --with-live555-tree=/usr/win32/

--enable-caca --with-caca-config-path=/usr/win32/bin

--with-xml2-config-path=/usr/win32/bin

--with-dvdnav-config-path=/usr/win32/bin

--disable-cddax --disable-vcdx --enable-goom

--enable-twolame --enable-dvdread

--enable-shared-libvlc

--enable-debug

想知道每个--enable,--disable是什么意思,可以使用如下命令将configure的参数信息保存到中,以后对照该文件查看修改vlc编译脚本。

./configure -h >

步骤四:运行vlc脚本

转换下脚本的编码格式:

dos2unix

运行脚本:

./

如果脚本遇到了类似Permission denied的错误,提升脚本的权限:

chmod 777

如果脚本运行成功,则会显示如下信息:

vlc configuration

--------------------

vlc version : 0.8.6i

system: mingw32

architecture: i686 mmx

build flavour : debug optim devel

vlc aliases : svlc wxvlc

You can tune the compiler flags in vlc-config.

To build vlc and its plugins, type `./compile' or `make'.

步骤五:作一点点修改工作

由于在编译完成后会要求,这显然是不对的。应该直接去调用,解决方案为:

修改"/tmp/vlc-0.8.6i"目录下的libtool文件4760行

prog)

case $host in

*cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;

esac

为:

prog)

case $host in

#*cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; //这一行注释掉

*cygwin*) output=`$echo $output` ;;

esac

步骤六:make

运行:

make

如果是双核的电脑,可以运行:

make -j2

如果的电脑有N多个cpu,则参数可以为-jN,N为cpu个数。这样能将几个cpu都利用起来,执行时间会缩短一些。

make的执行期间可能会出现错误,需要修改一些文件,当修改完成后,再执行make,以前make的东西会保留而继续make刚才出错的地方。其实这种方式很方便我们以后修改源代码,重新make的时候它只会编译修改的地方,很节省时间。

错误1:

In file included from file.c:30:

/usr/lib/gcc/i686-pc-mingw32/3.4.4/../../../../i686-pc-mingw32/include/sys/stat.

h:113: error: parse error before "off_t"

/usr/lib/gcc/i686-pc-mingw32/3.4.4/../../../../i686-pc-mingw32/include/sys/stat.

h:118: error: parse error before '}' token

make[4]: *** [libaccess_output_file_plugin_a-file.o] Error 1

make[4]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules/access_output'

make[3]: *** [all-modules] Error 1

make[3]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules/access_output'

make[2]: *** [all-recursive] Error 1

make[2]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules'

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory `/home/wangwei1/vlc-0.8.6i'

make: *** [all] Error 2

解决方案:

//在"/usr/i686-pc-mingw32/include/sys"目录下的stat.h的文件开始处添加如下代码

#ifndef _OFF_T DEFINED

typedeflong off_t;

#define _OFF_T DEFINED

#endif

错误2:

libdtstofloat32_plugin.a(libdtstofloat32_plugin_a-dtstofloat32.o): In function `

Open':

/home/wangwei1/vlc-0.8.6i/modules/audio_filter/converter/dtstofloat32.c:219: und

efined reference to `_dca_init'

libdtstofloat32_plugin.a(libdtstofloat32_plugin_a-dtstofloat32.o): In function `

DoWork':

/home/wangwei1/vlc-0.8.6i/modules/audio_filter/converter/dtstofloat32.c:303: und

efined reference to `_dca_syncinfo'

/home/wangwei1/vlc-0.8.6i/modules/audio_filter/converter/dtstofloat32.c:312: und

efined reference to `_dca_frame'

/home/wangwei1/vlc-0.8.6i/modules/audio_filter/converter/dtstofloat32.c:331: und

efined reference to `_dca_blocks_num'

/home/wangwei1/vlc-0.8.6i/modules/audio_filter/converter/dtstofloat32.c:335: und

efined reference to `_dca_block'

/home/wangwei1/vlc-0.8.6i/modules/audio_filter/converter/dtstofloat32.c:341: und

efined reference to `_dca_samples'

/home/wangwei1/vlc-0.8.6i/modules/audio_filter/converter/dtstofloat32.c:331: und

efined reference to `_dca_blocks_num'

libdtstofloat32_plugin.a(libdtstofloat32_plugin_a-dtstofloat32.o): In function `

Destroy':

/home/wangwei1/vlc-0.8.6i/modules/audio_filter/converter/dtstofloat32.c:376: und

efined reference to `_dca_free'

libdtstofloat32_plugin.a(libdtstofloat32_plugin_a-dtstofloat32.o): In function `

CloseFilter':

/home/wangwei1/vlc-0.8.6i/modules/audio_filter/converter/dtstofloat32.c:430: und

efined reference to `_dca_free'

collect2: ld returned 1 exit status

make[6]: *** [libdtstofloat32_] Error 1

make[6]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules/audio_filter/conve

rter'

make[5]: *** [all-modules] Error 1

make[5]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules/audio_filter/conve

rter'

make[4]: *** [all-recursive] Error 1

make[4]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules/audio_filter'

make[3]: *** [all] Error 2

make[3]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules/audio_filter'

make[2]: *** [all-recursive] Error 1

make[2]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules'

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory `/home/wangwei1/vlc-0.8.6i'

make: *** [all] Error 2

解决方案:

修改".../vlc-0.8.6i"目录下的vlc-config 文件

dtstofloat32)

ldflags="${ldflags} -ldts_pic"

为:

dtstofloat32)

ldflags="${ldflags} -ldts"

错误3:

/usr/win32/lib/libFLAC.a(bitwriter.o):bitwriter.c:(.text+0x3fb): undefined refer

ence to `_ntohl@4'

/usr/win32/lib/libFLAC.a(bitwriter.o):bitwriter.c:(.text+0x488): undefined refer

ence to `_ntohl@4'

/usr/win32/lib/libFLAC.a(bitwriter.o):bitwriter.c:(.text+0x4e5): undefined refer

ence to `_ntohl@4'

/usr/win32/lib/libFLAC.a(bitwriter.o):bitwriter.c:(.text+0x57f): undefined refer

ence to `_ntohl@4'

/usr/win32/lib/libFLAC.a(bitwriter.o):bitwriter.c:(.text+0x5d5): undefined refer

ence to `_ntohl@4'

/usr/win32/lib/libFLAC.a(bitwriter.o):bitwriter.c:(.text+0x66f): more undefined

references to `_ntohl@4' follow

collect2: ld returned 1 exit status

make[4]: *** [libflacdec_] Error 1

make[4]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules/codec'

make[3]: *** [all-modules] Error 1

make[3]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules/codec'

make[2]: *** [all-recursive] Error 1

make[2]: Leaving directory `/home/wangwei1/vlc-0.8.6i/modules'

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory `/home/wangwei1/vlc-0.8.6i'

make: *** [all] Error 2

解决方案:

修改".../vlc-0.8.6i"目录下的vlc-config 文件

flacdec)

ldflags="${ldflags} -lFLAC"

为:

flacdec)

ldflags="${ldflags} -lFLAC -lws2_32"

错误4:

/usr/lib/gcc/i686-pc-mingw32/3.4.4/../../../../i686-pc-mingw32/include/wchar.h:4

27: error: `off_t' does not name a type

make[3]: *** [libaxvlc_a-main.o] Error 1

make[3]: Leaving directory `/home/wangwei1/vlc-0.8.6i/activex'

make[2]: *** [all] Error 2

make[2]: Leaving directory `/home/wangwei1/vlc-0.8.6i/activex'

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory `/home/wangwei1/vlc-0.8.6i'

make: *** [all] Error 2

解决方案:

//在"/usr/i686-pc-mingw32/include/"目录下的wchar.h的文件开始处添加如下代码

#ifndef _OFF_T DEFINED

typedeflong off_t;

#define _OFF_T DEFINED

#endif

一般会遇到这四个错误,如果还出现了其他错误,肯定是哪一步搞错了,如果还是有错误,RPWT。

步骤七:打包

执行以下命令就会得到绿色版的vlc:

make package-win32-base

在vlc-0.8.6i的目录下又会出现一个目录vlc-0.8.6i,里面就是编译好的vlc了。

如果执行:

make package-win32-zip

得到的zip文件就是官网上提供的/win32/*.zip文件了。

如果想得到安装文件(后面讲ActiveX的时候会用到),首先需要下载NSIS 2.41,给个连接:[url]/nsis/?download[/url]。

安装NSIS 2.41,然后在打包好的vlc-0.8.6i下面右键,选择Compile NSIS .。

期间会出错误,有关Mozilla插件的:

Error in macro InstallFile . macroline 1

Error in . "E:" . line 445 -- aborting creation process

用文本编译器打开,在第445行前加上;(分号)注释起来。

;!insertmacro InstallFile

重新Compile NSIS .。运行成功之后,在编译好的vlc-0.8.6i同级目录里面就会出现vlc-${VERSION}-这个文件。这个就是自己编译的vlc的安装文件了。(文件名应该是,但是可能NSIS的脚本的问题,${VERSION}替换不了,手动改一下就行了。)

2009-07-09更新:

的第7行加入

!define VERSION "0.8.6i"

可以解决${VERSION}的问题。

至此,vlc-0.8.6i算是编译完成了。

2010-04-09更新:

错误修正:

如果运行vlc出现了“Windows无法访问指定设备...您可能没有合适权限访问”,或者“Permission denied”错误,请在打包好的vlc-0.8.6i目录下执行以下命令。增加两个文件的运行权限。

chmod 755 st

windows平台下vlc编译之三:vlc-0.9.4的编译

如果你已经成功编译了vlc-0.8.6i,那么编译vlc-0.9.4就跟玩似的。

在这简单的介绍下编译过程。如果有什么不明白的,先好好看看前两篇日志。

1. 解压源码及库文件。

注意:如果你编译过vlc-0.8.6i,请先执行以下命令删除以前的库文件。

rm -rf /usr/win32

还是在Windows下直接用rar解压源文件吧,用tar xzvf来解压最后可能会出现exe的执行权限问题。

源文件:/pub/videolan/vlc/0.9.4/2,解压到X:/cygwin/home/yourname下。

第三方库:2,解压到X:/cygwin/下。

(

在我的公共邮箱提供了下载,具体下载方式为:

1). 登录

2). 用户名:jeremiah_vlc

3). 密码:发邮件给我(**********************),我会告知。

4). 在“我的文件夹”的“Jeremiah_VLC相关资源”有所有资料的超大附件连接。

)

2. 解压完库文件做一点点清理工作

rm -rf /usr/win32/bin/moc

rm -rf /usr/win32/bin/rcc

rm -rf /usr/win32/bin/uic

3. 解压完源码做一点点修改工作

用文本编辑器或vi打开vlc-0.9.4/,

修改

AM_GNU_GETTEXT_VERSION([0.17])

AM_GNU_GETTEXT_VERSION([0.15])

或运行

sed -i 's/AM_GNU_GETTEXT_VERSION(0.17)/AM_GNU_GETTEXT_VERSION(0.15)/g'

4. 执行bootstrap,注意杀毒软件可能引起会Permission Denied。

./bootstrap

5. 显示Successfully bootstrapped后就可以编辑vlc脚本了。

这里有个问题需要详细的说明一下,vlc官方提供的第三方库qt4有问题,相关的skins2不好用。如果禁用掉qt4和skins2,最后得到的vlc没有界面,可以在命令行下面运行。保存以下脚本为(见附件)。(如果想解决qt4的问题,得到有界面的vlc,请直接看8)

PATH=/usr/win32/bin:$PATH

PKG_CONFIG_LIBDIR=/usr/win32/lib/pkgconfig

CPPFLAGS="-I/usr/win32/include -I/usr/win32/include/ebml"

LDFLAGS=-L/usr/win32/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/bin

--enable-avcodec --enable-avformat --enable-swscale

--enable-faad --enable-flac --enable-theora

--with-wx-config-path=/usr/win32/bin

--with-freetype-config-path=/usr/win32/bin

--with-fribidi-config-path=/usr/win32/bin

--enable-live555 --with-live555-tree=/usr/win32/

--disable-qt4 --disable-skins2

--enable-caca --with-caca-config-path=/usr/win32/bin

--with-xml2-config-path=/usr/win32/bin

--with-dvdnav-config-path=/usr/win32/bin

--disable-cddax --disable-vcdx --enable-goom

--enable-twolame --enable-dvdread

--enable-debug--enable-dca

--disable-mkv --disable-taglib

运行以下命令运行脚本:

dos2unix

./

6. make

make

[or make -j2]

Jeremiah在make的时候没有遇到错误,如果你遇到错误,请把错误直接贴到google上搜索解决方法。

7. 打包,根据自己的需求来吧。

make package-win32-base

make package-win32-zip

关于如何制作vlc的安装文件,看上一篇日志吧。(基本上报错就是一些language的错误或者skins、的错误,原则就是哪行出错了,就用;(分号)把哪行注释起来。)

8. 解决下qt4的问题。

先把以下脚本保存为(见附件)。

PATH=/usr/win32/bin:$PATH

PKG_CONFIG_LIBDIR=/usr/win32/lib/pkgconfig

CPPFLAGS="-I/usr/win32/include -I/usr/win32/include/ebml"

LDFLAGS=-L/usr/win32/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/bin

--enable-avcodec --enable-avformat --enable-swscale

--enable-faad --enable-flac --enable-theora

--with-wx-config-path=/usr/win32/bin

--with-freetype-config-path=/usr/win32/bin

--with-fribidi-config-path=/usr/win32/bin

--enable-live555 --with-live555-tree=/usr/win32/

--enable-caca --with-caca-config-path=/usr/win32/bin

--with-xml2-config-path=/usr/win32/bin

--with-dvdnav-config-path=/usr/win32/bin

--disable-cddax --disable-vcdx --enable-goom

--enable-twolame --enable-dvdread

--enable-debug--enable-dca

--disable-mkv --disable-taglib

类似于5.执行脚本,可能会出现以下问题:

/usr/win32/include/qt4/QtCore/qatomic_windows.h:394: error: previous declaration

`long int InterlockedIncrement(long int*)' here

make[6]: *** [libqt4_plugin_] Error 1

make[6]: Leaving directory `/cygdrive/c/vlc/modules/gui/qt4'

make[5]: *** [all] Error 2

make[5]: Leaving directory `/cygdrive/c/vlc/modules/gui/qt4'

make[4]: *** [all-recursive] Error 1

make[4]: Leaving directory `/cygdrive/c/vlc/modules/gui'

make[3]: *** [all] Error 2

make[3]: Leaving directory `/cygdrive/c/vlc/modules/gui'

make[2]: *** [all-recursive] Error 1

make[2]: Leaving directory `/cygdrive/c/vlc/modules'

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory `/cygdrive/c/vlc'

make: *** [all] Error 2

需要去下载两个文件:

1. [url]/download/cygwin/release-2/w32api/2[/url]

2. [url]/pub/videolan/vlc/0.8.5/contrib/2[/url]

运行解压命令解压这两个包。

tar xjvf 2 -C /

tar xjvf 2

继续执行make,报错如下:

/usr/lib/gcc/i686-pc-mingw32/3.4.4/../../../../i686-pc-mingw32/bin/ld: cannot fi

nd -lqjpeg

collect2: ld returned 1 exit status

make[6]: *** [libqt4_] Error 1

make[6]: Leaving directory `/home/wangwei1/vlc-0.9.4/modules/gui/qt4'

make[5]: *** [all] Error 2

make[5]: Leaving directory `/home/wangwei1/vlc-0.9.4/modules/gui/qt4'

make[4]: *** [all-recursive] Error 1

make[4]: Leaving directory `/home/wangwei1/vlc-0.9.4/modules/gui'

make[3]: *** [all] Error 2

make[3]: Leaving directory `/home/wangwei1/vlc-0.9.4/modules/gui'

make[2]: *** [all-recursive] Error 1

make[2]: Leaving directory `/home/wangwei1/vlc-0.9.4/modules'

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory `/home/wangwei1/vlc-0.9.4'

make: *** [all] Error 2

将刚才解压得到的qt4目录下面的lib/libqjpeg.a拷贝到/usr/win32/lib中。进入到qt4-4.4.1-win32-bin目录中执行:

cp lib/libqjpeg.a /usr/win32/lib

再进入到vlc-0.9.4中执行make,应该就没有错误了。然后可以按照7.打包了。

windows平台下vlc编译之四:精简vlc

vlc太大,组件太多,我们根据业务需求,能用的仅仅是几个组件而已,其他不用的我们就该去掉。这里Jeremiah根据自己的情况精简了vlc,vlc-0.9.4最后得到的安装文件3518KB,cab文件3520KB;vlc-0.8.6i的安装文件3087KB,cab文件3264KB。相对于原来几十兆来说,小了N多。

1. 业务需求。

Jeremiah所用的业务需求是:(1)播放本地avi文件。(2)播放ts封装的rtp流。(3)播放rtsp流。

2. vlc-0.9.4的精简

脚本(见附件)如下:

PATH=/usr/win32/bin:$PATH

PKG_CONFIG_LIBDIR=/usr/win32/lib/pkgconfig

CPPFLAGS="-I/usr/win32/include -I/usr/win32/include/ebml"

LDFLAGS=-L/usr/win32/lib

CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin"

./configure

--host=i686-pc-mingw32

--disable-gtk

--enable-avcodec

--enable-avformat

--enable-libmpeg2

--enable-live555 --with-live555-tree=/usr/win32/

--disable-nls

--disable-skins2

--disable-qt4

--disable-macosx-defaults

--disable-hal

--disable-dbus

--disable-dbus-control

--disable-telepathy

--disable-mmx

--disable-sse

--disable-altivec

--disable-coverage

--disable-release

--enable-sout

--disable-lua

--disable-httpd

--disable-libproxy

--disable-audioscrobbler

--disable-taglib

--disable-dvdnav

--disable-dshow

--disable-bda

--disable-smb

--disable-dvbpsi

--disable-v4l2

--disable-libcdio

--disable-libcddb

--disable-vcdx

--disable-cdda

--disable-vcd

--disable-dvb

--disable-screen

--disable-ogg

--disable-mkv

--disable-mod

--disable-mpc

--disable-gme

--disable-mad

--disable-id3tag

--disable-swscale

--disable-imgresample

--disable-faad

--disable-real

--disable-realrtsp

--disable-libtar

--disable-a52

--disable-dca

--disable-flac

--disable-vorbis

--disable-tremor

--disable-speex

--disable-tarkin

--disable-theora

--disable-dirac

--disable-schroedinger

--disable-png

--disable-zvbi

--disable-telx

--disable-cmml

--disable-kate

--disable-x11

--disable-xvideo

--disable-glx

--disable-xinerama

--disable-opengl

--disable-sdl

--disable-sdl-image

--disable-freetype

--disable-fribidi

--disable-fontconfig

--disable-libxml2

--disable-pulse

--disable-alsa

--disable-upnp

--disable-ncurses

--disable-visual

--disable-atmo

--disable-bonjour

--disable-libgcrypt

--disable-gnutls

--disable-remoteosd

--enable-shared=yes

--enable-x264

--enable-vlc

--enable-activex

脚本请参考:

./configure -h

以及:[url]/blog/post/2007/12/14/Configure-step-in-VLC-building[/url]

make通过只后,删除locale文件夹,这个文件夹是用本地语言作界面的。删除plugins中的200多dll,只保留:

libaccess_file_

libaout_directx_

libasf_

libaudio_format_

libavcodec_

libavformat_

libavi_

libconverter_fixed_

libconverter_float_

libhotkeys_

liblive555_

libmpeg_audio_

libpacketizer_copy_

libpacketizer_h264_

libpacketizer_vc1_

libplaylist_

librc_

librtp_

libsubtitle_

libtrivial_channel_mixer_

libtrivial_mixer_

libts_

libugly_resampler_

libvout_directx_

libwaveout_

再用.nsi脚本编译,修改n个错误之后就生成了较小的安装文件了。

3. 精简vlc-0.8.6i

脚本(见附件)如下:

PKG_CONFIG_PATH=/usr/win32/lib/pkgconfig

CPPFLAGS="-I/usr/win32/include -I/usr/win32/include/ebml"

LDFLAGS=-L/usr/win32/lib

CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin"

./configure

--with-freetype-config-path=/usr/win32/bin

--with-fribidi-config-path=/usr/win32/bin

--enable-ffmpeg --with-ffmpeg-mp3lame --with-ffmpeg-faac

--with-ffmpeg-zlib

--enable-live555 --with-live555-tree=/usr/win32/

--disable-nls

--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-dts

--disable-real

--disable-xml

--disable-x264

--enable-sout

--enable-activex

--enable-shared-libvlc

--enable-release

make之后删除http,locale,skins,osdmenu文件夹,plugins保留:

libaccess_file_

libaccess_udp_

libaout_directx_

libasf_

libaudio_format_

libavi_

libffmpeg_

libfloat32tos16_

libfloat32_mixer_

libipv4_

libmpeg_audio_

libmpgatofixed32_

librc_

libs16tofixed32_

libs16tofloat32swab_

libs16tofloat32_

libs8tofloat32_

libsubtitle_

libtrivial_channel_mixer_

libtrivial_mixer_

libts_

libu8tofixed32_

libu8tofloat32_

libugly_resampler_

libvobsub_

libvout_directx_

libwaveout_

使用.nsi脚本来做安装文件就ok了。

windows平台下vlc编译之五:vlc-0.9.6的编译

前两天Jeremiah偶尔用最新的Cygwin编译了下vlc-0.9.6,好像修改一个错误就编译通过了,很简单,在这大体写一下。

1. 安装最新的Cygwin,图片见附件()。(如何卸载Cygwin或者使用双Cygwin,请看下一篇日志:《Cygwin的卸载与新旧双版本运行》)

Cygwin下载:[url]/[/url]。选择通过网络安装。

强烈建议通过Jeremiah提供的本地文件安装:

Cygwin-new(20081208)在我的公共邮箱提供了下载,具体下载方式为:

1). 登录

2). 用户名:jeremiah_vlc

3). 密码:发邮件给我(**********************),我会告知。

4). 在“我的文件夹”的“Jeremiah_VLC相关资源”有所有资料的超大附件连接。

Archive

unzip

zip

Devel

autoconf

automake

binutils

cvs

gcc

gcc-core

gcc-g++

gcc-mingw

gcc-mingw-core

gcc-mingw-g++

gdb

gettext

gettext-devel

git

libiconv

libgcrypt-devel

libtool

make

mingw-runtime

nasm

patchutils

pkg-config

subversion

Editor

vim

Libs

expat

libgcrypt

Web

curl

wget

2. 下载源码和库:

源码:[url]/pub/videolan/vlc/0.9.6/2[/url]

库:/downfile/2/7691f26e0285d472e5642666e3c6cbf94d2bd21d7032ea01

3. 解压源文件到e:/cygwin/home/yourname/。解压库到e:/cygwin/。

删除E:/cygwin/usr/win32/bin/的moc,rcc,uic。

修改vlc-0.9.6/,

修改

AM_GNU_GETTEXT_VERSION([0.17])

AM_GNU_GETTEXT_VERSION([0.15])

或运行

sed -i 's/AM_GNU_GETTEXT_VERSION(0.17)/AM_GNU_GETTEXT_VERSION(0.15)/g'

4. 保存脚本(见附件)。

PATH=/usr/win32/bin:$PATH

PKG_CONFIG_LIBDIR=/usr/win32/lib/pkgconfig

CPPFLAGS="-I/usr/win32/include -I/usr/win32/include/ebml"

LDFLAGS=-L/usr/win32/lib

CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin"

./configure

--host=i686-pc-mingw32

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

--enable-avcodec --enable-avformat --enable-swscale

--enable-faad --enable-flac --enable-theora

--enable-live555 --with-live555-tree=/usr/win32/

--enable-caca --with-caca-config-path=/usr/win32/bin

--with-xml2-config-path=/usr/win32/bin

--with-dvdnav-config-path=/usr/win32/bin

--disable-cddax --disable-vcdx --enable-goom

--enable-twolame --enable-dvdread

--enable-debug--enable-dca

--disable-mkv --disable-taglib

5. 运行./bootstrap && dos2unix ./ && ./ && make。

6. 出错:

_la-vlm.o input/.libs/libvlccore_la-vlmshell.o misc/.libs/libvlccore_la-revision

.o || /usr/bin/sed -e '/^[BCDGRS][ ]/s/.*[ ]([^ ]*)/1 DATA/;/^.*[ ]__nm__

/s/^.*[ ]__nm__([^ ]*)[ ][^ ]*/1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //' | sort |

uniq > .libs/'

make[4]: *** [] Error 1

make[4]: Leaving directory `/home/wangwei1/vlc-0.9.6/src'

make[3]: *** [all-recursive] Error 1

make[3]: Leaving directory `/home/wangwei1/vlc-0.9.6/src'

make[2]: *** [all] Error 2

make[2]: Leaving directory `/home/wangwei1/vlc-0.9.6/src'

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory `/home/wangwei1/vlc-0.9.6'

make: *** [all] Error 2

打开libtool第144行:

修改

global_symbol_pipe=""

global_symbol_pipe="sed -n -e 's/^.*[ ]([ABCDGIRSTW][ABCDGIRSTW]*)[ ][]*()([_A-Za-z][_A-Za-z0-9]*)$/123 3/p'"

继续make && make package-win32-base。

百度空间中的VLC研究:/liuxu0909/blog/category/Vlc

海狗哥:/539865/178696 //vlc-1.0.0的编译

/539865/339181 //vlc1.1.0编译

Fedora12 下源码编译vlc-1.1.5成功, 附操作说明:

/jianxi258/archive/2010/11/21/

V4L2的开发流程

一般操作流程(视频设备):

1. 打开设备文件。 int fd=open("/dev/video0",O_RDWR);

2. 取得设备的capability,看看设备具有什么功能,比如是否具有视频输入,或者音频输入输出等。VIDIOC_QUERYCAP,struct v4l2_capability

3. 选择视频输入,一个视频设备可以有多个视频输入。VIDIOC_S_INPUT,struct v4l2_input

4. 设置视频的制式和帧格式,制式包括PAL,NTSC,帧的格式个包括宽度和高度等。

VIDIOC_S_STD,VIDIOC_S_FMT,struct v4l2_std_id,struct v4l2_format

5. 向驱动申请帧缓冲,一般不超过5个。struct v4l2_requestbuffers

6. 将申请到的帧缓冲映射到用户空间,这样就可以直接操作采集到的帧了,而不必去复制。mmap

7. 将申请到的帧缓冲全部入队列,以便存放采集到的数据.VIDIOC_QBUF,struct v4l2_buffer

8. 开始视频的采集。VIDIOC_STREAMON

9. 出队列以取得已采集数据的帧缓冲,取得原始采集数据。VIDIOC_DQBUF

10. 将缓冲重新入队列尾,这样可以循环采集。VIDIOC_QBUF

11. 停止视频的采集。VIDIOC_STREAMOFF

12. 关闭视频设备。close(fd);

常用的结构体(参见/usr/include/linux/videodev2.h):

struct v4l2_requestbuffers reqbufs;//向驱动申请帧缓冲的请求,里面包含申请的个数

struct v4l2_capability cap;//这个设备的功能,比如是否是视频输入设备

struct v4l2_input input; //视频输入

struct v4l2_standard std;//视频的制式,比如PAL,NTSC

struct v4l2_format fmt;//帧的格式,比如宽度,高度等

struct v4l2_buffer buf;//代表驱动中的一帧

v4l2_std_id stdid;//视频制式,例如:V4L2_STD_PAL_B

struct v4l2_queryctrl query;//某一类型的控制

struct v4l2_control control;//具体控制的值


本文标签: 视频 编译 需要 模块 文件