63 lines
2.2 KiB
C#
63 lines
2.2 KiB
C#
using System.Threading.Channels;
|
||
|
||
namespace SHH.CameraService;
|
||
|
||
/// <summary>
|
||
/// 视频数据高速通道
|
||
/// <para>作用:解耦 采集线程(Producer) 和 发送线程(Consumer)</para>
|
||
/// <para>特性:使用 BoundedChannel,当网络发送慢时,自动丢弃旧帧(DropOldest),防止内存溢出。</para>
|
||
/// </summary>
|
||
public class VideoDataChannel
|
||
{
|
||
// 创建一个有限容量的通道 (容量 5)
|
||
// 如果发送端太慢,这就满了,DropOldest 会丢弃最旧的帧,保证实时性
|
||
private readonly Channel<VideoPayload> _channel = Channel.CreateBounded<VideoPayload>(
|
||
new BoundedChannelOptions(5)
|
||
{
|
||
FullMode = BoundedChannelFullMode.DropOldest, // 核心策略:丢弃旧帧
|
||
SingleReader = true, // 只有一个 ZeroMQWorker 在读
|
||
SingleWriter = false //可能有多个相机线程在写
|
||
});
|
||
|
||
// ★★★ 新增:公开 Reader 属性,让外部可以直接调用 ReadAsync ★★★
|
||
public ChannelReader<VideoPayload> Reader => _channel.Reader;
|
||
|
||
/// <summary>
|
||
/// 写入数据 (生产者调用)
|
||
/// </summary>
|
||
public ValueTask WriteAsync(VideoPayload payload)
|
||
{
|
||
return _channel.Writer.WriteAsync(payload);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取数据流 (消费者调用)
|
||
/// </summary>
|
||
public IAsyncEnumerable<VideoPayload> ReadAllAsync(CancellationToken ct)
|
||
{
|
||
return _channel.Reader.ReadAllAsync(ct);
|
||
}
|
||
}
|
||
|
||
// 附带:如果您的项目中还没有定义 VideoPayload,这里是一个最小实现
|
||
// 如果 SHH.Contracts 中已有,请忽略此类
|
||
public class VideoPayload
|
||
{
|
||
/// <summary> 相机唯一标识 </summary>
|
||
public string CameraId { get; set; } = string.Empty;
|
||
|
||
/// <summary> 采集时间 </summary>
|
||
public DateTime CaptureTime { get; set; }
|
||
|
||
/// <summary> 发送时间 </summary>
|
||
public DateTime DispatchTime { get; set; }
|
||
|
||
/// <summary> 原始宽 </summary>
|
||
public int OriginalWidth { get; set; }
|
||
|
||
/// <summary> 原始高 </summary>
|
||
public int OriginalHeight { get; set; }
|
||
|
||
/// <summary> 已编码的图片数据 (JPG) </summary>
|
||
public byte[] OriginalImageBytes { get; set; } = Array.Empty<byte>();
|
||
} |