You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
8.0 KiB
243 lines
8.0 KiB
using System.Runtime.InteropServices;
|
|
|
|
namespace EC.Util.CameraSDK;
|
|
|
|
public class DaHuaSdk : ICameraSdk
|
|
{
|
|
#region Fields
|
|
|
|
private IntPtr LoginId { get; set; } = IntPtr.Zero;
|
|
|
|
private int Channel { get; } = 0;
|
|
|
|
#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(null, 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
|
|
|
|
private IntPtr Hwnd { get; set; }
|
|
|
|
private IntPtr RealplayHandle { get; set; } = IntPtr.Zero;
|
|
|
|
private int RealplayPort { get; set; } = -1;
|
|
|
|
public override void StartPlay(IntPtr hwnd)
|
|
{
|
|
if (!ConnectSuccess() || IsPlaying()) return;
|
|
Hwnd = hwnd;
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) StartPlayLinux();
|
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) StartPlayLinux();
|
|
else Hwnd = IntPtr.Zero;
|
|
}
|
|
|
|
private void StartPlayWindows()
|
|
{
|
|
RealplayHandle = DaHuaOriSdk.CLIENT_RealPlayEx(LoginId, Channel, Hwnd, DaHuaOriSdk.EM_RealPlayType.Realplay);
|
|
if (RealplayHandle == IntPtr.Zero) BuildException();
|
|
}
|
|
|
|
private void StartPlayLinux()
|
|
{
|
|
bool ret;
|
|
if (RealDataCallBack == null && RealplayPort < 0)
|
|
{
|
|
int nPort = -1;
|
|
if (!DhPlaySdk.PLAY_GetFreePort(ref nPort)) DhPlaySdk.BuildException(this, nPort);
|
|
if (!DhPlaySdk.PLAY_OpenStream(nPort, 0, 0, 3 * 1024 * 1024)) DhPlaySdk.BuildException(this, nPort);
|
|
if (!DhPlaySdk.PLAY_Play(nPort, Hwnd)) DhPlaySdk.BuildException(this, nPort);
|
|
RealplayPort = nPort;
|
|
}
|
|
RealplayHandle = DaHuaOriSdk.CLIENT_RealPlayEx(LoginId, Channel, IntPtr.Zero, DaHuaOriSdk.EM_RealPlayType.Realplay);
|
|
if (RealplayHandle < 0) BuildException();
|
|
RealDataCallBack ??= DefaultRealDataCallBack;
|
|
ret = DaHuaOriSdk.CLIENT_SetRealDataCallBackEx2(RealplayHandle, RealDataCallBack, IntPtr.Zero, (uint)(DaHuaOriSdk.EM_REALDATA_FLAG.RAW_DATA));
|
|
if (!ret) BuildException();
|
|
}
|
|
|
|
public override void StopPlay()
|
|
{
|
|
if (!IsPlaying()) return;
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) StopPlayLinux();
|
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) StopPlayLinux();
|
|
Hwnd = IntPtr.Zero;
|
|
}
|
|
|
|
private void StopPlayWindows()
|
|
{
|
|
bool ret = DaHuaOriSdk.CLIENT_StopRealPlayEx(RealplayHandle);
|
|
RealplayHandle = IntPtr.Zero;
|
|
if (!ret) BuildException();
|
|
}
|
|
|
|
private void StopPlayLinux()
|
|
{
|
|
bool ret = DaHuaOriSdk.CLIENT_StopRealPlayEx(RealplayHandle);
|
|
RealplayHandle = IntPtr.Zero;
|
|
RealDataCallBack = null;
|
|
if (RealplayPort >= 0)
|
|
{
|
|
DhPlaySdk.PLAY_Stop(RealplayPort);
|
|
DhPlaySdk.PLAY_CloseStream(RealplayPort);
|
|
DhPlaySdk.PLAY_ReleasePort(RealplayPort);
|
|
RealplayPort = -1;
|
|
}
|
|
if (!ret) BuildException();
|
|
}
|
|
|
|
public DaHuaOriSdk.RealDataCallBack? RealDataCallBack { get; set; }
|
|
|
|
private void DefaultRealDataCallBack(IntPtr lRealHandle, uint dwDataType, IntPtr pBuffer, uint dwBufSize, IntPtr param, IntPtr dwUser)
|
|
{
|
|
if (RealplayPort < 0 || dwBufSize <= 0) return;
|
|
switch (dwDataType)
|
|
{
|
|
case 0:
|
|
//original unencrypted stream
|
|
DhPlaySdk.PLAY_InputData(RealplayPort, pBuffer, dwBufSize);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public override bool IsPlaying()
|
|
{
|
|
return RealplayHandle != IntPtr.Zero;
|
|
}
|
|
|
|
#endregion Video Method
|
|
}
|