mingw编译vlc

1,前言:

根据INSTALL.WIN32的描述,作者推荐大家在gnu/linux系统上,使用mingw32跨平台编译win32版本的vlc.exe(以及附属产品)

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.

本文安装的os环境是win7,试试看吧,可能也很多问题吧。

另外,mingw/minsys没有再带gettext工具,可能无法编译多语言支持,(TODO: 给minsys装上gettext工具)

mingw-get.exe install mingw32-gettext

2,下载安装mingw和minsys

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


3,下载vlc的源代码


http://download.videolan.org/pub/videolan/vlc/1.0.2/


tar xvjpf vlc-1.0.2.tar.bz2 -C /h

解压到一个位置,本文的位置在/h,一个内存盘



4,下载预编译的第三方contrib库依赖

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


5,检查pkg-config工具

http://jaist.dl.sourceforge.net/project/pkgconfiglite/0.28-1/pkg-config-lite-0.28-1_bin-win32.zip

解压,复制lib和share文件夹到/usr更目录,覆盖


6,配置

如果,出现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



7, 编译

$ PATH=/usr/win32/bin:$PATH make -j


如果make -j 失败,试试make


8, FAQ

.

1) 未定义WSA_QOS_EUNKNOWNPSOBJ

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


2) moc 不能执行

/usr/win32/bin 俩面有3个文件 moc.exe rcc.exe uic.exe 另外还有3个不带.exe的文件,minsys会无法区分,建议把不带.exe的三个文件删掉,或者重命名成.elf的,


3) input_slider.cpp构造中调用构造

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.


4) vtable-thunks检查

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


6.1) modules/codec/png.c 找不到 png_infopp_NULL

          手动添加定义 #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;

6.3)  还是x264.c报错,x264_nal_encode找不到,

/* 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界面,应该可以作为转码服务器使用吧。

9,打包

目标地址下/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

mingw编译vlc_第1张图片

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?

mingw编译vlc_第2张图片


10, 调试

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



=====================================================================================


11,截图:

mingw编译vlc_第3张图片

参考:

vlc官方模块编写指南:
http://wiki.videolan.org/Documentation:Hacker%27s_Guide/How_To_Write_a_Module

vlc官方filter指南:
http://wiki.videolan.org/Hacker_Guide/Video_Filters

vlc编译和结构分析

http://blog.csdn.net/szu030606/article/details/7210758


简单的模块编写讨论

http://forum.videolan.org/viewtopic.php?f=32&t=57085


你可能感兴趣的:(MinGW,VLC)