162 lines
4.5 KiB
C
Raw Permalink Normal View History

#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