diff --git a/STATE.md b/STATE.md index fbd054c..13450ea 100644 --- a/STATE.md +++ b/STATE.md @@ -2,6 +2,45 @@ 给下一个会话的交接。**权威运行器:`scripts/library_run.py`**(不要再恢复旧的 `hevc_lib.py`)。 +## 2026-10-11:画质策略落地(闸门对齐 / 门槛 / VMAF)—— 先读这一节 + +**结论:闸门以前把帧配错了对**,靠它判死过 14 个健康编码(9.6 h 里烧掉 12.4 h lane 时间、13 项被 park)。 +完整细节、验收数字与决策台账(D-01…D-06)在队列仓 `docs/QUALITY-POLICY-PLAN.md`;本节只记引擎侧改了什么、怎么复现。 + +**改了什么**(`scripts/library_run.py`,commit `7d16fed`) + +1. **偏移搜索**(`ssim_vs_source`):原来是 `range(-100, 101, 10)` —— 步长 10,**永远试不到 ±1/±2**;而本库实测位移是恒定 + **−1 帧**(`-fps_mode cfr` 在丢帧处插重复帧;1499/1500、1495/1500 帧都是 −1)。现在三段:**细搜步长 1、±6 帧** → + 粗搜步长 10、±100(原样保留)→ **逐帧 ±2 最佳匹配**(`ALIGN_FINE` / `ALIGN_PERFRAME`);命中即停,判定行写明走了哪一段。 +2. **负偏移方向修好**:旧代码 `f.seek(max(0, off) * fs)` 只把参考往前挪,于是**所有负偏移与 off=0 同分** —— + 日志里那句 "verified at −100 frames" 其实什么都没对齐。 +3. **临时文件带 PID**(两条 lane 共用暂存目录,固定名会互踩);`pair_*.log` 解析完即删(否则全库一轮攒出 GB 级垃圾)。 +4. **窗口解码重试一次 + 保留 ffmpeg stderr**(进 `stats["decode_error"]`,由 FAIL 信息带出):一次偶发解码失败曾白扔一个 + 已经跑完的 16.7 分钟编码,而旧代码把报错丢掉、只剩 `FAIL ssim: no frames compared`。闸门解码另用 + `GATE_STALL_S = 3600`(`trim` 到窗口前本来就不写任何字节,用编码器的 900 s 阈值会误杀)。 +5. **两处 SSIM 滤镜加 900 s 超时** —— 卡死的 ffmpeg 不再能永久堵住一条 lane(今天确有一个空转烧 4500 s CPU 的例子)。 +6. **门槛**:`SSIM_MEAN_MIN 0.98 → 0.995`、`SSIM_MEAN_MIN_REDO 0.975 → 0.990`、新增 `SSIM_MEAN_MIN_FALLBACK 0.990` + (业主释放项走第二档,原先是让 mean **完全失效**);per-frame floor 0.985 与坏帧占比 ≤1% 不变。 + 触发对齐搜索的条件也改成按**实际门槛**(原硬编码 `mean < 0.985`,门槛一升就会出现"没触发搜索就判死"的新冤案)。 +7. **对齐说明不再绕过判定**:它原来走第 4 个返回值(调用方当作 `irreg` = 时间轴不规则 → **跳过整条画面判定**), + canary 与两个 x265 项就是这么通过的(mean 门槛从没生效)。现在只进 `stats["align_note"]` + 日志,门槛照常执行。 +8. **VMAF observe-only**(`VMAF_OBSERVE`):在同一对齐偏移上算,判定行带 `vmaf480 mean/min` —— **480p 尺度**; + 同一窗口原生读 95.85/93.76、480p 读 98.27/96.97(+2.4/+3.2),所以标了尺度;**从不参与判据**。 + +**怎么复现验收**(队列仓内,只用本地缓存产物,不碰库) + +```bash +python cache/lean_verify.py # sign 双向 / 旧值 0.9808 复现 / 细搜找到 −1 / 错画面簇仍被拒 +python cache/vmaf_native.py --original <快照原档> --converted <线上档> --offset -1 # 原生分辨率 VMAF 标定 +``` + +**实测锚点**:`危机领导力` 索引配对 0.9808 → 对齐 **0.9976**;`爆款` 0.9862 → **0.9974**;canary `上瘾` 0.9662 → **0.9968** +(装盘 + 安装后回读 SHA-256 一致)。 +⚠ 比较 mean 必须同帧数:偏移搜索上限 1200 帧 —— 同一配对 1500 帧读 0.9808、1200 帧读 0.9832。 +⚠ 原生 ffmpeg/ffprobe 读不了 CJK 路径(`Illegal byte sequence`),复核线上档要用 Python `subprocess` 传路径。 + +**现在两档都停着**(业主 2026-10-11:先把程序收尾)。恢复由队列仓的看板/lane 控制,不在引擎侧;本仓不要自己起编码。 + ## 现在在跑什么 **只有 x265 一档在跑**(2026-10-09 20:51:41 起,单档启动器 `run/relaunch_x265.sh`)。