Ejemplo n.º 1
0
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);
	}
}
Ejemplo n.º 2
0
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 (&current_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;
}