Creating C# application using Hikvision SDK for DS-7116HVI-SL

Discussion in 'Cameras, NVR / DVR's, hardware & more' started by Srinivas Cheruku, Aug 3, 2017.

Share This Page

  1. Jivakula

    Jivakula n3wb

    Joined:
    Sep 21, 2018
    Messages:
    6
    Likes Received:
    0
    Location:
    Sofia, Bulgaria
    Dear Curious, thank you the information. I changed the DLL files with these from 32 bits version but with them I cannot finish the initialization process. Also, I read all posts and followed what Vilius was did/wrote and I did the same, but I stuck on this RealPlay_V40.
    If I change this:
    "Hik_PrevInfo.hPlayWnd = real_play;" to
    Hik_PrevInfo.hPlayWnd = IntPtr.Zero;
    the the result of
    realPlayId = VideoHelper.NET_DVR_RealPlay_V40(Hik_LoginID, ref Hik_PrevInfo, null, pUser);
    is 0 and more.
    So, my hPlayWnd(real_play) is a pictureBox.

    I will continue to search for the error in my code.

    With regards,
    Jivakula
     
  2. curiousDev

    curiousDev Young grasshopper

    Joined:
    Aug 16, 2017
    Messages:
    31
    Likes Received:
    2
    In this moment I dont have spare time to peek on ur piece of code. I will be able to look at this in 4-5 hours.
    Can you try my code with RealPlay_V40 from previous posts and then if it will work (which should since I tested it) compare it with yours?
    I am asumming you want to display this video in picturebox, right? If yes then it can not be Hik_PrevInfo.hPlayWnd = IntPtr.Zero.
     
  3. curiousDev

    curiousDev Young grasshopper

    Joined:
    Aug 16, 2017
    Messages:
    31
    Likes Received:
    2
    I just looked at and tested out your code. I havent noticed initializing and login parts of your code like SDKMethods.NET_DVR_Init and NET_DVR_Login_V30 but I assume you did it in another place of ur program.

    By doing this you just got rid of your destination component for video which means you will display nothing in your form. Leave it like it was before Hik_PrevInfo.hPlayWnd = real_play where real_play is a handler e.g. your pictureBox videoPanel.Handle.

    Result >= 0 is perfect that means no error occured.

    Since you didnt post definitions of your SDK structures (e.g. NET_DVR_PREVIEWINFO) I couldnt verify everything.
    So far I found following 'errors'. Well not really errors your values works too which a bit surprised me.
    1. Hik_PrevInfo.bBlocked = false; //this is not a bool variable but uint with values 0 - Non-Blocking Streaming or 1- Blocking Streaming
    2. IntPtr pUser = new IntPtr(Hik_PrevInfo.lChannel); //use IntPtr pUser = IntPtr.Zero

    First of all try to change back Hik_PrevInfo.hPlayWnd = real_play and if you will still struggle with something then I will need to get more info about ur structure definitions
     
  4. Jivakula

    Jivakula n3wb

    Joined:
    Sep 21, 2018
    Messages:
    6
    Likes Received:
    0
    Location:
    Sofia, Bulgaria
    Dear Curious, in the code I use "Hik_PrevInfo.hPlayWnd = real_play;" but then result(realPlayId) of VideoHelper.NET_DVR_RealPlay_V40(Hik_LoginID, ref Hik_PrevInfo, null, pUser) always is -1. When I change it to "Hik_PrevInfo.hPlayWnd = IntPtr.Zero;" the result always is 0 or more. That was only for the test.

    The structure of NET_DVR_PREVIEWINFO is on another place in my code, in "VideoHelper" class, here is copy:

    private static VideoHelper.NET_DVR_PREVIEWINFO Hik_PrevInfo;
    public struct NET_DVR_PREVIEWINFO
    {
    public bool bBlocked;
    public bool bPassbackRecord;
    public byte byPreviewMode;
    public byte byProtoType;
    public byte[] byRes;
    public byte[] byStreamID;
    public uint dwLinkMode;
    public uint dwStreamType;
    public IntPtr hPlayWnd;
    public int lChannel;
    }

    Attached is VideoHelper class.

    Also, if I import DLL the result is -1:
    public delegate void fRealDataCallBack_V30(int lRealHandle, uint dwDataType, byte[] pBuffer, uint dwBufSize, IntPtr pUser);
    [DllImport("HCNetSDK.dll", EntryPoint = "NET_DVR_RealPlay_V40")]
    public static extern int NET_DVR_RealPlay_V40(int lUserID, ref VideoHelper.NET_DVR_PREVIEWINFO lpPreviewInfo, fRealDataCallBack_V30 fRealDataCallBack_V30, IntPtr pUser);

    Maybe the problem I think is in that pictureBox, the size is 8:
    private PictureBox videoPanel;
    handle = videoPanel.Handle;
    real_play = handle;
    Hik_PrevInfo.hPlayWnd = real_play;
     

    Attached Files:

    Last edited: Sep 28, 2018
  5. Jivakula

    Jivakula n3wb

    Joined:
    Sep 21, 2018
    Messages:
    6
    Likes Received:
    0
    Location:
    Sofia, Bulgaria
    Here is my code where I use DllImport for "NET_DVR_RealPlay_V40", not VideoHelper class and the result is the same -1:

    private bool InitHikvision()
    {
    try
    {
    Hik_Init = VideoHelper.NET_DVR_Init();

    if (Hik_Init)
    {
    VideoHelper.NET_DVR_SetConnectTime(2000, 1);
    VideoHelper.NET_DVR_SetReconnect(10000, 3);
    }
    else
    {
    frmObject.frmMain.to_log("Hikvision initialization: " + VideoHelper.NET_DVR_GetLastError());

    var bmp = new Bitmap(videoPanel.ClientSize.Width, videoPanel.ClientSize.Height);
    using (Graphics g = Graphics.FromImage(bmp))
    {
    g.DrawString("Hikvision initialization: " + VideoHelper.NET_DVR_GetLastError(), new Font("Verdana", (float)12, FontStyle.Bold, GraphicsUnit.Pixel), new SolidBrush(Color.Red), (float)20, (float)20);
    g.Dispose();
    }
    videoPanel.Image = bmp;

    return false;
    }
    }
    catch (Exception ex)
    {
    return false ;
    }

    return true;
    }

    private void GetCameraInfo()
    {
    try
    {
    if (id > 0)
    {
    cm = frmObject.GetCameraByID(id);

    camera_port = cm.port;
    camera_zone = cm.zone.ToString();
    camera_ip = cm.ip;
    camera_user_name = cm.user_name.ToString();
    camera_pass = cm.password.ToString();
    camera_name = cm.camera.ToString();
    camera_type = cm.camera_type;
    device_type = cm.device_type;
    device_channel = cm.device_channel;

    GetCameraType(camera_type);

    ushort port = Convert.ToUInt16(camera_port);

    Hik_DeviceInfo = new VideoHelper.NET_DVR_DEVICEINFO_V30();
    Hik_LoginID = VideoHelper.NET_DVR_Login_V30(camera_ip, port, camera_user_name, camera_pass, ref Hik_DeviceInfo);

    if (Hik_LoginID < 0)
    {
    VideoHelper.NET_DVR_Logout(Hik_LoginID);
    VideoHelper.NET_DVR_Cleanup();
    play_video = false;

    frmObject.frmMain.to_log("Hikvision camera login: " + VideoHelper.NET_DVR_GetLastError());

    var bmp = new Bitmap(videoPanel.ClientSize.Width, videoPanel.ClientSize.Height);
    using (Graphics g = Graphics.FromImage(bmp))
    {
    g.DrawString("Unable login of Hikvision camera: " + camera_ip + ":" + camera_port + " - " + camera_name, new Font("Verdana", (float)12, FontStyle.Bold, GraphicsUnit.Pixel), new SolidBrush(Color.Red), (float)20, (float)20);
    g.Dispose();
    }
    videoPanel.Image = bmp;
    return;
    }
    }
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
    }

    [DllImport("HCNetSDK.dll", EntryPoint = "NET_DVR_RealPlay_V40")]
    public static extern int NET_DVR_RealPlay_V40(int lUserID, ref LPNET_DVR_PREVIEWINFO lpPreviewInfo, fRealDataCallBack_V30 fRealDataCallBack_V30, IntPtr pUser);

    public struct LPNET_DVR_PREVIEWINFO
    {
    public int lChannel; // Channel no.
    public uint dwStreamType; // Stream type 0-main stream,1-sub stream,2-third stream,3-forth stream,4-fifth stream,5-sixth stream,7-seventh stream,8-eighth stream,9-ninth stream,10-tenth stream
    public uint dwLinkMode; // Protocol type: 0-TCP, 1-UDP, 2-Muticast, 3-RTP,4-RTP/RTSP, 5-RSTP/HTTP
    public IntPtr hPlayWnd; // Play window's handle; set NULL to disable preview
    public uint bBlocked; //If data stream requesting process is blocked or not: 0-no, 1-yes
    //if true, the SDK Connect failure return until 5s timeout , not suitable for polling to preview.
    public uint bPassbackRecord; //0- not enable ,1 enable
    public byte byPreviewMode; // Preview mode 0-normal preview,2-delay preview
    //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = Defines.STREAM_ID_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byStreamID;//Stream ID
    public byte byProtoType; //0-private,1-RTSP
    public byte byRes1;
    public byte byVideoCodingType;
    public uint dwDisplayBufNum; //soft player display buffer size(number of frames), range:1-50, default:1
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 216, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes;
    }

    private void RealPlay_Hikvision(int channel)
    {
    videoPanel.Refresh();
    real_play = handle;

    LPNET_DVR_PREVIEWINFO PrevInfo = new LPNET_DVR_PREVIEWINFO();

    if (play_video == true)
    {
    VideoHelper.NET_DVR_StopRealPlay(realPlayId);

    videoPanel.Refresh();
    play_video = false;
    }

    try
    {
    PrevInfo.hPlayWnd = real_play;
    PrevInfo.lChannel = channel; //Preview channel NO.
    PrevInfo.dwStreamType = 0; //0-main stream, 1-sub stream, 2-stream3, 3-stream4.
    PrevInfo.dwLinkMode = 0; //0-TCP mode, 1-UDP mode, 2-Multi-play mode, 3-RTP mode, 4-RTP/RTSP, 5-RTSP over HTTP
    PrevInfo.bBlocked = 0;
    PrevInfo.byPreviewMode = 0;

    IntPtr pUser = new IntPtr(Hik_PrevInfo.lChannel);

    realPlayId = NET_DVR_RealPlay_V40(Hik_LoginID, ref PrevInfo, null, IntPtr.Zero);

    if (realPlayId < 0)
    {
    string message = string.Format("RealPlay_v40 failed, error code: {0}", VideoHelper.NET_DVR_GetLastError());
    frmObject.frmMain.to_log(message);

    var bmp = new Bitmap(videoPanel.ClientSize.Width, videoPanel.ClientSize.Height);
    using (Graphics g = Graphics.FromImage(bmp))
    {
    g.DrawString(message, new Font("Verdana", (float)12, FontStyle.Bold, GraphicsUnit.Pixel), new SolidBrush(Color.Red), (float)20, (float)20);
    g.Dispose();
    }
    videoPanel.Image = bmp;

    VideoHelper.NET_DVR_StopRealPlay(realPlayId);

    play_video = false;
    }
    else
    {
    play_video = true;
    }
    }
    catch (Exception ex)
    {
    play_video = false;

    frmObject.frmMain.to_log("Video player, Hikvision connect: " + camera_name + " - " + camera_ip + ":" + camera_port + " - " + ex.Message);

    var bmp = new Bitmap(videoPanel.ClientSize.Width, videoPanel.ClientSize.Height);
    using (Graphics g = Graphics.FromImage(bmp))
    {
    g.DrawString("Video player, Hikvision connect: " + camera_name + " - " + camera_ip + ":" + camera_port + " - " + ex.Message, new Font("Verdana", (float)12, FontStyle.Bold, GraphicsUnit.Pixel), new SolidBrush(Color.Red), (float)20, (float)20);
    g.Dispose();
    }
    videoPanel.Image = bmp;

    VideoHelper.NET_DVR_StopRealPlay(realPlayId);
    VideoHelper.NET_DVR_Logout(Hik_LoginID);
    VideoHelper.NET_DVR_Cleanup();
    }
    }
     
  6. curiousDev

    curiousDev Young grasshopper

    Joined:
    Aug 16, 2017
    Messages:
    31
    Likes Received:
    2
    What says error if result is -1 for RealPlay_V40?
    Also if you suspect that size of picture box is too small can you check with bigger size?
     
  7. Jivakula

    Jivakula n3wb

    Joined:
    Sep 21, 2018
    Messages:
    6
    Likes Received:
    0
    Location:
    Sofia, Bulgaria
    The error always is : "RealPlay_v40 failed, error code: 64" and from Hikvision description this is: NET_DVR_LOADPLAYERSDKFAILED - Failed to load player SDK.
     
  8. curiousDev

    curiousDev Young grasshopper

    Joined:
    Aug 16, 2017
    Messages:
    31
    Likes Received:
    2
    Due the lack of time (again) i will simply share with you my test solution which I have made yesterday basing on your code.
    I tested it and it works fine for me so please check it and let me know if it's the same for you.
     

    Attached Files:

  9. Jivakula

    Jivakula n3wb

    Joined:
    Sep 21, 2018
    Messages:
    6
    Likes Received:
    0
    Location:
    Sofia, Bulgaria
    Dear Curious, thank you for you attention! From your test solution I found where the problem was! When I change in Visual Studio the properties of the project the builder "prefer 32-bit" and I use your Dlls then I start receiving the video from the cameras!

    PS: I found Dlls 64-bit and now everything is perfect without checked "prefer 32-bit" in the project properties!

    With regards,
    Jivakula
     
    Last edited: Sep 28, 2018
  10. ARJunior

    ARJunior n3wb

    Joined:
    Aug 24, 2015
    Messages:
    8
    Likes Received:
    0
    Hi,
    Very useful informations here. Thank you very much curiousDev and others.

    Could you please tell me what is the best way to stop current channel preview and start a new one in the same pictureBox ?
    Can I just make a call to NET_DVR_StopRealPlay(), set a new channel number then call one more time NET_DVR_RealPlay_V40() ?

    Thank you for help.
     
  11. curiousDev

    curiousDev Young grasshopper

    Joined:
    Aug 16, 2017
    Messages:
    31
    Likes Received:
    2
    Hey ARJunior,

    If you are getting RealPlay stream from Network Video Recorder (NVR/DVR) in my opinion it will be enough, there is no need to close and open connection to the same DVR between changing channels.
    But in case of connecting to diffrent cameras I would use also NET_DVR_Logout and NET_DVR_Cleanup and then connect to another camera.
    Well I am not 100% sure about this sience I wasn't implementing this scenario so far. It's just what common sense advice me.

    Best Regards,
    curious
     
    ARJunior likes this.
  12. ARJunior

    ARJunior n3wb

    Joined:
    Aug 24, 2015
    Messages:
    8
    Likes Received:
    0
    HI curious,
    Just tested and seems working well with steps described above ;)
    Thank you.

    Best regards.
     
  13. Rohit Singh

    Rohit Singh n3wb

    Joined:
    Nov 23, 2018
    Messages:
    1
    Likes Received:
    0
    Location:
    Noida
     
  14. darius

    darius n3wb

    Joined:
    Dec 4, 2018
    Messages:
    3
    Likes Received:
    0
    Location:
    Lithuania
    Hello everyone.
    Most of information written here was very useful. Thank's for that.
    Now i'm getting some problems with card reader access events. I always getting error 17 (Parameter error. Input or output parameters in the SDK API is NULL, or the value or format of the parameters does not match with the requirement.)
    Device is DS-K2602 with card reader attached for access monitoring.

    What i have done so far on button click:
    Code:
    bool succes = false;
    succes = HCNetSDK.NET_DVR_Cleanup();
    succes = HCNetSDK.NET_DVR_Init();
    NET_DVR_SDKSTATE sdkState;
    succes = HCNetSDK.NET_DVR_GetSDKState(out sdkState);
    HCNetSDK.NET_DVR_NETCFG_V30 pStruNetCfg = new HCNetSDK.NET_DVR_NETCFG_V30();
    HCNetSDK.NET_DVR_DEVICECFG_V40 pStruDevCfg = new HCNetSDK.NET_DVR_DEVICECFG_V40();
    
    HCNetSDK.NET_DVR_USER_LOGIN_INFO struLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
    HCNetSDK.NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
    struLoginInfo.bUseAsynLogin = false;
    struLoginInfo.wPort = 8000;
    struLoginInfo.sDeviceAddress = "192.168.5.64";
    byte[] name = new byte[64];
    struLoginInfo.sUserName = "user";
    struLoginInfo.sPassword = "pass";
    struLoginInfo.byProxyType = 0;
    UserID = HCNetSDK.NET_DVR_Login_V40(ref struLoginInfo, ref struDeviceInfoV40);
    
    byte[] lpOutBuffer1 = GetBytes(pStruNetCfg);
    uint dwOutBufferSize1 = Convert.ToUInt32(lpOutBuffer1.Length);
    uint lpBytesReturned1 = Convert.ToUInt32(lpOutBuffer1.Length);
    byte[] lpOutBuffer2 = GetBytes(pStruDevCfg);
    uint dwOutBufferSize2 = Convert.ToUInt32(lpOutBuffer2.Length);
    uint lpBytesReturned2 = Convert.ToUInt32(lpOutBuffer2.Length);
    succes = HCNetSDK.NET_DVR_GetDVRConfig(UserID, HCNetSDK.NET_DVR_GET_NETCFG_V30, 0, lpOutBuffer1, ref dwOutBufferSize1, ref lpBytesReturned1);
    succes = HCNetSDK.NET_DVR_GetDVRConfig(UserID, HCNetSDK.NET_DVR_GET_DEVICECFG_V40, 0, lpOutBuffer2, ref dwOutBufferSize2, ref lpBytesReturned2);
    //till here everything is working fine, but in bellow code i don't get it whats wrong
    
    uint dwCommand = HCNetSDK.NET_DVR_GET_ACS_EVENT; //2541
    IntPtr pUserData2 = new IntPtr();
    pUserData2 = IntPtr.Zero; //null
    
    HCNetSDK.fRemoteConfigCallback callback = new HCNetSDK.fRemoteConfigCallback(fRemoteConfigCallback);
    
    HCNetSDK.NET_DVR_ACS_EVENT_COND lpInBuffer = new HCNetSDK.NET_DVR_ACS_EVENT_COND();
    lpInBuffer.dwSize = (uint)Marshal.SizeOf(lpInBuffer);
    lpInBuffer.dwMajor = 0;
    lpInBuffer.dwMinor = 0;
    lpInBuffer.struStartTime.dwYear = 2018;
    lpInBuffer.struStartTime.dwMonth = 11;
    lpInBuffer.struStartTime.dwDay = 1;
    lpInBuffer.struStartTime.dwHour = 13;
    lpInBuffer.struStartTime.dwMinute = 0;
    lpInBuffer.struStartTime.dwSecond = 0;
    lpInBuffer.struEndTime.dwYear = 2018;
    lpInBuffer.struEndTime.dwMonth = 12;
    lpInBuffer.struEndTime.dwDay = 4;
    lpInBuffer.struEndTime.dwHour = 7;
    lpInBuffer.struEndTime.dwMinute = 0;
    lpInBuffer.struEndTime.dwSecond = 0;
    lpInBuffer.byCardNo = "";
    lpInBuffer.byName = "";
    lpInBuffer.byPicEnable = 0;
    lpInBuffer.dwBeginSerialNo = 0;
    lpInBuffer.dwEndSerialNo = 0;
    
    uint dwInBufferSize = Convert.ToUInt32(lpInBuffer.dwSize);
    IntPtr lpInBufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lpInBuffer));
    Marshal.StructureToPtr(lpInBuffer, lpInBufferPtr, false);
    
    var res = HCNetSDK.NET_DVR_StartRemoteConfig(UserID, dwCommand, ref lpInBufferPtr, lpInBuffer.dwSize, callback, ref pUserData2); //there always get error 17 that mentioned before
    
    fRemoteConfigCallback:
    Code:
    public delegate void fRemoteConfigCallback(ref uint dwType, ref byte[] lpBuffer, ref uint dwBufLen, ref IntPtr pUserData);
    
    inner fRemoteConfigCallback method which of course doesn't fire, because of errors in NET_DVR_StartRemoteConfig:
    Code:
    public void fRemoteConfigCallback(ref uint dwType, ref byte[] lpBuffer, ref uint dwBufLen, ref IntPtr pUserData)
    
    NET_DVR_ACS_EVENT_COND struct:
    Code:
    [StructLayoutAttribute(LayoutKind.Sequential)]
            public struct NET_DVR_ACS_EVENT_COND
            {
                public uint dwSize;
                public uint dwMajor;
                public uint dwMinor;
                public NET_DVR_TIME struStartTime;//NET_DVR_TIME struct is fine, because tried to get device time and i've got it
                public NET_DVR_TIME struEndTime;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ACS_CARD_NO_LEN)]//32
                public string byCardNo;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NAME_LEN)]//32
                public string byName;
                public byte byPicEnable;
                public byte byTimeType;
                [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I1)]
                public byte[] byRes2;
                public uint dwBeginSerialNo;
                public uint dwEndSerialNo;
                public uint dwEmployeeNo;
                [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 244, ArraySubType = UnmanagedType.I1)]
                public byte[] byRes;
            }
    
    NET_DVR_StartRemoteConfig :
    Code:
    public static extern int NET_DVR_StartRemoteConfig(int lUserID, uint dwCommand, ref IntPtr lpInBufferPtr, uint dwInBufferLen, fRemoteConfigCallback cbStateCallback, ref IntPtr pUserData);
    
    I think something wrong with NET_DVR_ACS_EVENT_COND struct or with NET_DVR_StartRemoteConfig method, but can't find what is it.
    I appreciate for any help you can provide to me.
     
  15. ARJunior

    ARJunior n3wb

    Joined:
    Aug 24, 2015
    Messages:
    8
    Likes Received:
    0
    Hi Darius,

    Try to modify structure of NET_DVR_ACS_EVENT_COND like this, maybe it can help :

    Code:
           public struct NET_DVR_ACS_EVENT_COND
           {
               public uint dwSize;
               public uint dwMajor;
               public uint dwMinor;
               public NET_DVR_TIME struStartTime;
               public NET_DVR_TIME struEndTime;
               [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SDKConst.ACS_CARD_NO_LEN, ArraySubType = UnmanagedType.I1)]
               public byte [] byCardNo;
               [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SDKConst.NAME_LEN, ArraySubType = UnmanagedType.I1)]
               public byte [] byName;
               public byte byPicEnable;
               public byte byTimeType;
               [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I1)]
               public byte[] byRes2;
               public uint dwBeginSerialNo;
               public uint dwEndSerialNo;
               public uint dwEmployeeNo;
               [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 244, ArraySubType = UnmanagedType.I1)]
               public byte[] byRes;
           }
    
    Regards.
     
  16. darius

    darius n3wb

    Joined:
    Dec 4, 2018
    Messages:
    3
    Likes Received:
    0
    Location:
    Lithuania
    Hi ARJunior,
    i modified struct as you suggested, but now i have to convert empty string to byte array of fixed length. When i do that it still throws same error code.
    I convert it with following code:
    Code:
    byte[] cardNo = new byte[32];
    cardNo = Encoding.ASCII.GetBytes(("").PadRight(32, '\0'));
    lpInBuffer.byCardNo = cardNo;
    
    is this the right way to do it?

    Anny more suggestions?
     
  17. darius

    darius n3wb

    Joined:
    Dec 4, 2018
    Messages:
    3
    Likes Received:
    0
    Location:
    Lithuania
    Oh my .... I found the problem, silly me :D
    Problem was that in struct was defined two properties that should not be in that struct.
    They are
    Code:
    public byte byTimeType;
    
    and
    Code:
    public uint dwEmployeeNo;
    
    Because those properties was in struct, size of struct does not fit required definition size, that's why i always get same parameter invalid error.
    I think that was some copy paste mistake.
    Now i tested and works the same with my properties declaration as this
    Code:
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ACS_CARD_NO_LEN)]//32
    public string byCardNo;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NAME_LEN)]//32
    public string byName;
    
    and also with your suggested declaration as this
    Code:
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SDKConst.ACS_CARD_NO_LEN, ArraySubType = UnmanagedType.I1)]
    public byte [] byCardNo;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SDKConst.NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte [] byName;
    
    Also thank you for your time. :)
     
  18. ARJunior

    ARJunior n3wb

    Joined:
    Aug 24, 2015
    Messages:
    8
    Likes Received:
    0
    Hello,

    Any hint on how to get channel information status, specially if channel is actually used or not by NVR ?

    According to SDK I defined struct of NET_DVR_CHAN_INFO like below but I don't really know which function from dll I have to use to make call :

    Code:
       public struct NET_DVR_CHAN_INFO
        {
            public uint dwSize;                   // Structure size
            public byte byValid;                  // Whether this channel is valid or not: 0- invalid, 1- valid
            public byte byUsed;                   // Whether this channel is used or not: 0- not used, 1- in use
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes1;                 // Reserved, please set to 0
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]
            public byte[] sChanName;              // Channel name
            public NET_DVR_COLOR struVideoColor;  // Signal source video color
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 44, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes2;                 // Reserved, please set to 0
        }
    
    Thank you in advance.
     
  19. curiousDev

    curiousDev Young grasshopper

    Joined:
    Aug 16, 2017
    Messages:
    31
    Likes Received:
    2
    Hey ARJunior

    I checked the SDK and in my opinion you should use function called NET_DVR_GetDeviceConfig and structure which you have found is an output parameter LPVOID lpOutBuffer,


    BOOL NET_DVR_GetDeviceConfig( LONG lUserID, DWORD dwCommand, DWORD dwCount, LPVOID lpInBuffer, DWORD dwInBufferSize, LPVOID lpStatusList, LPVOID lpOutBuffer, DWORD dwOutBufferSize);

    Generally this dll function can be used to get few outputs depending on dwCommand which will be delivered during the call for your purpose value for it is equal to 1654.
    More infos you can find in a programming manual.

    I wasn't try to implement it yet.
    Hope it will be usefull for you let me know.

    Best regards
    curious
     
  20. ARJunior

    ARJunior n3wb

    Joined:
    Aug 24, 2015
    Messages:
    8
    Likes Received:
    0
    Hi Curious,
    Thank you very much ! Will take a look at this in the week and try ton implement.

    Best Regards
     
  21. ARJunior

    ARJunior n3wb

    Joined:
    Aug 24, 2015
    Messages:
    8
    Likes Received:
    0
    Hello,

    I've take a look at SDK manual but things aren't clear for me.

    Using NET_DVR_GetDeviceConfig() function with NET_DVR_GET_SIGNAL_SOURCE_INFO command (1654) means we have to define some values in instance of struct NET_DVR_DEVICEID_INFO like for example sDeviceID.
    But according to SDK manual, this value is returned by NET_DVR_AddNetSignal function which I don't use, so I don't know exactly how to set parameters correctly :(
    I think I have to define lpInBuffer as below to use in NET_DVR_GetDeviceConfig() function :
    Code:
    NET_DVR_DEVICEID_INFO deviceIdInfo = new NET_DVR_DEVICEID_INFO();
    deviceIdInfo.dwSize = (uint)Marshal.SizeOf(deviceIdInfo);
    deviceIdInfo.sDeviceID =               // ??
    deviceIdInfo.dwChan = lChannel;
    deviceIdInfo.dwInputSignalIndex =  // ??
    
    IntPtr lpInBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(deviceIdInfo));
    Marshal.StructureToPtr(deviceIdInfo, lpInBuffer, false);
    uint dwInBufferSize = Convert.ToUInt32(deviceIdInfo.dwSize);          
    
    This is how I've defined structure of NET_DVR_DEVICEID_INFO :
    Code:
    public struct NET_DVR_DEVICEID_INFO
    {
        public uint dwSize;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]
        public int[] sDeviceID;
        public uint dwChan;
        public uint dwInputSignalIndex;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 60, ArraySubType = UnmanagedType.I1)]
        public byte[] byRes;
    }
    
    Any help would be appreciated.
    Best regards
     
  22. curiousDev

    curiousDev Young grasshopper

    Joined:
    Aug 16, 2017
    Messages:
    31
    Likes Received:
    2
    Hi,

    Unfortunatelly my device doesnt support this funtionality.
    Here is what I have done, maybe it will help you somehow.


    structures definitions:

    Code:
    
    public struct NET_DVR_CHAN_INFO
        {
            public uint dwSize;                   // Structure size
            public byte byValid;                  // Whether this channel is valid or not: 0- invalid, 1- valid
            public byte byUsed;                   // Whether this channel is used or not: 0- not used, 1- in use
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes1;                 // Reserved, please set to 0
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SDKConst.NAME_LEN, ArraySubType = UnmanagedType.I1)]  //SDKConst.NAME_LEN = 32
            public byte[] sChanName;              // Channel name
            public NET_DVR_COLOR struVideoColor;  // Signal source video color
            public ushort wResolutionX;
            public ushort wResolutionY;
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 44, ArraySubType = UnmanagedType.I1)]
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 40, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes2;                 // Reserved, please set to 0
        }
        
        public struct NET_DVR_COLOR
        {
            public byte byBrightness;
            public byte byContrast;
            public byte bySaturation;
            public byte byHue;
        }
    
    public struct NET_DVR_DEVICEID_INFO
        {
            public uint dwSize;
            public uint dwDeviceIndex;
            public byte byWallNo;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 27, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes1;
            public uint dwChan;
            public uint dwInputSignalIndex;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 60, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes;
        }
    call:

    Code:
     Hik_LoginID = SDKMethods.NET_DVR_Login_V30(ip, port, user, password, ref struDeviceInfo);
                if (Hik_LoginID < 0)
                {
                    //result.AddError(string.Format("Login failed, error code: {0}\n", SDKMethods.NET_DVR_GetLastError()));
                    //result.IsSuccessful = false;
    
                    SDKMethods.NET_DVR_Cleanup();
                    return;
                }
                
                NET_DVR_DEVICEID_INFO deviceIdInfo = new NET_DVR_DEVICEID_INFO();
                deviceIdInfo.dwSize = (uint)Marshal.SizeOf(deviceIdInfo);
                deviceIdInfo.dwDeviceIndex = 0;
                deviceIdInfo.dwChan = channel;  //I put here 36
                deviceIdInfo.dwInputSignalIndex = 0;
    
                IntPtr lpInBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(deviceIdInfo));
                Marshal.StructureToPtr(deviceIdInfo, lpInBuffer, false);
                uint dwInBufferSize = Convert.ToUInt32(deviceIdInfo.dwSize);
    
                NET_DVR_CHAN_INFO deviceChannelInfo = new NET_DVR_CHAN_INFO();
                deviceChannelInfo.struVideoColor = new NET_DVR_COLOR();
    
                IntPtr lpOutBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(deviceChannelInfo));
                Marshal.StructureToPtr(deviceChannelInfo, lpOutBuffer, false);
                uint dwOutBufferSize = Convert.ToUInt32(deviceIdInfo.dwSize);
    
                uint statusList = 555;
                IntPtr lpStatusList = Marshal.AllocHGlobal(Marshal.SizeOf(statusList));
                Marshal.StructureToPtr(statusList, lpStatusList, false);
                
    
                if (!SDKMethods.NET_DVR_GetDeviceConfig(Hik_LoginID, 1654, 1, lpInBuffer, dwInBufferSize, lpStatusList, lpOutBuffer, dwOutBufferSize))
                {
                    string message = string.Format("GetChannelInfoStatus failed, error code: {0}", SDKMethods.NET_DVR_GetLastError());
                    Console.WriteLine(message);
                }
    If you will look closer my structure definitions has some diffrent fields it's because I took them from header file. Don't know why but it's diffrent than programming manual.
    Noticable diffrence is in NET_DVR_DEVICEID_INFO where you can find dwDeviceIndex, byWallNo, byRes1 instead of yours int[] sDeviceID.

    As return value of calling NET_DVR_GetDeviceConfig I am getting false and GetLastError giving me value -> 23 - Device does not support this function.

    I havent check NET_DVR_AddNetSignal since the above function doesnt work for me. First of all I wanted to test NET_DVR_GetDeviceConfig with some 'standard' values for dwDeviceIndex like 0 or 1.

    I am curious if you will get diffrent results than me.

    Best regards.
     
  23. ARJunior

    ARJunior n3wb

    Joined:
    Aug 24, 2015
    Messages:
    8
    Likes Received:
    0
    Hey Curious,

    Yes, I've seen different structure from SDK manual and header file too ( NET_DVR_CHAN_INFO and NET_DVR_DEVICEID_INFO are concerned about this) !
    Don't know which ones we have to use but the two give me the same result, error code 23 like you.
    I've tried several values for dwDeviceIndex with no luck until now :(

    Thank you for your time.
    Best Regards
     
  24. ARJunior

    ARJunior n3wb

    Joined:
    Aug 24, 2015
    Messages:
    8
    Likes Received:
    0
    Oh...found one error in your NET_DVR_CHAN_INFO structure.
    If you look at header file, byte byEnabled doesn't exist anymore.
    By the way, my goal to detect if channel is used or not is reminding me to use this byte ! Don't you ?
     
  25. curiousDev

    curiousDev Young grasshopper

    Joined:
    Aug 16, 2017
    Messages:
    31
    Likes Received:
    2
    Hello again ARJunior,

    I am not sure if that is error since it's c++.
    Dll header definition has BYTE byRes1[3] while the one in programming manual has
    BYTE byUsed and BYTE byRes1[2] those two together is kinda BYTE byRes1[3]. If we use this structure as a pointer in call then that array [3] can be splitted at those two fields. The size will be the same.
    I have no idea why in manual they put something else than it is in header file. For me two splitted fields seems to be more readable without guessing what means first byte of array [3].

    I was counting you will get any other result than me. In this case we cannot be sure if we did something wrong or if it is a matter of our devices (still i believe if we screw up something we should get error '17 - Parameter error...').

    Best regards.
    curious
     
Tags: