feat: 增加了摄像头硬件复位和唤醒逻辑
This commit is contained in:
		@@ -11,6 +11,7 @@ static class CameraAddr
 | 
			
		||||
    public const UInt32 STORE_NUM = BASE + 0x13;
 | 
			
		||||
    public const UInt32 EXPECTED_VH = BASE + 0x14;
 | 
			
		||||
    public const UInt32 CAPTURE_ON = BASE + 0x15;
 | 
			
		||||
    public const UInt32 CAMERA_POWER = BASE + 0x16; //[0]: rstn, 0 is reset. [8]: power down, 1 is down.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Camera
 | 
			
		||||
@@ -26,7 +27,7 @@ class Camera
 | 
			
		||||
 | 
			
		||||
    const uint CAM_I2C_ADDR = 0x3C;
 | 
			
		||||
    const Peripherals.I2cClient.I2cProtocol CAM_PROTO = Peripherals.I2cClient.I2cProtocol.SCCB;
 | 
			
		||||
    const byte PLL_MUX = 10;
 | 
			
		||||
    const byte PLL_MUX = 60;
 | 
			
		||||
    const UInt32 FrameAddr = 0x00;
 | 
			
		||||
 | 
			
		||||
    // 动态分辨率参数
 | 
			
		||||
@@ -161,6 +162,56 @@ class Camera
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async ValueTask<Result<bool>> EnableCameraHardware(bool isEnable)
 | 
			
		||||
    {
 | 
			
		||||
        {
 | 
			
		||||
            var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAMERA_POWER, (isEnable ? 0x00000001u : 0x00000000u));
 | 
			
		||||
            if (!ret.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to write STORE_ADDR: {ret.Error}");
 | 
			
		||||
                return new(ret.Error);
 | 
			
		||||
            }
 | 
			
		||||
            if (!ret.Value)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error("STORE_ADDR write returned false");
 | 
			
		||||
                return new(new Exception("STORE_ADDR write returned false"));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async ValueTask<Result<bool>> SleepCameraHardware(bool isEnable)
 | 
			
		||||
    {
 | 
			
		||||
        {
 | 
			
		||||
            var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAMERA_POWER, (isEnable ? 0x00000101u : 0x00000001u));
 | 
			
		||||
            if (!ret.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to write STORE_ADDR: {ret.Error}");
 | 
			
		||||
                return new(ret.Error);
 | 
			
		||||
            }
 | 
			
		||||
            if (!ret.Value)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error("STORE_ADDR write returned false");
 | 
			
		||||
                return new(new Exception("STORE_ADDR write returned false"));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        await Task.Delay(5);
 | 
			
		||||
        {
 | 
			
		||||
            var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAMERA_POWER, 0x00000101);
 | 
			
		||||
            if (!ret.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to write STORE_ADDR: {ret.Error}");
 | 
			
		||||
                return new(ret.Error);
 | 
			
		||||
            }
 | 
			
		||||
            if (!ret.Value)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error("STORE_ADDR write returned false");
 | 
			
		||||
                return new(new Exception("STORE_ADDR write returned false"));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 读取一帧图像数据
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -177,7 +228,7 @@ class Camera
 | 
			
		||||
            this.ep,
 | 
			
		||||
            this.taskID, // taskID
 | 
			
		||||
            FrameAddr,
 | 
			
		||||
            (int)(_currentWidth * _currentHeight * 2), // 使用当前分辨率的动态大小
 | 
			
		||||
            (int)_currentFrameLength, // 使用当前分辨率的动态大小
 | 
			
		||||
            this.timeout);
 | 
			
		||||
 | 
			
		||||
        if (!result.IsSuccessful)
 | 
			
		||||
@@ -250,7 +301,6 @@ class Camera
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -157,6 +157,7 @@ public class HttpVideoStreamService : BackgroundService
 | 
			
		||||
        }
 | 
			
		||||
        _cameraEnable = isEnabled;
 | 
			
		||||
        await _camera.EnableCamera(_cameraEnable);
 | 
			
		||||
        await _camera.SleepCameraHardware(!_cameraEnable);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -437,8 +437,11 @@ public class UDPClientPool
 | 
			
		||||
            int outstanding = sentCount - (found.HasValue ? found.Value : 0);
 | 
			
		||||
 | 
			
		||||
            // If outstanding >= 512, wait for some data to be received
 | 
			
		||||
            if (outstanding >= 512)
 | 
			
		||||
            if (outstanding >= 512){
 | 
			
		||||
                logger.Debug($"Outstanding data packets: {outstanding}, waiting for more data to be received...");
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // Send next address package
 | 
			
		||||
            var ret = await UDPClientPool.SendAddrPackAsync(endPoint, new SendAddrPackage(optsList[sentCount]));
 | 
			
		||||
@@ -475,9 +478,9 @@ public class UDPClientPool
 | 
			
		||||
        {
 | 
			
		||||
            var bytes = udpDatas[i].Data;
 | 
			
		||||
            var expectedLen = ((optsList[i].BurstLength + 1) * 4);
 | 
			
		||||
            if (bytes.Length != expectedLen)
 | 
			
		||||
                return new(new Exception($"Expected {expectedLen} bytes but received {bytes.Length} bytes at segment {i}"));
 | 
			
		||||
            resultData.AddRange(bytes);
 | 
			
		||||
            if ((bytes.Length - 4) != expectedLen)
 | 
			
		||||
                return new(new Exception($"Expected {expectedLen} bytes but received {bytes.Length - 4} bytes at segment {i}"));
 | 
			
		||||
            resultData.AddRange(bytes[4..]); // Skip the first 4 bytes (header)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Validate total data length
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6882
									
								
								src/APIClient.ts
									
									
									
									
									
								
							
							
						
						
									
										6882
									
								
								src/APIClient.ts
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -340,7 +340,7 @@ import {
 | 
			
		||||
  AlertTriangle,
 | 
			
		||||
  MoreHorizontal,
 | 
			
		||||
} from "lucide-vue-next";
 | 
			
		||||
import { VideoStreamClient, CameraConfigRequest } from "@/APIClient";
 | 
			
		||||
import { VideoStreamClient, CameraConfigRequest, ResolutionConfigRequest } from "@/APIClient";
 | 
			
		||||
import { useEquipments } from "@/stores/equipments";
 | 
			
		||||
 | 
			
		||||
const eqps = useEquipments();
 | 
			
		||||
@@ -597,7 +597,8 @@ const refreshResolutions = async () => {
 | 
			
		||||
  try {
 | 
			
		||||
    addLog("info", "正在获取支持的分辨率列表...");
 | 
			
		||||
    const resolutions = await videoClient.getSupportedResolutions();
 | 
			
		||||
    supportedResolutions.value = resolutions;
 | 
			
		||||
    supportedResolutions.value = resolutions.resolutions;
 | 
			
		||||
    console.log("支持的分辨率列表:", supportedResolutions.value);
 | 
			
		||||
    
 | 
			
		||||
    // 获取当前分辨率
 | 
			
		||||
    const currentRes = await videoClient.getCurrentResolution();
 | 
			
		||||
@@ -629,7 +630,11 @@ const changeResolution = async () => {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // 设置新分辨率
 | 
			
		||||
    const success = await videoClient.setResolution(selectedResolution.value.width, selectedResolution.value.height);
 | 
			
		||||
    const resolutionRequest = new ResolutionConfigRequest({
 | 
			
		||||
      width: selectedResolution.value.width,
 | 
			
		||||
      height: selectedResolution.value.height
 | 
			
		||||
    });
 | 
			
		||||
    const success = await videoClient.setResolution(resolutionRequest);
 | 
			
		||||
    
 | 
			
		||||
    if (success) {
 | 
			
		||||
      // 刷新流信息
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user