window10_ffmpeg-msys2-msvc编译 - 弦外之音

/ 0评 / 2

之前的文章都是通过 msys2+MinGW 的方式编译ffmpeg。今天就来讲解如何用 msys2 + msvc 的方式来编译ffmpeg。

ffmpeg 的源码是跨平台的,通过 configure(shell脚本) 实现不同平台的编译规则。在 configure 的时候指定 --toolchain=msvc 就可以 使用 msvc 来编译 ffmpeg。

window10 的CMD 无法运行 configure 脚本,所以需要装 msys2 ,装了 msys2 就能运行 configure 。

msys2 自行安装,msvc 是使用的vs2019 的,所以也请自行安装 vs2019,msvc 其实是一个统称,实际上 configure 里面用到的是 vs2019 里面的 cl.exe 跟 link.exe。 cl.exe 可以用来编译C代码,link.exe 用来链接的。

为了在 msys2 命令行使用 vs2019 的环境变量,需要做以下操作:

MSYS2 环境继承vs2019 的环境变量 操作教程:

1,修改 C:\msys64\msys2_shell.cmd 中的 rem set MSYS2_PATH_TYPE=inherit,去掉rem,取消这⼀句的注释。使MSYS2的环境变量继承当前CMD的窗口的环境变量。

2,重命名 C:/msys64/usr/bin/link.exeC:/msys64/usr/bin/link.bak , 避免和MSVC 的link.exe抵触。这个是网上文章的做法,这个一步操作其实在新版的ffmpeg 里面是不需要的,因为在 configure里面编译的时候,调用的是 ./compat/window/mslink ,如下:

 ./compat/window/mslink 代码
#!/bin/sh
​
LINK_EXE_PATH=$(dirname "$(command -v cl)")/link
if [ -x "$LINK_EXE_PATH" ]; then
    "$LINK_EXE_PATH" $@
else
    link.exe $@
fi
exit $?

上面是 mslink 的代码,可以看到,他的逻辑就是优先 使用 跟 cl.exe 同目录下的 link.exe。cl.exe 只有在vs2019 那里才有,C:/msys64/usr/bin 目录下没有 cl.exe,所以会优选使用 vs2019 里面的link.exe,所以不重命名 C:/msys64/usr/bin/link.exe 也没关系。

3,上面的 C:\msys64\msys2_shell.cmd 文件已经修改好了,现在要找到 x64 Native Tools Command Prompt for VS 2019 这个命令工具。

点击 x64 Native Tools Command Prompt for VS 2019 打开命令行,一定要这样打开命令行,这样命令行才能有 vs2019 的环境变量,然后才能让 msys2 来继承,我之前说的 MSYS2_PATH_TYPE=inherit 继承的环境变量 是当前窗口的环境变量就是这个意思。

千万不要用下面这种 win+R 的方式打开命令行,这样子打开命令行是没有 vs2019 的环境变量的。



4,演示完错误的打开CMD的方式,我们继续操作,在 x64 Native Tools Command Prompt for VS 2019 命令窗口输入 cd c:\msys64\ 先回到 msys64目录,然后再输入 .\msys2_shell.cmd -mingw64,启动 msys2 命令行窗口,如图:

#回到 MSYS2 的安装目录
cd c:\msys64\
#启动 msys2 命令行
.\msys2_shell.cmd -mingw64

5,在 msys2 命令行窗口 输入 echo $LIB ,可以看到 msys2 命令行窗口 已经继承了 vs2019 的 lib 环境变量。

6,再输入一下 which cl.exe ,确认一下 cl.exe 是在vs2019的目录下,同时看下cl.exe的目录是否有link.exe。


MSYS2 + MSVC 环境已经准备好了,MSYS2 命令行已经继承了 vs2019 的环境变量,下面开始编译ffmpeg,本文要编译的ffmpeg版本为 n4.4.1。

网网上的一些教程 编译ffmpeg 的时候,会 下载编译 x264fdk-aac ,然后引入ffmpeg 里面。但是 n4.4.1版本的 ffmpeg 已经基于微软的 MediaFoundation 实现了 h264 ,aac 编解码器,分别是 h264_mf 跟 aac_mf ,mf 是 MediaFoundation 的缩写。所以不需要 再编译 x264 ,也不需要编译 fdk-aac ,比较方便。

早期ffmpeg版本,例如4.2版本是没有 264 编码器的,只是自带了一个264的解码器。因为 x264fdk-aac ,这些库的版权不是ffmpeg的,所以没有直接集成进ffmpeg。ffmpeg也在开发自己的编解码器,4.4版的时候终于开发出了 h264_mf 跟 aac_mf 。

编解码器都是按照标准实现的,例如用 h264_mf 编码的mp4文件,同样能用 x264 的库去解码,反之亦然。除非项目需要,一定要用 x264fdk-aac 来进行编解码,否则用 ffmpeg 4.4.1 版本自带的 h264 ,acc 编解码器即可。

mp3 的编解码器,ffmpeg 4.4 也自带了,叫 mp3_mf ,所以也不需要下载编译 lame 库。

vp8 ,v9 标准的解码器,ffmpeg 4.4 自带了,但是vp8 ,v9 标准的编码器ffmpeg 4.4 没有自带。本文暂时不讲解 msys2 + MSVC 环境中 如何引入 vp8 ,v9 编码器到 ffmpeg 4.4 里。


下面开始正式 编译 ffmpeg。、

开始操作:

1,下载 FFmpeg-n4.4.1.zip ,百度网盘,提取码:rpo3 ,下载好之后解压到 C:\msys64\home\loken\ffmpeg ,这个目录是我们之前文章经常用的目录。

2,安装所需软件,pacman -S diffutils make pkg-config yasm

3,进入 FFmpeg-n4.4.1 源码目录

cd /home/loken/ffmpeg/FFmpeg-n4.4.1

4,执行configure ,如下:

./configure \
--prefix=/home/loken/ffmpeg/build64/ffmepg-4.4-msvc \
--enable-gpl \
--enable-nonfree \
--enable-shared \
--toolchain=msvc
​
make -j8
make install

5,编译完成之后,build64/ffmepg-4.4-msvc 目录如下:

因为 configure的时候使用了 --enable-shared 开启了编译动态库,所以生成了 一堆的 lib 跟 dll 文件,avcodec-58 等等库是以动态库的方式给 ffmpeg.exe 调用的。如果使用 --disable-shared ,avcodec-58,avdevice-58 等库是直接以静态库的方式集成进去 ffmpeg.exe,ffmpeg.exe 文件会比较大。

--disable-shared 的编译方式,只会生成 ffmpeg.exe 跟 ffprobe.exe 两个文件,而且这两个exe文件的运行不需要依赖其他的dll。

configure --enable-shared 会在bin目录生成 一堆 lib 跟 dll,ffmpeg 的api函数可以以动态库的方式给其他项目使用。

configure --disable-shared 会在lib目录生成 一堆 .a 后缀的静态库,ffmpeg 的api函数可以以静态库的方式给其他项目使用。

纠正: configure 脚本并没有 --disable-shared 这个选项,实际上不指定 --enable-shared 就是编译静态库。ffmpeg 的静态库跟动态库是互斥的,只能编译出静态库,或者只编译出动态库。

可以看到,msys2 + msvc 编译出来的 ffmpeg.exe 非常精简,不像之前 msys2 + MinGW 编译出来的 ffmpeg.exe 运行需要拷贝 libwinpthread-1 等库过来。

6,查看 ffmpeg.exe 支持的编解码器,

cd /home/loken/ffmpeg/build64/ffmepg-4.4-msvc/bin
​
./ffmpeg.exe -codecs > support_codecs.txt

从 support_codecs.txt 里面可以看到 h264_mf ,aac_mf , mp3_mf 等编码器。


MSYS2 + MSVC 编译ffmpeg 讲解完毕,下面用qt creator来调试一下 ffmpeg 的dll库,相对于MInGW编译方式,MSVC 编译有个好处,可以直接debug进去 ffmpeg api函数的内部实现。

qt creator创建 ffmpeg 项目的步奏,在《window10_ffmpeg调试环境搭建-自己编译》 文中最后已经讲过,本文不再重复讲,直接给出qt项目的zip包。直接下载即可。

ffmpeg-verison-msvc.zip 百度网盘,提取码:6kc3

运行效果如下图:

我选择了两种编译方式,MinGW 64-bit 跟 MSVC2019 64bit,两种方式都能打印出 ffmpeg 版本号。但是只有 MSVC 的方式能够断点进去 av_version_info() 函数的内部实现。

这里注意,MSVC 能断点调试的前提是不能移动或者删除之前的编译目录,也就是不能移动 C:\msys64\home\loken\ffmpeg\FFmpeg-n4.4.1 ,因为 lib 文件里面的符号定位,是定位到这个目录的文件的。

补充,需要安装CDB编调试器,要不QT MSVC环境虽然能编译成功,但不能断点调试。

CDB编调试器安装:https://www.cnblogs.com/lixuejian/p/12915174.html ,注意安装过程需要翻墙。


版权所属:知识星球:弦外之音,QQ:2338195090。 由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注