static void _process_data_leader (ArvGvStreamThreadData *thread_data, ArvGvStreamFrameData *frame, ArvGvspPacket *packet, guint32 packet_id) { if (frame->buffer->priv->status != ARV_BUFFER_STATUS_FILLING) return; if (packet_id != 0) { frame->buffer->priv->status = ARV_BUFFER_STATUS_WRONG_PACKET_ID; return; } frame->buffer->priv->gvsp_payload_type = arv_gvsp_packet_get_payload_type (packet); frame->buffer->priv->frame_id = arv_gvsp_packet_get_frame_id (packet); if (frame->buffer->priv->gvsp_payload_type != ARV_GVSP_PAYLOAD_TYPE_H264) { if (G_LIKELY (thread_data->timestamp_tick_frequency != 0)) frame->buffer->priv->timestamp_ns = arv_gvsp_packet_get_timestamp (packet, thread_data->timestamp_tick_frequency); else { GTimeVal time; g_get_current_time (&time); frame->buffer->priv->timestamp_ns = ((guint64) time.tv_sec * 1000000000LL) + ((guint64) time.tv_usec * 1000) ; } } else frame->buffer->priv->timestamp_ns = g_get_real_time () * 1000LL; if (frame->buffer->priv->gvsp_payload_type == ARV_GVSP_PAYLOAD_TYPE_IMAGE) { frame->buffer->priv->x_offset = arv_gvsp_packet_get_x_offset (packet); frame->buffer->priv->y_offset = arv_gvsp_packet_get_y_offset (packet); frame->buffer->priv->width = arv_gvsp_packet_get_width (packet); frame->buffer->priv->height = arv_gvsp_packet_get_height (packet); frame->buffer->priv->pixel_format = arv_gvsp_packet_get_pixel_format (packet); } if (frame->packet_data[packet_id].time_us > 0) { thread_data->n_resent_packets++; arv_log_stream_thread ("[GvStream::_process_data_leader] Received resent packet %u for frame %u", packet_id, frame->frame_id); } }
static void * arv_gv_stream_thread (void *data) { ArvGvStreamThreadData *thread_data = data; ArvGvStreamFrameData *frame; ArvGvspPacket *packet; guint32 packet_id; guint32 frame_id; GTimeVal current_time; guint64 time_us; GPollFD poll_fd; size_t read_count; int timeout_ms; int n_events; int i; gboolean first_packet = TRUE; thread_data->frames = NULL; arv_debug_stream_thread ("[GvStream::stream_thread] Packet timeout = %g ms", thread_data->packet_timeout_us / 1000.0); arv_debug_stream_thread ("[GvStream::stream_thread] Frame retention = %g ms", thread_data->frame_retention_us / 1000.0); if (thread_data->callback != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_INIT, NULL); poll_fd.fd = g_socket_get_fd (thread_data->socket); poll_fd.events = G_IO_IN; poll_fd.revents = 0; packet = g_malloc0 (ARV_GV_STREAM_INCOMING_BUFFER_SIZE); do { if (thread_data->frames != NULL) timeout_ms = thread_data->packet_timeout_us / 1000; else timeout_ms = ARV_GV_STREAM_POLL_TIMEOUT_US / 1000; n_events = g_poll (&poll_fd, 1, timeout_ms); g_get_current_time (¤t_time); time_us = current_time.tv_sec * 1000000 + current_time.tv_usec; if (n_events > 0) { thread_data->n_received_packets++; read_count = g_socket_receive (thread_data->socket, (char *) packet, ARV_GV_STREAM_INCOMING_BUFFER_SIZE, NULL, NULL); frame_id = arv_gvsp_packet_get_frame_id (packet); packet_id = arv_gvsp_packet_get_packet_id (packet); if (first_packet) { thread_data->last_frame_id = frame_id - 1; first_packet = FALSE; } frame = _find_frame_data (thread_data, frame_id, packet, packet_id, read_count, time_us); if (frame != NULL) { ArvGvspPacketType packet_type = arv_gvsp_packet_get_packet_type (packet); if (packet_type != ARV_GVSP_PACKET_TYPE_OK && packet_type != ARV_GVSP_PACKET_TYPE_RESEND) { arv_debug_stream_thread ("[GvStream::stream_thread]" " Error packet at dt = %" G_GINT64_FORMAT ", packet id = %u" " frame id = %u", time_us - frame->first_packet_time_us, packet_id, frame->frame_id); arv_gvsp_packet_debug (packet, read_count, ARV_DEBUG_LEVEL_DEBUG); frame->error_packet_received = TRUE; thread_data->n_error_packets++; } else { /* Check for duplicated packets */ if (packet_id < frame->n_packets) { if (frame->packet_data[packet_id].received) thread_data->n_duplicated_packets++; else frame->packet_data[packet_id].received = TRUE; } /* Keep track of last packet of a continuous block starting from packet 0 */ for (i = frame->last_valid_packet + 1; i < frame->n_packets; i++) if (!frame->packet_data[i].received) break; frame->last_valid_packet = i - 1; switch (arv_gvsp_packet_get_content_type (packet)) { case ARV_GVSP_CONTENT_TYPE_DATA_LEADER: _process_data_leader (thread_data, frame, packet, packet_id); break; case ARV_GVSP_CONTENT_TYPE_DATA_BLOCK: _process_data_block (thread_data, frame, packet, packet_id, read_count); break; case ARV_GVSP_CONTENT_TYPE_DATA_TRAILER: _process_data_trailer (thread_data, frame, packet, packet_id); break; default: thread_data->n_ignored_packets++; break; } _missing_packet_check (thread_data, frame, packet_id, time_us); } } else thread_data->n_ignored_packets++; } else frame = NULL; _check_frame_completion (thread_data, time_us, frame); } while (!thread_data->cancel); _flush_frames (thread_data); if (thread_data->callback != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_EXIT, NULL); g_free (packet); return NULL; }