用msys2与mingw编译FFmpeg
  1bTlX33AWdQ4 2023年11月02日 56 0

FFmpeg 官网提供了两种编译源码的方法。

1,msys2 + mingw (本文的编译方法)

2,msys2 + msvc

MinGW 在前面文章​​《MinGW介绍》​​已经介绍过了,MinGW 就是 把 gcc 编译器移植到 windows 了,并且提供了一些 以前只有在 Linux 才有的函数,例如 pthread_create() 。


为什么需要安装 msys2 ?

因为 windows 环境只能执行 batch 脚本,不能执行 shell 脚本。同时 windows 的 CMD 命令行,也没有 make,ls,mkdir 这些 linux 的命令。所以需要安装 msys2,可以把 msys2 理解成一个 linux 的环境,在 msys2 里面可以执行 shell 脚本跟很多linux的操作。


msys2 的安装请看 ​​《MSYS2介绍》​​,下面开始操作,打开普通的命令行窗口,执行以下命令,进入 msys2 环境:

cd C:\msys64
.\msys2_shell.cmd -mingw64

上面的 ​​-mingw64​​ 是使用 64位的 gcc,如果需要使用 32 位 gcc,可以用 ​​-mingw32​

在 msys2 环境下,安装一些 必要的软件:

# 刷新软件包数据
pacman -Sy
# 安装mingw-w64。
pacman -S mingw-w64-x86_64-toolchain
pacman -S git
pacman -S make
pacman -S automake
pacman -S autoconf
pacman -S perl
pacman -S mingw-w64-x86_64-SDL2
pacman -S libtool
pacman -S mingw-w64-x86_64-cmake
pacman -S pkg-config
pacman -S yasm
pacman -S diffutils
# 编译x264 需要 nasm
pacman -S nasm

小技巧, pacman -Ss 关键字:在仓库中搜索含关键字的包。


然后上 Github 下载 ​​FFmpeg-n4.4.1.zip​​ 代码,放到 下图中的目录,这样 msys2 环境也能找到。

用msys2与mingw编译FFmpeg_linux

用msys2与mingw编译FFmpeg_动态库_02


进入 FFmpeg-n4.4.1 目录,开始编译,命令如下:

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

./configure \
--prefix=/home/loken/ffmpeg/build64/ffmpeg-n4.4.1-mingw \
--enable-gpl \
--enable-debug=3 \
--disable-optimizations \
--disable-asm \
--disable-stripping \
--enable-nonfree \
--enable-sdl2 \
--enable-shared

make -j8
make install

上面的命令执行完之后,ffmpeg-n4.4.1-mingw 目录的结构如下:

用msys2与mingw编译FFmpeg_FFmpeg_03

可以看到,FFmpeg 的 makefile 特别智能,帮我们生成了 lib 导入库,这样就能很方便被 msvc 使用。

我们用 DependenciesGui.exe 查看一下 ffmpeg.exe 的整体依赖情况

用msys2与mingw编译FFmpeg_动态库_04

上图中,圈出来的 dll 都是 mingw 里面的 dll。因为 mingw 编译出来的 ffmpeg 依赖这些 mingw 的库,所以只能在 msys2 环境下跑 ffmpeg.exe ,如果想在 WinCMD 创建运行 ffmpeg.exe ,需要把这些依赖的库拷贝到 跟 ffmpeg.exe 同级的目录。


我们可以 使用 以下命令 查看 avutil-56.dll 导出了哪些函数给我们使用。

dumpbin /EXPORTS avutil-56.dll > avutil-56.txt

用msys2与mingw编译FFmpeg_命令行_05

从里面找到了一个 av_version_info 函数,注意那个地址 0005C570 。


我们现在测试一下 这个 avutil 动态库 在 MSVC 编译环境下好不好用。在 D 盘新建一个 目录 ffmpeg-test ,再创建一个 version.c 文件,内容如下:

#include <stdio.h>
const char *av_version_info(void);
int main()
{
printf("Hello FFMPEG, version is %s\n", av_version_info());
return 0;
}

上面 av_version_info 函数 的声明是我从 avutil.h 头文件里面扣出来的。

把 avutil.lib ,avutil-56.dll 也复制 到 ffmpeg-test 目录。

把 C:\msys64\mingw64\bin 目录下的 libwinpthread-1.dll 也拷贝到 ffmpeg-test 目录。如下:

用msys2与mingw编译FFmpeg_命令行_06

上面这样做是因为 avutil-56.dll 依赖 libwinpthread-1.dll 。


然后 打开 vs2019 x64 的命令窗口,进入 ffmpeg-test 目录。

用msys2与mingw编译FFmpeg_FFmpeg_07

执行以下命令开始编译:

cl.exe /c version.c
link.exe /DEBUG /OUT:version.exe version.obj avutil.lib

用msys2与mingw编译FFmpeg_FFmpeg_08

因此,MinGW 的 gcc 编译出来的 FFmpeg 动态库是好使的。


之前 dumpbin 的时候,av_version_info 函数的左边有个 0005C570 地址。这个是什么东西呢?

现在我们用 WinDbg 断点调试 一个 version.exe 文件 ,用 ​​bu version!main​​ 打一个断点,如下:

用msys2与mingw编译FFmpeg_linux_09

没看出 0005C570 跟 调试器的哪个地址有关系,暂时不管。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
1bTlX33AWdQ4