/** *该类用于与Xilinx FPGA芯片(K7) XDMA框架进行交互 * */ #ifndef DATACAPTURE_H #define DATACAPTURE_H #include #include #include #include #include "./XDmaCommDef.h" #include "./PcieFun.h" #include "./GIOParams.h" #include #include #include class Device_File { public: Device_File::Device_File() : h(INVALID_HANDLE_VALUE) {} std::string get_windows_error_msg() { char msg_buffer[256]; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg_buffer, 256, NULL); return{ msg_buffer, 256 }; } Device_File(const std::string& path, DWORD accessFlags) { size_t size = path.length(); wchar_t* buffer = new wchar_t[size + 1]; MultiByteToWideChar(CP_ACP, 0, path.c_str(), size, buffer, size * sizeof(wchar_t)); buffer[size] = 0; //确保以 '\0' 结尾 qDebug() << QString::fromWCharArray(buffer) ; h = CreateFile(buffer, accessFlags, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) { QString errorStr = "Event: Opening device Event file failed: " ; qDebug() << errorStr; std::cout << "error: " << get_windows_error_msg() << std::endl; } delete buffer; buffer = NULL; } ~Device_File() { if (h != INVALID_HANDLE_VALUE) { CloseHandle(h); h = INVALID_HANDLE_VALUE; } } template T read(long address) { T buffer; if (INVALID_SET_FILE_POINTER == SetFilePointer(h, address, NULL, FILE_BEGIN)) { std::string errorStr = get_windows_error_msg(); std::cout << "errorStr001: " << errorStr << std::endl; return buffer; } unsigned long num_bytes_read; if (!ReadFile(h, &buffer, sizeof(T), &num_bytes_read, NULL)) { std::string errorStr = "read : Failed to read from stream! " /*+ get_windows_error_msg()*/; qDebug() << QString::fromStdString(errorStr); return buffer; } else if (num_bytes_read != sizeof(T)) { qDebug() << "read : Failed to read all bytes!"; return buffer; } return buffer; } int write(long address, DWORD size, BYTE* buffer) { if (INVALID_SET_FILE_POINTER == SetFilePointer(h, address, NULL, FILE_BEGIN)) { // std::string errorStr = "write : SetFilePointer failed: " /*+ get_windows_error_msg()*/; // qDebug() << QString::fromStdString(errorStr); } unsigned long wr_size; if (!WriteFile(h, (void*)(buffer), (DWORD)(size), &wr_size, NULL)) { // std::string errorStr = "write : Failed to read from stream! "/* + get_windows_error_msg()*/; // qDebug() << QString::fromStdString(errorStr); } else if (wr_size != size) { // qDebug() << "write : Failed to write all bytes!"; } return wr_size; } private: HANDLE h; }; typedef void (*SystemStateCallback)(uint channelIndex, const QByteArray& state, void* userData); typedef void (*pCallbackFunc_OnCaptrueData)(uint8_t* pData, uint32_t nDataSize, uint32_t nChannelIndex, void* pOwner); class DataCapture : public QObject { Q_OBJECT public: explicit DataCapture(QObject* parent = nullptr, char* device_base_path = nullptr); virtual ~DataCapture(); /**********************主要接口*****************************/ /** * @brief 设置采集回调函数 */ void SetCaptureCallback(pCallbackFunc_OnCaptrueData pCallbackFunc_CaptrueData, void* pOwner); /** * @brief 开始采集 */ void StartCapture(GFrameFormat* captureParam, void* openglview = nullptr); /** * @brief 停止采集 */ void StopCapture(int channelIndex); /** * @brief 通过设置回调来获取每路光纤端口的系统状态数据,与 StartCapture() 接口独立。 */ void SetSystemStatusCallback(int channelIndex, SystemStateCallback callback, void* user, bool isOpen); /**********************下面为非必要接口*****************************/ /** * @brief 获取延时信息 返回结构体 */ CaptureDelayStatusInfo* GetDelayStatus(int channelIndex); /** * @brief 开启上位机发送图像数据到显卡→显卡在屏幕上绘制出对应图像数据的耗时 */ void SetImgDisplayDelayTest(int channelIndex, bool isStart); /** * @brief 是否正在采集数据 * @return */ bool IsCapture(int channelIndex) { return m_bIsStartCaptureMap.value(channelIndex); } /** * @brief SetFullScreenWgt 设置全屏播放的控件 * @param channelIndex 端口号 * @param fullScreenOpenglview 全屏播放的控件 */ void SetFullScreenWgt(int channelIndex = -1, void* fullScreenOpenglview = nullptr); void SetOsdHidden(bool isHidden) {m_bIsHiddenOsd = isHidden ; } void SetShowErrorFrame(bool isShow) {m_bIsShowErrorFrame = isShow ; } private slots: void OnSlotCaptureCmdDataTimeOut(); private: QString ShowHex(char* str, int length); //Hex to String int GetByteOfPixel(ePixelType ePT); typedef void (DataCapture::*ThreadRunFunPtr)(); static void ThreadEntry(ThreadRunFunPtr pRunFun, void* pOwner); typedef void (DataCapture::*ReadEventThreadRunFunPtr)(int channelIndex); static void ThreadEntry_ReadEvent(ReadEventThreadRunFunPtr pRunFun, void* pOwner, int channelIndex); //1.数据采集处理线程 bool StartThread_CaptureDeviceData(); void StopThread_CaptureDeviceData(); void ThreadFun_CaptureDeviceData(); //2.系统状态线程 void ThreadFun_GetSysStates(); //命令采集 //3.中断通知读取线程 void StartThread_DealInterEvent(int channelIndex); void StopThread_DealInterEvent(int channelIndex); void ThreadFun_ReadInterEvent(int channelIndex); qint64 CurrentTime(); inline void SleepAccurate(int milliseconds); //设备数据采集线程 bool m_bThreadRunning_CaptureDevice; std::thread* m_ptrThread_CaptureDevice; bool m_bGetSysStatesThreadRuning; //获取系统状态 std::thread* m_ptrThread_GetSysStates; //*************************************** //显示控件 QMap m_frameFormatMap; //key: 通道号 value:图像格式 QMap m_iFrameSizeMap; //key: 通道号 value: 每路对应的帧size QMap m_pInterEventMap; // key: 通道号 value: 中断事件对应Map QMap m_pCaptureBuffMap; //key: 通道号 value: 采集buff缓存Map QMap m_bIsStartCaptureMap; //key: 通道号 value:是否开始采集状态 QMap m_uiHostReadBuffNoMap; //key: 通道号 value: 上位机在上一个循环中最后读到的BuffNo索引值 取值: 0~(ChannelCacheNum-1) QMap m_uiCaptureFrameNoMap; //key: 通道号 value: 采集的当前帧编号 QMap m_uiCaptureLossFrameNoMap; //key: 通道号 value: 采集丢帧数统计 QMap m_varCaptureCMDMap; // /key: ChannelIndex value:动态数组 命令采集 //帧率计算 QMap m_uiCurrFrameRateCountMap; //key: 通道号 value:当前帧数 QMap m_iFrameTimeStartMap; //key: 通道号 value:开始统计的时间戳 QMap m_uiCalcuFramesMap; //key: 通道号 value: 多少帧数计算一次 100 QMap m_dCaptureFrameRateMap; //key: 通道号 value:采集帧率 QMap m_iHostDealImgToDrawMap; //key: 通道号 value: 上位机从采集到图像到处理完,调用显卡绘制接口开始进行绘制的时间 单位:毫秒 QMap m_bStartImgDisplayDelayMap; //key: 通道号 value:是否开启上位机发送图像数据到显卡→显卡在屏幕上绘制出对应图像数据的耗时 QMap m_iImgDisplayDelayTestIndexMap; //key: 通道号 value: 上位机发送图像数据到显卡→显卡在屏幕上绘制出对应图像数据 显示计数 1-15 QMap m_uiMaxFrameNoMap; //key: 通道号 value:每路最大帧编号 QMap m_varStatusDetectTimerMap; //key: 通道号 value:状态监测定时器 QMap m_bIsInterEventTimeOutMap; //读取中断数据是否超时 //事件中断线程 QMap m_bEventInterThreadRunningMap; //key:通道号 value:事件中断线程运行状态 QMap m_ptrThread_EventInterMap; //key:通道号 value:事件中断线程 QMap m_pFunCallBackMap; QMap m_pSysStateUserMap; QMap m_pSynEventMap; //key:通道号 value:同步事件 uint m_iTestFrameIndex; QTimer m_varTestVideoTimer; QTimer m_varCaptureCmdDataTimer; uint m_iCaptureEnableStatus; //采集使能状态 std::string m_strDevicePath; //采集卡地址 //采集延时状态数组 CaptureDelayStatusInfo m_szCaptureStatus[ChannelCacheNum]; byte* m_szY8ImgData_Thread01; byte* m_szRGBAImgData_Thread01; byte* m_szY8ImgData_Thread02; byte* m_szRGBAImgData_Thread02; // uint m_uiCpuCoreCount;//CPU核心数 bool m_bIsOpenRecordThread; bool m_bIsOpenCaptureThread; uint uiThreadSleepTime; //线程休眠时间 bool m_bIsHiddenOsd; bool m_bIsShowErrorFrame; uint m_uiAXIFrequence = 0; QMap m_uiCpuCoreIndexUsedMap; pCallbackFunc_OnCaptrueData m_pCallbackFunc_OnCaptrueData; void* m_pOwner_OnCaptrueData; }; #endif // DATACAPTURE_H