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
|