🎬 第一章 FFmpeg入门简介
📄 一句话概括

2011 年 FFmpeg 内部闹翻,一部分人出走建了 libav,四年后合并回来。 这段历史今天还在影响你:函数前缀 av_、包名 av、两套版本号,全是那次分裂的遗留。

📝 本节和前面几节的关系

1.1.2 讲了许可证这条外部的线,这一节讲项目内部那条线。 1.1.4 把许可证再拆细一层。

一、2011 年发生了什么

事情的起点是一次内部矛盾,不是技术分歧:

时间 事件 对用户的影响


2011.03 一部分开发者出走,另立 libav 暂时看不出来 2011-2015 libav 拿到域名与发行版渠道 Linux 上装的其实叫 libav 2015.08 libav 合并回 FFmpeg 名字恢复,但 API 已经长歪了 2018 libav 12.3 发布,之后停更 只剩老系统还在用

四年里最实际的伤害不是「谁对谁错」,是补丁要打两遍。 一个安全漏洞修好,两边各提交一次;发行版维护者得盯着两个仓库。

这段历史对今天的人来说,唯一的意义是: 你在老教程里看到 libav-tools 这个包名,别以为是另一个软件,它就是当年的 FFmpeg。

二、痕迹一:所有函数都带 av_ 前缀

libav 当年干的第一件事是统一命名。这套命名 FFmpeg 后来照着用了,一直没改:

今天的函数 拆开看 归哪个库


avformat_open_input av + format + 动作 libavformat avcodec_send_packet av + codec + 动作 libavcodec av_frame_alloc av + frame + 动作 libavutil avfilter_graph_create av + filter + 动作 libavfilter

命名规律很清楚:av 开头,接着是库名,最后是动词。 认得出这个规律,看到一个新函数名就能猜到它在哪个头文件里。

连 Python 那个绑定包都叫 av——它绑的就是这套接口,名字直接继承了。 所以本课的 Demo 里到处是 av.open、av.VideoFrame,根子在这儿。

三、痕迹二:同一个编码,两个名字

这是最容易让人困惑的一处,也是那次分裂留下的最深印记:

名字 谁实现 能编码吗 能解码吗


h264 FFmpeg 自研 不能 能 libx264 外部 x264 项目 能 不能 hevc FFmpeg 自研 不能 能 libx265 外部 x265 项目 能 不能

两个名字分工明确:自研的只管解,外挂的只管编。 所以压 H.264 你绕不开 x264——FFmpeg 自己没写编码器。

但实际用起来会有一个反直觉的现象:你对 h264 说要编码,它也能成。 因为 FFmpeg 内部有个别名表,会把请求转给 libx264。 名字是入口,实现是它替你选的——这一点在本节 Demo 表里能直接看到。

四、痕迹三:两套版本号从此并存

libav 那边用 11、12 这样的小号,FFmpeg 这边用 2.x、3.x,互不通气。 于是老系统里能同时存在两个「版本 12」:

看到的版本号 可能指谁 怎么区分


12 libav 12 包名叫 libav-tools 2.8 FFmpeg 2.8 包名叫 ffmpeg libavcodec 56 库接口版本 只出现在 -version 里

所以看到「我装的 FFmpeg 12」这种说法,先问一句:哪个 12? FFmpeg 的发行版号从来没到过 12,那是 libav 的号。

今天的实用结论只有一条: 在 Debian 系上装 ffmpeg 这个包,别装 libav-tools。后者是历史遗留,可能指向老东西。

五、动手 Demo:一次分叉留下的三种痕迹

下面把三种痕迹各自查一遍:函数前缀、名字与实现、版本号。 其中第三张表会让你看到「名字不等于实现」的真实表现。

import av

def mk(name, mode):
    try:
        return av.codec.Codec(name, mode)
    except Exception:
        return None

for n, md in ((u"h264", u"r"), (u"h264", u"w"), (u"hevc", u"w")):
    c = mk(n, md)
    print(n, u"编码" if md == u"w" else u"解码", u"->", c.name if c else u"无")

实跑输出:

--------------------------------------------------------------------
Libav 政变——一次分叉留下的三种痕迹
--------------------------------------------------------------------

**① 2011 年 3 月,FFmpeg 项目内部闹翻,一部分人出走建了 libav**

**理由说是「代码质量与决策流程」,实质是两派互不买账。**
**libav 拿到了域名、服务器、以及一大批发行版的信任,**
**于是 2011 到 2015 这四年,Debian、Ubuntu、Fedora 里装的其实叫 libav。**
**2015 年 8 月,libav 剩下的人撑不住,合并回 FFmpeg。**

**② 痕迹一:函数前缀 av_ 留在了所有 API 里**

**libav 当年干的第一件事是统一命名:所有对外函数加 av_ 前缀。**
**这套前缀 FFmpeg 后来照着用了,一直没改。**
**所以今天你看到 avformat_open_input、avcodec_send_packet,全是那次分叉的遗产。**

  今天的函数                       名字里的段     归哪个库
  ---------------------------------------------------------------
  avformat_open_input              avformat       libavformat
  avcodec_send_packet              avcodec        libavcodec
  av_frame_alloc                   av_frame       libavutil
  av_packet_unref                  av_packet      libavcodec
  avfilter_graph_create_filter     avfilter       libavfilter

**连 PyAV 这个 Python 包都叫 av——它绑的就是这套 av 接口。**

**③ 痕迹二:同一个编码,两个名字并存**

**h264 是 FFmpeg 自己写的解码器,libx264 是外挂 x264 的编码器。**
**两套名字今天还在同一张表里,这是「自研」与「外挂」的分界。**

  你写的名字     方向     实际拿到谁     长名
  ---------------------------------------------------------------------------
  h264           编码     libx264        libx264 H.264 / AVC / MPEG-4 AVC
  libx264        编码     libx264        libx264 H.264 / AVC / MPEG-4 AVC
  h264           解码     h264           H.264 / AVC / MPEG-4 AVC / MPEG-
  hevc           解码     hevc           HEVC (High Efficiency Video Codi
  hevc           编码     libx265        libx265 H.265 / HEVC
  vp9            编码     libvpx-vp9     libvpx VP9
  libvpx-vp9     编码     libvpx-vp9     libvpx VP9

**看第三列:写 h264 要编码器,实际拿到的是 libx264;写 hevc 要编码器,拿到的是 libx265。**
**FFmpeg 里「名字」和「实现」不是一回事,名字只是个入口,实现由它替你选。**
**这就是装 FFmpeg 时总要纠结 x264 的原因——H.264 没有自研的编码器,**
**那个 h264 只会解码;你对它说要编码,它得转手交给 libx264。**

**④ 痕迹三:分支代号与版本号从此各走各的**

**libav 那边用 11、12 这样的小版本号,FFmpeg 这边用 2.x、3.x。**
**两边对同一个 bug 的修复常常只进一边,发行版维护者得看着办。**
**这也是当年最实际的伤害:Debian 的安全补丁要打两遍。**

  年份        发生了什么                               结果
  -----------------------------------------------------------------------------
  2011        分裂,libav 拿走域名与发行版渠道         用户装到的是 libav
  2011-15     两边各自修 bug,补丁不共享               发行版要维护两套
  2015        合并回 FFmpeg,从 2.8 版起项目名恢复     libav 只剩零星维护
  2018        libav 最后一个版本 12.3 发布             只剩少数老系统还在用

第一张表是函数前缀:av 加库名加动词,规律一眼能看出来。 这一套命名是 libav 时代立的规矩,FFmpeg 一直沿用。

第二张表是重点。注意第三列: 写 h264 要编码,实际拿到的是 libx264;写 hevc 要编码,拿到的是 libx265。 而写 h264 要解码,拿到的还是 h264 自己。

这说明 FFmpeg 里「名字」和「实现」是两层: 名字是你写的入口,实现由内部的别名表替你决定。

第三张表是版本号的分叉。 看到「FFmpeg 12」这种说法要警惕——FFmpeg 的发行版号没到过 12。

30 秒实验

  1. 数前缀:ffmpeg -h full | grep "^av" 数不出东西,但如果你翻头文件,会发现几乎每个公开函数都以 av 开头。随便打开一个 libavformat/avformat.h 数前 20 行就知道了。
  2. 验别名:ffmpeg -h encoder=h264 和 ffmpeg -h encoder=libx264 输出是一样的。两次都指向同一个实现,这就是别名表在起作用。
  3. 查包名:在 Debian 系上 apt-cache show libav-tools,如果提示不存在,说明这个包已经被清理掉了——分叉的影响正在慢慢消失。

常见误区

  1. 以为 h264 是编码器。它在解码方向是自研实现,在编码方向只是个别名,实际干活的是 libx264。想知道真身,看 -encoders 的输出。
  2. 以为 libav 是 FFmpeg 的旧名字。它曾经是一个独立分支,有自己的版本号和发布节奏,不是简单改名。
  3. 以为这段历史跟今天无关。你敲的每个 av_ 函数、Python 里那个 av 包名,都是它的直接遗产。
自测三问(点开对答案) 1. 为什么 FFmpeg 的公开函数都以 av_ 开头? —— 因为 libav 分支当年推行了统一命名规范,FFmpeg 合并回来时沿用了这套规范,之后为了兼容就没再改。 2. 写 `-c:v h264` 和写 `-c:v libx264` 有什么区别? —— 实际效果一样,两者最终都走 libx264。但显式写 libx264 更清楚,也不会因为别名表变动而失效。 3. 一个老教程说「需要 FFmpeg 11 以上」,你该怎么理解? —— 大概率是把 libav 的版本号当成了 FFmpeg 的。FFmpeg 的发行版号 2026 年才到 8.x,没有 11。应该说清楚是哪个库、哪个主版本。

相关笔记