Files
Ayay/SHH.CameraSdk/Core/Services/DisplayWindowManager.cs

63 lines
2.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace SHH.CameraSdk;
/// <summary>
/// 动态窗口管理器
/// 职责:根据业务指令动态创建/销毁 OpenCV 播放窗口,并管理流订阅
/// </summary>
public class DisplayWindowManager
{
// 存储活跃的渲染器实例Key = AppId (如 "UI_Preview_Main")
private readonly ConcurrentDictionary<string, FrameConsumer> _activeWindows = new();
/// <summary>
/// 开启一个本地播放窗口
/// </summary>
/// <param name="appId">业务标识 (将作为窗口标题)</param>
/// <param name="deviceId">要观看的设备ID</param>
public void StartDisplay(string appId, int deviceId)
{
// 如果窗口已存在,直接返回(防止重复创建)
if (_activeWindows.ContainsKey(appId)) return;
Console.WriteLine($"[DisplayManager] 正在创建窗口: {appId} -> Device {deviceId}...");
// 1. 动态创建渲染器
var renderer = new FrameConsumer(appId);
// 2. 启动渲染循环 (由于我们之前加了懒加载逻辑,此时不会立即弹窗,直到有帧数据过来)
renderer.Start();
// 3. 存入字典管理
if (_activeWindows.TryAdd(appId, renderer))
{
// 4. 【关键】建立数据订阅:将设备流导向这个渲染器
GlobalStreamDispatcher.Subscribe(appId, deviceId, frame =>
{
// 引用计数 +1防止在渲染前被回收
frame.AddRef();
renderer.Enqueue(frame);
});
}
else
{
renderer.Dispose(); // 并发冲突处理
}
}
/// <summary>
/// 关闭并销毁窗口
/// </summary>
public void StopDisplay(string appId)
{
if (_activeWindows.TryRemove(appId, out var renderer))
{
Console.WriteLine($"[DisplayManager] 正在关闭窗口: {appId}");
// 1. 取消订阅 (停止接收数据)
GlobalStreamDispatcher.Unsubscribe(appId);
// 2. 销毁渲染器 (OpenCV DestroyWindow 会在 FrameConsumer 内部触发)
renderer.Dispose();
}
}
}