FFmpeg/FFmpeg2026-08-01method 2.0
Rust adoption decisionRust 采用决策 · C + assembly · media framework · 1,827,590 lines of C/headers plus 194,278 lines of hand-written asmC + 汇编 · 媒体框架 · C 与头文件 1,827,590 行,另有手写汇编 194,278 行
PARTIAL
replace the layer attacker bytes reach first替换攻击者字节最先抵达的那一层
Authorization授权 · APPROVE

Hostile bytes hit the container demux and bitstream parse layer first. That layer is 72,465 lines across 210 files, 3.6% of a 2,021,868-line tree, and it already sits behind a table-driven interface hosting 368 independent demuxer modules. Requirement and seam line up. The other 96% is excluded for one reason: 194,278 lines of it are hand-written assembly that carries the throughput and no part of the safety objective, and a rewrite inherits none of it.攻击者的字节最先落在容器 demux 与 bitstream parse 层。这一层 72,465 行,分布在 210 个文件里,占 2,021,868 行代码树的 3.6%,而且早就位于一个表驱动接口之后,接口上挂着 368 个互相独立的 demuxer 模块。需求和接缝对得上。剩下的 96% 被排除只有一个理由:其中 194,278 行是手写汇编,扛的是吞吐量,不承担安全目标的任何部分,重写一行也继承不到。

Conditional. Re-open if a demuxer replacement cannot reach bit-exact output parity on the FATE corpus, if the per-module boundary adds measurable decode overhead, or if no maintainer commits to the Rust modules. With this many modules, an unowned subsystem rots fast.有条件。出现下面任何一种情况就重开:替换后的 demuxer 在 FATE 语料上达不到逐位一致的输出;按模块划分的边界带来可测的解码开销;没有 maintainer 认领这些 Rust 模块。模块这么多,无人认领的子系统烂得很快。

Scope范围 the container demux/parse layer only, behind the existing module interface只做容器 demux/parse 层,走现有模块接口 Confidence置信度 MEDIUM Robustness稳健性 CONDITIONAL security-parser · table-driven module framework with hand-tuned SIMD安全解析器 · 表驱动模块框架,配手工调优的 SIMD
Total code measured测得的代码总量
2,021,868lines
C 1,567,523 + headers 260,067 + asm 194,278C 1,567,523 + 头文件 260,067 + 汇编 194,278
Authorized scope授权范围
72,465lines
demux 59,433 + bitstream parsers 13,032 · 210 files · 3.6%demux 59,433 + bitstream parser 13,032 · 210 个文件 · 3.6%
Excluded: hand-written asm排除项:手写汇编
194,278lines
.asm and .S · a rewrite inherits none of it.asm 与 .S · 重写一行也继承不到
Demuxer modules behind one struct挂在同一个 struct 后的 demuxer 模块
368modules个模块
libavformat/allformats.c registrationslibavformat/allformats.c 里的注册项
Decoder modules (out of scope)decoder 模块(范围外)
604modules个模块
libavcodec/allcodecs.c registrationslibavcodec/allcodecs.c 里的注册项
Codec layer left alone不动的编解码层
999,497lines
libavcodec .c+.h · 55% of C and headerslibavcodec 的 .c+.h · 占 C 与头文件的 55%

01The options备选方案

Same objective for every option: eliminate the memory-unsafety class at the point FFmpeg first interprets attacker-controlled bytes, without changing decode output or losing SIMD throughput.每个方案的目标都一样:在 FFmpeg 首次解释攻击者控制的字节的地方消除内存不安全这一整类缺陷,同时不改变解码输出,也不损失 SIMD 吞吐。

Option方案Scope范围Benefit收益Cost成本Time to value见效时间Compatibility / rollback兼容 / 回滚Evidence证据
Fuzz and harden the C demuxers对 C demuxer 做模糊测试和加固retain · the funded baseline, and it stays after the Rust modules land保留 · 有预算的基线,Rust 模块上线后继续保留STAYreduces incidence, class stays reachable降低发生率,整类缺陷仍然可达none new; existing triage load无新增;现有的分诊负担already running已经在跑native · no risk原生 · 无风险MODERATE
Sandbox the whole framework in the host在宿主里把整个框架沙箱化retain · what most large consumers actually do, and it composes with the Rust option保留 · 大型使用方实际就这么做,而且能和 Rust 方案叠加ADOPTcontains the class rather than removing it把这类缺陷关住,而不是移除host-side; IPC per stream宿主侧;每路流一次 IPCweeks数周unchanged framework · trivial rollback框架不变 · 回滚很轻STRONG
Rust demux/parse modulesRust 写的 demux/parse 模块recommended · smallest scope that removes the class where it matters推荐 · 在要紧的位置移除这类缺陷的最小范围PARTIALclass eliminated in the layer attacker bytes reach first在攻击者字节最先抵达的那一层消除整类缺陷per module; Rust toolchain + owners按模块计价;Rust 工具链 + 模块负责人one format一个格式的工期same module ABI · per-format rollback沿用同一模块 ABI · 按格式回滚MODERATE
Rewrite FFmpeg in Rust用 Rust 重写 FFmpegexclude · fails G3; the excluded 96% carries no part of the objective排除 · G3 不过;被排除的 96% 不承担目标的任何部分MIGRATEno additional safety benefit over the demux layer相比只做 demux 层,没有额外的安全收益re-create asm + 604 decoders重造汇编 + 604 个 decoderyears数年whole framework · no rollback整个框架 · 无回滚WEAK
Consumers adopt Rust media crates使用方改用 Rust 媒体 crateretain · works where the format set is small and known保留 · 格式集合小且已知时可行ADOPTclass removed for the formats the crate coverscrate 覆盖到的格式上,这类缺陷被移除per consumer; narrow format coverage按使用方计价;格式覆盖窄days per project每个项目数天different API · caller-side rollbackAPI 不同 · 在调用方回滚MODERATE

02Evidence ledger证据账本

States are evidence scoped to named options. They do not add up to a score. The performance half of the usual proposal is recorded as UNKNOWN rather than argued, because no public FFmpeg profile exists.每个状态都是绑定到具体方案的证据,不能相加成分数。常见提案里性能那一半记为 UNKNOWN,不拿来论证:没有公开的 FFmpeg 性能剖析。

D1 · Requirement & ownership需求与归属
SUPPORTS · rust optionsSTRONG
368 demuxer modules and 68 bitstream parsers own the first interpretation of attacker-controlled container data, in 72,465 lines of C.368 个 demuxer 模块和 68 个 bitstream parser 负责第一次解释攻击者控制的容器数据,共 72,465 行 C。
libavformat/*dec.c and *demux*.c (142 files) · libavcodec/*_parser.c (68 files)
D2 · End-to-end reach端到端影响
UNKNOWN · rust-fullUNKNOWN
The performance half of a full-rewrite proposal cannot be evaluated. No public FFmpeg profile gives the time share of the C that a Rust port would replace, and a line share is not a time share.全量重写提案里性能那一半无法评估。没有公开的 FFmpeg 剖析给出 Rust 移植要替换的那部分 C 占多少时间,而行数占比不等于时间占比。
no public end-to-end decode profile
D3 · Tail & runtime尾延迟与运行时
N/ASTRONG
No managed runtime or collector exists, so there is no runtime mechanism in any tail to remove.没有托管运行时,也没有回收器,尾部里没有可以拿掉的运行时机制。
C framework, no GC
D4 · Fleet footprint机群规模
N/ASTRONG
FFmpeg runs inside the caller's process or batch job; this decision changes no fleet density.FFmpeg 跑在调用方的进程或批处理作业里;这个决策不改变任何机群密度。
library and CLI invocation model
D5 · Startup shape启动形态
N/ASTRONG
Transcode jobs are long-lived relative to process start; startup is not a stated constraint.相对于进程启动,转码作业是长时任务;启动时间不在已声明的约束里。
no startup requirement asserted
D6 · Safety & correctness安全与正确性
SUPPORTS · rust-demux-partialSTRONG
The demux/parse layer interprets length fields, offsets and indices supplied by the file; replacing it in Rust removes that class by construction at the exact boundary.demux/parse 层解释的是文件给出的长度字段、偏移量和索引;用 Rust 替换它,就在这条边界上从构造上消除了这类缺陷。
libavformat demuxer read_header/read_packet implementations
D7 · Concurrency & invariants并发与不变量
NEUTRAL · allMODERATE
Frame- and slice-level threading already exists in the C implementation; no option is blocked by the language on this axis.C 实现里已经有帧级和 slice 级线程;在这条轴上没有方案被语言卡住。
libavcodec/pthread_frame.c · pthread_slice.c
D8 · Distribution分发
DISFAVORS · rust-fullMODERATE
FFmpeg builds across an unusually wide platform and architecture matrix, including targets carried mainly by their C toolchain and per-architecture assembly.FFmpeg 要在一个异常宽的平台与架构矩阵上构建,其中一些目标主要靠各自的 C 工具链和按架构写的汇编撑着。
libavcodec/{x86,aarch64,arm,ppc,riscv,loongarch,mips}/ subtrees
D9 · Ecosystem & alternatives生态与替代品
SUPPORTS · rust-demux-partialMODERATE
Rust container parsers exist and one is shipped inside a major C/C++ media stack behind a C API, so the integration shape is demonstrated rather than theoretical.Rust 的容器解析器是存在的,其中一个已经带着 C API 发布在一个主流 C/C++ 媒体栈里,集成形态有实物可看。
https://github.com/mozilla/mp4parse-rust — mp4parse plus mp4parse_capi, shipped into mozilla-central
D10 · Boundary & compatibility边界与兼容
SUPPORTS · rust-demux-partialSTRONG
Demuxers register through a struct-shaped module interface, so the boundary is one registration per format with packets crossing in bulk — not a per-sample FFI call.demuxer 通过一个 struct 形态的模块接口注册,边界就是每个格式注册一次,packet 成批穿过,不是每个 sample 调一次 FFI。
libavformat/avformat.h:565 typedef struct AVInputFormat · 368 registered demuxers
D11 · Delivery economics交付经济性
DISFAVORS · rust-fullSTRONG
A full rewrite must re-create 194,278 lines of hand-written assembly and 604 decoder modules, none of which serve the safety objective; the per-module option prices only the formats it replaces.全量重写必须重造 194,278 行手写汇编和 604 个 decoder 模块,它们都不服务于安全目标;按模块推进的方案只为自己替换掉的那些格式付钱。
*.asm and *.S (420 files, 194,278 lines) · 604 registered decoders
D12 · Counterfactual反事实
SUPPORTS · c-fuzz, sandboxSTRONG
Two funded alternatives already operate: continuous fuzzing with an active triage pipeline, and host-side sandboxing by large consumers. The Rust option composes with both rather than replacing them.已经有两条有预算的替代路线在跑:带活跃分诊流程的持续模糊测试,以及大型使用方在宿主侧做的沙箱。Rust 方案和这两条叠加,不取代它们。
https://ffmpeg.org/security.html — project security process and CVE ledger

N/A lenses: D4 fleet footprint and D5 startup shape do not bear on this objective. FFmpeg is invoked as a library or a batch process inside the caller's own deployment.N/A 维度:D4 机群规模和 D5 启动形态与本目标无关。FFmpeg 是在调用方自己的部署里以库或批处理进程的形式被调用的。

03What decided it决定性证据

The attack surface is 3.6% of the codebase攻击面只占代码库的 3.6%

Container demux is 59,433 lines across 142 files. The bitstream parsers add 13,032 across 68 more. Total: 72,465 lines, 3.6% of the tree. Attacker-controlled bytes get interpreted there first. Framework-wide proposals target something about twenty-eight times bigger.容器 demux 是 142 个文件、59,433 行。bitstream parser 再加 68 个文件、13,032 行。合计 72,465 行,占代码树的 3.6%。攻击者控制的字节最先在这里被解释。而面向整个框架的提案,瞄准的体量大约是它的二十八倍。

libavformat/*dec.c, *demux*.c · libavcodec/*_parser.c

194,278 lines of hand-written assembly are the reason not to widen不该扩大范围的理由:194,278 行手写汇编

FFmpeg's throughput lives in .asm and .S files spread over seven architecture subtrees. A Rust rewrite inherits none of it. Either you keep that assembly over FFI or you write it again. Both add cost, and the safety objective is already satisfied by 3.6% of the tree.FFmpeg 的吞吐量在 .asm 和 .S 里,散布在七个架构子树中。Rust 重写一行也继承不到。要么用 FFI 把这些汇编留着,要么重新写一遍。两条路都加成本,而安全目标靠代码树的 3.6% 就已经满足。

420 asm files · libavcodec's x86, aarch64 and arm subtrees are 147,380 lines with their C wrappers

The seam is already a module table接缝已经是一张模块表

Demuxers register as struct instances. There are 368. A Rust demuxer is one more registration: selectable per format, removable per format. Packets cross in bulk, not one sample at a time.demuxer 以 struct 实例的形式注册,一共 368 个。一个 Rust demuxer 就是多一条注册记录:按格式启用,按格式移除。packet 成批穿过,不是一个 sample 过一次。

libavformat/avformat.h:565 · 300 ff_*_demuxer definitions

The integration shape has shipped elsewhere这种集成形态别处已经上线了

Mozilla maintains a Rust ISO-BMFF parser with a C API wrapper, and ships pinned revisions of it into Firefox. The project describes it as a pure-Rust replacement for the metadata parser the browser needs. Same language pair. Same boundary shape, same kind of host.Mozilla 维护一个带 C API 包装的 Rust ISO-BMFF 解析器,并以固定 revision 的方式发进 Firefox。项目自己的说法是:这是浏览器所需元数据解析器的纯 Rust 替代。语言组合相同。边界形态相同,宿主类型也相同。

github.com/mozilla/mp4parse-rust · mp4parse + mp4parse_capi

The performance half of the proposal is unmeasurable today提案里性能那一半,今天量不出来

No public FFmpeg profile separates time in SIMD kernels from time in C control flow. Without that split, a speedup claim is arithmetic on line counts. D2 stays UNKNOWN. The full-rewrite option carries no benefit interval as a result.没有公开的 FFmpeg 剖析把 SIMD kernel 的时间和 C 控制流的时间分开。缺了这一刀,任何加速比都只是拿行数做算术。D2 保持 UNKNOWN。全量重写方案因此没有收益区间。

no public end-to-end decode profile

04What Rust buys here, and what it doesn'tRust 在这里买得到什么,买不到什么

Buys买得到

  • Class elimination at the entry point在入口处消除整类缺陷a Rust demuxer cannot produce a memory-unsafety defect while interpreting the length fields and offsets a hostile file supplies.Rust 写的 demuxer 在解释恶意文件给出的长度字段和偏移量时,产生不了内存不安全缺陷。
  • Per-format blast radius爆炸半径收敛到单个格式the module table means one format can be replaced, shipped, and unregistered independently of the other 367.有模块表在,一个格式可以独立于另外 367 个被替换、发布、下架。
  • A parity harness that already exists对齐用的验收台已经有了FFmpeg's own bit-exact regression suite answers 'did the output change' before release, which keeps this option cheap to try.FFmpeg 自带的逐位一致回归套件能在发布前回答「输出变了没有」,这让这个方案试起来很便宜。

Doesn't buy买不到

  • Any throughput improvement任何吞吐提升the speed is in 194,278 lines of hand-written assembly; a Rust demuxer neither helps nor is meant to.速度在那 194,278 行手写汇编里;Rust demuxer 帮不上忙,也不打算帮。
  • Safety for the codec layer编解码层的安全性999,497 lines of libavcodec stay in C; this scope does not reach them and the report does not pretend otherwise.libavcodec 的 999,497 行继续留在 C;本范围够不到那里,报告也不假装够得到。
  • Freedom from logic bugs摆脱逻辑缺陷format confusion, integer semantics and resource exhaustion survive the language change and still need fuzzing.格式混淆、整数语义、资源耗尽都能挺过换语言,仍然要靠模糊测试。

05Who has done this before同型先例

Mozilla · mp4parse-rust

PARTIAL SHIPPED

A Rust ISO-BMFF parser with a C API wrapper lives as a standalone crate. Firefox ships pinned revisions of it, in place of the metadata parser the browser relied on before.一个带 C API 包装的 Rust ISO-BMFF 解析器以独立 crate 的形式维护。Firefox 以固定 revision 的方式引入,取代浏览器原先依赖的元数据解析器。

matches匹配: same language pair, same container-parsing boundary, C API in a large native media stack语言组合相同,容器解析的边界相同,同样是大型原生媒体栈里的 C API · differs不匹配: track metadata only, one container family, and a browser's threat model rather than a general transcoder只做 track 元数据,只覆盖一个容器家族,威胁模型是浏览器的,不是通用转码器的
first-party · project README

Mozilla · Stylo

PARTIAL SHIPPED

One subsystem with a clean interface got replaced in Rust inside a large C++ codebase, and shipped in about two years. The same organisation's whole-engine replacement was cancelled.在一个大型 C++ 代码库里,一个接口干净的子系统被 Rust 替换,大约两年上线。同一家机构的整引擎替换则被取消。

matches匹配: component-scoped replacement inside a large native codebase with an existing internal interface在已有内部接口的大型原生代码库里做组件级替换 · differs不匹配: CSS styling had a parallelism benefit; this scope claims safety onlyCSS 样式计算有并行化收益;本范围只主张安全性
first-party · engineer account

Google · Android memory-safety program

INCREMENTAL

Memory safety's share of Android vulnerabilities fell from 76% to below 20%. Mass rewriting was explicitly not the method. New code was made safe and old C/C++ was left to age out. Their data puts vulnerability density in older code 3.4–7.4× below new code.内存安全类缺陷在 Android 漏洞中的占比从 76% 降到 20% 以下。大规模重写被明确排除在做法之外。路线是让新代码安全,让旧的 C/C++ 自然老化。他们的数据显示,旧代码的漏洞密度比新代码低 3.4–7.4×。

matches匹配: same requirement class and the same 'scope the replacement' conclusion需求类别相同,结论同样是「把替换范围划小」 · differs不匹配: OS-wide programme; figures are C/C++-relative rather than component-attributed那是操作系统级的计划;数字相对的是 C/C++ 整体,没有按组件归因
first-party · vendor security blog

Mozilla · Servo as Gecko replacement

CANCELLED

The whole-engine replacement was costed at thousands of engineer-years against a handful of funded positions. It was cancelled. The component extractions shipped.整引擎替换的估算是数千人年,对面只有为数不多的带薪岗位。项目被取消。真正上线的是拆出来的组件。

matches匹配: the outcome the excluded full-rewrite option is heading toward at 2,021,868 lines被排除的全量重写方案在 2,021,868 行的体量下,正走向同样的结局 · differs不匹配: a browser engine, and Servo had a research budget FFmpeg does not对象是浏览器引擎,而且 Servo 有 FFmpeg 没有的研究预算
first-party · engineer account

06What to do next可逆路径

Pick the format by exposure, not by taste按暴露面挑格式,不按口味

FFmpeg's security contacts rank the container formats by attacker reachability and by how often each one shows up in reports, then name the first target. The ranking has to come out of the project's own CVE ledger and fuzzing findings, not out of opinion. If no format stands out, stop: sandboxing alone is the better answer. Only documentation changes here.FFmpeg 的安全联系人按攻击者可达性和历史报告量给容器格式排序,并点名第一个目标。排序必须来自项目自己的 CVE 记录和模糊测试结果,不能靠印象。如果没有哪个格式明显更突出,就停:单靠沙箱是更好的答案。这一步只动文档。

1–2 weeks1–2 周

Measure the module boundary before writing the module先量接缝,再写模块

Two engineers who know both C and Rust register a null Rust demuxer through the existing struct interface, then time it against the C equivalent on the same inputs. Passing means boundary overhead sits inside noise under the project's own timing methodology, with the measurement published. Visible per-packet crossing cost means stop — the seam is wrong even though the objective is right. Rollback is one deletion. Nothing was registered by default.两位同时熟悉 C 和 Rust 的工程师,用现有的 struct 接口注册一个空的 Rust demuxer,在同一批输入上和 C 版本对时。通过的标准是:按项目自己的计时方法,边界开销落在噪声以内,并公开测量结果。逐 packet 的穿越成本只要看得见,就停——接缝错了,哪怕目标是对的。回滚只是删掉这个模块。默认本来就没注册它。

2 weeks2 周

Ship one Rust demuxer behind a build flag先用编译开关放出一个 Rust demuxer

The Rust module maintainers implement the chosen format in Rust, disabled by default, with a differential-fuzzing harness pointed at the C demuxer. Three things have to hold: bit-exact output on the project's regression corpus, identical accept/reject decisions under differential fuzzing, and no measured decode regression. At twelve weeks without bit-exactness, stop and publish the divergences. Rollback unregisters the module. The C demuxer stays the default for that format.Rust 模块维护者用 Rust 实现选定的格式,默认关闭,并配一套对着 C demuxer 跑的差分模糊测试。三条必须同时成立:在项目回归语料上输出逐位一致;差分模糊测试下接受/拒绝的判断完全相同;解码没有可测的退化。到第十二周仍然做不到逐位一致,就停下来,把差异公布出去。回滚就是取消注册。那个格式的默认实现仍然是 C demuxer。

8–12 weeks8–12 周

Name owners before adding the second module加第二个模块之前,先把人定下来

Before a second module lands, FFmpeg maintainers name at least two committed reviewers for the Rust subsystem and write down what happens to unowned modules. No Rust module is enabled by default without two people who can review and release changes to it. If ownership lapses, disable them. An unmaintained parser is worse than none. The C demuxers never left, and they become the default again.在第二个模块进来之前,FFmpeg maintainer 要为这个 Rust 子系统点名至少两位承诺投入的评审人,并把无人认领模块的处理写成明文政策。没有两个人能评审并发布改动的 Rust 模块,不许默认开启。归属一旦断了,就关掉。没人维护的解析器比没有更糟。C demuxer 一直都在,会重新变回默认。

ongoing持续

07Arguing both sides对称反证

Against migrating反驳「迁移」

PASSEnd-to-end reach端到端影响No performance benefit is claimed for the selected option, and the full-rewrite option's performance case is recorded UNKNOWN rather than estimated from line counts.选定方案不主张任何性能收益;全量重写方案的性能论证记为 UNKNOWN,没有拿行数去估。
PASSAttribution归因The safety delta is attributed to the language property at the demux boundary only; no architecture or format change is credited to Rust.安全收益只归因于 demux 边界上的语言属性;没有把任何架构或格式改动算到 Rust 头上。
HITBaseline and regime基线与口径Format selection currently rests on structural exposure, because the project's CVE ledger is not published with per-component attribution.格式的挑选目前靠结构性暴露面,因为项目的 CVE 记录没有按组件归因公布。
HITBoundary and compatibility边界与兼容Per-packet boundary cost has not been measured yet. The path spends two weeks on a null module before anyone writes a real one.逐 packet 的边界成本还没有测过。所以路径里先花两周做一个空模块,然后才动真的。
PASSDelivery ownership交付归属The path blocks the second Rust module on two named reviewers and defines what happens if ownership lapses.路径把第二个 Rust 模块卡在「两位具名评审人」上,并规定了归属断掉时怎么办。

Against staying反驳「不动」

PASSFunded counterfactual有预算的反事实Fuzzing with active triage and host-side sandboxing are both recorded as options that stay in place after the Rust modules land.带活跃分诊的模糊测试和宿主侧沙箱都被记为方案,并且在 Rust 模块上线之后继续保留。
HITCost of inaction不动的代价Staying entirely in C leaves the memory-unsafety class reachable in the 72,465 lines that interpret hostile files first.完全留在 C,就是让内存不安全这一整类缺陷在最先解释恶意文件的那 72,465 行里保持可达。
PASSUnsafe-surface omission遗漏不安全面The report names the demux/parse surface explicitly rather than treating FFmpeg's maturity as a substitute for safety.报告明确点出 demux/parse 这块面,没有拿 FFmpeg 的成熟度当安全性的替代品。
PASSNative-advantage denial否认 Rust 侧已有战绩A shipped Rust container parser inside another large native media stack is cited as working evidence, not dismissed as a toy.另一个大型原生媒体栈里已经上线的 Rust 容器解析器,被当作可用证据引用,没有当玩具打发掉。
PASSStop condition停止条件The authorized scope is bounded at the demux layer with explicit acceptance thresholds, so this is neither an open-ended rewrite nor an open-ended 'fuzz forever'.授权范围止于 demux 层,并带明确的验收阈值:既不是没有边界的重写,也不是没有边界的「一直 fuzz 下去」。

08How this was produced方法与记录

FFmpeg/FFmpeg at 946272b · static read-only analysis · why-not-rust method 2.0FFmpeg/FFmpeg @ 946272b · 只读静态分析 · why-not-rust 方法 2.0

Repository: github.com/FFmpeg/FFmpeg at commit 946272b, shallow clone, 10,511 tracked files. Scope: the whole repository, with the libavformat demux/parse layer as the selected component. Sampling: 1,567,523 lines of C, 260,067 of headers, 110,661 in .S and 83,617 in .asm files, for 2,021,868 lines total; libavcodec 999,497; libavformat 272,807, of which 59,433 across 142 files are demux. Module counts come from the registration tables: 368 extern const FFInputFormat demuxer declarations in libavformat/allformats.c, and 604 extern const FFCodec decoder declarations in libavcodec/allcodecs.c. Per-directory figures count .c and .h together; the 1,567,523 figure is .c only, and each lens states which. The authorized scope is 59,433 lines of libavformat demux plus 13,032 lines of libavcodec bitstream parsers, 72,465 in total across 210 files. No build, test, benchmark or network call was run against the project. Objective: eliminate the memory-unsafety class at the point FFmpeg first interprets attacker-controlled bytes, without changing decode output or losing SIMD throughput. User-supplied facts: none. D2 is recorded UNKNOWN, not estimated. No public profile separates time in SIMD kernels from time in C control flow, and converting the 3.6% line share into a speedup would be a method error. The full-rewrite option therefore carries no benefit interval instead of a favourable one. This is a structured decision protocol, not a statistical predictor.仓库:github.com/FFmpeg/FFmpeg,commit 946272b,浅克隆,10,511 个纳入版本管理的文件。范围:整个仓库,选定组件是 libavformat 的 demux/parse 层。采样:C 1,567,523 行,头文件 260,067 行,.S 文件 110,661 行,.asm 文件 83,617 行,合计 2,021,868 行;libavcodec 999,497 行;libavformat 272,807 行,其中 142 个文件、59,433 行属于 demux。模块数量取自注册表:libavformat/allformats.c 中 368 条 extern const FFInputFormat demuxer 声明,libavcodec/allcodecs.c 中 604 条 extern const FFCodec decoder 声明。按目录统计的数字把 .c 和 .h 一起计入;1,567,523 这个数字只算 .c,每个维度都会写明用的是哪一种。授权范围是 libavformat demux 的 59,433 行,加 libavcodec bitstream parser 的 13,032 行,合计 72,465 行,分布在 210 个文件中。没有对该项目执行任何构建、测试、基准或网络调用。目标:在 FFmpeg 首次解释攻击者控制的字节的地方消除内存不安全这一整类缺陷,同时不改变解码输出,也不损失 SIMD 吞吐。用户提供的事实:无。D2 记为 UNKNOWN,不做估算:没有公开剖析把 SIMD kernel 的时间与 C 控制流的时间分开,把 3.6% 的行数占比换算成加速比属于方法错误。全量重写方案因此没有收益区间,而不是拿到一个好看的区间。这是一套结构化的决策流程,不是统计预测器。

What we don't know证据缺口What it would change会改变什么
Per-component attribution of FFmpeg's CVE ledgerFFmpeg CVE 记录的按组件归因Format selection currently rests on structural exposure. With attribution, step 1 gets a defensible first target; without it, the first module may be the wrong one.格式挑选目前靠结构性暴露面。有了归因,第 1 步就能给出站得住的首个目标;没有的话,第一个模块可能选错。
Measured per-packet boundary cost at the module interface模块接口上逐 packet 边界成本的实测If crossing cost is material, the seam is wrong even though the objective is right, and the option reverts to sandboxing plus fuzzing.如果穿越成本大到要紧,接缝就是错的,哪怕目标是对的,方案会退回沙箱加模糊测试。
End-to-end decode profile separating asm from C把汇编和 C 分开的端到端解码剖析Absent this, the performance half of any full-rewrite proposal stays UNKNOWN and that option keeps an empty benefit interval.没有它,任何全量重写提案里性能那一半都保持 UNKNOWN,那个方案的收益区间也一直是空的。