🎬 第一章 编译FFmpeg源码并搭建开发环境
📄 一句话概括

顺序是先把 x264、x265 编成库,再让 FFmpeg 去链它们。 MSVC 产物是 .lib 加 -60.dll,与 MinGW 的 .dll.a 不能互换。

📝 本节和前面几节的关系

1.2.5 装的是通用依赖,这一篇还要额外编两个编码器。 下一篇 1.2.7 是同一件事的 MinGW 版本,两篇对照着看最清楚。

一、为什么要先编 x264 与 x265

FFmpeg 自己不含 H.264 编码器,它只负责「调」外面的库。 所以 --enable-libx264 的意思不是「编译 x264」,而是「去链已经存在的 x264」。 先有库,才有得链。 顺序 编什么 产物 给谁用


1 x264 libx264.lib + .dll FFmpeg 的 H.264 编码 2 x265 libx265.lib + .dll FFmpeg 的 H.265 编码 3 FFmpeg avcodec.lib 等 + DLL 你的程序

顺序不能颠倒。 先编 FFmpeg 再补 x264, 只能把 FFmpeg 删了重编一遍——configure 的结果是写死在 config.h 里的,改不了。 x264 与 x265 自己也要用汇编器。 这就是 1.2.5 里 yasm 与 nasm 的用处; 没有它们,configure 会在汇编那一步失败。

二、configure 的四组参数

一条 configure 命令里,参数按用途分四组: 组 参数 作用


工具链 --toolchain=msvc 用 cl 编 产物 --enable-shared --disable-static 只出动态库 外部库 --enable-libx264 --enable-libx265 开两个编码器 许可 --enable-gpl x264 是 GPL,必须开

--enable-shared --disable-static 这一组,二次开发必须开。 静态库会把所有代码塞进你的 exe, 体积几十兆,改一次库就要重编整个工程;动态库只留导入库,链接快、换库方便。 --extra-cflags 与 --extra-ldflags 是给 x264 指路的。 FFmpeg 不知道 x264 装在哪, 得靠这两个参数把 include 与 lib 目录传进去。 少传一个会怎样: configure 报「找不到 libx264」,然后把 H.264 编码关掉, 整个编译照样成功。 这是最容易白编一次的地方。

三、产物清单:编完该看见什么

文件 是什么 二次开发要不要


avcodec.lib 导入库,链接时用 要 avcodec-60.dll 运行时库,发版要带 要 libavcodec/avcodec.h 头文件 要 libavcodec.dll.a MinGW 的导入库 不要 libavcodec.a 静态库 不要

三样配齐才叫「能开发」:头文件决定能不能编过,导入库决定能不能链上, DLL 决定运行时能不能起来。少一样,错在不同的阶段。 make install 之后,这三样都在 --prefix 指定的目录下,分别是 include、lib、 bin 三个子目录。

四、.lib 与 .dll.a 为什么不能互换

两者都是「导入库」,但格式不同,一个是 COFF,一个是 ar 归档。 项 .lib(MSVC) .dll.a(MinGW)


格式 COFF 导入库 GNU ar 归档 符号名 __imp_av_xxx _av_xxx 或 av_xxx 给谁用 cl / link gcc / ld 混用报错 LNK2019 undefined reference

混链的报错特别能骗人:符号明明在库里,链接器说找不到。 原因是 MSVC 找的是 __imp_ 前缀的导入符号,而 GNU 格式的导入库里存的是另一套名字。 名字对不上,跟有没有这个函数无关。 所以第一件事永远是「统一工具链」:Qt 用哪套、VS 用哪套、Python 绑定用哪套, FFmpeg 就跟着哪套编。 本机验不了这一步:cl.exe 不在 PATH,Visual Studio 目录也不在, INCLUDE 与 LIB 两个环境变量都是空的。清单是真的,执行需要另一台机器。

五、动手 Demo:MSVC 工具链编 5.0+Libx264+Libx265——命令怎么拼

本机没有 cl,所以这一段做两件事:拼命令并逐项检查开关,再看产物名。 最后用 PyAV 证明「本机这版确实带了 x264 与 x265」。

line = ("./configure --toolchain=msvc --arch=x86_64 --enable-shared "
        "--disable-static --enable-gpl --enable-libx264 --enable-libx265")

need = ["--toolchain=msvc", "--enable-shared", "--enable-gpl"]
for n in need:
    print(n, n in line)

实跑输出:

--------------------------------------------------------------------
MSVC 工具链编 5.0+Libx264+Libx265——命令怎么拼
--------------------------------------------------------------------

**① configure 那一行,参数分四组**

  组         参数                                  管什么
  --------------------------------------------------------------------------------
  工具链     --toolchain=msvc                      叫 cl 来编
  产物       --enable-shared                       出 DLL,二次开发要它
  外部库     --enable-libx264 --enable-libx265     开 H.264/H.265 编码
  许可       --enable-gpl                          x264 是 GPL,不开就编不进去

**② 拼出来的完整命令行(本课按教材参数复原)**

`./configure --toolchain=msvc --arch=x86_64 --enable-shared --disable-static `
`--enable-gpl --enable-libx264 --enable-libx265 --extra-cflags=-I../x264/in`
`clude --extra-ldflags=-LIBPATH:../x264/lib`

**③ 参数齐不齐,用代码检查一遍**

  开关                 在不在
  -------------------------------
  --toolchain=msvc     在
  --arch=x86_64        在
  --enable-shared      在
  --disable-static     在
  --enable-gpl         在
  --enable-libx264     在
  --enable-libx265     在

七个开关一个不缺。

**④ MSVC 出来的是这几个文件**

  文件                  是什么                 二次开发要不要
  ---------------------------------------------------------------
  avcodec.lib           导入库,编译时要它     要
  avcodec-60.dll        运行时库,发版要它     要
  avcodec/avcodec.h     头文件                 要
  avcodec.dll.a         MinGW 的导入库         不要,格式不同

**这里有一条硬规矩:`.lib` 与 `.dll.a` 不能互换。** 前者是 MSVC 的 COFF 导入库,
后者是 GNU 的 ar 归档;混着链,链接器会报「无法解析的外部符号」,而符号明明就在里面。

**⑤ 本机为什么验不了这一步**

`cl.exe` 不在 PATH(Demo 2 里查过),`INCLUDE` 与 `LIB` 两个环境变量都是 0 段。
MSVC 的编译能力绑在「开发者命令提示符」里那一套环境变量上,光装 VS 不进去点那一下,
命令行里永远找不到 cl。

**⑥ 本机能验的那一半:libx264 与 libx265 确实在**

`libx264`:在
`libx265`:在
`h264`:在
`hevc`:在

本机这版 FFmpeg(编解码器 557 个)是带 x264 与 x265 的。所以「有没有 x264」这一层能验;
「怎么把 x264 编进 FFmpeg」这一层验不到——那需要编译器。

七个开关一个不缺。 这类检查在真机上同样有用:长命令一行行看容易漏,交给代码数。 最后那几张表里,libx264 与 libx265 都「在」,说明本机这版带两个编码器。

30 秒实验

  1. 把本节的 configure 命令存成 build.sh,用 bash -x 跑一遍看每一步展开成什么。
  2. cl 找不到时,打开「x64 Native Tools Command Prompt」再敲一次,看有没有版本号。
  3. python -c "import av; print('libx264' in av.codec.codecs_available)" 确认本机这版带不带 x264。

常见误区

  1. 先编 FFmpeg 再补 x264。 configure 的结果写死在 config.h 里,补完只能删掉重编。
  2. 忘了 --enable-gpl。 开了 libx264 却不开 gpl,configure 直接报错退出。
  3. 拿 MinGW 的 Qt 去链 MSVC 编的 FFmpeg。 报 LNK2019,这不是「部分能用」,是一个符号都链不上。
自测三问(点开对答案) 1. 为什么必须先编 x264 再编 FFmpeg? —— FFmpeg 不含 H.264 编码器,只负责调用外部库。configure 时要能找到并链上已有的 x264。 2. `--enable-shared --disable-static` 对二次开发意味着什么? —— 只产出动态库:导入库小、链接快、换库不用重编整个工程。静态库会把代码全塞进 exe。 3. 看见 LNK2019 无法解析 `__imp_avcodec_send_packet`,最可能的原因是什么? —— 拿 GNU 格式的 .dll.a 给 MSVC 链了。符号名格式不同,必须换成 .lib。

相关笔记