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 秒实验
- 数前缀:
ffmpeg -h full | grep "^av"数不出东西,但如果你翻头文件,会发现几乎每个公开函数都以 av 开头。随便打开一个libavformat/avformat.h数前 20 行就知道了。 - 验别名:
ffmpeg -h encoder=h264和ffmpeg -h encoder=libx264输出是一样的。两次都指向同一个实现,这就是别名表在起作用。 - 查包名:在 Debian 系上
apt-cache show libav-tools,如果提示不存在,说明这个包已经被清理掉了——分叉的影响正在慢慢消失。
常见误区
- 以为 h264 是编码器。它在解码方向是自研实现,在编码方向只是个别名,实际干活的是 libx264。想知道真身,看
-encoders的输出。 - 以为 libav 是 FFmpeg 的旧名字。它曾经是一个独立分支,有自己的版本号和发布节奏,不是简单改名。
- 以为这段历史跟今天无关。你敲的每个
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。应该说清楚是哪个库、哪个主版本。- ☐ (本节完,下一节 1.1.4 开源许可协议简介)