162 lines
4.5 KiB
C
162 lines
4.5 KiB
C
|
|
#ifndef HIKDEVICE_H
|
|||
|
|
#define HIKDEVICE_H
|
|||
|
|
|
|||
|
|
// 先包含标准库头文件
|
|||
|
|
#include <mutex>
|
|||
|
|
#include <atomic>
|
|||
|
|
#include <vector>
|
|||
|
|
#include <functional>
|
|||
|
|
#include <string>
|
|||
|
|
#include <map>
|
|||
|
|
|
|||
|
|
// 禁用Windows的min/max宏
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
#ifndef NOMINMAX
|
|||
|
|
#define NOMINMAX
|
|||
|
|
#endif
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#include "IHikDevice.h"
|
|||
|
|
|
|||
|
|
// 海康SDK头文件
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
#include "HCNetSDK.h"
|
|||
|
|
#include "plaympeg4.h"
|
|||
|
|
#else
|
|||
|
|
#include "HCNetSDK.h"
|
|||
|
|
#include "LinuxPlayM4.h"
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 海康相机设备实现类
|
|||
|
|
*
|
|||
|
|
* 封装海康威视HCNetSDK和PlayM4解码库
|
|||
|
|
*/
|
|||
|
|
class CHikDevice : public IHikDevice
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
CHikDevice();
|
|||
|
|
~CHikDevice() override;
|
|||
|
|
|
|||
|
|
// ============ IHikDevice 接口实现 ============
|
|||
|
|
|
|||
|
|
int InitSDK() override;
|
|||
|
|
void CleanupSDK() override;
|
|||
|
|
|
|||
|
|
int Login(const HikDeviceConfig& config) override;
|
|||
|
|
void Logout() override;
|
|||
|
|
bool IsLoggedIn() const override;
|
|||
|
|
|
|||
|
|
int StartPreview() override;
|
|||
|
|
int StartPreviewEx(void* hWnd) override;
|
|||
|
|
void StopPreview() override;
|
|||
|
|
bool IsPreviewing() const override;
|
|||
|
|
|
|||
|
|
EHikDeviceStatus GetStatus() const override;
|
|||
|
|
|
|||
|
|
void SetDecodedFrameCallback(HikDecodedFrameCallback callback, void* pUser) override;
|
|||
|
|
void SetStatusCallback(HikDeviceStatusCallback callback, void* pUser) override;
|
|||
|
|
void SetExceptionCallback(HikExceptionCallback callback, void* pUser) override;
|
|||
|
|
|
|||
|
|
int GetCurrentFrame(unsigned char* pBuffer, int bufferSize, HikFrameInfo& frameInfo) override;
|
|||
|
|
|
|||
|
|
const HikDeviceConfig& GetConfig() const override;
|
|||
|
|
|
|||
|
|
int CaptureToFile(const std::string& filePath, bool isJpeg = true) override;
|
|||
|
|
int PTZControl(int command, bool stop, int speed = 4) override;
|
|||
|
|
int ConfigureOSD(bool showChanName, bool showOsd) override;
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
// ============ 内部回调函数 ============
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 海康实时数据回调(静态)
|
|||
|
|
*/
|
|||
|
|
static void CALLBACK HikRealDataCallback(LONG lRealHandle, DWORD dwDataType,
|
|||
|
|
BYTE* pBuffer, DWORD dwBufSize, void* pUser);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief PlayM4 解码回调(静态)
|
|||
|
|
* 注意:Windows和Linux/ARM的回调签名不同
|
|||
|
|
*/
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
static void CALLBACK PlayM4DecodeCallback(long nPort, char* pBuf, long nSize,
|
|||
|
|
FRAME_INFO* pFrameInfo, long nUser, long nReserved2);
|
|||
|
|
#else
|
|||
|
|
static void CALLBACK PlayM4DecodeCallback(int nPort, char* pBuf, int nSize,
|
|||
|
|
FRAME_INFO* pFrameInfo, void* nUser, int nReserved2);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 海康异常回调(静态)
|
|||
|
|
*/
|
|||
|
|
static void CALLBACK HikSDKExceptionCallback(DWORD dwType, LONG lUserID, LONG lHandle, void* pUser);
|
|||
|
|
|
|||
|
|
// ============ 内部方法 ============
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 处理解码后的视频帧
|
|||
|
|
*/
|
|||
|
|
void ProcessDecodedFrame(char* pBuf, long nSize, FRAME_INFO* pFrameInfo);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 处理异常
|
|||
|
|
*/
|
|||
|
|
void HandleException(DWORD dwType);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 更新设备状态
|
|||
|
|
*/
|
|||
|
|
void UpdateStatus(EHikDeviceStatus status);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief YV12转RGB32
|
|||
|
|
*/
|
|||
|
|
void ConvertYV12ToRGB32(const unsigned char* yPlane, const unsigned char* uPlane,
|
|||
|
|
const unsigned char* vPlane, unsigned char* rgbData,
|
|||
|
|
int width, int height);
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
// SDK 初始化状态
|
|||
|
|
std::atomic<bool> m_bSDKInitialized{false};
|
|||
|
|
|
|||
|
|
// 登录相关
|
|||
|
|
LONG m_lUserID = -1;
|
|||
|
|
HikDeviceConfig m_config;
|
|||
|
|
|
|||
|
|
// 预览相关
|
|||
|
|
LONG m_lRealPlayHandle = -1;
|
|||
|
|
std::atomic<bool> m_bPreviewing{false};
|
|||
|
|
|
|||
|
|
// PlayM4 解码相关
|
|||
|
|
LONG m_lPlayM4Port = -1;
|
|||
|
|
std::atomic<bool> m_bPlayM4Playing{false};
|
|||
|
|
|
|||
|
|
// 设备状态
|
|||
|
|
std::atomic<EHikDeviceStatus> m_status{EHikDeviceStatus::Disconnected};
|
|||
|
|
|
|||
|
|
// 当前帧数据
|
|||
|
|
mutable std::mutex m_frameMutex;
|
|||
|
|
std::vector<unsigned char> m_currentFrameData;
|
|||
|
|
HikFrameInfo m_currentFrameInfo;
|
|||
|
|
|
|||
|
|
// 回调函数
|
|||
|
|
HikDecodedFrameCallback m_frameCallback = nullptr;
|
|||
|
|
void* m_pFrameCallbackUser = nullptr;
|
|||
|
|
|
|||
|
|
HikDeviceStatusCallback m_statusCallback = nullptr;
|
|||
|
|
void* m_pStatusCallbackUser = nullptr;
|
|||
|
|
|
|||
|
|
HikExceptionCallback m_exceptionCallback = nullptr;
|
|||
|
|
void* m_pExceptionCallbackUser = nullptr;
|
|||
|
|
|
|||
|
|
// 错误码
|
|||
|
|
mutable int m_lastError = 0;
|
|||
|
|
|
|||
|
|
// 静态成员:端口到实例的映射(解决64位系统回调指针截断问题)
|
|||
|
|
static std::map<long, CHikDevice*> s_portDeviceMap;
|
|||
|
|
static std::mutex s_mapMutex;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
#endif // HIKDEVICE_H
|