172 lines
5.0 KiB
C++
172 lines
5.0 KiB
C++
#ifndef GVSPPARSER_H
|
|
#define GVSPPARSER_H
|
|
|
|
#include <QObject>
|
|
#include <QByteArray>
|
|
#include <QImage>
|
|
#include <QAtomicInt>
|
|
#include <cstdint>
|
|
|
|
// GVSP packet types (GigE Vision 2.1 standard)
|
|
#define GVSP_LEADER_PACKET 0x01
|
|
#define GVSP_TRAILER_PACKET 0x02
|
|
#define GVSP_PAYLOAD_PACKET 0x03
|
|
|
|
// Payload types
|
|
#define PAYLOAD_TYPE_IMAGE 0x0001
|
|
#define PAYLOAD_TYPE_BINARY 0x0003
|
|
#define PAYLOAD_TYPE_POINTCLOUD 0x8000 // Vendor-specific for point cloud data
|
|
|
|
// Image format
|
|
#define PIXEL_FORMAT_12BIT_GRAY 0x010C0001
|
|
#define PIXEL_FORMAT_MONO16 0x01100005 // Mono16 format (legacy)
|
|
#define PIXEL_FORMAT_MONO16_LEFT 0x01100006 // Mono16 format for left IR camera
|
|
#define PIXEL_FORMAT_MONO16_RIGHT 0x01100007 // Mono16 format for right IR camera
|
|
#define PIXEL_FORMAT_MONO8_LEFT 0x01080006 // Mono8 format for left IR camera (downsampled)
|
|
#define PIXEL_FORMAT_MONO8_RIGHT 0x01080007 // Mono8 format for right IR camera (downsampled)
|
|
#define PIXEL_FORMAT_MJPEG 0x02180001 // MJPEG format for RGB camera
|
|
|
|
// Image dimensions
|
|
#define IMAGE_WIDTH 1224
|
|
#define IMAGE_HEIGHT 1024
|
|
#define IR_DISPLAY_WIDTH 612 // Downsampled IR display width
|
|
#define IR_DISPLAY_HEIGHT 512 // Downsampled IR display height
|
|
#define RGB_WIDTH 1920
|
|
#define RGB_HEIGHT 1080
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
// GVSP packet header (GigE Vision 2.1 standard - 8 bytes)
|
|
struct GVSPPacketHeader {
|
|
uint16_t status; // Status flags
|
|
uint16_t block_id; // Block ID (frame number)
|
|
uint8_t packet_format; // Packet type: 0x01=Leader, 0x02=Trailer, 0x03=Payload
|
|
uint8_t reserved; // Reserved byte
|
|
uint16_t packet_id; // Packet ID within block
|
|
};
|
|
|
|
// Image data leader
|
|
struct GVSPImageDataLeader {
|
|
uint16_t reserved;
|
|
uint16_t payload_type;
|
|
uint32_t timestamp_high;
|
|
uint32_t timestamp_low;
|
|
uint32_t pixel_format;
|
|
uint32_t size_x;
|
|
uint32_t size_y;
|
|
uint32_t offset_x;
|
|
uint32_t offset_y;
|
|
uint16_t padding_x;
|
|
uint16_t padding_y;
|
|
};
|
|
|
|
// Image data trailer
|
|
struct GVSPImageDataTrailer {
|
|
uint32_t reserved;
|
|
uint16_t payload_type;
|
|
uint32_t size_y;
|
|
};
|
|
|
|
// Binary data leader (for depth data)
|
|
struct GVSPBinaryDataLeader {
|
|
uint16_t reserved;
|
|
uint16_t payload_type;
|
|
uint32_t timestamp_high;
|
|
uint32_t timestamp_low;
|
|
uint32_t file_size;
|
|
uint32_t name_len;
|
|
char file_name[256];
|
|
};
|
|
|
|
// Binary data trailer
|
|
struct GVSPBinaryDataTrailer {
|
|
uint32_t reserved;
|
|
uint16_t payload_type;
|
|
uint32_t checksum;
|
|
};
|
|
|
|
// Point cloud data leader (vendor-specific, payload_type = 0x8000)
|
|
struct GVSPPointCloudDataLeader {
|
|
uint16_t reserved;
|
|
uint16_t payload_type; // 0x8000
|
|
uint32_t timestamp_high;
|
|
uint32_t timestamp_low;
|
|
uint32_t data_size; // Total size of point cloud data
|
|
};
|
|
|
|
// Point cloud data trailer
|
|
struct GVSPPointCloudDataTrailer {
|
|
uint32_t reserved;
|
|
uint16_t payload_type; // 0x8000
|
|
uint32_t checksum;
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
|
|
class GVSPParser : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit GVSPParser(QObject *parent = nullptr);
|
|
~GVSPParser();
|
|
|
|
void parsePacket(const QByteArray &packet);
|
|
void reset();
|
|
|
|
signals:
|
|
void leftImageReceived(const QByteArray &jpegData, uint32_t blockId); // 左红外图像(JPEG)
|
|
void rightImageReceived(const QByteArray &jpegData, uint32_t blockId); // 右红外图像(JPEG)
|
|
void rgbImageReceived(const QByteArray &jpegData, uint32_t blockId); // RGB图像(MJPEG)
|
|
void pointCloudDataReceived(const QByteArray &cloudData, uint32_t blockId);
|
|
void parseError(const QString &error);
|
|
|
|
// 兼容旧代码
|
|
void imageReceived(const QImage &image, uint32_t blockId);
|
|
void depthDataReceived(const QByteArray &depthData, uint32_t blockId);
|
|
|
|
private:
|
|
// 每种数据流的独立接收状态
|
|
struct StreamState {
|
|
bool isReceiving;
|
|
uint32_t blockId;
|
|
QByteArray dataBuffer;
|
|
size_t expectedSize;
|
|
size_t receivedSize;
|
|
int packetCount;
|
|
|
|
// 图像特有信息
|
|
uint32_t imageWidth;
|
|
uint32_t imageHeight;
|
|
uint32_t pixelFormat;
|
|
|
|
StreamState() : isReceiving(false), blockId(0), expectedSize(0),
|
|
receivedSize(0), packetCount(0), imageWidth(0),
|
|
imageHeight(0), pixelFormat(0) {}
|
|
};
|
|
|
|
void handleLeaderPacket(const uint8_t *data, size_t size);
|
|
void handlePayloadPacket(const uint8_t *data, size_t size);
|
|
void handleTrailerPacket(const uint8_t *data, size_t size);
|
|
|
|
void processImageData(StreamState *state);
|
|
void processDepthData(StreamState *state);
|
|
void processPointCloudData(StreamState *state);
|
|
|
|
// 为每种数据类型维护独立的状态
|
|
StreamState m_leftIRState; // 左红外
|
|
StreamState m_rightIRState; // 右红外
|
|
StreamState m_rgbState; // RGB
|
|
StreamState m_depthState; // 深度数据
|
|
StreamState m_pointCloudState; // 点云数据
|
|
|
|
// Statistics
|
|
uint32_t m_lastBlockId;
|
|
int m_imageSequence;
|
|
|
|
// Async processing control
|
|
QAtomicInt m_imageProcessingCount;
|
|
};
|
|
|
|
#endif // GVSPPARSER_H
|