🎬 第五章 AVUtil通用工具层理论及案例实战
📄 一句话概括

每个编码器都带着一份选项清单,分为通用项与专有项。 每一项不只是一个键,还有类型、默认值、范围与可选值。

📝 本节和前面几节的关系

5.4 讲怎么把键传进去,这一节讲这些键到底是什么。 下一章 6.1 转去协议层。

一、清单分两份存

编码器对象上有 supported_options,里面是 generic 与 private。 清单 本机个数 是什么


generic 109 所有编码器共有的通用项 private 48 libx264 自己加的专有项

分两份存很省事:换一个编码器,通用项几乎不变,专有项整份换掉。 crf、preset、tune、profile 都在 private 里,因为它们只有 x264 这类编码器才有。 g 与 b 在 generic 里,因为所有编码器都讲 GOP 与码率。

二、每一项是九条信息

这不是键值对,是一条完整的说明书。 字段 含义


name 键名 help 一句话说明 type 值的类型 is_array 是不是数组 default 默认值 min/max 允许范围 flags 对编码还是解码有效 choices 枚举型的可选值

「默认值」这一栏最有用,也最容易看错。 crf 的默认是 -1,profile 的默认是 -99。 负数在这里表示「不指定」,不是「取这个值」。 「flags」这一栏能省事:它写明这一项是只管编码、还是编解码都管。 想找一个解码参数时,看这一栏就能筛掉一半。

三、三种形态

给值的写法不一样,给错了不报错。 形态 例子 怎么给


普通值 b、g、crf 直接给数 枚举 aq-mode 从 choices 挑名字 位组合 flags、flags2 多个名字加号连

位组合最容易写错。 flags 有二十个可选名字(unaligned、qpel、loop、gray 等), 给一个名字是「只开这个」,给两个加号连起来是「两个都开」。 给错类型不会立刻报错,可能等到编码中途才失败,也可能干脆按默认值走。 所以改选项前先查清单里的 type。

四、这份清单最实际的用法

不知道某个键存不存在、默认多少、能填什么,直接查清单。 疑问 清单里看哪一栏


有没有这个键 有就说明支持 默认是多少 default 能填什么值 type 与 choices 改这一项有用吗 flags,看方向对不对

比翻文档快,而且准。 文档写的可能是别的版本,清单是这一台机器上这一份库的真实情况。 这解释了一个常见困惑:网上抄来的参数在自己机器上没效果,很可能是这个编码器压根没有那个键。 清单里查一下就清楚了。 第八章讲编解码实战时会反复用到这一节。 到那时候,把清单当成查字典的工具就够了。

五、动手 Demo:选项——一个键能带多少种形态

拆开 preset 这一项,看一条选项到底带多少信息。

import av
import av.logging

av.logging.set_level(av.logging.ERROR)
cc = av.CodecContext.create("libx264", "w")
av.logging.set_level(av.logging.WARNING)
so = cc.supported_options
print(len(so.generic), len(so.private))
for o in so.private:
    if o.name == "preset":
        print(o.name, o.type.name, o.default, o.flags.name)

实跑输出:

--------------------------------------------------------------------
选项——一个键能带多少种形态
--------------------------------------------------------------------

**① 编码器自己就带着一份选项清单**

  清单        个数     是什么
  -----------------------------------------------
  generic     109      所有编码器共有的通用项
  private     48       libx264 自己加的专有项

**通用项与专有项分两份存,这个设计很省事**:换一个编码器,通用项几乎不变,专有项整份换掉。

**② 每一项不是「键值对」,而是一条完整的说明**

拿 preset 这一项拆开看,它有九个字段:名字、说明、类型、是不是数组、默认值、最小值、最大值、
适用标志、可选值。

  字段        preset 的值
  ------------------------------------------
  name        preset
  type        STRING
  default     medium
  choices     0 个
  flags       ENCODING_PARAM|VIDEO_PARAM

**「默认值」这一栏最有用。** crf 的默认是 -1,意思是「不用这个模式」;
profile 的默认是 -99,也是「不指定」。**负数在这里表示「没设」。**

**③ 三种形态:普通值、枚举、位组合**

  形态       例子              怎么给值
  --------------------------------------------------------
  普通值     b、g、crf         直接给数
  枚举       aq-mode           从 choices 里挑一个名字
  位组合     flags、flags2     多个名字用加号连

**位组合最容易写错。** flags 有二十个可选名字(unaligned、qpel、loop…),
给一个名字是「只开这个」,给两个加号连起来是「两个都开」。

**给错类型的值不会立刻报错**,可能等到编码中途才失败,或者干脆按默认值走。
**所以改选项之前先查清单里的 type。**

**④ 这一节的实际用法**

**不知道某个键存不存在、默认是多少、能填什么,就看这份清单。** 比翻文档快,
而且准——文档写的可能是别的版本。

**这也解释了一个常见困惑**:网上抄来的参数在自己机器上没效果,很可能是这个编码器压根没有那个键。
清单里查一下就清楚了。

109 与 48 是两个清单的条数,一个通用一个专有。 o.flags 直接格式化会打成数字,要用它的 name 属性才出名字。

30 秒实验

  1. 把 preset 换成 crf,看它的默认值与类型。
  2. 数一数 generic 里有多少项的 flags 含 ENCODING_PARAM。
  3. 找一个 choices 不为空的项,把可选值打出来。

常见误区

  1. 把 -1、-99 当有效值。 这些负数表示「不指定」。
  2. 给枚举项随便填数。 要从 choices 里挑名字,填错按默认走。
  3. 以为文档写的就是本机有的。 以清单为准,文档可能对应别的版本。
自测三问(点开对答案) 1. generic 与 private 差在哪? —— generic 是所有编码器共有的通用项,private 是某个编码器自己加的专有项。 2. crf 的默认值是 -1,什么意思? —— 表示不指定,即不使用 CRF 模式。负数在选项里普遍表示「没设」。 3. 想知道某个参数能不能用,怎么查最快? —— 看 supported_options 的清单,比翻文档准,因为它是本机这一份库的真实情况。

相关笔记