认识ffmpeg编译、以及参数解释


学习文章 : https://ffmpeg.xianwaizhiyin.net/build-ffmpeg/configure-args.html

ffmpeg
libav_codec
libav_format
libav_filter
libav_device
libav_util
libsw_resample
libsw_scale
lib_postproc
文件格式和协议库(Protocol\Demuxer\Muxer层)
音频重采样,对数字音频声道数、数据格式、采样率等信息转换
封装了Codec层-为开发者提供第三方Codec
音视频滤镜库
输入输出设备库-比如编译了ffplay
核心代码库
图像格式转换-可YUV_2_RGB
进行后期处理-如filter会用

源码

去掉一些说明文件后

~/ffmpeg-4.2.2 $ ls
compat     fftools      libavformat    libswresample  presets
configure  libavcodec   libavresample  libswscale     tests
doc        libavdevice  libavutil      Makefile       tools
ffbuild    libavfilter  libpostproc    
  1. doc/build_system.txt,编译 FFmpeg 的一些教程。
  2. doc/filter_design.txt ,filter 滤镜的设计原理。
  3. doc/writing_filters.txt,如何自己写一个滤镜加进去 FFmpeg。
  4. doc/issue_tracker.txt,FFmpeg 的 bug 或者 feature 的跟踪流程
  5. doc/multithreading.txt,FFmpeg 里面的多线程,有两种,Slice threading 跟 Frame threading
  6. doc/optimization.txt ,编解码器的优化方法,FFmpeg 还有一部分函数是可以用汇编 SIMD 优化,他的一些函数如果被优化得晦涩难懂,可以查看早期的 gitlog
  7. doc/rate_distortion.txt,对失真率的简单讨论。

编译参数

环境目录

  • prefix 代表前缀目录

  • libdir 代表静态库目录

  • shlibdir动态库的安装目录默认会把动态库安装到系统的动态库目录。

  • pkgconfigdir 代表 pkg 文件的安装目录。

  • pkg 是用来给第三方软件找到 FFmpeg 静态库,动态库的安装目录的。

链接库

  • --disable-static\ --enable-shared , FFmpeg 默认会生成静态库
  • --extra-cflags,传递 标识选项 给 C 编译器
  • --extra-cxxflags,传递 标识选项 给 C++ 编译器
  • --extra-ldflags,传递 标识选项 给 LD 链接器
  • --extra-ldexeflags,生成 exe 的时候传递给 链接器 的 选项
  • --extra-ldsoflags,生成 so 动态库的时候传递给 链接器 的 选项
  • --extra-libs,指定额外的库,实际上就是往链接器加选项
  • --env="ENV=override" 这个是最重要的,可以覆盖环境变量

编译速度、程序大小

  • --enable-small,把 FFmpeg 的体积减少。

  • --disable-doc,不编译生成文档,可以节省编译时间。

  • --disable-programs,开启\关闭的可执行文件( ffmpeg)。针对某个不生成 --disable-ffplay,如果全部关闭则只生成静态库\动态库。

  • --disable-avdevice--disable-avcodec--disable-avformat--disable-swresample--disable-swscale--disable-postproc--disable-avfilter。开启\关闭的,如果只需要可执行文件,可以指定不生成这些库,但是可能程序会缺少某个库的功能。(在开发filter模块的时候可以手动的关闭一些库,会减少很多编译时间)

  • --disable-indevs --disable-outdevs --disable-bsfs --disable-protocols --disable-filters --disable-encoders --disable-decoders --disable-muxers --disable-demuxers --disable-parsers 这十个对应的设备,我们先全部关闭然后再放开我们需要的,主要还是为了缩小代码体积。如果没有后面的配置,ffmpeg编译出是最小的体积,只是没有任何功能。

由于 默认的编译会给 ffmpeg.exe 加上很多的编/解码器跟解/复用器,在嵌入式设备\或者零时开发上为了使程序体积更小、编译更快,可以采用此种方法。其他的 滤镜,协议,也可以如此裁剪。

  1. 可执行程序属性
    • --disable-pthreads--disable-w32threads--disable-os2threads关闭多线程。如果禁用了性能会下降非常多

    • --disable-network,如不需要处理网络协议,可以启动这个选项,可以减小软件大小 跟节省编译时间。

  2. 编码器
    • --enable-libx264,启用 x264 作为 h.264 的编解码器。--enable-libx265,启用 x265 作为 h.265 的编解码器。(现在一般是这2个,以前就有h262)
    • --enable-encoder=rawvideo --enable-encoder=mpeg4 使能编码器rawvideo对应yuv,mpeg4对应mp4
    • --enable-decoder=rawvideo --enable-decoder=mpeg4 --enable-decoder=movtext 使能解码器,这里需要开启movtext才能解压mp4
    • --enable-muxer=aiff --enable-muxer=h263 --enable-muxer=mp4 --enable-muxer=rawvideo 使能合成器
    • --enable-demuxer=aac --enable-demuxer=aiff --enable-demuxer=h263 --enable-demuxer=mov --enable-demuxer=rawvideo 使能分离器
    • --enable-parser=aac --enable-parser=h263 --enable-parser=mpegaudio --enable-parser=mpeg4video 使能解析器
    • --enable-indev=v4l2 --enable-outdev=v4l2 使能输入设备,输出设备(如果不使能就只能编解码不能采集视频)
    • --enable-filter=scale 使能过滤器,这个是用来转换yuv的格式,yuv有多种格式要互相转换。
  3. 环境工具(不同平台使用不同工具)
    • --cc=CC 指定 C 程序的编译器。--cxx=CXX 指定 C++ 的编译器。--ld=LD 指定链接器。
    • --custom-allocator,自定义内存分配器,可以把 malloc 换成jemalloc 之类的。
    • --arch=x86_32/i386/x86_64/arm64,
  4. 协议
    • --enable-protocol=file 使能文件协议,这个必须放开

编译脚本(下文简称为configure

~/ffmpeg-4.2.2 $ cat load.sh
#!/bin/bash

if [ -d build ];then
	mkdir build
fi

./configure \
    --prefix=build \
    --enable-gpl \
    --enable-nonfree \
    --enable-debug=3 \
    --disable-optimizations \
    --disable-asm \
    --disable-stripping \
    --disable-ffprobe \
    --disable-ffplay

通过git控制代码版本,在执行configure后产生的新文件如下:

~/ffmpeg-4.2.2 $ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	config.h
	doc/config.texi
	ffbuild/.config
	ffbuild/config.fate
	ffbuild/config.log
	ffbuild/config.mak
	ffbuild/config.sh
	libavcodec/bsf_list.c
	libavcodec/codec_list.c
	libavcodec/parser_list.c
	libavdevice/indev_list.c
	libavdevice/outdev_list.c
	libavfilter/filter_list.c
	libavformat/demuxer_list.c
	libavformat/muxer_list.c
	libavformat/protocol_list.c
	libavutil/avconfig.h

永远再执行一遍configure也同样可以看到主要的配置文件如下

License: nonfree and unredistributable
config.h is unchanged
libavutil/avconfig.h is unchanged
libavfilter/filter_list.c is unchanged
libavcodec/codec_list.c is unchanged
libavcodec/parser_list.c is unchanged
libavcodec/bsf_list.c is unchanged
libavformat/demuxer_list.c is unchanged
libavformat/muxer_list.c is unchanged
libavdevice/indev_list.c is unchanged
libavdevice/outdev_list.c is unchanged
libavformat/protocol_list.c is unchanged
ffbuild/config.sh is unchanged

之后再过滤下执行configure后的打印信息,这里的打印信息就是告诉你执行make编译后:会得到的程序和它会具有的功能信息

~/ffmpeg-4.2.2 $ cat log | grep :
External libraries:
External libraries providing hardware acceleration:
Libraries:
Programs:
Enabled decoders:
Enabled encoders:
Enabled hwaccels:
Enabled parsers:
Enabled demuxers:
Enabled muxers:
Enabled protocols:
Enabled filters:
Enabled bsfs:
Enabled indevs:
Enabled outdevs:
License: nonfree and unredistributable

然后执行make -j16编译运行,这里的16表示用16个子线程同时编译,我只了解一点shell多线程技术,对于make这个工具不是特别了解,国内文章对它的解释也比较模糊,其中有一篇文章说道**“j后面的数字应该为CPU核心数的两倍”**不知道是不是准确的,至此我还特意用shell分别对16线程和无限制线程测试(我的电脑是8核心的),很明显无限制线程花费的时间要比16少的多(可能是我不太明白shell多线程和程序进程多线程的区别吧),有兴趣的可以自己研究一下

make后再看看文件变化情况,还是一样通过git status这里加上configurtion前的文件后新产生的基本都是.d和.o文件,有3533个文件变化或产生

~/ffmpeg-4.2.2 $ git status | wc -l
3533

编译后的信息:

~/ffmpeg-4.2.2 $ du ffmpeg ffmpeg_g
68M	ffmpeg
68M	ffmpeg_g

~/ffmpeg-4.2.2 $  ldd ffmpeg_g
	linux-vdso.so.1 (0x00007ffea3f66000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4c782ef000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f4c782d3000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4c780ab000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f4c7a510000)

~/ffmpeg-4.2.2 $ file ffmpeg_g
ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=5a51fa6f5eb1997656814577ef36b945fd21a07b, for GNU/Linux 3.2.0, with debug_info, not stripped

可以看到还是依赖了系统的一些动态库,即使是静态链接情况下(前面脚本里面没有加 --enable-shared 就是使用静态库编译)

完整静态编译

需要再加上3个静态标志

~/ffmpeg-4.2.2 $ cat load.sh
#!/bin/bash

if [ ! -d build ];then
    mkdir build
fi

#在执行 这条命令之前,需要安装一些必备的静态库,因为操作系统为了节省硬盘空间,默认可能只有动态库,一些静态库需要手动安装的

#sudo apt install libc6-dev build-essential -y

./configure \
    --prefix=build \
    --enable-gpl \
    --enable-nonfree \
    --enable-debug=3 \
    --disable-optimizations \
    --disable-asm \
    --disable-stripping \
    --disable-ffprobe \
    --disable-ffplay \
    --extra-cflags="-static" \
    --extra-ldflags="-static" \
    --pkg-config-flags="--static"

编译后信息

~/ffmpeg-4.2.2 $ file ffmpeg_g
ffmpeg_g: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=9d75510c5c79ba9e47b1ea617e4f97308c75795e, for GNU/Linux 3.2.0, with debug_info, not stripped

~/ffmpeg-4.2.2 $ du ffmpeg_g
69M	ffmpeg_g

下载-编译脚本(Android)

#!/bin/bash

cd ~/

if [ ! -f "ffmpeg-4.2.2.tar.bz2" ];then
   wget https://ffmpeg.org/releases/ffmpeg-4.2.2.tar.bz2
   tar -xjvf ffmpeg-4.2.2.tar.bz2
fi
cd ffmpeg-4.2.2

path=($(ls ~/Library/Android/sdk/ndk/))
export NDK=$HOME/Library/Android/sdk/ndk/${path[0]}

echo -e "🌟\033[31m 检测ndk-build 版本,将使用${NDK}进行编译\033[0m"
echo -e "\n请选择要编译的版本架构:[64/32]"

read archbit

if [[ $archbit = 64 ]];then
	echo "start build for 64bit..."
	ARCH=aarch64
	CPU=armv8-a
	API=23
	PLATFORM=aarch64
	ANDROID=android
	CFLAGS=""
	LDFLAGS=""
elif [[ $archbit = 32 ]];then
	echo "start build for 32bit..."
	ARCH=arm
	CPU=armv7-a
	API=23
	PLATFORM=armv7a
	ANDROID=androideabi
	CFLAGS="-mfloat-abi=softfp -march=$CPU"
	LDFLAGS="-Wl,--fix-cortex-a8"
else
	exit
fi

export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin
export SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
export CROSS_PREFIX=$TOOLCHAIN/$ARCH-linux-$ANDROID-
export CC=$TOOLCHAIN/$PLATFORM-linux-$ANDROID$API-clang
export CXX=$TOOLCHAIN/$PLATFORM-linux-$ANDROID$API-clang++
export PREFIX=../ffmpeg-android/$CPU

function build_android {
  ./configure \
      --prefix=$PREFIX \
      --cross-prefix=$CROSS_PREFIX \
      --target-os=android \
      --arch=$ARCH \
      --cpu=$CPU \
      --cc=$CC \
      --cxx=$CXX \
      --nm=$TOOLCHAIN/$ARCH-linux-$ANDROID-nm \
      --strip=$TOOLCHAIN/$ARCH-linux-$ANDROID-strip \
      --enable-cross-compile \
      --sysroot=$SYSROOT \
      --extra-cflags="$CFLAGS" \
      --extra-ldflags="$LDFLAGS" \
      --extra-ldexeflags=-pie \
      --enable-runtime-cpudetect \
      --disable-static \
      --enable-shared \
      --disable-ffprobe \
      --disable-ffplay \
      --disable-debug \
      --disable-doc \
      --enable-avfilter \
      --enable-decoders \
      $ADDITIONAL_CONFIGURE_FLAG

  make clean
  make -j16
  make install
}

build_android

同样.需要的功能自行在上面取消 .这里的脚本只是实现的自动化编译功能,具体你要使用的ffmpeg功能还的按需所取

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值