Compare commits

..

No commits in common. "51b39cee077f795b714624ea00edb0d472b90bb5" and "f2c7c78b64bf434d54839bd9f8eb9b8d290de5fa" have entirely different histories.

6 changed files with 4 additions and 147 deletions

View File

@ -1,7 +1,6 @@
using System.Net; using System.Net;
using DotNext; using DotNext;
using Peripherals.PowerClient; using Peripherals.PowerClient;
using WebProtocol;
namespace Peripherals.CameraClient; namespace Peripherals.CameraClient;
@ -20,7 +19,7 @@ class Camera
{ {
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
readonly int timeout = 500; readonly int timeout = 2000;
readonly int taskID; readonly int taskID;
readonly int port; readonly int port;
readonly string address; readonly string address;
@ -44,7 +43,7 @@ class Camera
/// <param name="address">摄像头设备IP地址</param> /// <param name="address">摄像头设备IP地址</param>
/// <param name="port">摄像头设备端口</param> /// <param name="port">摄像头设备端口</param>
/// <param name="timeout">超时时间(毫秒)</param> /// <param name="timeout">超时时间(毫秒)</param>
public Camera(string address, int port, int timeout = 500) public Camera(string address, int port, int timeout = 2000)
{ {
if (timeout < 0) if (timeout < 0)
throw new ArgumentException("Timeout couldn't be negative", nameof(timeout)); throw new ArgumentException("Timeout couldn't be negative", nameof(timeout));
@ -226,7 +225,6 @@ class Camera
this.taskID, // taskID this.taskID, // taskID
FrameAddr, FrameAddr,
(int)_currentFrameLength, // 使用当前分辨率的动态大小 (int)_currentFrameLength, // 使用当前分辨率的动态大小
BurstType.ExtendBurst,
this.timeout); this.timeout);
if (!result.IsSuccessful) if (!result.IsSuccessful)
@ -464,20 +462,6 @@ class Camera
); );
} }
/// <summary>
/// 配置为960x540分辨率
/// </summary>
/// <returns>配置结果</returns>
public async ValueTask<Result<bool>> ConfigureResolution960x540()
{
return await ConfigureResolution(
hStart: 0, vStart: 0,
dvpHo: 960, dvpVo: 540,
hts: 1700, vts: 1500,
hOffset: 16, vOffset: 4
);
}
/// <summary> /// <summary>
/// 配置为320x240分辨率 /// 配置为320x240分辨率
/// </summary> /// </summary>
@ -559,9 +543,6 @@ class Camera
case "640x480": case "640x480":
result = await ConfigureResolution640x480(); result = await ConfigureResolution640x480();
break; break;
case "960x540":
result = await ConfigureResolution960x540();
break;
case "1280x720": case "1280x720":
result = await ConfigureResolution1280x720(); result = await ConfigureResolution1280x720();
break; break;

View File

@ -1,118 +0,0 @@
using System.Net;
using DotNext;
using Peripherals.PowerClient;
using WebProtocol;
namespace Peripherals.HdmiInClient;
static class HdmiInAddr
{
public const UInt32 BASE = 0xA000_0000;
public const UInt32 HdmiIn_CTRL = BASE + 0x0; //[0]: rstn, 0 is reset.
public const UInt32 HdmiIn_READFIFO = BASE + 0x1;
}
class HdmiIn
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
readonly int timeout = 500;
readonly int taskID;
readonly int port;
readonly string address;
private IPEndPoint ep;
// 动态分辨率参数
private UInt16 _currentWidth = 960;
private UInt16 _currentHeight = 540;
private UInt32 _currentFrameLength = 960 * 540 * 2 / 4; // RGB565格式2字节/像素按4字节对齐
/// <summary>
/// 初始化HDMI输入客户端
/// </summary>
/// <param name="address">HDMI输入设备IP地址</param>
/// <param name="port">HDMI输入设备端口</param>
/// <param name="timeout">超时时间(毫秒)</param>
public HdmiIn(string address, int port, int timeout = 500)
{
if (timeout < 0)
throw new ArgumentException("Timeout couldn't be negative", nameof(timeout));
this.address = address;
this.port = port;
this.ep = new IPEndPoint(IPAddress.Parse(address), port);
this.timeout = timeout;
}
public async ValueTask<Result<bool>> EnableTrans(bool isEnable)
{
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, HdmiInAddr.HdmiIn_CTRL, (isEnable ? 0x00000001u : 0x00000000u));
if (!ret.IsSuccessful)
{
logger.Error($"Failed to write HdmiIn_CTRL to HdmiIn at {this.address}:{this.port}, error: {ret.Error}");
return new(ret.Error);
}
if (!ret.Value)
{
logger.Error($"HdmiIn_CTRL write returned false for HdmiIn at {this.address}:{this.port}");
return false;
}
return true;
}
/// <summary>
/// 读取一帧图像数据
/// </summary>
/// <returns>包含图像数据的字节数组</returns>
public async ValueTask<Result<byte[]>> ReadFrame()
{
// 只在第一次或出错时清除UDP缓冲区避免每帧都清除造成延迟
// MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
logger.Trace($"Reading frame from HdmiIn {this.address}");
// 使用UDPClientPool读取图像帧数据
var result = await UDPClientPool.ReadAddr4BytesAsync(
this.ep,
this.taskID, // taskID
HdmiInAddr.HdmiIn_READFIFO,
(int)_currentFrameLength, // 使用当前分辨率的动态大小
BurstType.FixedBurst,
this.timeout);
if (!result.IsSuccessful)
{
logger.Error($"Failed to read frame from HdmiIn {this.address}:{this.port}, error: {result.Error}");
// 读取失败时清除缓冲区,为下次读取做准备
try
{
MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
}
catch (Exception ex)
{
logger.Warn($"Failed to clear UDP data after read error: {ex.Message}");
}
return new(result.Error);
}
logger.Trace($"Successfully read frame from HdmiIn {this.address}:{this.port}, data length: {result.Value.Length} bytes");
return result.Value;
}
/// <summary>
/// 获取当前分辨率
/// </summary>
/// <returns>当前分辨率(宽度, 高度)</returns>
public (int Width, int Height) GetCurrentResolution()
{
return (_currentWidth, _currentHeight);
}
/// <summary>
/// 获取当前帧长度
/// </summary>
/// <returns>当前帧长度</returns>
public UInt32 GetCurrentFrameLength()
{
return _currentFrameLength;
}
}

View File

@ -2,7 +2,6 @@ using System.Collections;
using System.Net; using System.Net;
using Common; using Common;
using DotNext; using DotNext;
using WebProtocol;
namespace Peripherals.LogicAnalyzerClient; namespace Peripherals.LogicAnalyzerClient;
@ -476,7 +475,6 @@ public class Analyzer
this.taskID, this.taskID,
AnalyzerAddr.STORE_OFFSET_ADDR, AnalyzerAddr.STORE_OFFSET_ADDR,
capture_length, capture_length,
BurstType.ExtendBurst, // 使用扩展突发读取
this.timeout this.timeout
); );
if (!ret.IsSuccessful) if (!ret.IsSuccessful)

View File

@ -1,7 +1,6 @@
using System.Net; using System.Net;
using Common; using Common;
using DotNext; using DotNext;
using WebProtocol;
namespace Peripherals.OscilloscopeClient; namespace Peripherals.OscilloscopeClient;
@ -320,7 +319,6 @@ class Oscilloscope
this.taskID, this.taskID,
OscilloscopeAddr.RD_DATA_ADDR, OscilloscopeAddr.RD_DATA_ADDR,
(int)OscilloscopeAddr.RD_DATA_LENGTH / 32, (int)OscilloscopeAddr.RD_DATA_LENGTH / 32,
BurstType.ExtendBurst, // 使用扩展突发读取
this.timeout this.timeout
); );
if (!ret.IsSuccessful) if (!ret.IsSuccessful)

View File

@ -1109,7 +1109,6 @@ public class HttpVideoStreamService : BackgroundService
return new List<(int, int, string)> return new List<(int, int, string)>
{ {
(640, 480, "640x480 (VGA)"), (640, 480, "640x480 (VGA)"),
(960, 540, "960x540 (qHD)"),
(1280, 720, "1280x720 (HD)"), (1280, 720, "1280x720 (HD)"),
(1280, 960, "1280x960 (SXGA)"), (1280, 960, "1280x960 (SXGA)"),
(1920, 1080, "1920x1080 (Full HD)") (1920, 1080, "1920x1080 (Full HD)")

View File

@ -433,12 +433,11 @@ public class UDPClientPool
/// <param name="endPoint">IP端点IP地址与端口</param> /// <param name="endPoint">IP端点IP地址与端口</param>
/// <param name="taskID">任务ID</param> /// <param name="taskID">任务ID</param>
/// <param name="devAddr">设备地址</param> /// <param name="devAddr">设备地址</param>
/// <param name="burstType">突发类型</param>
/// <param name="dataLength">要读取的数据长度4字节</param> /// <param name="dataLength">要读取的数据长度4字节</param>
/// <param name="timeout">超时时间(毫秒)</param> /// <param name="timeout">超时时间(毫秒)</param>
/// <returns>读取结果,包含接收到的字节数组</returns> /// <returns>读取结果,包含接收到的字节数组</returns>
public static async ValueTask<Result<byte[]>> ReadAddr4BytesAsync( public static async ValueTask<Result<byte[]>> ReadAddr4BytesAsync(
IPEndPoint endPoint, int taskID, UInt32 devAddr, int dataLength, BurstType burstType, int timeout = 1000) IPEndPoint endPoint, int taskID, UInt32 devAddr, int dataLength, int timeout = 1000)
{ {
var pkgList = new List<SendAddrPackage>(); var pkgList = new List<SendAddrPackage>();
var resultData = new List<byte>(); var resultData = new List<byte>();
@ -461,7 +460,7 @@ public class UDPClientPool
var opts = new SendAddrPackOptions var opts = new SendAddrPackOptions
{ {
BurstType = burstType, BurstType = BurstType.FixedBurst,
CommandID = Convert.ToByte(taskID), CommandID = Convert.ToByte(taskID),
IsWrite = false, IsWrite = false,
BurstLength = (byte)(currentSegmentSize - 1), BurstLength = (byte)(currentSegmentSize - 1),