Files
Ayay/SHH.CameraSdk/Core/Memory/SmartFrame.cs

95 lines
3.3 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.
using OpenCvSharp;
namespace SHH.CameraSdk;
/// <summary>
/// [零延迟核心] 智能帧(内存复用+引用计数)
/// 功能:封装 OpenCV Mat 实现物理内存复用,通过引用计数管理生命周期,避免 GC 频繁回收导致的性能抖动
/// 特性:引用归零自动回池,全程无内存分配/释放开销,支撑高帧率实时流处理
/// </summary>
public class SmartFrame : IDisposable
{
#region --- (Private Resources & States) ---
/// <summary> 所属帧池:用于引用归零后自动回收复用 </summary>
private readonly FramePool _pool;
/// <summary> 引用计数器:线程安全,控制帧的生命周期 </summary>
/// <remarks> 初始值 0激活后设为 1引用归零则自动回池 </remarks>
private int _refCount = 0;
#endregion
#region --- (Public Properties) ---
/// <summary> 帧数据物理内存载体OpenCV Mat 对象) </summary>
/// <remarks> 内存由帧池预分配,全程复用,不触发 GC </remarks>
public Mat InternalMat { get; private set; }
/// <summary> 帧激活时间戳(记录帧被取出池的时刻) </summary>
public DateTime Timestamp { get; private set; }
#endregion
#region --- (Constructor & Activation) ---
/// <summary>
/// 初始化智能帧(由帧池调用,外部禁止直接实例化)
/// </summary>
/// <param name="pool">所属帧池实例</param>
/// <param name="width">帧宽度</param>
/// <param name="height">帧高度</param>
/// <param name="type">帧数据类型(如 MatType.CV_8UC3</param>
internal SmartFrame(FramePool pool, int width, int height, MatType type)
{
_pool = pool;
// 预分配物理内存:内存块在帧池生命周期内复用,避免频繁申请/释放
InternalMat = new Mat(height, width, type);
}
/// <summary>
/// [生产者调用] 从帧池取出时激活帧
/// 功能:初始化引用计数,标记激活时间戳
/// </summary>
public void Activate()
{
// 激活后引用计数设为 1代表生产者驱动/管道)持有该帧
_refCount = 1;
// 记录帧被取出池的时间,用于后续延迟计算
Timestamp = DateTime.Now;
}
#endregion
#region --- (Reference Count Management) ---
/// <summary>
/// [消费者调用] 增加引用计数
/// 适用场景:帧需要被多模块同时持有(如同时分发到 UI 和 AI 分析)
/// </summary>
public void AddRef()
{
// 原子递增:线程安全,避免多线程竞争导致计数错误
Interlocked.Increment(ref _refCount);
}
#endregion
#region --- (Disposal & Pool Return) ---
/// <summary>
/// [消费者调用] 释放引用计数
/// 核心逻辑:引用归零后自动将帧归还至帧池,实现内存复用
/// </summary>
public void Dispose()
{
// 原子递减:线程安全,确保计数准确
if (Interlocked.Decrement(ref _refCount) <= 0)
{
// 引用归零:所有消费者均已释放,将帧归还池复用
_pool.Return(this);
}
}
#endregion
}