diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs
index 635c09b..42cd53c 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs
@@ -1041,28 +1041,28 @@ namespace JoyD.Windows.CS.Toprie
// 更新视频模式菜单项的选中状态
try
{
- int currentMode = _deviceManager.GetCurrentVideoMode();
+ var currentMode = _deviceManager.CurrentVideoMode;
switch (currentMode)
{
- case 0:
+ case VideoMode.Infrared:
thermalModeToolStripMenuItem.Checked = true;
break;
- case 1:
+ case VideoMode.VisibleLight:
visibleModeToolStripMenuItem.Checked = true;
break;
- case 2:
+ case VideoMode.Fusion1:
fusionMode1ToolStripMenuItem.Checked = true;
break;
- case 3:
+ case VideoMode.Fusion2:
fusionMode2ToolStripMenuItem.Checked = true;
break;
- case 4:
+ case VideoMode.Fusion3:
fusionMode3ToolStripMenuItem.Checked = true;
break;
- case 5:
+ case VideoMode.Fusion4:
fusionMode4ToolStripMenuItem.Checked = true;
break;
- case 6:
+ case VideoMode.Fusion5:
fusionMode5ToolStripMenuItem.Checked = true;
break;
}
@@ -1247,7 +1247,7 @@ namespace JoyD.Windows.CS.Toprie
if (_deviceManager != null)
{
Console.WriteLine("切换到红外模式");
- _deviceManager.SetVideoMode(0);
+ _deviceManager.SetVideoMode(VideoMode.Infrared);
}
}
catch (Exception ex)
@@ -1267,7 +1267,7 @@ namespace JoyD.Windows.CS.Toprie
if (_deviceManager != null)
{
Console.WriteLine("切换到自然模式");
- _deviceManager.SetVideoMode(1);
+ _deviceManager.SetVideoMode(VideoMode.VisibleLight);
}
}
catch (Exception ex)
@@ -1287,7 +1287,7 @@ namespace JoyD.Windows.CS.Toprie
if (_deviceManager != null)
{
Console.WriteLine("切换到融合模式1");
- _deviceManager.SetVideoMode(2);
+ _deviceManager.SetVideoMode(VideoMode.Fusion1);
}
}
catch (Exception ex)
@@ -1307,7 +1307,7 @@ namespace JoyD.Windows.CS.Toprie
if (_deviceManager != null)
{
Console.WriteLine("切换到融合模式2");
- _deviceManager.SetVideoMode(3);
+ _deviceManager.SetVideoMode(VideoMode.Fusion2);
}
}
catch (Exception ex)
@@ -1327,7 +1327,7 @@ namespace JoyD.Windows.CS.Toprie
if (_deviceManager != null)
{
Console.WriteLine("切换到融合模式3");
- _deviceManager.SetVideoMode(4);
+ _deviceManager.SetVideoMode(VideoMode.Fusion3);
}
}
catch (Exception ex)
@@ -1347,7 +1347,7 @@ namespace JoyD.Windows.CS.Toprie
if (_deviceManager != null)
{
Console.WriteLine("切换到融合模式4");
- _deviceManager.SetVideoMode(5);
+ _deviceManager.SetVideoMode(VideoMode.Fusion4);
}
}
catch (Exception ex)
@@ -1367,7 +1367,7 @@ namespace JoyD.Windows.CS.Toprie
if (_deviceManager != null)
{
Console.WriteLine("切换到融合模式5");
- _deviceManager.SetVideoMode(6);
+ _deviceManager.SetVideoMode(VideoMode.Fusion5);
}
}
catch (Exception ex)
diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs
index fb40335..8cd3403 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs
@@ -52,6 +52,21 @@ namespace JoyD.Windows.CS.Toprie
RedHot, // 红热,对应SDK参数6
Rainbow2 // 彩虹2,对应SDK参数7
}
+
+ ///
+ /// 视频模式枚举
+ /// 对应SDK文档中的7种视频模式:红外、可见光、融合1~5
+ ///
+ public enum VideoMode
+ {
+ Infrared, // 红外,对应SDK参数0
+ VisibleLight, // 可见光,对应SDK参数1
+ Fusion1, // 融合1,对应SDK参数2
+ Fusion2, // 融合2,对应SDK参数3
+ Fusion3, // 融合3,对应SDK参数4
+ Fusion4, // 融合4,对应SDK参数5
+ Fusion5 // 融合5,对应SDK参数6
+ }
///
/// 连接状态改变事件参数
@@ -163,6 +178,8 @@ namespace JoyD.Windows.CS.Toprie
private ImageMode _currentImageMode = ImageMode.Thermal;
// 当前色彩模式
private PaletteType _currentPaletteType = PaletteType.WhiteHot;
+ // 当前视频模式
+ private VideoMode _currentVideoMode = VideoMode.Infrared; // 默认红外模式
// 自动重连是否启用
private bool _autoReconnectEnabled = true;
// 自动重连定时器
@@ -2232,15 +2249,9 @@ namespace JoyD.Windows.CS.Toprie
///
/// 设置视频模式
///
- /// 视频模式(0:红外,1:自然,2-6:融合模式1-5)
- public void SetVideoMode(int videoMode)
+ /// 视频模式枚举
+ public void SetVideoMode(VideoMode videoMode)
{
- // 验证参数范围
- if (videoMode < 0 || videoMode > 6)
- {
- throw new ArgumentOutOfRangeException("videoMode", "视频模式必须在0-6范围内");
- }
-
// 调用SDK设置视频模式
SendVideoModeCommand(videoMode);
}
@@ -2248,8 +2259,8 @@ namespace JoyD.Windows.CS.Toprie
///
/// 获取当前视频模式
///
- /// 当前视频模式值(0-6)
- public int GetCurrentVideoMode()
+ /// 当前视频模式枚举
+ public VideoMode GetCurrentVideoMode()
{
lock (_sdkOperationLock)
{
@@ -2259,16 +2270,19 @@ namespace JoyD.Windows.CS.Toprie
throw new InvalidOperationException("设备未连接");
}
- // 调用SDK获取视频模式
- return _a8Sdk.GetVideoMode();
+ // 从设备同步视频模式到内部状态
+ SyncVideoModeFromDevice();
+
+ // 返回内部状态中的视频模式值
+ return _currentVideoMode;
}
}
///
/// 发送视频模式变更命令到设备
///
- /// 视频模式值
- private void SendVideoModeCommand(int videoMode)
+ /// 视频模式枚举值
+ private void SendVideoModeCommand(VideoMode videoMode)
{
lock (_sdkOperationLock)
{
@@ -2287,22 +2301,32 @@ namespace JoyD.Windows.CS.Toprie
continue;
}
- // 调用SDK设置视频模式
- _a8Sdk.SetVideoMode(videoMode);
+ // 调用SDK设置视频模式(转换为int)
+ _a8Sdk.SetVideoMode((int)videoMode);
// 短暂延迟,确保设置生效
Thread.Sleep(50);
// 简单验证:尝试读取视频模式确认设置成功
- int currentMode = _a8Sdk.GetVideoMode();
- if (currentMode == videoMode)
+ int currentModeInt = _a8Sdk.GetVideoMode();
+ if (Enum.IsDefined(typeof(VideoMode), currentModeInt))
{
- Log($"视频模式切换成功,当前模式: {videoMode}");
- return;
+ VideoMode currentMode = (VideoMode)currentModeInt;
+ if (currentMode == videoMode)
+ {
+ // 更新内部状态
+ _currentVideoMode = videoMode;
+ Log($"视频模式切换成功,当前模式: {videoMode}");
+ return;
+ }
+ else
+ {
+ Log($"视频模式验证失败,期望: {videoMode},实际: {currentMode}");
+ }
}
else
{
- Log($"视频模式验证失败,期望: {videoMode},实际: {currentMode}");
+ Log($"视频模式验证失败,获取到无效的视频模式值: {currentModeInt}");
}
}
catch (Exception ex)
@@ -2337,7 +2361,54 @@ namespace JoyD.Windows.CS.Toprie
get { return _currentPaletteType; }
set { _currentPaletteType = value; }
}
+
+ ///
+ /// 获取或设置当前视频模式
+ ///
+ public VideoMode CurrentVideoMode
+ {
+ get { return _currentVideoMode; }
+ set { _currentVideoMode = value; }
+ }
+ ///
+ /// 从设备同步视频模式到内部状态
+ ///
+ public void SyncVideoModeFromDevice()
+ {
+ try
+ {
+ // 确保设备已连接且SDK实例有效
+ if (_connectionStatus == ConnectionStatus.Connected && _a8Sdk != null)
+ {
+ // 获取当前设备的视频模式值
+ int currentValue = _a8Sdk.GetVideoMode();
+ Log($"从设备读取的视频模式值: {currentValue}");
+
+ // 验证视频模式值是否在有效范围内并转换为枚举
+ if (Enum.IsDefined(typeof(VideoMode), currentValue))
+ {
+ VideoMode actualMode = (VideoMode)currentValue;
+ _currentVideoMode = actualMode;
+ Log($"已更新内部状态为设备实际值: {actualMode} (值: {currentValue})");
+ }
+ else
+ {
+ Log($"警告:设备返回的视频模式值 {currentValue} 不在有效范围内(0-6),使用默认值");
+ }
+ }
+ else
+ {
+ Log($"同步视频模式失败:设备未连接或SDK未初始化");
+ }
+ }
+ catch (Exception ex)
+ {
+ Log($"同步视频模式时发生异常: {ex.Message}");
+ throw; // 重新抛出异常,让调用方知道发生了错误
+ }
+ }
+
///
/// 从设备同步色彩模式到内部状态
///
@@ -2458,11 +2529,11 @@ namespace JoyD.Windows.CS.Toprie
setSuccess = (currentValue == paletteValue);
// 如果设置成功,更新内部状态
- if (setSuccess)
- {
- _currentPaletteType = paletteType;
- Log($"内部状态_currentPaletteType已更新为: {paletteType}");
- }
+ if (setSuccess)
+ {
+ _currentPaletteType = paletteType;
+ Log($"内部状态_currentPaletteType已更新为: {paletteType}");
+ }
}
catch (Exception ex)
{
@@ -3181,7 +3252,7 @@ namespace JoyD.Windows.CS.Toprie
UpdateConnectionStatus(ConnectionStatus.Connected, "设备连接成功");
- // 连接成功后同步色彩模式
+ // 连接成功后同步色彩模式和视频模式
try
{
SyncPaletteTypeFromDevice();
@@ -3190,6 +3261,16 @@ namespace JoyD.Windows.CS.Toprie
{
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 同步色彩模式失败: {ex.Message}");
};
+
+ // 同步视频模式
+ try
+ {
+ SyncVideoModeFromDevice();
+ }
+ catch (Exception ex)
+ {
+ Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 同步视频模式失败: {ex.Message}");
+ };
}
else if (!token.IsCancellationRequested)
{
@@ -3703,7 +3784,7 @@ namespace JoyD.Windows.CS.Toprie
UpdateConnectionStatus(ConnectionStatus.Connected, $"设备 {deviceIp} 连接成功");
- // 重连成功后同步色彩模式
+ // 重连成功后同步色彩模式和视频模式
try
{
SyncPaletteTypeFromDevice();
@@ -3712,6 +3793,16 @@ namespace JoyD.Windows.CS.Toprie
{
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 重连后同步色彩模式失败: {ex.Message}");
};
+
+ // 同步视频模式
+ try
+ {
+ SyncVideoModeFromDevice();
+ }
+ catch (Exception ex)
+ {
+ Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 重连后同步视频模式失败: {ex.Message}");
+ };
StartConnectionCheck();
connectionSuccessful = true;
}
diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs
index 3d9a0e3..3d50950 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs
@@ -767,49 +767,208 @@ namespace JoyD.Windows.CS.Toprie
}
}
- public int Video_mode
+ private int _lastKnownVideoMode = 0; // 保存最后已知的视频模式值
+ private readonly object _videoModeLock = new object(); // 线程锁,确保线程安全
+
+ ///
+ /// 获取当前视频模式值(内部方法)
+ ///
+ /// 视频模式值,如果获取失败则返回上次已知值
+ private int GetVideoModeInternal()
{
- get
+ lock (_videoModeLock)
{
try
{
- // 使用SDK格式获取视频模式: +CMD:param_mode,param_value$
- string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.VIDEO_MODE}$";
+ const int maxRetries = 3;
+ int retryCount = 0;
+ bool success = false;
+ int resultValue = _lastKnownVideoMode;
- if (SendCommand(command, out string response))
+ while (retryCount < maxRetries && !success)
{
- return ParseResponseValue(response);
+ retryCount++;
+ // 使用SDK格式获取视频模式: +CMD:param_mode,param_value$
+ string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.VIDEO_MODE}$";
+
+ Log($"[视频模式读取] 开始获取视频模式值{(retryCount > 1 ? " (重试 " + retryCount + "/" + maxRetries + ")" : "")},发送命令: {command}");
+
+ if (SendCommand(command, out string response))
+ {
+ Log($"[视频模式读取] 收到响应: {response}");
+ try
+ {
+ int parsedValue = ParseResponseValue(response);
+
+ if (response != null && parsedValue != -1) // 确保响应有效且解析成功
+ {
+ Log($"[视频模式读取] 解析成功,当前值: {parsedValue},上一次值: {_lastKnownVideoMode}");
+ _lastKnownVideoMode = parsedValue;
+ resultValue = parsedValue;
+ success = true;
+ }
+ else if (retryCount < maxRetries)
+ {
+ Log($"[视频模式读取] 解析失败或响应无效,将重试...");
+ System.Threading.Thread.Sleep(200); // 短暂延迟后重试
+ }
+ else
+ {
+ Log($"[视频模式读取] 解析失败或响应无效,返回-1表示获取失败");
+ resultValue = -1; // 失败时返回-1而不是上次已知值
+ }
+ }
+ catch (Exception ex)
+ {
+ if (retryCount < maxRetries)
+ {
+ Log($"[视频模式读取] 解析异常: {ex.Message},将重试...");
+ System.Threading.Thread.Sleep(200); // 短暂延迟后重试
+ }
+ else
+ {
+ Log($"[视频模式读取] 解析异常: {ex.Message},重试次数已达上限");
+ resultValue = -1;
+ }
+ }
+ }
+ else if (retryCount < maxRetries)
+ {
+ Log($"[视频模式读取] 发送命令失败,将重试...");
+ System.Threading.Thread.Sleep(200); // 短暂延迟后重试
+ }
+ else
+ {
+ Log($"[视频模式读取] 发送命令失败,重试次数已达上限");
+ resultValue = -1;
+ }
}
- return 0; // 默认模式
+
+ return resultValue;
}
catch (Exception ex)
{
- Console.WriteLine($"获取视频模式失败: {ex.Message}");
- return 0;
+ Log($"[视频模式读取] 发生异常: {ex.Message}");
+ return -1;
}
}
- set
+ }
+
+ ///
+ /// 设置视频模式值(内部方法)
+ ///
+ /// 要设置的视频模式值
+ /// 设置是否成功
+ private bool SetVideoModeInternal(int value)
+ {
+ lock (_videoModeLock)
{
try
{
+ // 首先尝试获取当前值
+ int currentValue = GetVideoModeWithoutLock();
+ Log($"[视频模式设置] 开始设置视频模式值为: {value},尝试获取当前值: {currentValue}");
+
+ // 只有在成功获取到当前值(currentValue != -1)且与目标值相同时才跳过设置
+ // 如果获取失败(currentValue == -1),仍然执行设置操作,避免因获取失败而跳过设置
+ if (currentValue != -1 && currentValue == value)
+ {
+ Log($"[视频模式设置] 当前视频模式已为目标值,无需设置");
+ return true;
+ }
+ // 如果获取失败,记录日志说明将继续执行设置
+ else if (currentValue == -1)
+ {
+ Log($"[视频模式设置] 获取当前值失败,将执行设置操作");
+ }
+
// 使用SDK格式设置视频模式: +CMD:param_mode,param_value$
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_VIDEO_MODE},{value}$";
- if (SendCommand(command, out string response))
+ Log($"[视频模式设置] 发送命令: {command}");
+
+ bool success = SendCommand(command, out string response);
+ if (success && response != null)
{
- // 验证响应
- if (response != null)
+ Log($"[视频模式设置] 收到响应: {response}");
+
+ // 验证响应是否包含成功标记
+ bool responseValid = response.Contains("+RET:") &&
+ (!response.Contains("error") && !response.Contains("失败"));
+
+ if (responseValid)
{
- Console.WriteLine("设置视频模式成功");
+ Log($"[视频模式设置成功] 从 {_lastKnownVideoMode} 变更为 {value}");
+ _lastKnownVideoMode = value; // 更新最后已知值
+
+ // 验证设置是否生效
+ Log($"[视频模式设置] 验证设置是否生效...");
+ int validatedValue = GetVideoModeWithoutLock();
+ if (validatedValue == value)
+ {
+ Log($"[视频模式设置] 验证成功,当前值确认为: {validatedValue}");
+ return true;
+ }
+ else
+ {
+ Log($"[视频模式设置] 验证失败,当前值: {validatedValue},目标值: {value}");
+ return false;
+ }
}
+ else
+ {
+ Log($"[视频模式设置] 响应无效或失败: {response}");
+ return false;
+ }
+ }
+ else
+ {
+ Log($"[视频模式设置] 发送命令失败或未收到响应");
+ return false;
}
}
catch (Exception ex)
{
- Console.WriteLine($"设置视频模式失败: {ex.Message}");
+ Log($"[视频模式设置] 发生异常: {ex.Message}");
+ return false;
}
}
}
+
+ ///
+ /// 不带锁获取视频模式,避免在设置后验证时出现死锁
+ ///
+ private int GetVideoModeWithoutLock()
+ {
+ try
+ {
+ // 使用SDK格式获取视频模式: +CMD:param_mode,param_value$
+ string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.VIDEO_MODE}$";
+ if (SendCommand(command, out string response))
+ {
+ int result = ParseResponseValue(response);
+ // 如果解析结果不是特殊值-1,表示解析成功
+ if (result != -1)
+ {
+ return result;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log($"[GetVideoModeWithoutLock异常] {ex.Message}");
+ }
+ // 返回特殊值-1表示获取失败,而不是返回_lastKnownVideoMode
+ // 这样SetVideoModeInternal方法可以明确判断是否获取到了真实值
+ return -1;
+ }
+
+ // 保留原属性以保持向后兼容性
+ public int Video_mode
+ {
+ get => GetVideoModeInternal();
+ set => SetVideoModeInternal(value);
+ }
public void Set_area_pos(int index, SharedStructures.AreaPos area_data)
{
@@ -2251,28 +2410,13 @@ namespace JoyD.Windows.CS.Toprie
// 获取视频模式
public int GetVideoMode()
{
- try
- {
- return Video_mode;
- }
- catch (Exception ex)
- {
- Console.WriteLine($"获取视频模式失败: {ex.Message}");
- return 0;
- }
+ return GetVideoModeInternal();
}
// 设置视频模式
public void SetVideoMode(int mode)
{
- try
- {
- Video_mode = mode;
- }
- catch (Exception ex)
- {
- Console.WriteLine($"设置视频模式失败: {ex.Message}");
- }
+ SetVideoModeInternal(mode);
}
// 新增方法:获取图像数据