认识ffmpeg编译、以及参数解释
创始人
2024-05-13 18:19:54
0

文章目录

    • 源码
    • 编译参数
      • 环境目录
      • 链接库
      • 编译速度、程序大小
        • 可执行程序属性
        • 编码器
        • 环境工具(不同平台使用不同工具)
        • 协议
    • 编译脚本(下文简称为`configure`)
    • 完整静态编译
    • 下载-编译脚本(Android)

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

ffmpeglibav_codeclibav_formatlibav_filterlibav_devicelibav_utillibsw_resamplelibsw_scalelib_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/bashif [ -d build ];thenmkdir 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 ..." to include in what will be committed)config.hdoc/config.texiffbuild/.configffbuild/config.fateffbuild/config.logffbuild/config.makffbuild/config.shlibavcodec/bsf_list.clibavcodec/codec_list.clibavcodec/parser_list.clibavdevice/indev_list.clibavdevice/outdev_list.clibavfilter/filter_list.clibavformat/demuxer_list.clibavformat/muxer_list.clibavformat/protocol_list.clibavutil/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_glinux-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/bashif [ ! -d build ];thenmkdir 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/bashcd ~/if [ ! -f "ffmpeg-4.2.2.tar.bz2" ];thenwget https://ffmpeg.org/releases/ffmpeg-4.2.2.tar.bz2tar -xjvf ffmpeg-4.2.2.tar.bz2
fi
cd ffmpeg-4.2.2path=($(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 archbitif [[ $archbit = 64 ]];thenecho "start build for 64bit..."ARCH=aarch64CPU=armv8-aAPI=23PLATFORM=aarch64ANDROID=androidCFLAGS=""LDFLAGS=""
elif [[ $archbit = 32 ]];thenecho "start build for 32bit..."ARCH=armCPU=armv7-aAPI=23PLATFORM=armv7aANDROID=androideabiCFLAGS="-mfloat-abi=softfp -march=$CPU"LDFLAGS="-Wl,--fix-cortex-a8"
elseexit
fiexport 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/$CPUfunction 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_FLAGmake cleanmake -j16make install
}build_android

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

相关内容

热门资讯

晋祠导游词 晋祠导游词  作为一名专门为游客提供帮助的导游,通常需要准备好一份导游词,导游词具有极强的实用性,涉...
昆明大观楼导游词 昆明大观楼导游词  作为一名专门为游客提供帮助的导游,常常要写一份好的导游词,导游词是导游员在游览时...
许昌西湖公园的导游词 许昌西湖公园的导游词  今天,我带领大家来游览位于许昌市中心的西湖公园,希望我们能一起渡过一段快乐的...
刘公岛导游词 刘公岛导游词范文(精选5篇)  作为一名乐于助人的导游,总归要编写导游词,导游词是导游员同游客交流思...
九龙洞风景区导游词贵州导游词 九龙洞风景区导游词贵州导游词  作为一名默默奉献的导游,时常需要编写导游词,导游词一般是根据实际的游...
云南澜沧江导游词 云南澜沧江导游词  澜沧江是湄公河上游在中国境内河段的名称,藏语拉楚,意思为“獐子河”。它也是中国西...
新疆概况旅游导游词 新疆概况旅游导游词范文(精选3篇)  作为一名尽职尽责的导游,有必要进行细致的导游词准备工作,借助导...
颐和园的导游词资料 关于颐和园的导游词资料  导游词是导游人员引导游客观光游览时的讲解词,是导游员同游客交流思想,向游客...
北京导游词 北京导游词(合集15篇)  作为一名优秀的旅游从业人员,时常要开展导游词准备工作,一篇完整的导游词,...
泰山景点介绍导游词 泰山景点介绍导游词(通用5篇)  作为一位不辞辛劳的导游,通常需要准备好一份导游词,导游词可以加深游...
校园导游词 校园导游词  作为一名专门引导游客、助人为乐的导游,就难以避免地要准备导游词,导游词一般是根据实际的...
韩国景点导游词 韩国景点导游词  大家好!  首先,欢迎大家到韩国首尔来旅游,下面就由我给大家介绍一下这个具有东方神...
介绍洛阳的导游词 介绍洛阳的导游词  洛阳位于河南,在那里有许多的特色文化,那么关于介绍洛阳的导游词都有哪些呢?下面是...
桂林聚龙潭导游词 桂林聚龙潭导游词  作为一位无私奉献的导游,时常需要用到导游词,导游词不是以一代百、千篇一律的,它必...
炳灵寺石窟导游词 炳灵寺石窟导游词  作为一名尽职尽责的导游,常常要根据讲解需要编写导游词,导游词是导游人员引导游客观...
西安大雁塔导游词 西安大雁塔导游词500字  游客朋友们:  大家好!  欢迎大家到西安大雁塔观光旅游!  大雁塔位于...
马鞍山森林公园讲解词 马鞍山森林公园讲解词  森林公园的导游词篇一:马鞍山森林公园导游词  大家好!欢迎来到马鞍山森林公园...
武汉导游词 武汉导游词范文(精选8篇)  作为一无名无私奉献的导游,时常需要用到导游词,导游词是导游员进行实地口...
大慈岩导游词 大慈岩导游词五篇  篇一:大慈岩导游词  大慈岩概况 在前面大家可以往右看一下。我们会看到在山腰上有...
五爷庙和杨五郎的关系导游词 五爷庙和杨五郎的关系导游词  一提起五台山,就知道它是五台山香火最旺,许愿最灵的寺庙。万佛阁是五爷庙...