海康摄像头取流示例初始签入
This commit is contained in:
86
SHH.CameraSdk/Core/Scheduling/FrameController.cs
Normal file
86
SHH.CameraSdk/Core/Scheduling/FrameController.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
namespace SHH.CameraSdk;
|
||||
|
||||
/// <summary>
|
||||
/// 帧控制器(帧调度核心)
|
||||
/// 功能:管理订阅者的帧需求,基于需求动态判定每帧的处理命运(保留/丢弃、分发目标)
|
||||
/// 核心逻辑:采用“并集采样”策略,满足任意订阅者的帧率需求即保留帧,避免重复采样浪费资源
|
||||
/// </summary>
|
||||
public class FrameController
|
||||
{
|
||||
#region --- 私有资源与状态 (Private Resources & States) ---
|
||||
|
||||
/// <summary> 订阅者帧需求集合(线程安全) </summary>
|
||||
/// <remarks> Key:订阅者AppId,Value:该订阅者的帧需求配置 </remarks>
|
||||
private readonly ConcurrentDictionary<string, FrameRequirement> _requirements = new();
|
||||
|
||||
/// <summary> 全局决策序列号(原子递增,确保决策唯一标识) </summary>
|
||||
private long _globalSequence = 0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- 需求管理 (Requirement Management) ---
|
||||
|
||||
/// <summary>
|
||||
/// 注册/更新订阅者的帧需求
|
||||
/// 功能:新增订阅者需求或更新已有订阅者的目标帧率
|
||||
/// </summary>
|
||||
/// <param name="appId">订阅者唯一标识(如 "RemoteClient_01"、"AI_Behavior_Engine")</param>
|
||||
/// <param name="fps">目标帧率(单位:fps,需大于0,否则视为无效需求)</param>
|
||||
public void Register(string appId, int fps)
|
||||
{
|
||||
// 新增或更新需求:不存在则创建,存在则更新目标帧率
|
||||
_requirements.AddOrUpdate(appId,
|
||||
addValueFactory: _ => new FrameRequirement { AppId = appId, TargetFps = fps },
|
||||
updateValueFactory: (_, oldRequirement) =>
|
||||
{
|
||||
oldRequirement.TargetFps = fps;
|
||||
return oldRequirement;
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- 帧决策生成 (Frame Decision Generation) ---
|
||||
|
||||
/// <summary>
|
||||
/// [热路径] 判定当前物理帧是否需要保留并分发
|
||||
/// 核心逻辑:并集采样,只要任意订阅者达到采样间隔,就保留该帧并分发至对应订阅者
|
||||
/// </summary>
|
||||
/// <param name="currentTick">当前系统时间戳(单位:毫秒,建议使用 Environment.TickCount64)</param>
|
||||
/// <returns>帧决策结果(包含是否保留、分发目标等信息)</returns>
|
||||
public FrameDecision MakeDecision(long currentTick)
|
||||
{
|
||||
// 初始化决策对象,生成唯一序列号与时间戳
|
||||
var decision = new FrameDecision
|
||||
{
|
||||
Sequence = Interlocked.Increment(ref _globalSequence), // 原子递增,线程安全
|
||||
Timestamp = DateTime.Now
|
||||
};
|
||||
|
||||
// 遍历所有订阅者需求,判定是否需要为该订阅者保留当前帧
|
||||
foreach (var req in _requirements.Values)
|
||||
{
|
||||
// 跳过无效需求(目标帧率≤0)
|
||||
if (req.TargetFps <= 0) continue;
|
||||
|
||||
// 计算该订阅者的采样间隔(毫秒):1000ms / 目标帧率
|
||||
long interval = 1000 / req.TargetFps;
|
||||
|
||||
// 判定是否达到采样时间:当前时间 - 上次采样时间 ≥ 采样间隔(允许1s内相位对齐,自动合并)
|
||||
if (currentTick - req.LastCaptureTick >= interval)
|
||||
{
|
||||
// 加入分发目标列表
|
||||
decision.TargetAppIds.Add(req.AppId);
|
||||
// 更新该订阅者的上次采样时间,避免重复采样
|
||||
req.LastCaptureTick = currentTick;
|
||||
}
|
||||
}
|
||||
|
||||
// 判定是否保留该帧:存在分发目标则保留(IsCaptured=true),否则丢弃
|
||||
decision.IsCaptured = decision.TargetAppIds.Count > 0;
|
||||
|
||||
return decision;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
34
SHH.CameraSdk/Core/Scheduling/FrameDecision.cs
Normal file
34
SHH.CameraSdk/Core/Scheduling/FrameDecision.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace SHH.CameraSdk;
|
||||
|
||||
/// <summary>
|
||||
/// 帧决策结果模型
|
||||
/// 功能:告知驱动层单帧数据的处理命运(保留/丢弃、分发目标),是帧调度的核心指令
|
||||
/// 用途:由 FrameController 生成,传递给驱动层与分发器,指导帧的后续流转
|
||||
/// </summary>
|
||||
public class FrameDecision
|
||||
{
|
||||
#region --- 决策核心标识 (Decision Core Identification) ---
|
||||
|
||||
/// <summary> 决策序列号(全局唯一,关联帧的决策记录,用于追踪决策生命周期) </summary>
|
||||
public long Sequence { get; set; }
|
||||
|
||||
/// <summary> 决策生成时间戳(记录决策的创建时刻,默认当前时间) </summary>
|
||||
public DateTime Timestamp { get; set; } = DateTime.Now;
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- 帧处理决策 (Frame Processing Decision) ---
|
||||
|
||||
/// <summary> 帧是否被保留(true=保留并分发,false=直接丢弃,不进行后续处理) </summary>
|
||||
public bool IsCaptured { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- 帧分发目标 (Frame Distribution Targets) ---
|
||||
|
||||
/// <summary> 帧分发目标应用ID列表(记录该帧将服务的所有订阅者AppId) </summary>
|
||||
/// <remarks> 示例值:["WPF_Display_Main", "AI_Behavior_Engine"],仅当 IsCaptured 为 true 时有效 </remarks>
|
||||
public List<string> TargetAppIds { get; } = new();
|
||||
|
||||
#endregion
|
||||
}
|
||||
37
SHH.CameraSdk/Core/Scheduling/FrameRequirement.cs
Normal file
37
SHH.CameraSdk/Core/Scheduling/FrameRequirement.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
namespace SHH.CameraSdk;
|
||||
|
||||
/// <summary>
|
||||
/// 帧需求定义模型
|
||||
/// 功能:描述某个程序/模块对视频帧的消费需求,用于帧分发调度与帧率控制
|
||||
/// 用途:配合 FrameController,实现按订阅者需求精准分配帧资源,避免资源浪费
|
||||
/// </summary>
|
||||
public class FrameRequirement
|
||||
{
|
||||
#region --- 订阅者核心标识 (Subscriber Core Identification) ---
|
||||
|
||||
/// <summary> 订阅者唯一ID(如 "Client_A"、"AI_Service"、"WPF_Display_Main") </summary>
|
||||
/// <remarks> 用于区分不同的帧消费模块,作为帧分发路由的关键标识 </remarks>
|
||||
public string AppId { get; set; } = string.Empty;
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- 帧需求参数 (Frame Requirement Parameters) ---
|
||||
|
||||
/// <summary> 目标帧率(单位:fps,订阅者期望的每秒接收帧数,0 表示无特定需求) </summary>
|
||||
/// <remarks> 例如:UI 预览需 8fps,AI 分析需 2fps,按需分配以节省计算资源 </remarks>
|
||||
public int TargetFps { get; set; } = 0;
|
||||
|
||||
/// <summary> 上次获取帧的时间点(单位:毫秒,通常为 Environment.TickCount64) </summary>
|
||||
/// <remarks> 用于帧率控制算法,判断是否达到订阅者的目标帧率需求 </remarks>
|
||||
public long LastCaptureTick { get; set; } = 0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- 需求状态控制 (Requirement Status Control) ---
|
||||
|
||||
/// <summary> 需求是否激活(true=正常接收帧,false=暂停接收,保留配置) </summary>
|
||||
/// <remarks> 支持动态启停订阅,无需删除需求配置,提升灵活性 </remarks>
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user