FFmpeg的代码结构和编译系统
FFmpeg的目录结构
目录结构-
compact目录下主要是头文件,是为了兼容不同平台或系统的数据类型定义,例如compat/msvcrt/snprintf.h和snprintf.c是兼容C99的snprintf()和vsnprintf()声明及实现;
-
libavcodec目录下是编码/解码库所在的代码路径;
-
libavdevice目录下是和一些特定设备相关的接口实现,比如sdl显示设备,alsa音频输出设备,opengl图形加速设备,v4l2视频设备(比如摄像头);
-
libavfilter是一个类似DirecShow机制的帧处理函数集,通过graph-based机制,将不同处理功能的filter函数,链接(link)起来;
-
libavformat是复用/解复用库,一般用于多媒体文件的处理;
-
libavresample顾名思义,是一个重采样库,比如音频采样率从44.1KHz到96KHz;
-
libavutil是支撑FFmpeg的工具集,像fifo管理,内存管理,时间管理等;
-
libpostproc是后期处理库;
-
libswresample是音频重采样,格式转换和混合;功能和libavresample十分类似,是FFmpeg相对早期的实现方法;
-
libswscale是颜色空间转换和大小尺寸缩放的库;
-
cmdutils.c是用户使用命令行进行ffmpeg操作时用到的工具;
-
ffmpeg.c是ffmpeg工具的源码;
-
ffplay.c是一个基于FFmpeg库文件的播放器实例;
-
ffprobe.c是解析媒体文件格式信息的例子;
-
ffserver.c是RTSP/HTTP流媒体服务器的源代码;
-
configure是编译前执行配置的脚本;
FFmpeg的配置
FFmpeg在编译前需要进行配置,它的配置选项也极其丰富,可以通过如下命令来查看详细的配置信息,
./configure --help
下面,我们来分类了解一下FFmpeg的配置详情。
帮助选项
可以通过列表显示编解码器信息,复用/解复用信息,硬件加速,解析器,协议,过滤器,输入输出设备等信息,
Help options:
--help print this message
--list-decoders show all available decoders
--list-encoders show all available encoders
--list-hwaccels show all available hardware accelerators
--list-demuxers show all available demuxers
--list-muxers show all available muxers
--list-parsers show all available parsers
--list-protocols show all available protocols
--list-bsfs show all available bitstream filters
--list-indevs show all available input devices
--list-outdevs show all available output devices
--list-filters show all available filters
标准选项
比如把log输出重定向到某路径,编译后的库文件的安装路径等,[ ]里的内容是默认的配置,
Standard options:
--logfile=FILE log tests and output to FILE [config.log]
--disable-logging do not log configure debug information
--fatal-warnings fail if any configure warning is generated
--prefix=PREFIX install in PREFIX []
--bindir=DIR install binaries in DIR [PREFIX/bin]
--datadir=DIR install data files in DIR [PREFIX/share/ffmpeg]
--docdir=DIR install documentation in DIR [PREFIX/share/doc/ffmpeg]
--libdir=DIR install libs in DIR [PREFIX/lib]
--shlibdir=DIR install shared libs in DIR [LIBDIR]
--incdir=DIR install includes in DIR [PREFIX/include]
--mandir=DIR install man page in DIR [PREFIX/share/man]
--pkgconfigdir=DIR install pkg-config files in DIR [LIBDIR/pkgconfig]
--enable-rpath use rpath to allow installing libraries in paths
not part of the dynamic linker search path
use rpath when linking programs [USE WITH CARE]
--install-name-dir=DIR Darwin directory name for installed targets
开源许可的相关选项
Licensing options:
--enable-gpl allow use of GPL code, the resulting libs
and binaries will be under GPL [no]
--enable-version3 upgrade (L)GPL to version 3 [no]
--enable-nonfree allow use of nonfree code, the resulting libs
and binaries will be unredistributable [no]
配置选项
比如静态库和动态库的选择,编译优化等,
Configuration options:
--disable-static do not build static libraries [no]
--enable-shared build shared libraries [no]
--enable-small optimize for size instead of speed
--disable-runtime-cpudetect disable detecting cpu capabilities at runtime (smaller binary)
--enable-gray enable full grayscale support (slower color)
--disable-swscale-alpha disable alpha channel support in swscale
--disable-all disable building components, libraries and programs
--enable-raise-major increase major version numbers in sonames [no]
程序选项
每个选项对应一个可单独执行的程序,可选择编译还是不编译,
Program options:
--disable-programs do not build command line programs
--disable-ffmpeg disable ffmpeg build
--disable-ffplay disable ffplay build
--disable-ffprobe disable ffprobe build
--disable-ffserver disable ffserver build
文档选项
是否关闭生成文档,
Documentation options:
--disable-doc do not build documentation
--disable-htmlpages do not build HTML documentation pages
--disable-manpages do not build man documentation pages
--disable-podpages do not build POD documentation pages
--disable-txtpages do not build text documentation pages
模块功能配置
比如是否编译某些模块,压缩算法等配置,
Component options:
--disable-avdevice disable libavdevice build
--disable-avcodec disable libavcodec build
--disable-avformat disable libavformat build
--disable-swresample disable libswresample build
--disable-swscale disable libswscale build
--disable-postproc disable libpostproc build
--disable-avfilter disable libavfilter build
--enable-avresample enable libavresample build [no]
--disable-pthreads disable pthreads [autodetect]
--disable-w32threads disable Win32 threads [autodetect]
--disable-os2threads disable OS/2 threads [autodetect]
--disable-network disable network support [no]
--disable-dct disable DCT code
--disable-dwt disable DWT code
--disable-error-resilience disable error resilience code
--disable-lsp disable LSP code
--disable-lzo disable LZO decoder code
--disable-mdct disable MDCT code
--disable-rdft disable RDFT code
--disable-fft disable FFT code
--disable-faan disable floating point AAN (I)DCT code
--disable-pixelutils disable pixel utils in libavutil
独立功能选项
比如编解码开关,可以配置到某一编解码类型,
Individual component options:
--disable-everything disable all components listed below
--disable-encoder=NAME disable encoder NAME
--enable-encoder=NAME enable encoder NAME
--disable-encoders disable all encoders
--disable-decoder=NAME disable decoder NAME
--enable-decoder=NAME enable decoder NAME
--disable-decoders disable all decoders
--disable-hwaccel=NAME disable hwaccel NAME
--enable-hwaccel=NAME enable hwaccel NAME
--disable-hwaccels disable all hwaccels
--disable-muxer=NAME disable muxer NAME
--enable-muxer=NAME enable muxer NAME
--disable-muxers disable all muxers
--disable-demuxer=NAME disable demuxer NAME
--enable-demuxer=NAME enable demuxer NAME
--disable-demuxers disable all demuxers
--enable-parser=NAME enable parser NAME
--disable-parser=NAME disable parser NAME
--disable-parsers disable all parsers
--enable-bsf=NAME enable bitstream filter NAME
--disable-bsf=NAME disable bitstream filter NAME
--disable-bsfs disable all bitstream filters
--enable-protocol=NAME enable protocol NAME
--disable-protocol=NAME disable protocol NAME
--disable-protocols disable all protocols
--enable-indev=NAME enable input device NAME
--disable-indev=NAME disable input device NAME
--disable-indevs disable input devices
--enable-outdev=NAME enable output device NAME
--disable-outdev=NAME disable output device NAME
--disable-outdevs disable output devices
--disable-devices disable all devices
--enable-filter=NAME enable filter NAME
--disable-filter=NAME disable filter NAME
--disable-filters disable all filters
扩展库支持的配置
也就是依赖第三方的库文件,由FFmpeg提供接口调用相关的库,比如要开启x264的支持 ,
–enable-libx264,要关闭Intel硬件加速 , –disable-vaapi,
External library support:
Using any of the following switches will allow FFmpeg to link to the
corresponding external library. All the components depending on that library
will become enabled, if all their other dependencies are met and they are not
explicitly disabled. E.g. --enable-libwavpack will enable linking to
libwavpack and allow the libwavpack encoder to be built, unless it is
specifically disabled with --disable-encoder=libwavpack.
Note that only the system libraries are auto-detected. All the other external
libraries must be explicitly enabled.
Also note that the following help text describes the purpose of the libraries
themselves, not all their features will necessarily be usable by FFmpeg.
--enable-avisynth enable reading of AviSynth script files [no]
--disable-bzlib disable bzlib [autodetect]
--enable-chromaprint enable audio fingerprinting with chromaprint [no]
--enable-frei0r enable frei0r video filtering [no]
--enable-gcrypt enable gcrypt, needed for rtmp(t)e support
if openssl, librtmp or gmp is not used [no]
--enable-gmp enable gmp, needed for rtmp(t)e support
工具链配置选项
Toolchain options:
--arch=ARCH select architecture []
--cpu=CPU select the minimum required CPU (affects
instruction selection, may crash on older CPUs)
--cross-prefix=PREFIX use PREFIX for compilation tools []
--progs-suffix=SUFFIX program name suffix []
--enable-cross-compile assume a cross-compiler is used
--sysroot=PATH root of cross-build tree
--sysinclude=PATH location of cross-build system headers
--target-os=OS compiler targets OS []
--target-exec=CMD command to run executables on target
--target-path=DIR path to view of build directory on target
--target-samples=DIR path to samples directory on target
--tempprefix=PATH force fixed dir/prefix instead of mktemp for checks
--toolchain=NAME set tool defaults according to NAME
--nm=NM use nm tool NM [nm -g]
--ar=AR use archive tool AR [ar]
--as=AS use assembler AS []
--ln_s=LN_S use symbolic link tool LN_S [ln -s -f]
--strip=STRIP use strip tool STRIP [strip]
高级配置选项(专家级)
主要是和内存分配,编解码相关的一些高级选项,一般无需涉及,
Advanced options (experts only):
--malloc-prefix=PREFIX prefix malloc and related names with PREFIX
--custom-allocator=NAME use a supported custom allocator
--disable-symver disable symbol versioning
--enable-hardcoded-tables use hardcoded tables instead of runtime generation
--disable-safe-bitstream-reader
disable buffer boundary checking in bitreaders
(faster, but may crash)
--enable-memalign-hack emulate memalign, interferes with memory debuggers
--sws-max-filter-size=N the max filter size swscale uses [256]
优化选项(也是专家级),是和目标平台target有关的优化,比如音视频相关的指令及汇编代码,
Optimization options (experts only):
--disable-asm disable all assembly optimizations
--disable-altivec disable AltiVec optimizations
--disable-vsx disable VSX optimizations
--disable-power8 disable POWER8 optimizations
--disable-amd3dnow disable 3DNow! optimizations
--disable-amd3dnowext disable 3DNow! extended optimizations
--disable-mmx disable MMX optimizations
--disable-mmxext disable MMXEXT optimizations
--disable-sse disable SSE optimizations
--disable-sse2 disable SSE2 optimizations
--disable-sse3 disable SSE3 optimizations
--disable-ssse3 disable SSSE3 optimizations
开发者配置选项
在调试FFmpeg源代码时使用,
Developer options (useful when working on FFmpeg itself):
--disable-debug disable debugging symbols
--enable-debug=LEVEL set the debug level []
--disable-optimizations disable compiler optimizations
--enable-extra-warnings enable more compiler warnings
--disable-stripping disable stripping of executables and shared libraries
--assert-level=level 0(default), 1 or 2, amount of assertion testing,
2 causes a slowdown at runtime.
--enable-memory-poisoning fill heap uninitialized allocated space with arbitrary data
--valgrind=VALGRIND run "make fate" tests through valgrind to detect memory
leaks and errors, using the specified valgrind binary.
Cannot be combined with --target-exec
--enable-ftrapv Trap arithmetic overflows
--samples=PATH location of test samples for FATE, if not set use
$FATE_SAMPLES at make invocation time.
--enable-neon-clobber-test check NEON registers for clobbering (should be
used only for debugging purposes)
--enable-xmm-clobber-test check XMM registers for clobbering (Win64-only;
should be used only for debugging purposes)
--enable-random randomly enable/disable components
--disable-random
--enable-random=LIST randomly enable/disable specific components or
--disable-random=LIST component groups. LIST is a comma-separated list
of NAME[:PROB] entries where NAME is a component
(group) and PROB the probability associated with
NAME (default 0.5).
--random-seed=VALUE seed value for --enable/disable-random
--disable-valgrind-backtrace do not print a backtrace under Valgrind
(only applies to --disable-optimizations builds)
从上可知,FFmpeg源码的配置选项十分丰富,但是条理十分清晰,执行配置的操作也十分简单,只需要在configure脚本后跟上相关的选项即可,比如要开启x264的支持,可以如下,
./configure --enable-libx264 --enable-gpl
整个配置结束后,会在FFmpeg源代码的根目录下生成config.mak文件,其内容是configure脚本根据前述配置(可能很多选项是默认)自动生成的key-value值,供后面make编译使用。
FFmpeg的编译系统
FFmpeg的编译是依赖于源代码根目录下的Makefile进行的,首先通过include config.mak 将前述配置变量config.mak引入,这些配置将在整个编译过程中生效。同时还会引入common.mak,主要是一些公共变量定义以及方法定义,像变量ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil postproc swscale swresample 就定义了所有的库集合。另外,主Makefile还会引入library.mak,library.mak的主要作用是编译各个库的规则,如libavformat。
整个make的目标是如下语句,
all: $(AVPROGS)
而变量$(AVPROGS)则由下列语句获得,
AVPROGS := (PROGSSUF)$(EXESUF))
变量$(AVPROGS-yes)的定义如下,
AVPROGS-$(CONFIG_FFMPEG) += ffmpeg
AVPROGS-$(CONFIG_FFPLAY) += ffplay
AVPROGS-$(CONFIG_FFPROBE) += ffprobe
AVPROGS-$(CONFIG_FFSERVER) += ffserver
即配置程序的集合,make install的规则如下,
install: install-libs install-headers
完成lib库的安装以及头文件的安装。
总体来看,整个FFmpeg的编译系统也比较庞大,但是条理十分清晰,为了让FFmpeg可以跨多个平台进行编译,Makefile系统封装了很多的变量。通过配置文件,将不同平台不同编译选项的需求,统一用一套Makefile来完成,其跨平台性得到了玲离尽致的体现。