docs(STATE): 2026-10-13 交接(闸门配对修复 / preset 实测 / 子进程亲和真相 / run_pinned 事故)
This commit is contained in:
@@ -43,6 +43,77 @@ python cache/vmaf_native.py --original <快照原档> --converted <线上档> --
|
||||
cpu + gpu 两条 lane 在跑(`autostart_lanes=[cpu,gpu]`)。**本仓不要自己起编码** —— 引擎只作为 lane 的子进程被调用,
|
||||
单档启动器(`run/relaunch_x265.sh` 等)只在看板不参与时应急用。
|
||||
|
||||
## 2026-10-13:闸门配对修复 / preset 可选 / 子进程亲和真相 / run_pinned 事故
|
||||
|
||||
(控制面侧的对应记录见 `D:\dev\hoelee-resource-transcode\docs\OPERATIONS.md` 同名小节)
|
||||
|
||||
### 1. `run_pinned` 把 `capture_output` 传给 `Popen` → 三个 lane 秒失败 64 项(`eb4b0bd`)
|
||||
|
||||
引入子进程包装时把 `subprocess.run` 的语法糖 `capture_output` 直接透传给了 `Popen` ——
|
||||
`Popen` 不认这个参数,`run()` / `_sh` / 三个 ffmpeg 调用点全部 `TypeError`。因为失败是**秒级**的,
|
||||
队列会立刻重投,2.5 分钟内 **64 项把 3 次 attempts 烧光变 failed**。
|
||||
修法:在包装里展开 `capture_output=True` → `stdout/stderr=PIPE`。
|
||||
**修复被误判的项要精确**:`UPDATE files SET state='pending', attempts=0, fail_gear=NULL WHERE last_error LIKE '%capture_output%'`
|
||||
(按错误文本定位;不要整批重置 failed,那会掩盖真失败 —— 例如 `PermissionError [WinError 32]` 是真失败)。
|
||||
|
||||
### 2. 闸门:对齐修好了配对,判决却用旧配对的帧占比(`767fa3a`,业主的假拒绝)
|
||||
|
||||
`ssim_vs_source` 一直在做三阶段对齐搜索(fine ±6 / coarse ±100 / per-frame ±2),
|
||||
但 **触发条件只看 `min < 0.985` 和 `mean < 0.995`,漏了帧占比**;而且采用对齐结果时只更新了
|
||||
`lo/mean/n`,**判决消费的 `stats["below"]` 仍是直配的计数** → 于是出现
|
||||
`mean 0.9974(对齐后)但 20/1199 帧低于 0.85(直配)` 这种自相矛盾的判决,把 `0912 洞见` 反复拒掉。
|
||||
|
||||
改动:
|
||||
- 触发条件加上 `bad > MAX_BAD_SHARE * n`;
|
||||
- `_paired_ssim` / `_perframe_best` 现在返回 `below` 计数,并且**同样剔除近平坦帧**
|
||||
(之前对齐后的 min/mean 含黑场帧,会让对齐看起来比直配还差);
|
||||
- 采用对齐结果时同步 `stats["below"]`,并打印 `X frames below before, Y after`。
|
||||
|
||||
**验证方法(便宜且可复用,全部本地、不需真编码)**:同一个 60 s 窗口造三份夹具 ——
|
||||
健康对(应走快路径、0 坏帧)、**错位 1 帧的对**(`trim=start_frame=1`;实测
|
||||
`alignment repaired the pairing: 20 frame(s) below 0.85 before, 0 after`,与判决书 20/1199 逐项吻合)、
|
||||
真缺陷对(`hflip=enable='between(n,250,400)'`;mean 0.9612 / 151 帧 10.07% **仍被拒** ✓ 没变橡皮章)。
|
||||
脚本模式见 `C:/Users/hoelee/AppData/Local/hermes/cache/scratch/gate_fix_test.py`。
|
||||
|
||||
生产验收(`0912 洞见`,crf 24):`ssim min 0.9936 mean 0.9971 (1199 帧)` → `ok 580 MB -> 422 MB (73%)`。
|
||||
|
||||
### 3. 子进程亲和的真相(Windows)—— 别再指望"子进程继承 mask"
|
||||
|
||||
- **`CreateProcess` 不继承** affinity mask(Linux 的 `sched_setaffinity` 才继承)→ 引擎的
|
||||
`pin_to_e_cores()` 只覆盖引擎自己;实测三个 ffmpeg 全在 `0x3FFFFFF`(26 核)。
|
||||
- **事后补钉也不行**:对已跑的 ffmpeg 调 `SetProcessAffinityMask` 与 `AssignProcessToJobObject`
|
||||
都返回 `ERROR_ACCESS_DENIED(5)`(x265 自己为 NUMA 设线程亲和),而同一个调用打在 `ping`
|
||||
子进程上成功 → 是 ffmpeg/x265 拒绝,不是权限问题。
|
||||
- **唯一可行的机制 = Job Object 的 `JOB_OBJECT_LIMIT_AFFINITY`**:子进程创建时**继承 job 成员资格**,
|
||||
调度器对所有后代强制执行。控制面因此把引擎所在 job 带上亲和限;引擎里的 `pin_child()`
|
||||
只是 best-effort(对非 ffmpeg 子进程有效)。
|
||||
- **验证必须读 ffmpeg 子进程的 `ProcessorAffinity`**,不是引擎的、也不是看板上的。
|
||||
- 代价实测:同片段 pools=8,限核 11.2 s vs 不限 11.7 s(噪声内),输出字节一致。
|
||||
|
||||
### 4. preset 现在可由控制面指定(`5e27ede`)
|
||||
|
||||
新增 `--x265-preset` / `--nvenc-preset`(控制面按设置传入;常量只是手跑时的回落值)。
|
||||
**NVENC 默认 p6 → p7**(业主决定),x265 保持 `medium`。
|
||||
|
||||
x265 实测(crf 24、pools=2、1080p 60 s 窗口,耗时 = 编码器自报秒数 ±1 s):
|
||||
|
||||
| preset | 体积 | 帧率 | 耗时 | SSIM mean |
|
||||
|---|---|---|---|---|
|
||||
| ultrafast | 6.05 MB | 25.0 | 60 s | 0.9952 |
|
||||
| veryfast | 7.58 MB | 16.7 | 90 s | 0.9968 |
|
||||
| fast | 7.90 MB | 12.5 | 120 s | 0.9969 |
|
||||
| **medium(现用)** | 8.11 MB | 12.5 | 120 s | **0.9971** |
|
||||
| slow | 9.00 MB | 5.0 | 300 s | 0.9975 |
|
||||
|
||||
**固定 CRF 下换 preset 不会让文件变小**(±1–2%,另一个窗口方向甚至反转)→ 省体积要动 CRF,
|
||||
preset 是画质微调;`ultrafast` 的 SSIM 0.9952 紧贴 0.995 门槛(会把项推去重试),`slow` 是 2.5× 时间换 +0.0005。
|
||||
|
||||
nvenc(cq 31):p1/p2/p3 10.23 MB · p4/p5 9.49 · p6 9.44 · p7 9.41(同 cq 下 SSIM 全 0.9973);
|
||||
精确计时 p4 263 fps / p6 139 fps / p7 128 fps → **p7 = p4 的 2.05 倍时间换 0.9% 体积**。
|
||||
|
||||
⚠ **计时坑**:经引擎跑编码时,stall 看门狗的 30 s 轮询粒度会污染挂钟计时(两个不同 preset 都报 150.0 s)。
|
||||
要精确比速度就绕开引擎直接调 ffmpeg + `perf_counter`。
|
||||
|
||||
## 现在在跑什么
|
||||
|
||||
**只有 x265 一档在跑**(2026-10-09 20:51:41 起,单档启动器 `run/relaunch_x265.sh`)。
|
||||
|
||||
Reference in New Issue
Block a user