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