首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >给 FFmpeg 的 MOV muxer 加上 Common Encryption(cbcs)支持(五):踩过的坑与边界

给 FFmpeg 的 MOV muxer 加上 Common Encryption(cbcs)支持(五):踩过的坑与边界

原创
作者头像
TVP 悟空
发布于 2026-11-15 11:09:59
发布于 2026-11-15 11:09:59
70
举报

这一篇把实现过程中真正花时间修的问题汇总一下。很多都不是“加密算法”,

而是协议细节、整数边界、分派遗漏。

1. 分派遗漏:某些 codec 写了明文却带加密信号

MOV 写码器对每个 codec 有单独的分支。早期的 cbcs 初始化覆盖了所有轨道,

但下面这些分支根本没走加密写入:

  • APV:直接 avio_write 写明文;
  • 字幕(tx3g):样本条目里没有 sinf/tenc;
  • VVC/LCEVC:初始化了 subsample,但 packet 分支没加密。

结果就是“文件声明加密,实际是明文/无法解密”。我们的处理是:AC-3/E-AC-3

改成走整样本加密;VVC、LCEVC、APV、字幕、data-partitioned AVC 直接拒绝,

等对应路径实现后再放开。

2. RTP hinting 与加密互斥

-movflags +rtphint 会把 H.264/HEVC 重打包成 hint track,但加密路径没有

同步处理。两者一起用会写出打不开的文件,所以初始化阶段直接报错。

3. 整数边界,LLM review 的“重点关照对象”

bitstream 解析器里,get_ue_golomb_long() 返回的是无符号值,赋给

int 再比较上界,就可能变成负数绕过检查。典型例子:

  • PPS/SPS ID 用 31 位版本读取,255 的合法 ID 会 alias;
  • RPS 的 delta_idx 先加 1 再转 int,回绕成负数后下标越界;
  • 负/正参考图计数分开判断,16+17 超过 32 容量;
  • VPS 的 vps_num_hrd_parameters 不设上限,一个 10 亿的计数能把初始化 卡死;
  • entry-point 的 offset_len * count 先乘后比较,unsigned 回绕绕过检查。

修法高度一致:先按无符号读、先判界、再做加减乘除、最后窄化。

4. 解析器状态与 in-band 参数集

slice header 的长度依赖 SPS/PPS。很多流(尤其 hev1/Annex B)会**在

包里**携带新的 VPS/SPS/PPS。只解析 extradata 里的参数集,就会用旧状态去

算新 slice 的边界。

所以写码器在写每个 packet 时,要先按序解析包里的参数集,再测 slice;遇到

AV_PKT_DATA_NEW_EXTRADATA 还要重建解析器。

5. 碎片化(fragment)下的元数据

共享 moof 时,之前只 flush 第一个轨道的加密元数据,第二个轨道会越攒越多。

修法是把 flush 移到每个参与轨道都执行的位置。另一个 inherited 的问题是

“initial moov 里已经有样本”的 fragment 加密元数据,这个目前留作后续。

6. FATE 测试

我们补了这些用例:

  • AV1/H.264/H.264-mkv/HEVC/HEVC-ISO 的 cbcs round-trip;
  • 整样本音频(AAC,无 senc)round-trip;
  • VVC 拒绝测试(用 grep 匹配诊断信息 + 校验非零退出码)。

每个提交都单独编译并跑当时存在的 FATE,保证历史里每一步都是绿的。

下一篇聊过程本身:怎么和 LLM code review 配合,把几十条 finding 一点点

收敛成一个能合入的 patch。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 1. 分派遗漏:某些 codec 写了明文却带加密信号
  • 2. RTP hinting 与加密互斥
  • 3. 整数边界,LLM review 的“重点关照对象”
  • 4. 解析器状态与 in-band 参数集
  • 5. 碎片化(fragment)下的元数据
  • 6. FATE 测试
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档