测试与发布证据

CameraX 帧时间戳与传感器时钟来源对齐

只讲 CameraX ImageInfo/Camera2 传感器时间源、采集身份及跨时钟比较边界;不复述 AudioRecord 读帧偏移公式,也不声称 Cove 已使用 CameraX 分析时间戳。

审核状态: 内容已校验;中文稿供用户审核 · 2026-10-08 · Fact IDs: ANDROID-CAMERAX-ANALYSIS-2026-01, ANDROID-TIMEBASE-2026-10, ANDROID-CAMERA-TIMESTAMP-SOURCE-2026-10

直接回答

ImageInfo.getTimestamp 是附着在图像元数据上的时间戳,但 CameraX 文档说明其细节取决于提供图像的来源。ImageAnalysis.Analyzer 文档说图像时间戳以纳秒计且单调,并可在绑定到同一 camera instance 的 use case 之间比较。这是有边界的比较规则,不代表帧时间等于应用回调执行时间、推理完成时间或 UI 显示时间。 对 Camera2,CaptureResult.SENSOR_TIMESTAMP 表示传感器活动阵列第一行开始曝光的时间。CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE 指定该时间的来源;两项均从 API 21 起提供。REALTIME 表示 Camera2 文档定义的时间基准与 SystemClock.elapsedRealtimeNanos 相同。UNKNOWN 则只有单调递增属性,但起点未指定,不能一般化地与另一台相机或系统时钟比较。应把源类型作为时间戳身份的一部分,而不是可忽略的附加字段。 有效的同钟比较不只是两个递增数字。记录 CameraX 库版本、camera instance 或 camera ID、绑定的 use case、可取得的传感器时间源、时间戳数值及准确图像/采集身份。一次 Camera2 capture 的 SENSOR_TIMESTAMP 会出现在该次采集生成的所有图像缓冲中,且输出间相同。CameraX ImageInfo 时间戳与 Camera2 CaptureResult 只有在所选实现提供文档保证或经实测验证的关联时,才能当作同一采集;不能只因回调顺序接近就配对,输出可能延迟、丢弃、转换,或由 wrapper 提供。 采集时刻要与交付时刻分开。记录 ImageInfo.getTimestamp 为图像时间;如需衡量交付延迟,另用具名 SystemClock 字段记录回调入口。两者相减不自动等于相机处理延迟:时钟起点可能不同,回调会排队,传感器源也可能是 UNKNOWN。不要用附近的一次轮询校准 UNKNOWN,再报告一个可复用偏移去对齐 elapsedRealtimeNanos、boot time、音频或第二台相机。没有受支持共同时间源或采集身份关联时,跨域映射保持 unknown。 时间戳不代表滚动快门图像的所有像素同时曝光。Camera2 将 SENSOR_TIMESTAMP 定义为传感器阵列第一行开始曝光的时间,不同行可能在不同时间曝光。单一图像时间可以作为文档定义的帧锚点,但不是每个视觉事件的逐像素时间、保证的中点,也不是设备精度界限。若任务需要行级时间、滚动快门校正或传感器融合,应另行定义并引用对应采集元数据,不能把整帧默认为瞬时场景。 REALTIME 有用之处是 Android 文档说明它与 elapsedRealtimeNanos 共用时钟;这不保证相机曝光精度、回调延迟、音视频同步质量或任意设备上的测量精度。测试准确数据路径,只报告受支持的比较范围:CameraX 同 camera instance 的帧顺序,或 REALTIME 传感器时间戳与文档规定的同域值。UNKNOWN 应保留来源和 camera identity,只在该 stream 的文档范围内比较;不能把关系推广到另一台相机、系统启动时钟、音频路径或墙上时间。 安全的测试记录包括 camera ID/session、CameraX 版本和 use case、传感器时间源、ImageInfo 时间戳、可用的 Camera2 CaptureResult 身份与 SENSOR_TIMESTAMP、单独记录的回调到达时钟,以及必要时的方向/裁剪状态和关联方法。测试同相机多个 use case、重绑或切换相机、analyzer 延迟、缺失/partial capture result,以及设备实际报告的各类时间源。合成值只能验证比较代码,不能证明设备传感器时钟或 CameraX 到 Camera2 的采集身份映射。 本文不重复 AudioRecord.framePosition 到应用 read 分块的对齐方法。音频采集有不同的时间戳 API 和坐标原点。共同教训仅是时钟来源与事件身份必须明确;不能借用音频公式、假设 REALTIME 消除了所有同步误差,也不声称 Cove 当前读取 CameraX 分析时间戳。把时钟来源、采集身份、回调到达作为独立字段;不支持的元数据关系保持 unknown。

分析器回调晚于相机采集结果到达

相机功能分别记录 ImageProxy 帧和 Camera2 capture result。团队想把延迟的视觉结果关联回采集事件,并与应用事件时间比较;但尚未读取 SENSOR_INFO_TIMESTAMP_SOURCE,也未证明两个回调属于同一次采集。

决策

把 CameraX 图像时间、Camera2 传感器源/时间、采集身份和回调到达分别记录。只有文档支持的共同源和已验证的同次采集关联才能跨域比较。

预期结果

报告可保留同相机帧顺序或文档支持的 REALTIME 比较;不支持的跨源映射保持 unknown,不宣称逐像素时刻或设备精度。

需要收集的证据

只有将以下证据与同一模型文件和测试运行关联起来,结论才可复核:

  • ANDROID-CAMERA-TIMESTAMP-SOURCE-2026-10:官方事实卡记录 Camera2 SENSOR_TIMESTAMP、UNKNOWN/REALTIME 和首行曝光语义;共享时钟不等于精度或 Cove 实现证明。
  • ANDROID-CAMERAX-ANALYSIS-2026-01:CameraX Analysis 提供 ImageProxy 与时间戳上下文;同相机 use case 的可比范围仍依官方 API 文档。
  • ANDROID-TIMEBASE-2026-10:单调系统时钟只在具备共同基准的边界内比较;不能把 UNKNOWN 传感器源硬贴到 elapsedRealtime。

发布结论只对所记录的配置和验收集有效;扩大适用范围需要更多记录。

实施流程

  1. 固定相机路径和时间戳 API. 记录 CameraX 版本、provider 实现(若已知)、camera ID/session、绑定的 use case、API 级别,以及时间来自 ImageInfo、Camera2 CaptureResult 还是两者。不要以回调到达时刻替代图像时间。
  2. 读取并保留传感器时钟来源. Camera2 场景在可用时查询 SENSOR_INFO_TIMESTAMP_SOURCE,并将 UNKNOWN/REALTIME 与每次比较一起保存。文档只为 REALTIME 规定与 elapsedRealtimeNanos 同域;UNKNOWN 起点不明,不得靠猜测校准其他系统。
  3. 先证明采集身份再合并记录. 只有使用文档保证的关联或经版本固定、受控观察验证的同帧关系,才将 CameraX ImageInfo 时间戳与 CaptureResult 配对。记录缺失/partial result 与丢帧;仅凭回调顺序不算帧身份。
  4. 将回调到达存入独立时钟字段. 需要衡量交付延迟时,用具名系统时钟记录回调入口;只有来源文档证明时钟域相同时才做比较。否则保留两个原始值并标为无法相减;队列延迟与时间源原点是不同未知量。
  5. 尊重曝光与滚动快门语义. 把 SENSOR_TIMESTAMP 解释为该次采集第一行开始曝光。不能称为整帧中点或逐像素时刻;若使用行时间元数据,应放入另有文档的 rolling-shutter 方法。
  6. 测试支持与未知来源行为. 测试同相机 use case、相机重绑/切换、延迟回调、缺失 capture result 和实际报告的各类时钟源。断言 UNKNOWN 不做跨设备或音频合并,REALTIME 也不生成精度承诺;合成时钟值只验证代码。

让每个阶段的状态都可观察。失败信息应指出阶段、模型、运行时和恢复动作,同时避免记录用户私密内容。

验收标准

  • ImageInfo 时间戳、Camera2 SENSOR_TIMESTAMP 与回调到达作为独立事件保存,并关联可用的 camera/session identity 与时间源。
  • UNKNOWN 时间戳不跨相机、elapsedRealtime/boot 时钟、音频或应用回调时钟比较,除非具体集成有文档支持的共同源;否则映射保持 unknown。
  • REALTIME 仅在文档规定的共享时钟域内与 elapsedRealtimeNanos 比较;不推导曝光精度、回调延迟或同步质量。
  • CameraX 到 Camera2 的合并必须有文档或版本/设备实测的采集身份;SENSOR_TIMESTAMP 描述首行曝光起点,不说成整帧同时曝光。

决策对照表

维度选择或证据解读方式
ImageInfo 时间戳图像来源提供的元数据时间CameraX 说明细节依来源而异,同一 camera instance 的 use case 可按文档比较;回调到达是另一个事件。
Camera2 SENSOR_TIMESTAMP活动阵列首行开始曝光的时间标记传感器采集锚点;滚动快门下并非每行使用同一曝光时刻。
UNKNOWN 时间源起点未指定的单调时间值只保留文档支持的同相机范围;不推断它等于 elapsedRealtime、音频或其他相机时钟。
REALTIME 时间源Camera2 文档规定与 elapsedRealtimeNanos 同域允许比较时钟域,但不保证测量精度或音视频同步质量。

需要避免的失败模式

  • 把 ImageInfo 时间戳当作 analyzer 回调到达时间、推理完成或 UI 显示时间。
  • 未读取 SENSOR_INFO_TIMESTAMP_SOURCE,就假设单调时间戳等于 elapsedRealtimeNanos。
  • 仅凭两个回调顺序相近,就认定 ImageInfo 与 CaptureResult 属于同一帧。

还要避免静默回退、版本未固定、缺少取消处理,以及把不同配置的结果混在一起下结论。失败运行也应与成功记录一并保存。

最小复现记录

层级记录内容
设备厂商、型号、芯片、内存档位、操作系统版本
软件应用版本和 Git 提交号
模型系列、变体、版本、格式、文件长度、摘要、量化方式
运行时名称、版本、请求后端及实际后端证据
工作负载样例版本、输入摘要、提示词摘要、输出策略
结果完成、失败、取消、回退及保护隐私的诊断信息

发布检查表

  • ☐ 主要搜索问题已回答,且没有未经支持的数字。
  • ☐ 所有模型文件和运行时版本均已固定。
  • ☐ 代表性任务和失败处理策略均有说明。
  • ☐ 生命周期、取消、清理和回退均已测试。
  • ☐ 用户内容与网络边界均有说明。
  • ☐ 结论只适用于被记录的配置。
  • ☐ 新增测试结果时链接到原始方法或证据。

来源与相关证据

中文部署与排错专题见。奇连 AI 端侧专题。

常见问题

能否用 ImageInfo.getTimestamp 减去回调到达时间?

只有准确时间源和回调时钟被文档证明使用同一原点,且采集身份已建立时才可以。否则减法混合事件/时钟域;保留原值并把延迟标为 unknown。

Camera2 UNKNOWN 时间戳能否与音频或 elapsedRealtimeNanos 比较?

不要默认可以。UNKNOWN 起点未指定,Camera2 只支持其文档范围内的相机比较。音频、另一台相机、boot clock 和应用回调都应保持独立,除非精确集成提供有支持的关系。

REALTIME 是否能证明相机和音频精确同步?

不能。它只表示文档规定的时钟基准与 elapsedRealtimeNanos 相同;并不证明曝光精度、回调延迟、帧身份关联、滚动快门校正或同步误差界限。

SENSOR_TIMESTAMP 是整帧每个像素的时刻吗?

不是。Camera2 把它定义为首行开始曝光。滚动快门下不同的行可能有不同曝光时刻,应把该值作为文档定义的采集锚点,而不是整个场景同时成像的时间。