Building VLC from the source code ================================= If you want to build VLC from sources, you can do it in several ways: - On GNU/Linux, using the mingw32 cross-compiler. This method is preferred over all the others. - natively on Windows, using MSYS+MINGW (www.mingw.org) (MSYS is a minimal build environment to compile Unixish projects under windoze. It provides all the common Unix tools like sh, gmake...) Please note that the gettext utilities are not included in the default MSYS/MINGW packages so you won't be able to build VLC with i18n support. UNSUPPORTED METHODS ------------------- - natively on Windows, using cygwin (www.cygwin.com) with or without the POSIX emulation layer. This is the preferred way to compile vlc if you want to do it on Windows. Read http://wiki.videolan.org/Win32CompileCygwinNew to have a complete HOWTO - natively on Windows, using Microsoft Visual Studio. This will not work.
http://nchc.dl.sourceforge.net/project/mingw/Installer/mingw-get-inst/mingw-get-inst-20120426/mingw-get-inst-20120426.exe
选择以下组件:
C Compiler,
C++ Compiler,
MSYS basic system,
MinGW developer toolkit
打开MSYS终端
D:\MinGW\msys\1.0\msys.bat
http://download.videolan.org/pub/videolan/vlc/1.0.2/
tar xvjpf vlc-1.0.2.tar.bz2 -C /h
解压到一个位置,本文的位置在/h,一个内存盘
http://download.videolan.org/pub/videolan/vlc/1.0.2/contribs-1.0.2-gcc-4.2.1-sjlj-runtime-3.15.2-only.tar.bz2
---- or ------
http://people.videolan.org/~jb/Contribs/contrib-20111017-win32-bin-gcc-4.4.4-runtime-3.17-only.tar.bz2
http://jaist.dl.sourceforge.net/project/pkgconfiglite/0.28-1/pkg-config-lite-0.28-1_bin-win32.zip
解压,复制lib和share文件夹到/usr更目录,覆盖
如果,出现libavcodec找不到的错误,试试吧vlc整个目录删除,重新解压再configure。
PATH=/usr/win32/bin:$PATH \ PKG_CONFIG_PATH="/usr/win32/lib/pkgconfig" \ CPPFLAGS="-I/usr/win32/include -I/usr/win32/include/ebml" \ CXXFLAGS="-fpermissive" \ LDFLAGS="-L/usr/win32/lib" \ ./configure \ --with-contrib=/usr/win32 \ --enable-nls \ --enable-sdl \ --enable-faad \ --enable-flac \ --enable-theora \ --enable-live555 \ --enable-caca \ --enable-goom \ --enable-fb \ --enable-twolame \ --enable-dvdread \ --enable-debug \ --disable-cddax \ --disable-vcdx \ --disable-fluidsynth \ --disable-mkv \ --disable-taglib \ --prefix=`pwd`/dest
$ PATH=/usr/win32/bin:$PATH make -j
如果make -j 失败,试试make
/***************************************************************************** * winsock.c: POSIX replacements for Winsock ***************************************************************************** * Copyright © 2006-2008 Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <vlc_common.h> #include <errno.h> #include <vlc_network.h> #ifndef WSA_QOS_EUNKNOWNPSOBJ #define WSA_QOS_EUNKNOWNPSOBJ 11024L #endif typedef struct { int code; const char *msg; } wsaerrmsg_t;
/usr/win32/bin 俩面有3个文件 moc.exe rcc.exe uic.exe 另外还有3个不带.exe的文件,minsys会无法区分,建议把不带.exe的三个文件删掉,或者重命名成.elf的,
vlc-1.0.2\modules\gui\qt4\util\input_slider.cpp 构造函数调用构造函数,使用-fpermissive修改.
-fpermissive Downgrade some diagnostics about nonconformant code from errors to warnings. Thus, using -fpermissive will allow some nonconforming code to compile.
dnl Check for fvtable-thunks support for mingw32 if test "${SYS}" = "mingw32" -a "${CXX}" != "" then AC_LANG_PUSH(C++) AC_CACHE_CHECK([if \$CXX accepts -fvtable-thunks], [ac_cv_cxx_fvtable_thunks], [CXXFLAGS="${CXXFLAGS_save} -Wall -Werror -fvtable-thunks" AC_TRY_COMPILE([],,ac_cv_cxx_fvtable_thunks=yes, ac_cv_cxx_fvtable_thunks=no)]) if test "${ac_cv_cxx_fvtable_thunks}" = "yes"; then CXXFLAGS_mingw32_special="-fvtable-thunks" fi CXXFLAGS_save="${CXXFLAGS_save} ${CXXFLAGS_mingw32_special}"; CXXFLAGS="${CXXFLAGS_save}" AC_LANG_POP(C++) fi
5) win7上用msys环境执行bootstrap失败,很可能是autotool工具的版本问题,或者configure.ac的写作不规范,改了几处的quote,但是含有AS_IF等找不到的情况,有待研究。
6) linux上倒是可以很顺利的bootstrap来生成Makfile.am等工作,但是linux native编译可能存在的问题:
./configure --with-contrib=/usr/win32 --enable-nls --enable-sdl --disable-faad --enable-flac --enable-theora --enable-live555 --enable-caca --enable-goom --enable-fb --disable-twolame --disable-dvdread --enable-debug --disable-cddax --disable-vcdx --disable-fluidsynth --disable-mkv --disable-taglib --disable-glx --disable-qte --disable-skins2 --disable-fribidi --prefix=/root/harrywu/temp/vlc-1.0.2/dest
手动添加定义 #define png_infopp_NULL (png_infopp) NULL
6.2)modules/codec/x264.c
x264.c:995: error: ‘x264_param_t’ has no member named ‘b_bframe_pyramid’https://trac.macports.org/ticket/24230
发现在x264.h的213行,有这个定义
typedef struct x264_param_t { // ... int i_bframe_pyramid; /* Keep some B-frames as references: 0=off, 1=strict hierarchical, 2=normal */ // ...修改 modules/codec/x264.c : 995
b_bframe_pyramid -> i_bframe_pyramid;
/* x264_nal_encode: * encode a nal into a buffer, setting the size. * if b_annexeb then a long synch work is added * XXX: it currently doesn't check for overflow */ int x264_nal_encode( void *, int *, int b_annexeb, x264_nal_t *nal );在x264.c头部,声明一下这个函数, libx263.a里面应该有这个函数吧。
OK, linux 本地也编译过了,但是没有qt4界面,应该可以作为转码服务器使用吧。
目标地址下/bin/vlc.exe是不能直接运行的,需要打包
在打包之前,确保MSYS已经安装了zip工具
mingw-get.exe install msys-zip
make package-win32-zip
可以在当前目录下生成一个vlc-{version}.zip, 解压这个zip,运行里面的vlc.exe可以播放。
不过依然有个小问题,不能直接打开vlc的gui界面,有待调查,可以以 vlc.exe your_video_file_name.avi 播放文件,提示vlc -I qt
2013.3.20
进展一:如果实在migw的命令行下执行./vlc.exe可以打开gui界面,但是直接在win7里面双击就不行,可能是依赖某个msys的环境变量导致的。
进展二:如果在msys里面执行,用windbg查看,vlc加载了
ModLoad: 6e940000 6e964000 d:\MinGW\bin\libgcc_s_dw2-1.dll ModLoad: 6fc40000 6fd36000 d:\MinGW\bin\libstdc++-6.dll
ModLoad: 031e0000 03a5c000 c:\vlc-1.0.2\plugins\libqt4_plugin.dll
可能是qt4模块依赖于libgcc_s_dw2-1.dll & libstdc++-6.dll,
如果在mingw打开,可以通过/bin(d:\mingw\bin)找到这2个dll。
如果在win7直接打开,这2个dll的路径未知。
所以,把这2个dll复制到vlc的安装目录下,就可以打开GUI界面了。
进展三:调查libqt4_plugin.dll是否依赖libgcc_s_dw2-1.dll & libstdc++-6.dll?
1,被调试程序的Ctrl_C处理
./debugbreak.exe pid_of_vlc_exe
2,符号表设置
复制生成的所有.dll.dbg文件到dll所在的当前目录(.; ./plugins),或者,通过以下命令指定符号表位置,如果build-id和crc校验成功,mingw的gdb会自动加载这些符号表。
set debug-file-directory H:/symbols-1.0.2
3,源文件目录设置
gdb --pid pid_of_vlc_exe --directory source_dir
Breakpoint 1, vlc_entry__main (p_module=0x6237e8) at libvlc-module.c:1510 1510 vlc_module_begin () (gdb) bt #0 vlc_entry__main (p_module=0x6237e8) at libvlc-module.c:1510 #1 0x6a5b90aa in AllocateBuiltinModule (p_this=0x622c6c, pf_entry=0x6a544db8 <vlc_entry__main>) at modules/modules.c:1352 #2 0x6a5b7391 in __module_InitBank (p_this=0x622c6c) at modules/modules.c:140 #3 0x6a541663 in libvlc_InternalInit (p_libvlc=0x622c6c, i_argc=1, ppsz_argv=0x28fda0) at libvlc.c:330 #4 0x6a3014ef in libvlc_new (argc=0, argv=0x28fe24, p_e=0x28fe5c) at control/core.c:129 #5 0x004015b9 in WinMain@16 (hInstance=0x400000, hPrevInstance=0x0, lpCmdLine=0x4b3bf5 "", nCmdShow=10) at winvlc.c:163 #6 0x00402356 in main (argc=4974184, argv=0x4be5f8, __p__environ=0) at ../mingw/main.c:73 (gdb)可以看到调用链vlc.exe -> libvlc -> libvlccore
libvlccore使用装载一个builtin模块main。
vlc_entry__main是main模块的入口。
libvlc_InternalInit()是一个很长的函数,主要是加载了modules的列表,只是遍历所有plugins目录,加载模块,获取模块的描述信息(cap,score,callback等),最后得到一个module的列表。
后面__module_need()只要从里面搜索就可以了。
播放模块(vout)打开时候的栈
Breakpoint 1, OpenVideo (p_this=0x5cc101c) at direct3d.c:161 161 vout_thread_t * p_vout = (vout_thread_t *)p_this; (gdb) bt #0 OpenVideo (p_this=0x5cc101c) at direct3d.c:161 #1 0x6d7813e6 in OpenVideoVista (obj=0x5cc101c) at direct3d.c:111 #2 0x6a5b7e7f in __module_need (p_this=0x5cc101c, psz_capability=0x6a61b956 "video output", psz_name=0x5e033d0 "", b_strict=false) at modules/modules.c:581 #3 0x6a5908bc in __vout_Create (p_parent=0x5ca3c5c, p_fmt=0x5cdf77c) at video_output/video_output.c:490 #4 0x6a58fff2 in __vout_Request (p_this=0x5ca3c5c, p_vout=0x0, p_fmt=0x5cdf77c) at video_output/video_output.c:286 #5 0x6a58639b in RequestVout (p_resource=0x5c521e0, p_vout=0x0, p_fmt=0x5cdf77c, b_recycle=true) at input/resource.c:240 #6 0x6a586b08 in input_resource_RequestVout (p_resource=0x5c521e0, p_vout=0x0, p_fmt=0x5cdf77c, b_recycle=true) at input/resource.c:454 #7 0x6a56e7aa in vout_new_buffer (p_dec=0x5cdf5c4) at input/decoder.c:2328 #8 0x6a569e74 in decoder_NewPicture (p_decoder=0x5cdf5c4) at input/decoder.c:185 #9 0x66742c57 in GetNewPicture (p_dec=0x5cdf5c4) at libmpeg2.c:655 #10 0x66743303 in DpbNewPicture (p_dec=0x5cdf5c4) at libmpeg2.c:827 #11 0x66742014 in DecodeBlock (p_dec=0x5cdf5c4, pp_block=0x9dffe44) at libmpeg2.c:271 #12 0x6a56cc36 in DecoderDecodeVideo (p_dec=0x5cdf5c4, p_block=0x5be6358) at input/decoder.c:1458 #13 0x6a56d6c4 in DecoderProcessVideo (p_dec=0x5cdf5c4, p_block=0x5be6358, b_flush=false) at input/decoder.c:1821 #14 0x6a56dc40 in DecoderProcess (p_dec=0x5cdf5c4, p_block=0x5be6358) at input/decoder.c:1993 #15 0x6a56b5c3 in DecoderThread (p_this=0x5cdf5c4) at input/decoder.c:887 #16 0x6a5bfb2c in thread_entry (data=0x5cb03b0) at misc/threads.c:1093 #17 0x6a5bf7d5 in vlc_entry (data=0x5b8a970) at misc/threads.c:741 #18 0x766f1287 in msvcrt!_itow_s () from C:\Windows\syswow64\msvcrt.dll #19 0x766f1328 in msvcrt!_endthreadex () from C:\Windows\syswow64\msvcrt.dll #20 0x74ee33aa in KERNEL32!BaseCleanupAppcompatCacheSupport () from C:\Windows\syswow64\kernel32.dll #21 0x09dfffd4 in ?? () #22 0x774e9ef2 in ntdll!RtlpNtSetValueKey () from C:\Windows\system32\ntdll.dll #23 0x05cb3818 in ?? () #24 0x774e9ec5 in ntdll!RtlpNtSetValueKey () from C:\Windows\system32\ntdll.dll #25 0x766f12e5 in msvcrt!_endthreadex () from C:\Windows\syswow64\msvcrt.dll #26 0x00000000 in ?? () (gdb)
可以看出decoder模块要输出的时候,发现没有vout结构,于是在input/resource.c : 2328 处请求创建vout:
input_resource_RequestVout(...)从这里可以得到一个简单的方法查看模块的加载过程,break 一下某个模块的入口回调,等断点命中,查看堆栈。
另外:vlc里面,每一个module的使用者都有一个相应的结构体描述:
decoder module -> decoder_t
e.g.: decoder_t里面的解码回调函数来自decoder module里面的静态函数。
video output module-> vout_thread_t
e.g.: vout_thread_t里面的显示函数来自video output module里面的静态函数。
在libvlc-module.c中:
// Pretend we are a builtin module #define MODULE_NAME main #define MODULE_PATH main #define __BUILTIN__然后才包含<vlc_plugin.h>,而且这个文件的编译没有加__PLUGIN__编译,所以这个模块的入口是vlc_entry__main。
否则,就和其他外置模块类似了,使用这样的模块入口 vlc_entry__1_0_0e
# define MODULE_SYMBOL 1_0_0e
=====================================================================================
http://blog.csdn.net/szu030606/article/details/7210758
简单的模块编写讨论
http://forum.videolan.org/viewtopic.php?f=32&t=57085