530 个能解,占编解码器表的 95%,是编码器的 2.5 倍。 能解码不等于能播——播放器自带的解码器比这少得多。
3.11.5 讲能编的那 211 个,这一节讲能解的 530 个。 两个数一比,就能解释「ffplay 能放但浏览器放不了」这类问题。
一、95% 这个比例意味着什么
把总数拆开,能解的占了绝大多数:
能力 数量 占比
只能解 346 62% 能解也能编 184 33% 解码器合计 530 95% 编解码器总数 557 100%
解码器比编码器多 2.5 倍,原因很朴素: 世界上出现过的格式远多于「值得重新编码」的格式,能读就行,不必能写。
第一行 62% 是最值得注意的:这 346 个格式只能解、不能编。 它们的存在就是「历史包袱」这个词最具体的解释。
二、能解码不等于能播
这是本节最实用的一段,它解释了一大类「文件没坏但放不了」:
层次 谁来解 差异
ffmpeg 命令行 libavcodec 530 个全能用 系统播放器 自带解码器 通常几十个 浏览器 内置解码器 更少,只认主流几个
所以「ffplay 能放、浏览器放不了」不是文件坏了,是对方的解码器少。 解法不是修文件,是转成一个浏览器认识的编码(h264 加 aac)。
这条差异还有一个反向用法:选输出编码时以最弱的那个播放器为准。 要给浏览器看就一路 h264,别为了省点码率选个冷门编码。
三、硬解与软解在表里是两个条目
同一个格式,软件解和硬件解是两条独立的记录:
形态 例子 特点
软件解码 h264 CPU 算,什么机器都能跑 硬件解码 h264_qsv/h264_cuvid 要特定显卡,快但挑机器
本机这份是通用构建,硬件解码那几条不一定在——要 -decoders | grep qsv 查。
查不到不代表机器不支持硬解,可能只是这份二进制没编那一块。
这个「查不到有两种原因」的坑,在 3.11.4 的设备那一节也出现过一次。 凡是「清单里没有」的现象,都要先分清是「没编进去」还是「机器不支持」。
四、动手 Demo:530 个能解,2.5 倍于编码器
把方向再翻一次:只统计能解的,然后与能编的对比。 最后再看一个具体解码器的硬件加速配置数——这个数不为 0 说明它能交一部分活给显卡。
import av
both, donly = 0, 0
for n in av.codecs_available:
try:
r = av.codec.Codec(n, u"r")
except Exception:
continue
if not r.is_decoder:
continue
try:
w = av.codec.Codec(n, u"w")
except Exception:
donly += 1
continue
if w.is_encoder:
both += 1
else:
donly += 1
print(u"能解合计 %d" % (both + donly))
print(u"其中只能解 %d" % donly)
print(u"两边都能 %d" % both)
c = av.codec.Codec(u"h264", u"r")
print(u"解码器 %s" % c.name)
print(u"硬件配置数 %d" % len(c.hardware_configs or []))
实跑输出:
--------------------------------------------------------------------
3.11.6 -decoders——530 个能解,占绝大多数
--------------------------------------------------------------------
**① 解码器占了编解码器表的 95%**
能力 数量 占比
----------------------------------
只能解 346 62%
能解也能编 184 33%
解码器合计 530 95%
编解码器总数 557 100%
**解码器比编码器多 2.5 倍,原因很朴素:**
**世界上出现过的格式远多于「值得重新编码」的格式,能读就行,不必能写。**
**② 能解码不等于系统播放器能播**
层次 谁来解 差异
-------------------------------------------------------
ffmpeg 命令行 libavcodec 530 个全能用
系统播放器 自带解码器 通常几十个
浏览器 内置解码器 更少,只认主流几个
**这解释了「ffplay 能放但浏览器放不了」这类问题:不是文件坏了,是解码器少。**
**解法不是修文件,是转成一个浏览器认识的编码(h264+aac)。**
**③ 硬件解码和软件解码,在表里是两个条目**
形态 例子 特点
----------------------------------------------------------------
软件解码 h264 CPU 算,什么机器都能跑
硬件解码 h264_qsv/h264_cuvid 要特定显卡,快但挑机器
**本机这份是通用构建,硬件解码那几条不一定在——要 `-decoders | grep qsv` 查。**
**查不到不代表机器不支持硬解,可能只是这份二进制没编那一块。**
**④ 解码器也能查出细节**
项 值
------------------------------------------------------------------
名字 h264
完整名 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
能解的像素格式数 0
硬件加速配置数 5
**最后一行是个有用的信号:硬件加速配置数不为 0,说明这个解码器能交一部分活给显卡。**
**具体有哪几种、支持不支持,3.11.8 那一节会展开。**
「能解合计」这个数除以能编的那个数,就是本节标题里的倍数关系。 两个数都随构建变化,但「解远多于编」这个方向不会变。
最后一行是硬件加速的入口:配置数不为 0,说明这个解码器能交活给显卡。 具体有哪几种、哪几种在这台机器上可用,3.11.8 那一节展开讲。
h264 这个名字值得注意:它是内置解码器,与 libx264 不是一回事。
-c:v h264 走的是 FFmpeg 自研的那一套,-c:v libx264 走外挂库,两者参数集不同。
30 秒实验
- 数能解的:
ffmpeg -decoders | wc -l,与-encoders对比倍数。 - 查硬解:
ffmpeg -decoders | grep qsv,没有就说明这份构建没编硬件解码。 - 转成通用格式:
ffmpeg -i 冷门.mp4 -c:v libx264 -c:a aac 出.mp4,给浏览器看。
常见误区
- 以为 ffplay 能放就等于别人也能放。解码器数量差着几百个,浏览器只认主流几个。
- 把
h264和libx264当成同一个编码器。一个是内置解码器,一个是外挂编码库,参数不通用。 - 查不到
h264_qsv就断定机器不支持硬解。可能只是这份构建没编那一块。
自测三问(点开对答案)
1. 为什么解码器数量远多于编码器? —— 因为历史上出现过的格式很多,能读就够了;值得重新编码的格式少得多。 2. ffplay 能放、浏览器放不了,怎么解释? —— 两者的解码器数量差很多:ffmpeg 有几百个,浏览器只内置主流几个,不是文件坏了。 3. `-decoders` 里查不到 `h264_qsv`,有哪两种可能? —— 一是这份构建没编硬件解码模块,二是机器确实没有对应的硬件;要分开排查。- ☐ (本节完,下一节 3.11.7 -protocols)