#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; };