259 lines
8.8 KiB
C++
259 lines
8.8 KiB
C++
#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;
|
||
};
|
||
|