Développement d'une classe d'outils de capture basée sur le SDK Dahua Webcam (C++)

【Avant-propos】

Comme nous le savons tous, les webcams Dahua ne fournissent pas directement les packages de pilotes ROS correspondants, nous avons donc théoriquement deux manières d'obtenir des images de webcams en C++ :

La première consiste à capturer des images via la classe de capture vidéo d'OpenCV (FFmpeg) ;

La seconde consiste à encapsuler vous-même une classe d'outils de capture via le SDK officiellement fourni par Dahua.

Ici, nous nous concentrons principalement sur la deuxième méthode.

【Ressource】

Adresse de téléchargement du SDK Dahua

assistance https://support.dahuatech.com/tools/sdkExploit/24

【Informations sèches】

1. Créez d’abord une classe pour contenir la structure de données

#ifndef USERDEFINE_H
#define USERDEFINE_H

#include "dhnetsdk.h"
#include "dhconfigsdk.h"
#include <list>
#include <vector>

typedef struct
{
  LLONG lRealPlayHandle;
  unsigned long dwStatistic;
} DH_Channel_Info;

typedef struct
{
  LLONG lLoginHandle;
  int nChannelCount;
  char szDevIp[32];
  int nPort;
  char szUserName[32];
  char szPassWord[32];
  DH_Channel_Info channel[16];
} DH_Device_Info;

typedef std::list<DH_Device_Info*> DEVICE_LIST;
extern DEVICE_LIST g_DeviceList;

typedef std::vector<unsigned char> ONE_IMAGE_BUFFER;
extern ONE_IMAGE_BUFFER g_ImageBuffer;

extern bool g_SnapSuccFlag;

#endif

2. Créez une autre classe d'interface pour encapsuler l'API du SDK

#include "UserDefine.h"
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <map>

class DHCamera
{
public:
  DHCamera();
  ~DHCamera();
  bool initSDKClient();
  void initDeviceInfo(DH_Device_Info &stDeviceInfo);
  void loadDeviceInfo();
  void loginDev();
  void grabCamImage(LLONG loginHandle);
  void logoutDev();

public:
  std::map<std::string, LLONG> devHandles_map;
};

3. Jetons un coup d'œil à l'implémentation spécifique de la classe.

#include "DHCamera.h"

DEVICE_LIST g_DeviceList;
ONE_IMAGE_BUFFER g_ImageBuffer;
bool g_SnapSuccFlag = false;
static bool g_bNetSDKInitFlag = false;
static short g_nCmdSerial = 0;

void CALLBACK DisConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
  DHCamera* pThis = (DHCamera *)dwUser;
  if(NULL == pThis)
  {
    return;
  }

  printf("Call DisConnectFunc\n");
  printf("lLoginID[0x%x]", lLoginID);
  if (NULL != pchDVRIP)
  {
    printf("pchDVRIP[%s]\n", pchDVRIP);
  }
  printf("nDVRPort[%d]\n", nDVRPort);
  printf("dwUser[%p]\n", dwUser);
  printf("\n");
  return;
}

void CALLBACK HaveReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
  printf("Call HaveReConnect\n");
  printf("lLoginID[0x%x]", lLoginID);
  if (NULL != pchDVRIP)
  {
    printf("pchDVRIP[%s]\n", pchDVRIP);
  }
  printf("nDVRPort[%d]\n", nDVRPort);
  printf("dwUser[%p]\n", dwUser);
  printf("\n");
}

void CALLBACK SnapRev(LLONG lLoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser)
{
  std::vector<unsigned char> current_frame(pBuf, pBuf+RevLen);
  g_ImageBuffer.swap(current_frame);
  g_SnapSuccFlag = true;
}

DHCamera::DHCamera()
{
}

DHCamera::~DHCamera()
{
  DEVICE_LIST::iterator it = g_DeviceList.begin();
  while (it != g_DeviceList.end())
  {
    DH_Device_Info *pDeviceInfo = (*it);
    if (pDeviceInfo != nullptr)
    {
      delete pDeviceInfo;
      pDeviceInfo = nullptr;
    }
    it++;
  }
  g_DeviceList.clear();
}

bool DHCamera::initSDKClient()
{
  g_bNetSDKInitFlag = CLIENT_Init(DisConnectFunc, (LDWORD)this);
  CLIENT_SetAutoReconnect(HaveReConnect, 0);
  return g_bNetSDKInitFlag;
}

void DHCamera::initDeviceInfo(DH_Device_Info &stDeviceInfo)
{
  stDeviceInfo.lLoginHandle = 0UL;
  stDeviceInfo.nChannelCount = 0;
  stDeviceInfo.nPort = 0;
  memset(&stDeviceInfo.szDevIp , 0 , sizeof(stDeviceInfo.szDevIp));
  memset(&stDeviceInfo.szUserName , 0 , sizeof(stDeviceInfo.szUserName));
  memset(&stDeviceInfo.szPassWord , 0 , sizeof(stDeviceInfo.szPassWord));
  memset(&stDeviceInfo.channel , 0 , sizeof(stDeviceInfo.channel));
}

void DHCamera::loadDeviceInfo()
{
  DEVICE_LIST::iterator it = g_DeviceList.begin();
  while (it != g_DeviceList.end())
  {
    DH_Device_Info *pDeviceInfo = (*it);
    if (pDeviceInfo != nullptr)
    {
      delete pDeviceInfo;
      pDeviceInfo = nullptr;
    }
    it++;
  }
  g_DeviceList.clear();

  int start_ip = 150;
  int connect_num = 12;
  int port = 37777;

  for(int i = start_ip; i < (start_ip + connect_num); i++)
  {
    DH_Device_Info* device_info = new DH_Device_Info;
    initDeviceInfo(*device_info);
    std::string ip = "192.168.1.";
    strncpy(device_info->szDevIp, (ip+std::to_string(i)).c_str(), sizeof(device_info->szDevIp)-1);
    device_info->nPort = port;
    strncpy(device_info->szUserName, "admin", sizeof(device_info->szUserName)-1);
    strncpy(device_info->szPassWord, "admin123", sizeof(device_info->szPassWord)-1);
    g_DeviceList.push_back(device_info);
  }

  printf("Init Dev's Num : %d\n", g_DeviceList.size());
}

void DHCamera::loginDev()
{
  DEVICE_LIST::iterator it = g_DeviceList.begin();
  while(it != g_DeviceList.end())
  {
    DH_Device_Info *pDeviceInfo = (*it);
    if(pDeviceInfo == NULL)
    {
      it++;
      continue;
    }

    NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stInparam;
    memset(&stInparam, 0, sizeof(stInparam));
    stInparam.dwSize = sizeof(stInparam);
    strncpy(stInparam.szIP, pDeviceInfo->szDevIp, sizeof(stInparam.szIP) - 1);
    strncpy(stInparam.szPassword, pDeviceInfo->szPassWord, sizeof(stInparam.szPassword) - 1);
    strncpy(stInparam.szUserName, pDeviceInfo->szUserName, sizeof(stInparam.szUserName) - 1);
    stInparam.nPort = pDeviceInfo->nPort;
    stInparam.emSpecCap = EM_LOGIN_SPEC_CAP_TCP;

    NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stOutparam;
    memset(&stOutparam, 0, sizeof(stOutparam));
    stOutparam.dwSize = sizeof(stOutparam);

    pDeviceInfo->lLoginHandle = CLIENT_LoginWithHighLevelSecurity(&stInparam, &stOutparam);
    if(pDeviceInfo->lLoginHandle != 0)
    {
      devHandles_map.emplace(pDeviceInfo->szDevIp, pDeviceInfo->lLoginHandle);
      printf("CLIENT_LoginWithHighLevelSecurity %s[%d] Success\n" , pDeviceInfo->szDevIp , pDeviceInfo->nPort);
      usleep(500000);
    }
    else {
      printf("Failed to login IP[%s]\n", pDeviceInfo->szDevIp);
    }
  }
}

void DHCamera::logoutDev()
{
  DEVICE_LIST::iterator it = g_DeviceList.begin();
  while(it != g_DeviceList.end())
  {
    if((*it)->lLoginHandle != 0)
    {
      CLIENT_Logout((*it)->lLoginHandle);
    }
  }
  if (TRUE == g_bNetSDKInitFlag)
  {
    CLIENT_Cleanup();
    g_bNetSDKInitFlag = FALSE;
  }
}

void DHCamera::grabCamImage(long loginHandle)
{
  if (0 == loginHandle)
  {
    return;
  }
  // 设置抓图回调函数
  CLIENT_SetSnapRevCallBack(SnapRev, NULL);
  //事例中默认通道 ID 为 0、抓图模式为抓一幅图,用户可根据实际情况自行选择
  int nChannelId = 0;
  int nSnapType = 0; // 抓图模式;-1:表示停止抓图, 0:表示请求一帧, 1:表示定时发送请求, 2:表示连续请求
  // 发送抓图命令给前端设备
  SNAP_PARAMS stuSnapParams;
  stuSnapParams.Channel = nChannelId;
  stuSnapParams.mode = nSnapType;
  stuSnapParams.CmdSerial = ++g_nCmdSerial; // 请求序列号,有效值范围 0~65535,超过范围会被截断为 unsigned short
  if (FALSE == CLIENT_SnapPictureEx(loginHandle, &stuSnapParams))
  {
    printf("CLIENT_SnapPictureEx Failed!Last Error[%x]\n", CLIENT_GetLastError());
    return;
  }
  else
  {
    printf("CLIENT_SnapPictureEx succ\n");
  }
}

【Post-scriptum】

Si ce blog vous est utile, n'hésitez pas à liker !

Je suppose que tu aimes

Origine blog.csdn.net/weixin_39538031/article/details/131008912
conseillé
Classement