增加本地Cv2.ImShow播放的动态增加、移除的支持
This commit is contained in:
63
SHH.CameraSdk/Core/Services/DisplayWindowManager.cs
Normal file
63
SHH.CameraSdk/Core/Services/DisplayWindowManager.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user