持续相机采集与缓冲回收
www 工作副本 · M4(Arden · 2026-10-21 Asia/Shanghai)
双轨:本页已迁入 Vyntekwww;mvdocs camera-acquisition 仍在线对照。
实现边界:对拍 tipe46c042(M4-01…10 外形已落在公开头;仍 NON-STABLE / STUB,≠ TC-ACQ 验收)。Latest()= 有所有权预览槽(最近一次成功TryPostOwned的 Share;替换即关上一预览);FIFO 队首 =PeekIngressFront()。fake_camera_adapter.hpp有持帧 / 回调 Copy 外形;回调路径不AwaitReturnCompleted。CanRent/TryRent(MemoryPool*)在复制前。贯穿供应商 SDK 线程的归还泵与 TC 勾选 未关。Arden 不改实现。可勾选薄摘见 test-contracts-tc-acq.md。
关联:overview · memory-management · session-lifecycle · output-inspection · performance-and-diagnostics · 预览 http://127.0.0.1:8792
目标设计与 API 草案,尚未完整实施。总体边界和推进状态见设计概述。
编排权威见 toolflow.md。本文只负责采集缓冲、入口接管与 SDK 归还;连续采集由宿主 多次独立
Run(禁止用环表达相机流)。入口队列属成像/采集基建,不是 DAG/拓扑调度器。语言:下文示例为 C++。示意、非已发布 ABI。不能用托管引用计数掩盖 SDK 提前复用。
本文负责外借引用、SDK 地址稳定、同步复制、入口接管、满载、归还泵及预览解耦。实际适配器提供供应商协议证据。
关联:存储 · ToolFlow(编排;停止矩阵见 §7.4.3:停相机 ≠ 自动 Cancel Run) · 头文件 · 停止 · 观察 · 测试契约薄摘 TC-ACQ-*(Arden · R10;全文仍在 mvdocs test-contracts) · 场景 S11
两种采集接入
采集会话可以持续运行,但一次工具调用/输出暂存批次必须有结束边界。连续相机不能把整段无限采集作为一次直到停流才结束的工具调用;每个采集结果或有限批次单独发布,或由源适配器直接进入有界入口。流式推送若另行设计,需要自己的逐项接管协议,不能沿用“整次调用成功后统一路由”却提前消费部分暂存项。
| SDK 能力 | 接入方式 | 回调结束后 |
|---|---|---|
| 可显式持有帧,地址稳定,SDK 等待归还后再复用 | ImportNative(ReadOnly) 并由一次 releaseAsync 归还 | 在途图像保持那一份 SDK 引用 |
| 像素只在回调期间有效,或 SDK 无法保证后续稳定 | 回调内同步 Copy 到受控自有存储 | 原 SDK 缓冲立即按其协议归还 |
ReadOnly 不能约束外部 DMA 或 SDK。适配器必须确认采集写入及设备同步已经完成,并保证该 SDK 引用存活期间不覆盖数据;不能用语言层引用计数掩盖 SDK 会提前复用的事实。无法提供这项保证时选择复制。停止采集或设备断开若可能使已持有地址失效,也必须按供应商协议提前脱离或采用复制模式,不能承诺软件锁能挽救失效地址。
SDK 的“持有一帧”只与一次底层协调实体对应,图像 Share 不重复 AddRef SDK。最后归还时 Release 一次。每次缓冲进入新的外借周期取得新 BufferId,即使物理地址与上次相同;在同一外借周期只建立一个协调实体,禁止重复 ImportNative 同一地址制造不相干的锁。
Copy 也不是无限制分配许可。采集适配器在复制前取得自有池和入口预算,不能先拷贝再发现队列已无容量。回调不能阻塞等待 UI、算法结束或同一 SDK 线程执行归还;使用 TryPostOwned 或有明确时限的 SDK 专用接入策略。
入口接管和拒绝的最短示例
以下 image 已由适配器创建为稳定 ReadOnly 图像,且正好拥有一个待交接 handle:
// 示意:image 已是稳定 ReadOnly 句柄,且正好一个待交接 handle
vyntek::imaging::PixelImageHandle image = /* 适配器已创建 */;
bool accepted = false;
try {
accepted = input.TryPostOwned(std::move(image)); // 成功则接管所有权
} catch (...) {
// 抛错时不得接管:若 image 仍有效则关闭(实现约定)
throw;
}
if (!accepted) {
// 拒绝入队:关闭未接管的 image(若 move 后为空则无需再关)
}TryPostOwned 必须保证抛错时未接管。相机导入前的失败仍由适配器归还 SDK;导入成功后只能通过图像关闭触发归还,不能再在外层 finally 无条件调用 SDK Release。CPU Copy 成功但入队失败时也关闭复制图像。
SDK 池、归还泵与预览解耦
SDK 池的可用缓冲要覆盖采集占用、不同在途原图、消费者保留和正在归还的引用,并留采集余量。相同原图的多个 Share 不多占 SDK 池槽,但会延长该槽占用时间。小 ROI 同样可能占用完整相机大缓冲。用长期观察到的在途数量与持有时长确定容量,不能仅按显示帧率或工具数估算。
releaseAsync 在清理队列执行后可能还要投递 SDK 专属线程。适配器需要一个贯穿整个采集会话的归还泵;任务计数包含排队归还和实际回调执行,ReturnCompleted 只在 SDK 确认归还后完成。归还队列也必须有界或在采集入口预留归还容量,不能在所有引用都关闭后又积累无界清理工作。归还失败是会话故障,不能吞掉或重复调用同一个 Release。
预览使用一个有所有权的 Latest 槽,再由 UI 定时/合并取走最新图像,不能为每次采集无限 Post 一个带图像引用的 dispatcher 回调。被替换项立即关闭;槽位送入 ImageDisplay 后,其自有 handle 也按接管规则关闭。实时相机预览适配默认选 Snapshot,使 UI 暂停时最多保留一个受预算控制的显示副本;控件通用默认 RetainInput 仍适用于显式共享场景。
历史查看和长时间重试不能无限保留 SDK 槽位。宿主按保留时限把需要长期保存的内容复制到受配额约束的独立存储,再关闭 SDK 原图;历史副本同样有数量/字节上限。ROI 缓存也遵循此规则,不因逻辑图像小就忽略其牵连的 SDK 成本。
低拷贝指采集原图到算法可共享,并不承诺显示上传、颜色转换或历史保存都零拷贝。若可靠记录或慢算法超过采集速率,需调整采集速率、拒绝/丢弃策略或提供更多受控存储;不存在无限流量、零丢帧、有限内存和任意慢消费者同时成立的配置。
可勾选契约(Arden · R10 · 薄回链)
阶段 D 散文 → 可勾选:TC-ACQ-01…07(ImportNative vs 回调 Copy、TryPostOwned、满池/入口预算、归还泵与 ReturnCompleted、Latest 预览、回调不堵 SDK 归还)。薄摘表见 test-contracts-tc-acq.md;全文表见 mvdocs test-contracts §8(本波不迁完整 test-contracts)。薄场景 S11。会话排空/故障见 session-lifecycle.md TC-SESS-*。不改 toolflow v1.9 / T9 停止矩阵语义。
实现对拍(tip e46c042 · 按实)
头:
imaging/buffer.hpp·acquisition_session.hpp·fake_camera_adapter.hpp·memory_pool.hpp。注释仍写NON-STABLE ABI / STUB。公开入口仍吃ImageBuffer,不是规格示意里的PixelImageHandle入队。外形 ≠ 验收。
已有外形
| 表面 | 按实(tip e46c042) |
|---|---|
ImageBuffer::ImportNative(…, release) | 已有;exactly-once release |
AwaitReturnCompleted / ReturnCompleted | 已有(实现在 src/imaging,不再是头内空体) |
TryPostOwned(ImageBuffer) | 有界 ingress_(容量 8);满 → InvalidOperation;成功写入 Latest 预览 Share |
Latest() | 有所有权预览槽;替换关闭上一预览;空 → nullopt |
PeekIngressFront() | FIFO 队首窥视;不是 Latest |
CanRent / TryRent(MemoryPool*) | 复制前预算查询 + 真正租用;CanRent 真不等于已保留 |
fake_camera_adapter.hpp | 持帧 ImportNative 与回调 Copy 两策略外形;回调不 AwaitReturnCompleted |
| 归还泵 | Running 期间可泵(M4-04);kReturnQueueCapacity 有界;失败可观察 |
相对规格仍为 stub / 缺口
| 规格期望 | tip e46c042 现状 |
|---|---|
| 供应商相机适配(非 fake) | 无;仅 fake 适配外形 |
TryPostOwned(PixelImageHandle) 布尔三路径 | 仍为 Status TryPostOwned(ImageBuffer) |
| 贯穿真实 SDK 线程的 releaseAsync 泵 | 会话侧泵骨架在;未标供应商线程验收 |
| 预览槽禁止无界 dispatcher | Latest 槽已是单槽替换;UI 定时取走属显示(M5) |
| TC-ACQ-01…07 | 勾选仍空;无一标验收完成 |
文档状态:www 工作副本(2026-10-21,Asia/Shanghai)。可勾选见 Arden · R10(TC-ACQ- / S11);与 session-lifecycle / toolflow v1.9 §7.4.3 对齐。对拍 tip e46c042。*