284 lines
10 KiB
C
284 lines
10 KiB
C
|
|
/**
|
|||
|
|
*该类用于与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
|