本文记录FFmpeg的Configure脚本的源代码。Configure一方面用于检测FFmpeg的编译环境,另一方面根据用户配置的选项生成config.mak,config.h文件(可能还有config.asm),提供给Makefile使用。由于FFmpeg的configure脚本很复杂(一个4000-5000行的Shell脚本),难以逐行细致的分析,因此本文简单梳理一下它的结构。 Configure的整体流程可以分成以下几步:
需要注意的是,“enable avcodec”,“enable avformat”,“enable avutil”等中的enable()本身是一个函数。enable()的定义如下。
在这里需要注意,取出opt的值一般都是“--extra-ldflags=XXX”的形式,通过“${opt#*=}”截取获得“=”号后面的内容作为optval,对于“--extra-ldflags=XXX”来说,optval取值为“XXX”。 然后根据opt种类的不同,以及optval取值的不同,分别作不同的处理。
其中涉及到一个函数die_license_disabled(),它的定义如下所示。
从定义可以看出,die_license_disabled()首先会看第1个参数(对应“gpl”,“nonfree”)对应的组件是否enable,如果已经enable,则正常运行完函数;如果没有enable,则会检查第2个参数(对应“libx264”,“libfaac”)是否enable,如果第2个参数enable了,就会报错退出。 下面简单举例下面几个函数:
check_func()的定义如下所示。
PS1:Configure的日志位于config.log文件中。查看该文件有助于分析Configure的过程。
PS2:使用“sh -x script_name.sh”可以调试Shell脚本。
Configure文件的整体流程
Configure文件的整体流程如下所示。Set Default Value:设置各个变量默认值;下文简单梳理一下这些步骤。
Parse Options:解析输入的选项;
Check Compiler:检查编译器;
die_license_disabled():检查GPL等协议的设置情况;
Check:检查编译环境(数学函数,第三方类库等);
Echo info:控制台上打印配置信息;
Write basic info:向config.mak中写入一些基本信息;
print_config():向config.h、config.mak、config.asm中写入所有配置信息;
print_enabled():向config.mak写入所有enabled的组件信息;
pkgconfig_generate():向libavXXX/libavXXX.pc中写入pkgconfig信息(XXX代表avcodec,avformat等);
Set Default Value
Set Default Value部分设置一些Configure的默认值。例如下面的代码。# 默认参数 default parameters # 日志 logfile="config.log" # 安装路径 installation paths prefix_default="/usr/local" bindir_default='${prefix}/bin' datadir_default='${prefix}/share/ffmpeg' incdir_default='${prefix}/include' libdir_default='${prefix}/lib' mandir_default='${prefix}/share/man' shlibdir_default="$libdir_default" postproc_version_default="current" # 工具链 toolchain ar_default="ar" cc_default="gcc" cxx_default="g++" cc_version="unknown" host_cc_default="gcc" install="install" ln_s="ln -sf" nm_default="nm" objformat="elf" pkg_config_default=pkg-config ranlib="ranlib" strip_default="strip" yasmexe_default="yasm" nm_opts='-g' nogas=":" # 机器 machine arch_default=$(uname -m) cpu="generic" # 操作系统 OS target_os_default=$(tolower $(uname -s)) host_os=$target_os_default # alternative libpostproc version ALT_PP_VER_MAJOR=51 ALT_PP_VER_MINOR=2 ALT_PP_VER_MICRO=101 ALT_PP_VER=$ALT_PP_VER_MAJOR.$ALT_PP_VER_MINOR.$ALT_PP_VER_MICRO # 选项 configurable options # PROGRAM_LIST内容是 ffplay ffprobe ffserver ffmpeg enable $PROGRAM_LIST enable avcodec enable avdevice enable avfilter enable avformat enable avutil enable postproc enable stripping enable swresample enable swscale enable asm enable debug enable doc enable fastdiv enable network enable optimizations enable safe_bitstream_reader enable static enable swscale_alpha # 编译选项 build settings SHFLAGS='-shared -Wl,-soname,$$(@F)' FFSERVERLDFLAGS=-Wl,-E # 前缀后缀 LIBPREF="lib" LIBSUF=".a" FULLNAME='$(NAME)$(BUILDSUF)' # 名称 LIBNAME='$(LIBPREF)$(FULLNAME)$(LIBSUF)' # 动态库前缀后缀 SLIBPREF="lib" SLIBSUF=".so" # 名称 SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)' SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)' SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)' AS_O='-o $@' CC_O='-o $@' CXX_O='-o $@' host_cflags='-D_ISOC99_SOURCE -O3 -g' host_libs='-lm' target_path='$(CURDIR)'
需要注意的是,“enable avcodec”,“enable avformat”,“enable avutil”等中的enable()本身是一个函数。enable()的定义如下。
#把所有输入参数的值设置为"yes" enable(){ set_all yes $* }可以看出enable()调用了set_all()函数。并且将第1个参数设置为“yes”,并且将调用enable()时候的参数传递给set_all()。set_all()函数的定义如下所示。
#第一个参数为值,后面的参数为变量 set_all(){ value=$1 shift for var in $*; do eval $var=$value done }可以看出set_all()将传入的参数全部进行赋值。特定于enable()函数来说,就是将所有的输入变量赋值为“yes”。由此可见,“enable avcodec”实际上相当于执行了:
avcodec=”yes”
Parse Options
Parse Options部分用于解析Configure的附加参数。该部分的代码如下所示。#注意:opt不是参数列表(实际上也没有看见opt变量的定义) #原因是处在for循环中,当你没有为in指定列表时,for会默认取命令行参数列表。 #因此“opt”这个名字实际上是可以随便取的 for opt do # "#"用于去除特定字符前面的字符串 # optval内容为opt去掉"="以及其前面字符串之后的内容 optval="${opt#*=}" case "$opt" in # 不同的选项 --extra-ldflags=*) add_ldflags $optval ;; --extra-libs=*) add_extralibs $optval ;; --disable-devices) disable $INDEV_LIST $OUTDEV_LIST ;; --enable-debug=*) debuglevel="$optval" ;; --disable-everything) map 'eval unset ${$(toupper ${v%s})_LIST}' $COMPONENT_LIST ;; --enable-*=*|--disable-*=*) eval $(echo "${opt%%=*}" | sed 's/--/action=/;s/-/ thing=/') is_in "${thing}s" $COMPONENT_LIST || die_unknown "$opt" eval list=$$(toupper $thing)_LIST name=$(echo "${optval}" | sed "s/,/_${thing}|/g")_${thing} $action $(filter "$name" $list) ;; --enable-?*|--disable-?*) eval $(echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g') if is_in $option $COMPONENT_LIST; then test $action = disable && action=unset eval $action $$(toupper ${option%s})_LIST elif is_in $option $CMDLINE_SELECT; then $action $option else die_unknown $opt fi ;; --list-*) NAME="${opt#--list-}" is_in $NAME $COMPONENT_LIST || die_unknown $opt NAME=${NAME%s} eval show_list $NAME $$(toupper $NAME)_LIST ;; --help|-h) show_help ;; *) #% 就是从右边开始删除符合条件的字符串(符合条件的最短字符串) #%%是删除符合条件的最长的字符串 #删除“=”右边的内容 optname="${opt%%=*}" #删除左边的“--” optname="${optname#--}" optname=$(echo "$optname" | sed 's/-/_/g') #看看是否在opt列表中,不在的话就会返回错误 if is_in $optname $CMDLINE_SET; then eval $optname='$optval' elif is_in $optname $CMDLINE_APPEND; then append $optname "$optval" else die_unknown $opt fi ;; esac done
在这里需要注意,取出opt的值一般都是“--extra-ldflags=XXX”的形式,通过“${opt#*=}”截取获得“=”号后面的内容作为optval,对于“--extra-ldflags=XXX”来说,optval取值为“XXX”。 然后根据opt种类的不同,以及optval取值的不同,分别作不同的处理。
Check Compiler
Check Compiler用于检查编译器。这部分代码还没有细看,暂时不做分析。die_license_disabled()
die_license_disabled()用于检查是否指定了特定了License。像libx264、libfaac这些第三方类库,都需要指定特定的License才可以使用(例如libfaac必须指定nonfree)。开启这些第三方类库后如果没有指定License,Configure会立刻退出。这部分代码如下所示。#检查License #GPL die_license_disabled gpl libcdio die_license_disabled gpl libx264 die_license_disabled gpl libxavs die_license_disabled gpl libxvid die_license_disabled gpl x11grab #nonfree die_license_disabled nonfree libaacplus die_license_disabled nonfree libfaac die_license_disabled nonfree openssl #Version3 die_license_disabled version3 libopencore_amrnb die_license_disabled version3 libopencore_amrwb die_license_disabled version3 libvo_aacenc die_license_disabled version3 libvo_amrwbenc
其中涉及到一个函数die_license_disabled(),它的定义如下所示。
#不符合License则立刻结束 die_license_disabled() { enabled $1 || { enabled $2 && die "$2 is $1 and --enable-$1 is not specified."; } }
从定义可以看出,die_license_disabled()首先会看第1个参数(对应“gpl”,“nonfree”)对应的组件是否enable,如果已经enable,则正常运行完函数;如果没有enable,则会检查第2个参数(对应“libx264”,“libfaac”)是否enable,如果第2个参数enable了,就会报错退出。
Check
Check部分是Configure中最重要的部分。该部分用于检查编译环境(例如数学函数,第三方类库等)。这一部分涉及到很多的函数。包括check_cflags()、check_struct()、require()、check_lib()、check_header()、check_func()、check_mathfunc()等等。这些函数之间的调用关系如下图所示。check_func():用于检查函数。下面详细看看这几个函数。
check_header():用于检查头文件。
check_func_headers():用于同时检查头文件和函数。
check_mathfunc():用于检查数学类函数。
require():检查第三方类库。
check_cflags ():用于检查编译器的cflags标志参数。
check_func()
check_func()用于检查函数。它的输入参数一个函数名。Configure中与check_func()有关的代码如下所示。check_func isatty check_func localtime_r check_func ${malloc_prefix}memalign && enable memalign check_func mkstemp check_func mmap check_func ${malloc_prefix}posix_memalign && enable posix_memalign check_func setrlimit check_func strerror_r check_func strptime check_func sched_getaffinity check_func sysconf check_func sysctl
check_func()的定义如下所示。
check_func(){ log check_func "$@" func=$1 shift disable $func check_ld "cc" "$@" <
从check_func()的定义可以看出,该函数首先将输入的第1个参数赋值给func,然后生成一个下述内容的C语言文件。extern int $func(); int main(void){ $func(); }
最后调用check_ld()完成编译测试。check_ld()的定义如下所示。check_ld(){ log check_ld "$@" type=$1 shift 1 flags='' libs='' for f; do test "${f}" = "${f#-l}" && flags="$flags $f" || libs="$libs $f" done check_$type $($filter_cflags $flags) || return check_cmd $ld $LDFLAGS $flags -o $TMPE $TMPO $libs $extralibs }
其中check_cmd()是个很简单的函数,可以输出日志,如下所示。check_cmd(){ log "$@" "$@" >> $logfile 2>&1 }
例如,“check_func mkstemp”相当于编译了下述代码。extern int mkstemp(); int main(void){ mkstemp(); }check_header()
check_header()用于检查头文件。Configure中与check_header()有关的代码如下所示。check_header dlfcn.h check_header dxva2api.h -D_WIN32_WINNT=0x0600 check_header libcrystalhd/libcrystalhd_if.h check_header malloc.h check_header poll.h check_header sys/mman.h check_header sys/param.h check_header sys/resource.h check_header sys/select.h check_header termios.h check_header vdpau/vdpau.h check_header vdpau/vdpau_x11.h check_header X11/extensions/XvMClib.h check_header asm/types.h
check_header()的定义如下所示。check_header(){ log check_header "$@" header=$1 shift disable_safe $header check_cpp "$@" <int x; EOF }
从check_header()的定义可以看出,该函数首先将输入的第1个参数赋值给header,然后生成一个下述内容的C语言文件。#include <$header> int x;
最后调用check_cpp()完成编译测试。check_cpp()的定义如下所示。check_cpp(){ log check_cpp "$@" cat > $TMPC log_file $TMPC #-E选项,可以让编译器在预处理后停止,并输出预处理结果。 check_cmd $cc $CPPFLAGS $CFLAGS "$@" -E -o $TMPO $TMPC }
例如,“check_header malloc.h”相当于处理以下C语言文件。#includeint x; check_func_headers()
check_func_headers()用于同时检查头文件和函数。Configure中与check_header()有关的代码如下所示。check_func_headers conio.h kbhit check_func_headers windows.h PeekNamedPipe check_func_headers io.h setmode check_func_headers lzo/lzo1x.h lzo1x_999_compress check_func_headers windows.h GetProcessAffinityMask check_func_headers windows.h GetProcessTimes check_func_headers windows.h MapViewOfFile check_func_headers windows.h VirtualAlloc
check_func_headers()的定义如下所示。check_func_headers(){ log check_func_headers "$@" headers=$1 funcs=$2 shift 2 { for hdr in $headers; do echo "#include <$hdr>" done for func in $funcs; do echo "long check_$func(void) { return (long) $func; }" done echo "int main(void) { return 0; }" } | check_ld "cc" "$@" && enable $funcs && enable_safe $headers }
从check_func_headers()的定义可以看出,该函数首先将输入的第1个参数赋值给header,第2个参数赋值给funcs,然后生成一个下述内容的C语言文件。#include <$hdr> long check_$func (void) { return (long) $func; } int main(void) { return 0; }
例如,“check_func_headers windows.h PeekNamedPipe”相当于处理以下C语言文件。#includelong check_PeekNamedPipe (void) { return (long) PeekNamedPipe; } int main(void) { return 0; } check_mathfunc()
check_mathfunc()用于检查数学类函数。Configure中与check_mathfunc()有关的代码如下所示。check_mathfunc cbrtf check_mathfunc exp2 check_mathfunc exp2f check_mathfunc llrint check_mathfunc llrintf check_mathfunc log2 check_mathfunc log2f check_mathfunc lrint check_mathfunc lrintf check_mathfunc round check_mathfunc roundf check_mathfunc trunc check_mathfunc truncf
check_mathfunc()的定义如下所示。check_mathfunc(){ log check_mathfunc "$@" #数学函数名称 func=$1 shift disable $func check_ld "cc" "$@" <float foo(float f) { return $func(f); } int main(void){ return (int) foo; } EOF }
从check_mathfunc()的定义可以看出,该函数首先将输入的第1个参数赋值给func,然后生成一个下述内容的C语言文件。#includefloat foo(float f) { return $func(f); } int main(void){ return (int) foo; }
最后调用check_ld()完成编译测试。 例如,“check_mathfunc exp2”相当于编译连接了下面这个C文件。#includefloat foo(float f) { return exp2(f); } int main(void){ return (int) foo; } require()
require()用于检查第三方类库。Configure中与require()有关的代码如下所示。#检查第三方类库 # these are off by default, so fail if requested and not available #require()函数参数的规范:(名称,头文件,函数名,附加选项) #require2()函数参数规范类似 enabled avisynth && require2 vfw32 "windows.h vfw.h" AVIFileInit -lavifil32 enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init enabled libaacplus && require "libaacplus >= 2.0.0" aacplus.h aacplusEncOpen -laacplus enabled libass && require_pkg_config libass ass/ass.h ass_library_init enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && { check_lib celt/celt.h celt_decoder_create_custom -lcelt0 || die "ERROR: libcelt version must be >= 0.11.0."; } enabled libdc1394 && require_pkg_config libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdirac && require_pkg_config dirac "libdirac_decoder/dirac_parser.h libdirac_encoder/dirac_encoder.h" "dirac_decoder_init dirac_encoder_init" #测试libfaac enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType enabled libgsm && require libgsm gsm/gsm.h gsm_create -lgsm enabled libmodplug && require libmodplug libmodplug/modplug.h ModPlug_Load -lmodplug enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame enabled libnut && require libnut libnut.h nut_demuxer_init -lnut enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb enabled libopencv && require_pkg_config opencv opencv/cxcore.h cvCreateImageHeader enabled libopenjpeg && require libopenjpeg openjpeg.h opj_version -lopenjpeg enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex enabled libstagefright_h264 && require_cpp libstagefright_h264 "binder/ProcessState.h media/stagefright/MetaData.h media/stagefright/MediaBufferGroup.h media/stagefright/MediaDebug.h media/stagefright/MediaDefs.h media/stagefright/OMXClient.h media/stagefright/OMXCodec.h" android::OMXClient -lstagefright -lmedia -lutils -lbinder enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg enabled libutvideo && require_cpp utvideo "stdint.h stdlib.h utvideo/utvideo.h utvideo/Codec.h" 'CCodec*' -lutvideo -lstdc++ enabled libv4l2 && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl enabled libvo_aacenc && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg enabled libvpx && { enabled libvpx_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_dec_init_ver -lvpx || die "ERROR: libvpx decoder version must be >=0.9.1"; } enabled libvpx_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_enc_init_ver VPX_CQ" -lvpx || die "ERROR: libvpx encoder version must be >=0.9.6"; } } #测试libx264 enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 && { check_cpp_condition x264.h "X264_BUILD >= 118" || die "ERROR: libx264 version must be >= 0.118."; } enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore enabled openal && { { for al_libs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do check_lib 'AL/al.h' alGetError "${al_libs}" && break; done } || die "ERROR: openal not found"; } && { check_cpp_condition "AL/al.h" "defined(AL_VERSION_1_1)" || die "ERROR: openal version must be 1.1 or compatible"; } enabled mlib && require mediaLib mlib_types.h mlib_VectorSub_S16_U8_Mod -lmlib enabled openssl && { check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto || check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || die "ERROR: openssl not found"; }
由于上述代码量比较大。在这里我们只选择一个典型的例子——libx264来看一下。require()检测libx264的定义如下所示。#测试libx264 require libx264 x264.h x264_encoder_encode -lx264 && { check_cpp_condition x264.h "X264_BUILD >= 118" || die "ERROR: libx264 version must be >= 0.118."; }
从测试libx264的代码可以看出,require()函数的使用方式为:require {名称} {头文件} {函数名} {附加选项}require()函数定义如下所示。#检查依赖项的时候使用 require(){ name="$1" header="$2" func="$3" shift 3 check_lib $header $func "$@" || die "ERROR: $name not found" }
从require()的定义可以看出,该函数将第1个参数赋值给name,第2个参数赋值给header,第3个参数赋值给func。最后调用check_lib()函数。 check_lib()的定义如下所示。#检查类库 check_lib(){ log check_lib "$@" header="$1" func="$2" shift 2 check_header $header && check_func $func "$@" && add_extralibs "$@" }
可以看出check_lib()调用了check_header()、check_func()等几个函数完成检查工作。这两个函数在前文中已经介绍过,就不再重复了。 例如检测libx264的时候调用check_header()会生成以下临时文件:#includeint x; check_cflags ()
check_cflags()用于检查编译器的cflags标志参数。Configure中与check_cflags()有关的代码如下所示。#添加一些编译选项 # add some useful compiler flags if supported check_cflags -Wdeclaration-after-statement check_cflags -Wall check_cflags -Wno-parentheses check_cflags -Wno-switch check_cflags -Wno-format-zero-length check_cflags -Wdisabled-optimization check_cflags -Wpointer-arith check_cflags -Wredundant-decls check_cflags -Wno-pointer-sign check_cflags -Wcast-qual check_cflags -Wwrite-strings check_cflags -Wtype-limits check_cflags -Wundef check_cflags -Wmissing-prototypes check_cflags -Wno-pointer-to-int-cast check_cflags -Wstrict-prototypes check_cflags()函数的定义如下所示。 check_cflags(){ log check_cflags "$@" set -- $($filter_cflags "$@") check_cc "$@" <
从定义可以看出,check_cflags()调用了check_cc()执行命令。整个代码只有一行:int x;check_cc()的定义如下所示。check_cc(){ log check_cc "$@" cat > $TMPC log_file $TMPC #很多检查都调用了这个check_cmd #-c 只编译不链接 check_cmd $cc $CPPFLAGS $CFLAGS "$@" -c -o $TMPO $TMPC }可以看出check_cflags()将输入参数设置到命令行中,并最终调用了check_cmd。 除了上述几个函数之外,还有其他的一些检查编译环境的函数,在这里就不一一列举了。
Echo info
Echo info用于在控制台上打印配置信息。Configure中该部分的代码如下所示。#在控制台输出信息 echo "install prefix $prefix" echo "source path $source_path" echo "C compiler $cc" echo "ARCH $arch ($cpu)" if test "$build_suffix" != ""; then echo "build suffix $build_suffix" fi if test "$progs_suffix" != ""; then echo "progs suffix $progs_suffix" fi if test "$extra_version" != ""; then echo "version string suffix $extra_version" fi #${}的特异功能: #${file-my.file.txt}假如 $file 为空值,则使用 my.file.txt 作默认值。(保留没设定及非空值) #在这里,如果某个变量为空值,则取默认值为no echo "big-endian ${bigendian-no}" echo "runtime cpu detection ${runtime_cpudetect-no}" if enabled x86; then echo "${yasmexe} ${yasm-no}" echo "MMX enabled ${mmx-no}" echo "MMX2 enabled ${mmx2-no}" echo "3DNow! enabled ${amd3dnow-no}" echo "3DNow! extended enabled ${amd3dnowext-no}" echo "SSE enabled ${sse-no}" echo "SSSE3 enabled ${ssse3-no}" echo "AVX enabled ${avx-no}" echo "CMOV enabled ${cmov-no}" echo "CMOV is fast ${fast_cmov-no}" echo "EBX available ${ebx_available-no}" echo "EBP available ${ebp_available-no}" fi if enabled arm; then echo "ARMv5TE enabled ${armv5te-no}" echo "ARMv6 enabled ${armv6-no}" echo "ARMv6T2 enabled ${armv6t2-no}" echo "ARM VFP enabled ${armvfp-no}" echo "IWMMXT enabled ${iwmmxt-no}" echo "NEON enabled ${neon-no}" fi if enabled mips; then echo "MMI enabled ${mmi-no}" fi if enabled ppc; then echo "AltiVec enabled ${altivec-no}" echo "PPC 4xx optimizations ${ppc4xx-no}" echo "dcbzl available ${dcbzl-no}" fi if enabled sparc; then echo "VIS enabled ${vis-no}" fi echo "debug symbols ${debug-no}" echo "strip symbols ${stripping-no}" echo "optimize for size ${small-no}" echo "optimizations ${optimizations-no}" echo "static ${static-no}" echo "shared ${shared-no}" echo "postprocessing support ${postproc-no}" echo "new filter support ${avfilter-no}" echo "network support ${network-no}" echo "threading support ${thread_type-no}" echo "safe bitstream reader ${safe_bitstream_reader-no}" echo "SDL support ${sdl-no}" echo "Sun medialib support ${mlib-no}" echo "libdxva2 enabled ${dxva2-no}" echo "libva enabled ${vaapi-no}" echo "libvdpau enabled ${vdpau-no}" echo "AVISynth enabled ${avisynth-no}" echo "frei0r enabled ${frei0r-no}" echo "gnutls enabled ${gnutls-no}" echo "libaacplus enabled ${libaacplus-no}" echo "libass enabled ${libass-no}" echo "libcdio support ${libcdio-no}" echo "libcelt enabled ${libcelt-no}" echo "libdc1394 support ${libdc1394-no}" echo "libdirac enabled ${libdirac-no}" echo "libfaac enabled ${libfaac-no}" echo "libgsm enabled ${libgsm-no}" echo "libmodplug enabled ${libmodplug-no}" echo "libmp3lame enabled ${libmp3lame-no}" echo "libnut enabled ${libnut-no}" echo "libopencore-amrnb support ${libopencore_amrnb-no}" echo "libopencore-amrwb support ${libopencore_amrwb-no}" echo "libopencv support ${libopencv-no}" echo "libopenjpeg enabled ${libopenjpeg-no}" echo "libpulse enabled ${libpulse-no}" echo "librtmp enabled ${librtmp-no}" echo "libschroedinger enabled ${libschroedinger-no}" echo "libspeex enabled ${libspeex-no}" echo "libstagefright-h264 enabled ${libstagefright_h264-no}" echo "libtheora enabled ${libtheora-no}" echo "libutvideo enabled ${libutvideo-no}" echo "libv4l2 enabled ${libv4l2-no}" echo "libvo-aacenc support ${libvo_aacenc-no}" echo "libvo-amrwbenc support ${libvo_amrwbenc-no}" echo "libvorbis enabled ${libvorbis-no}" echo "libvpx enabled ${libvpx-no}" echo "libx264 enabled ${libx264-no}" echo "libxavs enabled ${libxavs-no}" echo "libxvid enabled ${libxvid-no}" echo "openal enabled ${openal-no}" echo "openssl enabled ${openssl-no}" echo "zlib enabled ${zlib-no}" echo "bzlib enabled ${bzlib-no}" echo for type in decoder encoder hwaccel parser demuxer muxer protocol filter bsf indev outdev; do echo "Enabled ${type}s:" eval list=$$(toupper $type)_LIST print_enabled '_*' $list | sort | pr -r -3 -t echo done license="LGPL version 2.1 or later" if enabled nonfree; then license="nonfree and unredistributable" elif enabled gplv3; then license="GPL version 3 or later" elif enabled lgplv3; then license="LGPL version 3 or later" elif enabled gpl; then license="GPL version 2 or later" fi echo "License: $license"
有关这段代码,有一个地方需要注意:很多的${}符号中的字符为“XXX-no”,这种格式的意思是如果XXX取值为空,则使用默认值“no”(这个规则比较奇特)。Write basic info
Write basic info用于向config.mak中写入一些基本信息。Configure中该部分的代码如下所示。#创建config.mak和config.h #根据情况也会创建config.asm echo "Creating config.mak and config.h..." test -e Makefile || $ln_s "$source_path/Makefile" . enabled stripping || strip="echo skipping strip" #重要:需要输出的文件 #TMPH是一个临时文件,最终会拷贝给config.h config_files="$TMPH config.mak" #写入config.mak文件 #首先写入一些基本信息 #"<config.mak < > config.mak eval echo "${lcname}_VERSION_MAJOR=$${name}_VERSION_MAJOR" >> config.mak } #获取版本 get_version LIBAVCODEC libavcodec/version.h get_version LIBAVDEVICE libavdevice/avdevice.h get_version LIBAVFILTER libavfilter/version.h get_version LIBAVFORMAT libavformat/version.h get_version LIBAVUTIL libavutil/avutil.h get_version LIBPOSTPROC libpostproc/postprocess.h get_version LIBSWRESAMPLE libswresample/swresample.h get_version LIBSWSCALE libswscale/swscale.h
关于这段代码,有以下几点需要注意: (1)“cat > config.mak <print_config() print_config()用于向config.h、config.mak、config.asm中写入所有配置信息。Configure中该部分的代码如下所示。 #输出所有的配置信息包含3类: #以“ARCH_”开头,包含系统架构信息 #以“HAVE_”开头,包含系统特征信息 #以“CONFIG_”开头,包含编译配置(数量最多,包含协议、复用器、编解码器等的配置,将近1000行) #config_files print_config ARCH_ "$config_files" $ARCH_LIST print_config HAVE_ "$config_files" $HAVE_LIST print_config CONFIG_ "$config_files" $CONFIG_LIST $CONFIG_EXTRA $ALL_COMPONENTS
从源代码中可以看出,其中调用了一个函数print_config()。print_config()的源代码如下所示。# 输出文本到config.mak,config.h等文件 # 该函数的示例调用方法:print_config CONFIG_ "$config_files" $CONFIG_LIST print_config(){ # 前缀 pfx=$1 # 文件列表 files=$2 # 位置参数可以用shift命令左移。比如shift 3表示原来的$4现在变成$1 shift 2 #for循环中,当没有in指定列表时,for会默认取命令行参数列表。 #在这里取的就是$CONFIG_LIST 等 for cfg; do # toupper():转换为大写 ucname="$(toupper $cfg)" # files= config.h config.mak config.asm # 循环输出 for f in $files; do # "x#*/"代表去取x的第一个slash之后的所有内容(不包括slash) # "#"代表删除从前往后最小匹配的内容 # "f##*."代表去取f的第一个"."之后的所有内容。在这里是“h”、“mak”等 # 在这里print_config_h(),print_config_mak(),print_config_asm() "print_config_${f##*.}" $cfg ${pfx}${ucname} >>$f done done }
可以看出print_config()的第1个参数是写入参数的前缀(例如可以取“ARCH_”、“HAVE_”、“CONFIG_”);第2个参数是文件列表(例如可以是“config.h config.mak config.asm”);第3个以后的的参数就是需要写入的变量(例如$ARCH_LIST、$CONFIG_LIST等)。 print_config()有两层循环:外层循环遍历了所有的变量(例如$CONFIG_LIST),内层循环遍历了所有文件(例如“config.h config.mak”),其中调用了一个函数print_config_XXX(),其中“XXX”根据文件后缀的不同可以取不同的值(例如“h”、“mak”)。下面举例看两个函数:print_config_h()和print_config_mak()。
print_config_h()
print_config_h()用于输出配置信息至config.h。该函数的源代码如下所示。#输出config.h的时候使用 #调用示例:print_config_h ffplay CONFIG_FFPLAY print_config_h(){ #command1 && command2 #&&左边的命令(命令1)返回真(即返回0,成功被执行)后,&&右边的命令(命令2)才能够被执行 #command1 || command2 #||左边的命令(命令1)未执行成功,那么就执行||右边的命令(命令2) enabled $1 && v=1 || v=0 #示例:#define CONFIG_FFPLAY 1 echo "#define $2 $v" }
从源代码中可以看出,参数1是变量名称,参数2是经过处理后准备写入文件的变量名称(变量名转换成了大写并且添加了前缀)。如果参数1所指向的变量是enabled的,那么v取值为1,那么写入文件的格式就是:#define {处理后变量名称} 1如果参数1所指向的变量不是enabled的,那么v取值为0,那么写入文件的格式就是:#define {处理后变量名称} 0print_config_mak()
print_config_mak()用于输出配置信息至config.mak。该函数的源代码如下所示。#输出config.mak的时候使用 print_config_mak(){ enabled $1 && v= || v=! echo "$v$2=yes" }从源代码中可以看出print_config_mak()的原理和print_config_h()是类似的。如果变量是enabled的,那么写入文件的格式就是:{处理后变量名称}=yes如果变量不是enabled的,那么写入文件的格式就是:!{处理后变量名称}=yesprint_enabled()
print_enabled()用于向config.mak写入所有enabled的组件信息。这方面功能通过print_enabled()函数完成,就不再详细分析了。pkgconfig_generate()
pkgconfig_generate()用于向libavXXX/libavXXX.pc中写入pkgconfig信息(XXX代表avcodec,avformat等)。这方面的代码还没有细看,以后有机会再进行补充。源代码(包含注释)
至此,FFmpeg的Configure的流程就大致梳理完毕了,最后附上和Configure有关的config.mak、config.h以及Configure本身的源代码。config.mak源代码
# FFmpeg config.mak # # 注释:雷霄骅 # leixiaohua1020@126.com # http://blog.csdn.net/leixiaohua1020 # # Configure脚本生成的Makefile,包含了各种配置信息。 # # Automatically generated by configure - do not modify! #基本信息 ifndef FFMPEG_CONFIG_MAK FFMPEG_CONFIG_MAK=1 FFMPEG_CONFIGURATION= #各种路径======================================== prefix=/usr/local LIBDIR=$(DESTDIR)${prefix}/lib SHLIBDIR=$(DESTDIR)${prefix}/bin INCDIR=$(DESTDIR)${prefix}/include BINDIR=$(DESTDIR)${prefix}/bin DATADIR=$(DESTDIR)${prefix}/share/ffmpeg MANDIR=$(DESTDIR)${prefix}/share/man #是个相对路径 SRC_PATH=. ifndef MAIN_MAKEFILE SRC_PATH:=$(SRC_PATH:.%=..%) endif #工具集========================================== CC_IDENT=gcc 4.6.2 (GCC) #架构 ARCH=x86 #编译器 CC=gcc CXX=g++ AS=gcc #链接器 LD=gcc DEPCC=gcc #汇编器 YASM=yasm YASMDEP=yasm #生成静态库.a工具 AR=ar RANLIB=ranlib CP=cp -p LN_S=ln -sf STRIP=strip #参数集========================================== #编译器的参数 CPPFLAGS= -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__ CFLAGS= -std=c99 -fno-common -fomit-frame-pointer -I/include/SDL -D_GNU_SOURCE=1 -Dmain=SDL_main -g -Wdeclaration-after-statement -Wall -Wno-parentheses -Wno-switch -Wno-format-zero-length -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wno-pointer-sign -Wcast-qual -Wwrite-strings -Wtype-limits -Wundef -Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes -O3 -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -Werror=missing-prototypes CXXFLAGS= -D__STDC_CONSTANT_MACROS ASFLAGS= -g #目标文件有关的参数 AS_O=-o $@ CC_O=-o $@ CXX_O=-o $@ #链接器有关的参数 LDFLAGS= -Wl,--as-needed -Wl,--warn-common -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil FFSERVERLDFLAGS=-Wl,-E SHFLAGS=-shared -Wl,--output-def,$$(@:$(SLIBSUF)=.def) -Wl,--out-implib,$(SUBDIR)lib$(SLIBNAME:$(SLIBSUF)=.dll.a) -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-auto-image-base -Wl,-Bsymbolic -Wl,--version-script,$(SUBDIR)lib$(NAME).ver YASMFLAGS=-f win32 -DPREFIX #前缀后缀======================================== BUILDSUF= PROGSSUF= #${NAME}位于每个liavXXX/Makefile中,例如avformat FULLNAME=$(NAME)$(BUILDSUF) LIBPREF=lib LIBSUF=.a #例如libavformat.a LIBNAME=$(LIBPREF)$(FULLNAME)$(LIBSUF) SLIBPREF= SLIBSUF=.dll EXESUF=.exe EXTRA_VERSION= DEPFLAGS=$(CPPFLAGS) $(CFLAGS) -MM CCDEP= CXXDEP=$(DEPCC) $(DEPFLAGS) $< | sed -e "/^#.*/d" -e "s,^[[:space:]]*$(*F)\.o,$(@D)/$(*F).o," > $(@:.o=.d) ASDEP= CC_DEPFLAGS=-MMD -MF $(@:.o=.d) -MT $@ AS_DEPFLAGS=-MMD -MF $(@:.o=.d) -MT $@ HOSTCC=gcc HOSTCFLAGS=-D_ISOC99_SOURCE -O3 -g -std=c99 -Wall HOSTEXESUF=.exe HOSTLDFLAGS= HOSTLIBS=-lm TARGET_EXEC= TARGET_PATH=$(CURDIR) #SDL SDL_LIBS=-L/lib -lmingw32 -lSDLmain -lSDL -mwindows SDL_CFLAGS=-I/include/SDL -D_GNU_SOURCE=1 -Dmain=SDL_main LIB_INSTALL_EXTRA_CMD=$$(RANLIB) "$(LIBDIR)/$(LIBNAME)" #链接 EXTRALIBS=-lavicap32 -lws2_32 -L/lib -lmingw32 -lSDLmain -lSDL -mwindows -lm -lz -lpsapi INSTALL=install LIBTARGET=i386 #例如libavformat.dll SLIBNAME=$(SLIBPREF)$(FULLNAME)$(SLIBSUF) #LIBVERSION变量位于library.mak #例如libavformat-53.dll #生成的Dll似乎就是这个版本的 SLIBNAME_WITH_VERSION=$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF) #例如libavformat-53.31.100.dll SLIBNAME_WITH_MAJOR=$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF) SLIB_CREATE_DEF_CMD= #生成导出库lib,会调用lib.exe SLIB_EXTRA_CMD=-lib.exe /machine:$(LIBTARGET) /def:$$(@:$(SLIBSUF)=.def) /out:$(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib) SLIB_INSTALL_NAME=$(SLIBNAME_WITH_MAJOR) SLIB_INSTALL_LINKS= SLIB_INSTALL_EXTRA_LIB=lib$(SLIBNAME:$(SLIBSUF)=.dll.a) $(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.def) SLIB_INSTALL_EXTRA_SHLIB=$(SLIBNAME:$(SLIBSUF)=.lib) SAMPLES:=$(FATE_SAMPLES) NOREDZONE_FLAGS=-mno-red-zone #版本信息======================================== libavcodec_VERSION=53.60.100 libavcodec_VERSION_MAJOR=53 libavdevice_VERSION=53.4.100 libavdevice_VERSION_MAJOR=53 libavfilter_VERSION=2.60.100 libavfilter_VERSION_MAJOR=2 libavformat_VERSION=53.31.100 libavformat_VERSION_MAJOR=53 libavutil_VERSION=51.34.101 libavutil_VERSION_MAJOR=51 libpostproc_VERSION=52.0.100 libpostproc_VERSION_MAJOR=52 libswresample_VERSION=0.6.100 libswresample_VERSION_MAJOR=0 libswscale_VERSION=2.1.100 libswscale_VERSION_MAJOR=2 #组件配置======================================== #ARCH_ !ARCH_ALPHA=yes !ARCH_ARM=yes !ARCH_AVR32=yes !ARCH_AVR32_AP=yes !ARCH_AVR32_UC=yes !ARCH_BFIN=yes !ARCH_IA64=yes !ARCH_M68K=yes !ARCH_MIPS=yes !ARCH_MIPS64=yes !ARCH_PARISC=yes !ARCH_PPC=yes !ARCH_PPC64=yes !ARCH_S390=yes !ARCH_SH4=yes !ARCH_SPARC=yes !ARCH_SPARC64=yes !ARCH_TOMI=yes ARCH_X86=yes ARCH_X86_32=yes !ARCH_X86_64=yes #HAVE_ !HAVE_ALTIVEC=yes HAVE_AMD3DNOW=yes HAVE_AMD3DNOWEXT=yes !HAVE_ARMV5TE=yes !HAVE_ARMV6=yes !HAVE_ARMV6T2=yes !HAVE_ARMVFP=yes HAVE_AVX=yes !HAVE_IWMMXT=yes !HAVE_MMI=yes HAVE_MMX=yes HAVE_MMX2=yes //略…… HAVE_YASM=yes #CONFIG_ CONFIG_BSFS=yes CONFIG_DECODERS=yes CONFIG_DEMUXERS=yes CONFIG_ENCODERS=yes CONFIG_FILTERS=yes !CONFIG_HWACCELS=yes CONFIG_INDEVS=yes CONFIG_MUXERS=yes CONFIG_OUTDEVS=yes CONFIG_PARSERS=yes CONFIG_PROTOCOLS=yes CONFIG_FFPLAY=yes CONFIG_FFPROBE=yes !CONFIG_FFSERVER=yes CONFIG_FFMPEG=yes !CONFIG_AVPLAY=yes !CONFIG_AVPROBE=yes !CONFIG_AVSERVER=yes CONFIG_AANDCT=yes CONFIG_AC3DSP=yes CONFIG_AVCODEC=yes CONFIG_AVDEVICE=yes CONFIG_AVFILTER=yes CONFIG_AVFORMAT=yes !CONFIG_AVISYNTH=yes !CONFIG_BZLIB=yes !CONFIG_CRYSTALHD=yes CONFIG_DCT=yes !CONFIG_DOC=yes CONFIG_DWT=yes !CONFIG_DXVA2=yes CONFIG_FASTDIV=yes CONFIG_FFT=yes !CONFIG_FREI0R=yes !CONFIG_GNUTLS=yes CONFIG_GOLOMB=yes !CONFIG_GPL=yes !CONFIG_GRAY=yes CONFIG_H264CHROMA=yes CONFIG_H264DSP=yes CONFIG_H264PRED=yes !CONFIG_HARDCODED_TABLES=yes CONFIG_HUFFMAN=yes !CONFIG_LIBAACPLUS=yes !CONFIG_LIBASS=yes !CONFIG_LIBCDIO=yes !CONFIG_LIBCELT=yes !CONFIG_LIBDC1394=yes !CONFIG_LIBDIRAC=yes !CONFIG_LIBFAAC=yes !CONFIG_LIBFREETYPE=yes !CONFIG_LIBGSM=yes !CONFIG_LIBMODPLUG=yes !CONFIG_LIBMP3LAME=yes !CONFIG_LIBNUT=yes !CONFIG_LIBOPENCORE_AMRNB=yes !CONFIG_LIBOPENCORE_AMRWB=yes !CONFIG_LIBOPENCV=yes !CONFIG_LIBOPENJPEG=yes !CONFIG_LIBPULSE=yes !CONFIG_LIBRTMP=yes !CONFIG_LIBSCHROEDINGER=yes !CONFIG_LIBSPEEX=yes !CONFIG_LIBSTAGEFRIGHT_H264=yes !CONFIG_LIBTHEORA=yes !CONFIG_LIBUTVIDEO=yes !CONFIG_LIBV4L2=yes !CONFIG_LIBVO_AACENC=yes !CONFIG_LIBVO_AMRWBENC=yes !CONFIG_LIBVORBIS=yes !CONFIG_LIBVPX=yes !CONFIG_LIBX264=yes !CONFIG_LIBXAVS=yes !CONFIG_LIBXVID=yes #此处省略将近1000条… CONFIG_RTMP_PROTOCOL=yes CONFIG_RTMPT_PROTOCOL=yes CONFIG_RTMPE_PROTOCOL=yes CONFIG_RTMPTE_PROTOCOL=yes CONFIG_RTMPS_PROTOCOL=yes CONFIG_RTP_PROTOCOL=yes CONFIG_TCP_PROTOCOL=yes !CONFIG_TLS_PROTOCOL=yes CONFIG_UDP_PROTOCOL=yes #Test ACODEC_TESTS=ac3_fixed adpcm_adx adpcm_ima_qt adpcm_ima_wav adpcm_ms adpcm_swf adpcm_yam alac aref flac g722 g723_1 g726 mp2 pcm_alaw pcm_f32be pcm_f32le pcm_f64be pcm_f64le pcm_mulaw pcm_s16be pcm_s16le pcm_s24be pcm_s24daud pcm_s24le pcm_s32be pcm_s32le pcm_s8 pcm_u8 wmav1 wmav2 VCODEC_TESTS=amv asv1 asv2 cljr dnxhd_1080i dnxhd_720p dnxhd_720p_10bit dnxhd_720p_rd dv dv50 dv_411 error ffv1 flashsv flashsv2 flv h261 h263 h263p huffyuv jpeg2000 jpegls ljpeg mjpeg mpeg mpeg1b mpeg2 mpeg2_422 mpeg2_idct_int mpeg2_ilace mpeg2_ivlc_qprd mpeg2thread mpeg2thread_ilace mpeg4 mpeg4_adap mpeg4_qpel mpeg4_qprd mpeg4adv mpeg4nr mpeg4thread mpng msmpeg4 msmpeg4v2 msvideo1 prores qtrle qtrlegray rc rgb roq rv10 rv20 snow snowll svq1 v210 vref wmv1 wmv2 yuv zlib zmbv LAVF_TESTS=aiff alaw asf au avi bmp caf dpx dv_fmt ffm flv_fmt gif gxf jpg mkv mmf mov mpg mulaw mxf mxf_d10 nut ogg pbmpipe pcx pgm pgmpipe pixfmt png ppm ppmpipe rm rso sgi sox swf tga tiff ts voc voc_s16 wav wtv yuv4mpeg LAVFI_TESTS=crop crop_scale crop_scale_vflip crop_vflip null pixdesc pixfmts_copy pixfmts_crop pixfmts_hflip pixfmts_null pixfmts_pad pixfmts_scale pixfmts_vflip scale200 scale500 vflip vflip_crop vflip_vflip SEEK_TESTS=seek_ac3_rm seek_adpcm_ima_wav seek_adpcm_ms_wav seek_adpcm_qt_aiff seek_adpcm_swf_flv seek_adpcm_yam_wav seek_alac_m4a seek_asv1_avi seek_asv2_avi seek_dnxhd_1080i_mov seek_dnxhd_720p_dnxhd seek_dnxhd_720p_rd_dnxhd seek_dv411_dv seek_dv50_dv seek_dv_dv seek_error_mpeg4_adv_avi seek_ffv1_avi seek_flac_flac seek_flashsv_flv seek_flv_flv seek_g726_wav seek_h261_avi seek_h263_avi seek_h263p_avi seek_huffyuv_avi seek_image_bmp seek_image_jpg seek_image_pcx seek_image_pgm seek_image_ppm seek_image_sgi seek_image_tga seek_image_tiff seek_jpegls_avi seek_lavf_aif seek_lavf_al seek_lavf_asf seek_lavf_au seek_lavf_avi seek_lavf_dv seek_lavf_ffm seek_lavf_flv seek_lavf_gif seek_lavf_gxf seek_lavf_mkv seek_lavf_mmf seek_lavf_mov seek_lavf_mpg seek_lavf_mxf seek_lavf_mxf_d10 seek_lavf_nut seek_lavf_ogg seek_lavf_rm seek_lavf_swf seek_lavf_ts seek_lavf_ul seek_lavf_voc seek_lavf_wav seek_lavf_wtv seek_lavf_y4m seek_ljpeg_avi seek_mjpeg_avi seek_mp2_mp2 seek_mpeg1_mpg seek_mpeg1b_mpg seek_mpeg2_422_mpg seek_mpeg2_idct_int_mpg seek_mpeg2i_mpg seek_mpeg2ivlc_qprd_mpg seek_mpeg2reuse_mpg seek_mpeg2thread_mpg seek_mpeg2threadivlc_mpg seek_mpeg4_adap_avi seek_mpeg4_adv_avi seek_mpeg4_nr_avi seek_mpeg4_qprd_avi seek_mpeg4_rc_avi seek_mpeg4_thread_avi seek_msmpeg4_avi seek_msmpeg4v2_avi seek_odivx_mp4 seek_pbmpipe_pbm seek_pcm_alaw_wav seek_pcm_f32be_au seek_pcm_f32le_wav seek_pcm_f64be_au seek_pcm_f64le_wav seek_pcm_mulaw_wav seek_pcm_s16be_mov seek_pcm_s16le_wav seek_pcm_s24be_mov seek_pcm_s24daud_302 seek_pcm_s24le_wav seek_pcm_s32be_mov seek_pcm_s32le_wav seek_pcm_s8_mov seek_pcm_u8_wav seek_pgmpipe_pgm seek_ppmpipe_ppm seek_rgb_avi seek_roqav_roq seek_rv10_rm seek_rv20_rm seek_snow53_avi seek_snow_avi seek_svq1_mov seek_wmav1_asf seek_wmav2_asf seek_wmv1_avi seek_wmv2_avi seek_yuv_avi endif # FFMPEG_CONFIG_MAKconfig.h源代码
/** * FFmpeg config.h * * 注释:雷霄骅 * leixiaohua1020@126.com * http://blog.csdn.net/leixiaohua1020 * * Configure脚本生成的config.h,包含了各种配置信息。 / /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H #define FFMPEG_CONFIGURATION "" #define FFMPEG_LICENSE "LGPL version 2.1 or later" #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" #define CC_TYPE "gcc" #define CC_VERSION __VERSION__ #define restrict restrict #define EXTERN_PREFIX "_" #define EXTERN_ASM _ #define SLIBSUF ".dll" #define ARCH_ALPHA 0 #define ARCH_ARM 0 #define ARCH_AVR32 0 #define ARCH_AVR32_AP 0 #define ARCH_AVR32_UC 0 #define ARCH_BFIN 0 #define ARCH_IA64 0 #define ARCH_M68K 0 #define ARCH_MIPS 0 #define ARCH_MIPS64 0 #define ARCH_PARISC 0 #define ARCH_PPC 0 #define ARCH_PPC64 0 #define ARCH_S390 0 #define ARCH_SH4 0 #define ARCH_SPARC 0 #define ARCH_SPARC64 0 #define ARCH_TOMI 0 #define ARCH_X86 1 #define ARCH_X86_32 1 #define ARCH_X86_64 0 #define HAVE_ALTIVEC 0 #define HAVE_AMD3DNOW 1 #define HAVE_AMD3DNOWEXT 1 #define HAVE_ARMV5TE 0 #define HAVE_ARMV6 0 #define HAVE_ARMV6T2 0 #define HAVE_ARMVFP 0 #define HAVE_AVX 1 #define HAVE_IWMMXT 0 #define HAVE_MMI 0 #define HAVE_MMX 1 #define HAVE_MMX2 1 //略…… #define HAVE_YASM 1 #define CONFIG_BSFS 1 #define CONFIG_DECODERS 1 #define CONFIG_DEMUXERS 1 #define CONFIG_ENCODERS 1 #define CONFIG_FILTERS 1 #define CONFIG_HWACCELS 0 #define CONFIG_INDEVS 1 #define CONFIG_MUXERS 1 #define CONFIG_OUTDEVS 1 #define CONFIG_PARSERS 1 #define CONFIG_PROTOCOLS 1 #define CONFIG_FFPLAY 1 #define CONFIG_FFPROBE 1 #define CONFIG_FFSERVER 0 #define CONFIG_FFMPEG 1 #define CONFIG_AVPLAY 0 #define CONFIG_AVPROBE 0 #define CONFIG_AVSERVER 0 #define CONFIG_AANDCT 1 #define CONFIG_AC3DSP 1 #define CONFIG_AVCODEC 1 #define CONFIG_AVDEVICE 1 #define CONFIG_AVFILTER 1 #define CONFIG_AVFORMAT 1 #define CONFIG_AVISYNTH 0 #define CONFIG_BZLIB 0 #define CONFIG_CRYSTALHD 0 #define CONFIG_DCT 1 #define CONFIG_DOC 0 #define CONFIG_DWT 1 #define CONFIG_DXVA2 0 #define CONFIG_FASTDIV 1 #define CONFIG_FFT 1 #define CONFIG_FREI0R 0 #define CONFIG_GNUTLS 0 #define CONFIG_GOLOMB 1 #define CONFIG_GPL 0 #define CONFIG_GRAY 0 #define CONFIG_H264CHROMA 1 #define CONFIG_H264DSP 1 #define CONFIG_H264PRED 1 #define CONFIG_HARDCODED_TABLES 0 #define CONFIG_HUFFMAN 1 #define CONFIG_LIBAACPLUS 0 #define CONFIG_LIBASS 0 #define CONFIG_LIBCDIO 0 #define CONFIG_LIBCELT 0 #define CONFIG_LIBDC1394 0 #define CONFIG_LIBDIRAC 0 #define CONFIG_LIBFAAC 0 #define CONFIG_LIBFREETYPE 0 #define CONFIG_LIBGSM 0 #define CONFIG_LIBMODPLUG 0 #define CONFIG_LIBMP3LAME 0 #define CONFIG_LIBNUT 0 #define CONFIG_LIBOPENCORE_AMRNB 0 #define CONFIG_LIBOPENCORE_AMRWB 0 #define CONFIG_LIBOPENCV 0 #define CONFIG_LIBOPENJPEG 0 #define CONFIG_LIBPULSE 0 #define CONFIG_LIBRTMP 0 #define CONFIG_LIBSCHROEDINGER 0 #define CONFIG_LIBSPEEX 0 #define CONFIG_LIBSTAGEFRIGHT_H264 0 #define CONFIG_LIBTHEORA 0 #define CONFIG_LIBUTVIDEO 0 #define CONFIG_LIBV4L2 0 #define CONFIG_LIBVO_AACENC 0 #define CONFIG_LIBVO_AMRWBENC 0 #define CONFIG_LIBVORBIS 0 #define CONFIG_LIBVPX 0 #define CONFIG_LIBX264 0 //此处省略将近1000条 #define CONFIG_RTMP_PROTOCOL 1 #define CONFIG_RTMPT_PROTOCOL 1 #define CONFIG_RTMPE_PROTOCOL 1 #define CONFIG_RTMPTE_PROTOCOL 1 #define CONFIG_RTMPS_PROTOCOL 1 #define CONFIG_RTP_PROTOCOL 1 #define CONFIG_TCP_PROTOCOL 1 #define CONFIG_TLS_PROTOCOL 0 #define CONFIG_UDP_PROTOCOL 1 #endif /* FFMPEG_CONFIG_H */Configure的源代码
#!/bin/sh # # FFmpeg configure script # # Copyright (c) 2000-2002 Fabrice Bellard # Copyright (c) 2005-2008 Diego Biurrun # Copyright (c) 2005-2008 Mans Rullgard # # 注释:雷霄骅 # leixiaohua1020@126.com # http://blog.csdn.net/leixiaohua1020 # # 添加了注释的FFmpeg的Configure文件 # # Prevent locale nonsense from breaking basic text processing. LC_ALL=C export LC_ALL # make sure we are running under a compatible shell # try to make this part work with most shells try_exec(){ echo "Trying shell $1" type "$1" > /dev/null 2>&1 && exec "$@" } unset foo (: ${foo%%bar}) 2> /dev/null E1="$?" (: ${foo?}) 2> /dev/null E2="$?" if test "$E1" != 0 || test "$E2" = 0; then echo "Broken shell detected. Trying alternatives." export FF_CONF_EXEC if test "0$FF_CONF_EXEC" -lt 1; then FF_CONF_EXEC=1 try_exec bash "$0" "$@" fi if test "0$FF_CONF_EXEC" -lt 2; then FF_CONF_EXEC=2 try_exec ksh "$0" "$@" fi if test "0$FF_CONF_EXEC" -lt 3; then FF_CONF_EXEC=3 try_exec /usr/xpg4/bin/sh "$0" "$@" fi echo "No compatible shell script interpreter found." echo "This configure script requires a POSIX-compatible shell" echo "such as bash or ksh." echo "THIS IS NOT A BUG IN FFMPEG, DO NOT REPORT IT AS SUCH." echo "Instead, install a working POSIX-compatible shell." echo "Disabling this configure test will create a broken FFmpeg." if test "$BASH_VERSION" = '2.04.0(1)-release'; then echo "This bash version ($BASH_VERSION) is broken on your platform." echo "Upgrade to a later version if available." fi exit 1 fi #帮助菜单 show_help(){ cat <> $logfile } log_file(){ log BEGIN $1 pr -n -t $1 >> $logfile log END $1 } echolog(){ log "$@" echo "$@" } warn(){ log "WARNING: $*" WARNINGS="${WARNINGS}WARNING: $*n" } #出错了 die(){ echolog "$@" cat <