裸视频可分析:生成工作区、设置提示、逐帧力与按来源选画笔

pass 只认 frames.csv 与 session.json,裸视频此前因此只能播放;现在为它在应用自己的目录里生成
这两份文件并复用既有链路,链路重算的力按帧存入结果并标注为「重算」,box 的空白箭头画布改按帧
来源走共享画笔。
apps/studio/tests 497 项、shared/tests 471 项(2 个已知墙钟失败)、autocal 358 项、ui_check 634 项
均 0 失败,lint_gate 与 doc_lint 无发现;真实 GL 快照见 .scratch/bare-video/snapshots。
This commit is contained in:
ykcheungab
2026-10-05 16:57:02 +08:00
parent c0a10e6adb
commit 92b2f2fcd7
6 changed files with 518 additions and 51 deletions
+23 -4
View File
@@ -9,7 +9,8 @@
一次约 4.8 分钟。Part A 把这一遍跑一次,只存回放真正要画的东西。
格式版本从 1 升到 2:帧记录里多了深度通道。旧结果不会被误读 —— 版本不符直接
`AnalysisFormatError`,重跑一遍即可(结果本来就是可重算的)。
`AnalysisFormatError`,重跑一遍即可。力的通道**没有**再升版本:它追加在记录最后,老读端按原偏移
仍能读出同一帧,只是没有力(第 1 节末)。
## 1. 结果模型
@@ -43,9 +44,27 @@ zlib level 6。
而且一旦有深度值落在岛外就会**静默丢掉一个测量**。
`provenance` 随结果存:算法版本、传感器配置及其内容哈希、标定 id、单位、参考帧 id、首个输出
帧 id、解码偏移、逐通道的"重算/记录"标记(`flow`、`depth` 重算,`forces` 记录)、`complete`
标志与计数。`counts` 另记 `depth_frames` / `depth_nonzero_frames` / `depth_nonzero_max` /
`depth_pixels` 与实测的 `frame_record_bytes`,进度面板和"这一帧为什么是空的"都读它。
帧 id、解码偏移、逐通道的"重算/记录"标记(`flow`、`depth` 重算;`forces` 见第 1.1 节)、
`synthetic` 与 `synthetic_source`、`complete` 标志与计数。`counts` 另记深度与力通道的计数与实测
的 `frame_record_bytes`,进度面板和"这一帧为什么是空的"都读它。
**帧记录可以再带一份力,追加在最后。** 裸视频没有 `forces.csv`,pass 就把链路算出的力按帧存下:
`FRAME_FLAG_FORCE` 后接六个 float32 与两个标志位,28 B/帧。版本不变的理由见开头;读数取不到时存
`NaN`。
### 1.1 裸视频的输入:生成的工作区
pass 只认一种输入形状(一个目录里的 `frames.csv`、`session.json` 与 `raw_*.mp4`),而形状本身是
好的:帧身份、时间与链路都来自录制自己的元数据。裸视频因此**不新增第二条代码路径**,而是把这两个
文件为它*生成*出来(`analysis/bare_video.py`):`frames.csv` 给容器每一帧一行
(`t_rel_s = index / fps`),`session.json` 给出 `device`/`stats`/`files` 与一个 `synthetic` 块;
裸视频只有容器时间,所以容器的钟**就是**信号时间(第 5 节)。
凡是 `recording_identity` 会哈希的字段都只由**视频与所选配置**决定,不含任何时钟:重开同一条视频
就是同一个 key;标定进 key 的是**文件内容**的摘要。视频以 `raw_0001.mp4` 放进工作区(能硬链接就
链接):一个文件就是一段,因此**多文件输入直接拒绝**并列出文件名。工作区写在应用自己的派生数据根
(`paths.video_workspace_dir()`),**绝不写在操作员视频旁边**;`synthetic` 块被 pass 抄进
`provenance.synthetic`/`synthetic_source`,重算出来的测量因此不可能被当成记录的测量读。
## 2. Keyframe:候选位置与有效掩码