Enable People Counting

During the people counting, the number of entered, exited, or passed people (including adult and child) can be counted.

  • Make sure you have called NET_DVR_Init to initialize the development environment.

  • Make sure you have called NET_DVR_Login_V40 to log in to the device.

Figure 1 Programming Flow of Enabling People Counting

  1. Call NET_DVR_GetDeviceAbility, set dwAbilityType to "DEVICE_ABILITY_INFO" (macro definition value: 0x011), and set pInBuf to the message XML_Desc_VcaChanAbility for getting VCA channel capability to check if people counting is supported by this device.

    The VCA channel capability is returned in the message XML_VcaChanAbility by pOutBuf.

    If supports, the node <PDC> will be returned in the capability message, and then you can continue to perform the following steps.

    Otherwise, people counting is not supported by device, please end this task.

  2. Optional: Call NET_DVR_GetDeviceConfig with NET_DVR_GET_PDC_RULECFG_V42 (command No.: 3405) and specify lpInBuffer as NET_DVR_PDC_RULE_COND for getting people counting parameters, including detection region (line), arming schedule, linkage action, and so on, for reference.

    The people counting parameters are returned in the structure NET_DVR_PDC_RULE_CFG_V42 by lpOutBuffer.

  3. Call NET_DVR_SetDeviceConfig with NET_DVR_SET_PDC_RULECFG_V42 (command No.: 3406), specify lpInBuffer as NET_DVR_PDC_RULE_COND, and set lpInParamBuffer to NET_DVR_PDC_RULE_CFG_V42 for enabling people counting and set parameters.
    Note:
    • To receive alarm in platform, the linkage action must be set to "center" (upload to center).

    • Setting people counting parameters is also available by logging in to device via web page.

  4. Optional: Set lCommand of alarm/event callback function MSGCallBack to "COMM_ALARM_PDC" (command No.: 0x1103) for automatically uploading people counting data by the structure NET_DVR_PDC_ALRAM_INFO in arming mode (see Receive Alarm/Event in Arming Mode) or listening mode (see Receive Alarm/Event in Listening Mode) when people counting is enabled.
  5. Optional: Refer to Search Data and Report for searching people counting data and get report.

Sample Code for Enabling People Counting

#include <stdio.h>
#include <iostream>
#include "Windows.h"
#include "HCNetSDK.h"
using namespace std;

//Time macro definition
#define GET_YEAR(_time_)      (((_time_)>>26) + 2000) 
#define GET_MONTH(_time_)     (((_time_)>>22) & 15)
#define GET_DAY(_time_)       (((_time_)>>17) & 31)
#define GET_HOUR(_time_)      (((_time_)>>12) & 31) 
#define GET_MINUTE(_time_)    (((_time_)>>6)  & 63)
#define GET_SECOND(_time_)    (((_time_)>>0)  & 63)

BOOL CALLBACK MessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
{
    //The following code is for reference only. Actually, directly processing data and saving file in this callback function is not suggested.
    //For example, process the data in the message response API in message mode (PostMessage). 

    switch(lCommand) 
    {       
        case COMM_ALARM_PDC: //People counting alarm information.
	    {
              NET_DVR_PDC_ALRAM_INFO struPDCAlarmInfo = {0};
              memcpy(&struPDCAlarmInfo, pAlarmInfo, sizeof(struPDCAlarmInfo));
              if (struPDCAlarmInfo.byMode == 0) //0-Real-time statistics, real-time quantity is calculated after the latest clearing (including device reboot, manual clearing or auto clearing at 00:00 of every day).
              {
                  NET_DVR_TIME  struAbsTime = {0};
                  struAbsTime.dwYear = GET_YEAR(struPDCAlarmInfo.uStatModeParam.struStatFrame.dwAbsTime);
                  struAbsTime.dwMonth = GET_MONTH(struPDCAlarmInfo.uStatModeParam.struStatFrame.dwAbsTime);
                  struAbsTime.dwDay = GET_DAY(struPDCAlarmInfo.uStatModeParam.struStatFrame.dwAbsTime);
                  struAbsTime.dwHour = GET_HOUR(struPDCAlarmInfo.uStatModeParam.struStatFrame.dwAbsTime);
                  struAbsTime.dwMinute = GET_MINUTE(struPDCAlarmInfo.uStatModeParam.struStatFrame.dwAbsTime);
                  struAbsTime.dwSecond = GET_SECOND(struPDCAlarmInfo.uStatModeParam.struStatFrame.dwAbsTime);

                  //Device IP address, port, channel, people exited, people entered, VCA alarm or not, absolute time
                  printf("DevIP:[%s]Port[%d]Channel[%d]single frame:Channel[%d]LeaveNum[%d]EnterNum[%d]Smart[%d]\
                  AbsTime[%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d]\n", struPDCAlarmInfo.struDevInfo.struDevIP.sIpV4, \
                  struPDCAlarmInfo.struDevInfo.wPort, struPDCAlarmInfo.struDevInfo.byChannel, \
                  struPDCAlarmInfo.byChannel, struPDCAlarmInfo.dwLeaveNum, struPDCAlarmInfo.dwEnterNum,\
                  struPDCAlarmInfo.bySmart, struAbsTime.dwYear, struAbsTime.dwMonth, struAbsTime.dwDay,\
                  struAbsTime.dwHour, struAbsTime.dwMinute, struAbsTime.dwSecond);
              }
              if (struPDCAlarmInfo.byMode == 1) //1-Periodic statistics, increased quantity within specific statistics period, update once per specified statistics period (default: 15 minutes, minimum: 1 minute and maximum: 60 minutes)
              {
                  NET_DVR_TIME  struStartTime = {0};
                  NET_DVR_TIME  struEndTime = {0};
                  struStartTime = struPDCAlarmInfo.uStatModeParam.struStatTime.tmStart;
                  struEndTime = struPDCAlarmInfo.uStatModeParam.struStatTime.tmEnd;


                  //Device IP address, port, channel, people exited, people entered, people passed, VCA alarm or not, start time, end time
                  printf("DevIP:[%s]Port[%d]Channel[%d]single frame:Channel[%d]LeaveNum[%d]EnterNum[%d]PassingNum[%d]Smart[%d]\
                  StartTime[%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d]EndTime[%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d]\n",\
                  struPDCAlarmInfo.struDevInfo.struDevIP.sIpV4, struPDCAlarmInfo.struDevInfo.wPort,\
                  struPDCAlarmInfo.struDevInfo.byChannel, struPDCAlarmInfo.byChannel, struPDCAlarmInfo.dwLeaveNum,\
                  struPDCAlarmInfo.dwEnterNum, struPDCAlarmInfo.dwPassingNum, struPDCAlarmInfo.bySmart, struStartTime.dwYear,\
                  struStartTime.dwMonth, struStartTime.dwDay, struStartTime.dwHour, struStartTime.dwMinute,\
                  struStartTime.dwSecond, struEndTime.dwYear, struEndTime.dwMonth, struEndTime.dwDay, struEndTime.dwHour, \
                  struEndTime.dwMinute, struEndTime.dwSecond);
              }
              //Process other information
              break;
	    }       
        
        default:
        {
            printf("Other alarms, alarm type: 0x%x\n", lCommand);
            break;
        }
    }

    return TRUE;
}

void main() {
    //---------------------------------------
    // Initialize
    NET_DVR_Init();
    //Set connected time and reconnected time
    NET_DVR_SetConnectTime(2000, 1);
    NET_DVR_SetReconnect(10000, true);

    //---------------------------------------
    // Log in to device
    LONG lUserID;

    //Login parameters, including device IP address, user name, password, and so on.
    NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};
    struLoginInfo.bUseAsynLogin = 0; //Synchronous login mode
    strcpy(struLoginInfo.sDeviceAddress, "192.0.0.64"); //IP address
    struLoginInfo.wPort = 8000; //Service port
    strcpy(struLoginInfo.sUserName, "admin"); //User name
    strcpy(struLoginInfo.sPassword, "abcd1234"); //Password
  
    //Device information, output parameter
    NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {0};

    lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
    if (lUserID < 0)
    {
        printf("Login failed, error code: %d\n", NET_DVR_GetLastError());
        NET_DVR_Cleanup();
        return;
    }
  
    //Set alarm callback function
    NET_DVR_SetDVRMessageCallBack_V31(MessageCallback, NULL);
  
    //Enable arming
    LONG lHandle;
    NET_DVR_SETUPALARM_PARAM  struAlarmParam={0};
    struAlarmParam.dwSize=sizeof(struAlarmParam);
    //Setting other arming parameters is not supported.

    lHandle = NET_DVR_SetupAlarmChan_V41(lUserID, & struAlarmParam);
    if (lHandle < 0)
    {
        printf("NET_DVR_SetupAlarmChan_V41 error, %d\n", NET_DVR_GetLastError());
        NET_DVR_Logout(lUserID);
        NET_DVR_Cleanup(); 
        return;
    }
  
    Sleep(50000); //During waiting, if the device uploaded alarm information, receive and handle the alarm information in the alarm callback function.

    //Close uploading channel to disarm.
    if (!NET_DVR_CloseAlarmChan_V30(lHandle))
    {
        printf("NET_DVR_CloseAlarmChan_V30 error, %d\n", NET_DVR_GetLastError());
        NET_DVR_Logout(lUserID);
        NET_DVR_Cleanup(); 
        return;
    }
  
    //Log out
    NET_DVR_Logout(lUserID);
    //Release SDK resource
    NET_DVR_Cleanup();
    return;
}

Call NET_DVR_Logout and NET_DVR_Cleanup to log out from device and release resources.