Files
CodeRepository/Projects/App_DataCapturer/GdPCIE/DataCapture.h

284 lines
10 KiB
C
Raw Normal View History

2026-02-01 22:23:06 +08:00
/**
*Xilinx FPGA芯片(K7) XDMA框架进行交互
*
*/
#ifndef DATACAPTURE_H
#define DATACAPTURE_H
#include <QObject>
#include <QFuture>
#include <QThreadPool>
#include <QtConcurrent/QtConcurrent>
#include "./XDmaCommDef.h"
#include "./PcieFun.h"
#include "./GIOParams.h"
#include <iostream>
#include <atomic>
#include <thread>
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 <typename T>
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<int, GFrameFormat> m_frameFormatMap; //key: 通道号 value:图像格式
QMap<int, int > m_iFrameSizeMap; //key: 通道号 value: 每路对应的帧size
QMap<int, Device_File*> m_pInterEventMap; // key: 通道号 value: 中断事件对应Map
QMap<int, unsigned char*> m_pCaptureBuffMap; //key: 通道号 value: 采集buff缓存Map
QMap<int, bool> m_bIsStartCaptureMap; //key: 通道号 value:是否开始采集状态
QMap<int, int> m_uiHostReadBuffNoMap; //key: 通道号 value: 上位机在上一个循环中最后读到的BuffNo索引值 取值: 0~(ChannelCacheNum-1)
QMap<int, uint> m_uiCaptureFrameNoMap; //key: 通道号 value: 采集的当前帧编号
QMap<int, uint> m_uiCaptureLossFrameNoMap; //key: 通道号 value: 采集丢帧数统计
QMap<int, DynamicArray*> m_varCaptureCMDMap; // /key: ChannelIndex value:动态数组 命令采集
//帧率计算
QMap<int, uint> m_uiCurrFrameRateCountMap; //key: 通道号 value:当前帧数
QMap<int, int64_t> m_iFrameTimeStartMap; //key: 通道号 value:开始统计的时间戳
QMap<int, uint> m_uiCalcuFramesMap; //key: 通道号 value: 多少帧数计算一次 100
QMap<int, double> m_dCaptureFrameRateMap; //key: 通道号 value:采集帧率
QMap<int, int> m_iHostDealImgToDrawMap; //key: 通道号 value: 上位机从采集到图像到处理完,调用显卡绘制接口开始进行绘制的时间 单位:毫秒
QMap<int, bool> m_bStartImgDisplayDelayMap; //key: 通道号 value:是否开启上位机发送图像数据到显卡→显卡在屏幕上绘制出对应图像数据的耗时
QMap<int, ushort> m_iImgDisplayDelayTestIndexMap; //key: 通道号 value: 上位机发送图像数据到显卡→显卡在屏幕上绘制出对应图像数据 显示计数 1-15
QMap<int, uint > m_uiMaxFrameNoMap; //key: 通道号 value:每路最大帧编号
QMap<int, QTimer*> m_varStatusDetectTimerMap; //key: 通道号 value:状态监测定时器
QMap<int, bool> m_bIsInterEventTimeOutMap; //读取中断数据是否超时
//事件中断线程
QMap<int, bool> m_bEventInterThreadRunningMap; //key:通道号 value:事件中断线程运行状态
QMap<int, std::thread*> m_ptrThread_EventInterMap; //key:通道号 value:事件中断线程
QMap<int, SystemStateCallback> m_pFunCallBackMap;
QMap<int, void*> m_pSysStateUserMap;
QMap<int, HANDLE> 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<void*, uint> m_uiCpuCoreIndexUsedMap;
pCallbackFunc_OnCaptrueData m_pCallbackFunc_OnCaptrueData;
void* m_pOwner_OnCaptrueData;
};
#endif // DATACAPTURE_H