Files
d330viewer/include/dkam_gige_stream.h
2026-01-14 18:07:26 +08:00

259 lines
8.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "dkam_asyncqueue.h"
#include "dkam_base_type.h"
#include "dkam_gige_camera.h"
#include "dkam_log.h"
#define GVSP_MAX_INCOMIN_SIZE 65535 //收到数据最大尺寸其实巨帧也不过9000多个这最为了方便直接用16位的最大值 。
#define SOCKET_SELECT_TIMEOUT_US_DEFAULT 10000 //select超时时间
#define PACKET_TIMEOUT_US_DEFAULT 400000 //重发包超时时间
#define BLOCK_TIMEOUT_US_DEFAULT 1000000 //block完整性检查评估的超时时间
#define PACKET_RESEND_FLAG_DEFAILT TRUE //重发包使用
#define PACKET_RESEND_RATIO_DEFAULT 1 //重发比例默认100%
#define MAX_BUFFER_LENGTH_DEFAULT 4 //最长的缓冲区大小默认4
#define NET_SPEED_STATISTICS_UNIT_TIME_US 1000000 //网速计时的默认时间区间1s
#define SEND_TO_SOURCE_SOURCE_TIME_US_DEFAULT 3000000 //默认发包破防火墙的间隔 3s
#define MAX_DISCARD_BLOCK_NUM 2000 //最大认为系统丢弃block数量
//block数据类型目前主要用IMAGE
typedef enum {
BUFFER_PAYLOAD_TYPE_UNKNOWN = -1,
BUFFER_PAYLOAD_TYPE_IMAGE = 0x0001,
BUFFER_PAYLOAD_TYPE_RAWDATA = 0x0002,
BUFFER_PAYLOAD_TYPE_FILE = 0x0003,
BUFFER_PAYLOAD_TYPE_CHUNK_DATA = 0x0004,
BUFFER_PAYLOAD_TYPE_EXTENDED_CHUNK_DATA = 0x0005, /* Deprecated */
BUFFER_PAYLOAD_TYPE_JPEG = 0x0006,
BUFFER_PAYLOAD_TYPE_JPEG2000 = 0x0007,
BUFFER_PAYLOAD_TYPE_H264 = 0x0008,
BUFFER_PAYLOAD_TYPE_MULTIZONE_IMAGE = 0x0009
} BufferPayloadType;
//block收到数据的状态
typedef enum {
BUFFER_STATUS_SUCCESS = 0,
BUFFER_STATUS_UNKNOWN = -1,
BUFFER_STATUS_CLEARED = -2,
BUFFER_STATUS_TIMEOUT = -3,
BUFFER_STATUS_MISSING_PACKETS = -4,
BUFFER_STATUS_WRONG_PACKET_ID = -5,
BUFFER_STATUS_WRONG_PACKET = -6,
BUFFER_STATUS_SIZE_MISMATCH = -7,
BUFFER_STATUS_FILLING = -8,
BUFFER_STATUS_ABORTED = -9
} BufferStatus;
typedef struct {
unsigned short status;
unsigned short block_id;
unsigned int packet_infos;
} GvspHeader;
typedef struct {
unsigned short flags;
unsigned short payload_type;
unsigned int timestamp_high;
unsigned int timestamp_low;
unsigned int pixel_format;
unsigned int width;
unsigned int height;
unsigned int x_offset;
unsigned int y_offset;
unsigned int gvsp_payload_size;
} GvspDataLeader;
typedef struct {
unsigned int payload_type;
unsigned int data0;
} GvspDataTrailer;
typedef struct {
GvspHeader header;
unsigned char data[1];
} GvspPacket;
typedef struct
{
AsyncQueue *in_buffer;
AsyncQueue *out_buffer;
}StreamDataBuffer;
typedef struct {
int received; //是否收到包的布尔量
long long time_us; //重发该包请求的时间
} StreamPacketData;
typedef struct {
PhotoInfo *buffer;
unsigned int block_id;
int buffer_status; //当前包的状态最好并入到PhotoInfo中发便用户层查看
int last_valid_packet; //连续的有效包中的最后一包,用于重发时检查的起点
long long first_packet_time_us; //收到首包的时间,用于后面的统计
long long last_packet_time_us; //收到最后一包的时间,在完整性检查是查看是否超时
int error_packet_received; //收到错误包,以此决定是不是可以将此包送到用户层
int packet_resend_num; //每次重发包的次数避免过多重发包请求干扰正常的GVCP通信。
unsigned int n_packets; //一个block的总包数
StreamPacketData *packet_data; //每包的信息
} StreamBlockData;
class GigeStream
{
public:
GigeStream(DataStreamPrivateInfo *stream_private_info,
unsigned short channel_index,
int gvsp_socket_id,
int interface_address,
int device_address,
int source_stream_port,
int stream_port,
int packet_size,
long long timestamp_tick_frequency,
cameralog *logfile);
~GigeStream();
int Capture(PhotoInfo *buffer);
int TryCapture(PhotoInfo *buffer);
int TimeoutCapture(PhotoInfo *buffer, long long timeout);
void FlushBuffer();
int SetMaxBufferLength(unsigned int length);
int GetMaxBufferLength();
void SetPacketResendFlag(unsigned int flag);
int GetPacketResendFlag();
int SetPacketResendRatio(double ratio);
double GetPacketResendRatio();
int SetSocketSelectTimeout(unsigned int timeout);
int GetSocketSelectTimeout();
int SetPacketTimeout(unsigned int timeout);
int GetPacketTimeout();
int SetBlockTimeout(unsigned int timeout);
int GetBlockTimeout();
int SetSendtoStreamPortBreakFirewallTimeout(unsigned int timeout);
int GetSendtoStreamPortBreakFirewallTimeout();
//Statistics();
void GetBlockStatistics(
unsigned int *completed_buffers,
unsigned int *failures,
unsigned int *timeouts,
unsigned int *underruns,
unsigned int *aborteds,
unsigned int *missing_frames,
unsigned int *block_camera_wrong,
unsigned int *size_mismatch_errors);
void GetPacketStatistics(
unsigned int *received_packets,
unsigned int *missing_packets,
unsigned int *error_packets,
unsigned int *ignored_packets,
unsigned int *resend_requests,
unsigned int *resent_packets,
unsigned int *duplicated_packets);
void GetRecieveTimeStatistics(StatisticsData *o_statistics_data);
int GetNetSpeed();
float GetBlockRate();
int thread_exit;
private:
#ifdef _WIN32
//接收点云数据线程
static unsigned int _stdcall Stream_Thread(void* arg);
#else
static void* Stream_Thread(void* arg);
#endif
void loop();
StreamBlockData* process_packet(GvspPacket *packet, int recv_num, long long time_us);
StreamBlockData* find_block_data(GvspPacket *packet, unsigned int block_id, unsigned int packet_id, int recv_num, long long time_us);
void process_packet_leader(StreamBlockData *block, GvspPacket *packet, unsigned int packet_id);
void process_packet_payload(StreamBlockData *block, GvspPacket *packet, unsigned int packet_id, unsigned int recv_num);
void process_packet_tailer(StreamBlockData *block, GvspPacket *packet, unsigned int packet_id);
void packet_resend_check(StreamBlockData *block, unsigned int packet_id, long long time_us);
void send_packet_request(unsigned int block_id, int resend_first_packet_id, int resend_last_packet_id);
void write_recive_data(StreamBlockData *block);
void check_block_complete(StreamBlockData *block,long long time_us);
void capture_data_process(PhotoInfo *buffer, PhotoInfo *temp_buffer);
void flush_blocks();
void sendto_stream_source_data();
void RecieveTimeStatistics(int data);
void NetSpeedStatistics(int recv_num, long long time_us);
void BlockRateStatistics(long long time_us);
#ifdef _WIN32
HANDLE stream_on_thread_id;
#else
pthread_t stream_on_thread_id;
#endif
unsigned short channel_index_;
StreamDataBuffer stream_data;
StatisticsData statistics_data;
DataStreamPrivateInfo stream_private_info_;
List *all_blocks;
int gvsp_socket_id_;
int resend_socket_id_;
int interface_address_;
//int *interface_socket_address;
int device_address_;
//int *device_socket_address;
struct sockaddr_in resend_addr;
struct sockaddr_in sendto_source_addr;
unsigned short source_stream_port_;
unsigned short stream_port_;
long long timestamp_tick_frequency_;
unsigned short resend_req_id;
unsigned int last_block_id;
unsigned int max_buffer_length_;
unsigned int packet_payload_size_;
unsigned int max_payload_size_;
unsigned int current_buffer_length;
int packet_resend_flag_;
double packet_resend_ratio_;
unsigned int socket_select_timeout_us_;
unsigned int packet_timeout_us_;
unsigned int block_timeout_us_;
unsigned int sento_stream_source_time_us_;
/* Statistics */
//block部分的数据统计
unsigned int n_completed_buffers;
unsigned int n_failures;
unsigned int n_timeouts;
unsigned int n_underruns;
unsigned int n_aborteds;
unsigned int n_missing_frames;
unsigned int n_block_camera_wrong;
unsigned int n_size_mismatch_errors;
//packet部分的数据统计
unsigned int n_received_packets;
unsigned int n_missing_packets;
unsigned int n_error_packets;
unsigned int n_ignored_packets;
unsigned int n_resend_requests;
unsigned int n_resent_packets;
unsigned int n_duplicated_packets;
//网速部分的统计,这里主要是时间,这段时间收到的数据量和以此计算出来的网速;
long long n_start_time_us;
long long n_recv_num_unit_time;
unsigned int n_net_speed;
long long n_block_start_time_us;
unsigned int n_block_recv_num_unit_time;
float n_block_rate;
cameralog *logfilestream;
//重发包计时
time_t start_time_resend;
time_t end_time_resend;
};