using System.Runtime.InteropServices; namespace EC.Util.CameraSDK; public class DaHuaSDK : ICameraSDK { #region Fields private IntPtr LoginId { get; set; } = IntPtr.Zero; private IntPtr RealplayHandle { get; set; } = IntPtr.Zero; private int Channel { get; } = 1; #endregion Fields public DaHuaSDK(CameraInfo cameraInfo) : base(cameraInfo) { } #region Base Method public override bool Init() { bool ret = ConnectSuccess(); if (ret) return true; DaHuaOriSDK.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stuInParam = new(); stuInParam.dwSize = (uint)Marshal.SizeOf(stuInParam); stuInParam.szIP = CameraInfo.Ip; stuInParam.nPort = CameraInfo.Port; stuInParam.szUserName = CameraInfo.UserName; stuInParam.szPassword = CameraInfo.Password; stuInParam.emSpecCap = DaHuaOriSDK.EM_LOGIN_SPAC_CAP_TYPE.TCP; stuInParam.pCapParam = IntPtr.Zero; DaHuaOriSDK.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stuOutParam = new(); stuOutParam.dwSize = (uint)Marshal.SizeOf(stuOutParam); LoginId = DaHuaOriSDK.CLIENT_LoginWithHighLevelSecurity(ref stuInParam, ref stuOutParam); ret = ConnectSuccess(); if (ret) DaHuaOriSDK.CLIENT_SetAutoReconnect(delegate (IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser) { LoginId = lLoginID; }, IntPtr.Zero); else BuildException(); return ret; } public override bool Destory() { bool ret = ConnectSuccess(); if (!ret) return true; ret = DaHuaOriSDK.CLIENT_Logout(LoginId); if (ret) LoginId = IntPtr.Zero; else BuildException(); return ret; } public override bool ConnectSuccess() { return LoginId != IntPtr.Zero; } internal override void BuildException() { uint errCode = (uint)DaHuaOriSDK.CLIENT_GetLastError(); if (errCode == 0) return; errCode -= 0x80000000; throw CameraException.New(CameraInfo, (int)errCode); } #endregion Base Method #region Ptz Method private static class GPIParams { public static int Size { get; private set; } public static Type Type { get; private set; } static GPIParams() { DaHuaOriSDK.DH_PTZ_LOCATION_INFO info = new(); Size = Marshal.SizeOf(info); Type = info.GetType(); } } public override PtzInfo GetPtzInfo() { bool ret = ConnectSuccess(); if (!ret) return PtzInfo.Default; DaHuaOriSDK.DH_PTZ_LOCATION_INFO entity = new(); int nBufLen = GPIParams.Size; int pRetLen = 0; IntPtr ptrBuf = Marshal.AllocHGlobal(GPIParams.Size); Marshal.StructureToPtr(entity, ptrBuf, true); try { ret = DaHuaOriSDK.CLIENT_QueryDevState(LoginId, (int)DaHuaOriSDK.EM_DEVICE_STATE.PTZ_LOCATION, ptrBuf, nBufLen, ref pRetLen, 3000); if (!ret) { BuildException(); return PtzInfo.Default; } object? objBuf = Marshal.PtrToStructure(ptrBuf, GPIParams.Type); if (objBuf == null) return PtzInfo.Default; entity = (DaHuaOriSDK.DH_PTZ_LOCATION_INFO)objBuf; return PtzInfo.New(entity.nPTZPan, entity.nPTZTilt, entity.nPTZZoom); } finally { Marshal.FreeHGlobal(ptrBuf); } } public override bool TryGetPtzInfo(out PtzInfo ptzInfo) { bool ret = ConnectSuccess(); if (!ret) { ptzInfo = PtzInfo.Default; return false; } DaHuaOriSDK.DH_PTZ_LOCATION_INFO entity = new(); int nBufLen = GPIParams.Size; int pRetLen = 0; IntPtr ptrBuf = Marshal.AllocHGlobal(GPIParams.Size); Marshal.StructureToPtr(entity, ptrBuf, true); try { ret = DaHuaOriSDK.CLIENT_QueryDevState(LoginId, (int)DaHuaOriSDK.EM_DEVICE_STATE.PTZ_LOCATION, ptrBuf, nBufLen, ref pRetLen, 3000); if (!ret) { BuildException(); ptzInfo = PtzInfo.Default; return false; } object? objBuf = Marshal.PtrToStructure(ptrBuf, GPIParams.Type); if (objBuf == null) { ptzInfo = PtzInfo.Default; return false; } entity = (DaHuaOriSDK.DH_PTZ_LOCATION_INFO)objBuf; ptzInfo = PtzInfo.New(entity.nPTZPan, entity.nPTZTilt, entity.nPTZZoom); return true; } finally { Marshal.FreeHGlobal(ptrBuf); } } public override bool PtzMove(int cmd, int stop, int speed) { if (!ConnectSuccess()) return false; bool stopret = stop == 1; bool ret = DaHuaOriSDK.CLIENT_DHPTZControlEx2(LoginId, Channel, (uint)cmd, speed, speed, 0, stopret, IntPtr.Zero); if (!ret) BuildException(); return ret; } public override bool PtzPreset(int cmd, int presetId) { if (!ConnectSuccess()) return false; bool ret = DaHuaOriSDK.CLIENT_DHPTZControlEx2(LoginId, Channel, (uint)DaHuaOriSDK.EM_EXTPTZ_ControlType.POINT_MOVE, 0, presetId, 0, false, IntPtr.Zero); if (!ret) BuildException(); return ret; } #endregion Ptz Method #region Video Method public override void StartPlay(IntPtr hwnd) { if (!ConnectSuccess() || IsPlaying()) return; RealplayHandle = DaHuaOriSDK.CLIENT_RealPlayEx(LoginId, Channel, hwnd, DaHuaOriSDK.EM_RealPlayType.Realplay); if (RealplayHandle == IntPtr.Zero) BuildException(); } public override void StopPlay() { if (!IsPlaying()) return; bool ret = DaHuaOriSDK.CLIENT_StopRealPlayEx(RealplayHandle); RealplayHandle = IntPtr.Zero; if (!ret) BuildException(); } public override bool IsPlaying() { return RealplayHandle != IntPtr.Zero; } #endregion Video Method }