摘要

视觉理解(Perception)模块的很多离线实验都要“从录像的某个时间窗口里取几帧”:比如请求 74.6–74.8 秒,每 100 毫秒一帧。做法是先让视频解码库 OpenCV 跳转(seek)到窗口附近,再顺序往后读,返回时间不早于请求起点、且早于窗口右端的帧。

在一段训练录像上,这个采样器对 74.6–74.8 秒的请求返回了空列表。本实验(内部批次号 B085)先确认原因:OpenCV 声称跳到了 74.1 秒,实际读到的第一帧却是 146.725 秒的画面——晚了约 72 秒,而且画面本身就是 146 秒的内容,不只是时间标签错了。采样器于是直接越过了整个窗口。

修复:跳转后核对第一帧,如果已经越过请求起点(或立刻到达文件末尾),就关闭解码器、只重开一次,从头顺序解码到请求窗口。修复后该窗口恢复为 2 帧,长窗口逐帧与独立的 FFmpeg 读数一致,旧的正确窗口结果全部保持。

要回答的问题

  • 空结果是“跳错了位置”还是“时间报错了”?
  • 能否在不伪造时间、不改变原有采样语义的前提下恢复这些帧?
  • 修复会不会改变以前正确的采样结果?

数据与来源

  • 出问题的是一段训练来源(内部编号 source12)的裁剪录像。
  • 回归对照用了旧实验 B074 的 8 个采样窗口,覆盖三个训练来源组和一个已经曝光过的评估组。冻结测试来源(17–22)不打开。
  • “真值”参照是另一个解码工具 FFmpeg 报告的源时间戳(PTS,presentation timestamp,视频文件中每帧应在何时显示的时间),并人工查看了原生画面。

方法

  1. 复现并对照。 保存旧行为的输出,同时用 FFmpeg 读取源 PTS 和解码画面。人工查看两张原生图:74.6304 秒本应是一个技能选择页(高级夜影魔法子技能),OpenCV 跳转后第一帧却是 146.725 秒的装备选择页。这证明是定位错误。
  2. 兼容修复。 在私有采样函数里,跳转后检查首帧:若跳过了请求起点或立即 EOF,就关闭并重开一次,从头顺序解码到窗口。正确的跳转仍走原路径。不按平均帧率推算时间,不补帧;实际存在的时间空洞仍是空洞。
  3. 处理新发现的负起始时钟。 重开时发现,该源第一帧 OpenCV 报告的时间是 −66.733 毫秒,而 FFmpeg 的首帧 PTS 是 0。对正时间窗口的恢复,只跳过这些有限、有序的启动帧;不把负数钳成 0,也不输出窗口之前的图片。
  4. 保持语义。 函数签名、四个输出字段、100 毫秒默认间隔和 1 毫秒“原生帧”分支、“窗口右端不包含”、错误类型都不变。采样配方的版本号升为 v2,已有运行器会拒绝把旧版本算出的完成任务当成新算法结果续跑,旧文件保留。

设置

  • OpenCV 4.10.0;离线运行,本机单次测量。
  • 测试:先写 19 个新测试,修复前 12 个失败、7 个通过;修复和负起始时间边界处理后补到 24 个新采样测试,另加 1 个“旧完成缓存不得续跑”的隔离测试。最终受影响测试共 170 个。

结果

检查 结果
原 74.6–74.8 秒、100 毫秒采样 0 帧 → 2 帧,首帧 74.6304 秒
同窗口原生帧采样 6 帧,时间全部与 FFmpeg 源 PTS 一致
74.6–147 秒原生连续窗口 2136 帧,全部与独立 FFmpeg 序列一致,无插帧、无重复帧
三次恢复的首帧像素 与对应 FFmpeg 源帧平均绝对差为 0
旧 B074 八个窗口 2133 个到达时间(毫秒取整)保持;已保存的 1417 个帧序号保持;8 次都不需要重开
聚焦及受影响测试 170 个通过,22.86 秒

旧记录里有一部分没有保存帧序号,所以帧序号只核对了 1417 条,到达时间核对了全部 2133 条。

成本:本次运行中,触发恢复的短窗口单次约 4.1 秒(含错误跳转和重开),较长窗口约 11.9 秒。这只是一次离线测量,不是 p95,也不能算作手动截图或 App 的延迟。

失败与负结果

  • 第一版修复被负起始时钟拦住(恢复时第一帧时间为负),失败目录保留,之后才补上负时钟处理。
  • 第二版验证完成了 2/6/2136 帧的恢复,但验证脚本错误地假设所有旧记录都有帧序号而停下;只修正了核对脚本,旧结果保留,这不是产品失败。
  • 原始的 start_ms=0 路径仍会明确拒绝这类负起始时钟,也就是说“从视频第 0 秒开始采样”这个场景并没有被修好;这类源做全片扫描应继续用已有的 FFmpeg 路径。

局限

  • 只重新解码并核对采样结果,没有重跑检测或文字识别,不代表任何识别准确率或时序实时成绩。
  • OpenCV 报告的解码时间和帧序号仍只是解码器元数据,不被升级为通用的源 PTS 或全局帧序号认证。
  • 没有对全部历史材料做时间审计,也没有完整视频召回检查;未重跑全套测试,之前已有的 2 个全套失败不在本轮处理范围。
  • 项目目标(每字段 ≥95%、≥10 场独立对局、App 3 秒内)均未达成或未测得。

结论与下一步

问题确认为 OpenCV 在这段源上的跳转定位错误,采用“越界即从头顺序解码”的离线恢复,修复了空窗口且不改变旧的正确结果。代价是触发恢复时要多花几秒,适合离线取样,不是实时方案。下一步回到伤害预览与目标生物关系、整图漏项精审;保留源 0 秒时钟的限制,优先用现有源 PTS 工具供样,不无限扩大解码器重写。