🎬 第二章 把控FFmpeg骨架:【八大金刚】核心开发库
📄 一句话概括

八个库是「一底七柱」:libavutil 打底,其余七个各管一段。 能数出条目的是 codec、format、filter 三个,其余四个靠规则干活。

📝 本节和前面几节的关系

第一章把库编出来了,从这一章开始认它们各自管什么。 这一篇先给全景,2.2 起一个一个拆。

一、八个库,一句话一个

教材叫「八大金刚」,指的是这八个。 库 一句话 本机版本


libavutil 底座:内存、字典、日志、枚举 60 libavcodec 编解码器,五百多个 62 libavformat 容器读写,四百多个格式 62 libavfilter 滤镜,四百多个 11 libavdevice 摄像头、声卡、屏幕 62 libswscale 缩放与像素格式 9 libswresample 音频重采样 6 libpostproc 画面后处理,本机没有 —

这八行按「离业务远近」排:越往上越是工具,越往下越是具体功能。 你自己写的第一行代码, 多半从中间的 libavformat 开始。

二、谁垫在谁身上

依赖关系是一棵树,根是 libavutil。 库 底下垫着谁


libavutil 没有 libavcodec libavutil libavformat libavutil、libavcodec libavfilter libavutil、libswscale、libswresample libavdevice libavformat、libavcodec libswscale libavutil libswresample libavutil

这张表能回答「为什么链接时要加那么多库」。 用 libavformat 读文件,它自己要 avcodec 解、 avutil 打底,三个库一行都少不了。 链接顺序也有讲究:被依赖的放后面,否则 GNU ld 会报未定义符号。 -lavformat -lavcodec -lavutil 这个顺序不是随便写的。

三、三个能数的,四个数不出的

能数出条目的是 codec、format、filter,它们有「注册表」。 库 数什么 本机数量


libavcodec codecs_available 557 libavformat formats_available 414 libavfilter filters_available 468

这三个数很像,但含义差得远。 557 是「能压/能解的东西」,414 是「能装/能拆的盒子」, 468 是「能对画面做的动作」。 三个数对不上别人的构建,就是装的不是同一版。 这是排「我这儿没有某某功能」时最快的判断方法。

四、一张图看懂数据怎么流

步 谁在干 手里拿的是什么


读 libavformat AVPacket(压缩包) 解 libavcodec AVFrame(原始帧) 改 libavfilter 还是 AVFrame 转 libswscale/swresample 换格式的帧 编 libavcodec 新 AVPacket 写 libavformat 进容器

这条流水线是全课的主干,后面每一章都在放大其中一段。 转封装只走「读 → 写」两步,转码才把中间四步全走一遍。 记住这张表,就看懂了「为什么转封装快、转码慢」。

五、动手 Demo:八个库的账本——每个库能数出多少条目

这一段把能数的三个数出来,再摆一遍依赖关系。 数不出来的一律标「—」,不编数字。

import av, av.filter

print(len(av.codec.codecs_available))
print(len(av.formats_available))
print(len(av.filter.filters_available))
print(len(av.video.format.names))

实跑输出:

--------------------------------------------------------------------
八个库的账本——每个库能数出多少条目
--------------------------------------------------------------------

**① 有的库能数,有的库数不出来**

  库                能数出的东西             数量
  ---------------------------------------------------
  libavcodec        codecs_available         557
  libavformat       formats_available        414
  libavfilter       filters_available        468
  libswscale        像素格式名               267
  libavutil         工具函数,数不出         —
  libavdevice       设备,靠格式名间接看     —
  libswresample     采样格式,数不出         —
  libpostproc       本机没编进来             0

**这四个数不是同一层的东西。** 前三个是「条目表」,
第四个是「枚举量」——像素格式在 libavutil 里定义,只是由 libswscale 负责转换。

**② 一层压一层,谁离不开谁**

  库                底下垫着谁
  ----------------------------------------------------------
  libavutil         没有,它是最底
  libavcodec        libavutil
  libavformat       libavutil、libavcodec
  libavfilter       libavutil、libswscale、libswresample
  libavdevice       libavformat、libavcodec
  libswscale        libavutil
  libswresample     libavutil
  libpostproc       libavutil

**这张表解释了一个常见困惑:只读一个文件,链接时要加三四个库。**
libavformat 自己要 avcodec 帮忙,avcodec 又要 avutil 打底。少加一个,链接器就报一堆未定义符号。

**③ 三个数的量级记住了有用**

编解码器 **557** 个、格式 **414** 个、滤镜 **468** 个。
看见某个格式报「不认识」,先数一遍这三个数——数出来跟别人的不一样,就是两人装的不是同一版构建,
不是代码写错了。

三个条目数加一个枚举量:557、414、468、267。 前三个是注册表,最后一个是枚举,量级不同但都能当「构建指纹」用。

30 秒实验

  1. python -c "import av; print(len(av.codec.codecs_available))",跟本节表格对一下数。
  2. 找一个网上的 FFmpeg 版本对照表,看 557 对应哪个大版本。
  3. 把八个库名按依赖顺序排一行,再从右往左删,看删到哪个链接会报错。

常见误区

  1. 以为八个库是八个独立的东西。 它们是一棵树,libavutil 必须在。
  2. 链接时不按依赖顺序写 -l。 GNU ld 从右往左解析,顺序错就报未定义符号。
  3. 拿三个条目的数量当版本号。 它们是构建指纹,不同构建可能同数量。
自测三问(点开对答案) 1. 八个库里哪一个不能省? —— libavutil。其余七个都直接或间接依赖它,没有它什么都链接不上。 2. 557、414、468 分别是什么? —— 编解码器、格式、滤镜的条目数。一个是压解能力,一个是容器,一个是对画面的动作。 3. 为什么转封装比转码快? —— 转封装只走「读包 → 写包」,不经过解码与编码;转码要把中间四步全走一遍。

相关笔记