[aravis/timeout-resend: 4/4] gv_stream: track received packets for more than one frame.



commit 5a8d8740d53456a5e7b8f2568efa59fce8d913dd
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Tue Mar 1 11:16:03 2011 +0100

    gv_stream: track received packets for more than one frame.
    
    This is a preparatory work for the ability to do multiple packet resends,
    and to be able to receive late packets (ie: packets arriving after the
    beginning of a new frame).

 src/arvbuffer.h   |    7 +-
 src/arvgvstream.c |  358 +++++++++++++++++++++++++++++++++--------------------
 src/arvgvstream.h |    5 +-
 3 files changed, 228 insertions(+), 142 deletions(-)
---
diff --git a/src/arvbuffer.h b/src/arvbuffer.h
index 1e616c6..1d168da 100644
--- a/src/arvbuffer.h
+++ b/src/arvbuffer.h
@@ -33,7 +33,8 @@ typedef void (*ArvFrameCallback)	(ArvBuffer *buffer);
  * ArvBufferStatus:
  * @ARV_BUFFER_STATUS_SUCCESS: the buffer contains a valid image
  * @ARV_BUFFER_STATUS_CLEARED: the buffer is cleared
- * @ARV_BUFFER_STATUS_MISSING_BLOCKS: image has missing blocks
+ * @ARV_BUFFER_STATUS_MISSING_PACKETS: stream has missing packets
+ * @ARV_BUFFER_STATUS_WRONG_PACKET_ID: stream has packet with wrong id
  * @ARV_BUFFER_STATUS_SIZE_MISMATCH: the received image didn't fit in the buffer data space
  * @ARV_BUFFER_STATUS_FILLING: the image is currently being filled
  * @ARV_BUFFER_STATUS_ABORTED: the filling was aborted before completion
@@ -42,7 +43,9 @@ typedef void (*ArvFrameCallback)	(ArvBuffer *buffer);
 typedef enum {
 	ARV_BUFFER_STATUS_SUCCESS,
 	ARV_BUFFER_STATUS_CLEARED,
-	ARV_BUFFER_STATUS_MISSING_BLOCKS,
+	ARV_BUFFER_STATUS_TIMEOUT,
+	ARV_BUFFER_STATUS_MISSING_PACKETS,
+	ARV_BUFFER_STATUS_WRONG_PACKET_ID,
 	ARV_BUFFER_STATUS_SIZE_MISMATCH,
 	ARV_BUFFER_STATUS_FILLING,
 	ARV_BUFFER_STATUS_ABORTED
diff --git a/src/arvgvstream.c b/src/arvgvstream.c
index 53e2d33..5738faf 100644
--- a/src/arvgvstream.c
+++ b/src/arvgvstream.c
@@ -1,6 +1,6 @@
 /* Aravis - Digital camera library
  *
- * Copyright © 2009-2010 Emmanuel Pacaud
+ * Copyright © 2009-2011 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,6 +36,7 @@
 #include <sys/socket.h>
 
 #define ARV_GV_STREAM_INCOMING_BUFFER_SIZE	65536
+#define ARV_GV_STREAM_THREAD_N_FRAMES		2
 
 enum {
 	ARV_GV_STREAM_PROPERTY_0,
@@ -49,15 +50,19 @@ static GObjectClass *parent_class = NULL;
 /* Acquisition thread */
 
 typedef struct {
+	gboolean received;
+	guint	n_requests;
+} ArvGvStreamPacketData;
+
+typedef struct {
 	ArvBuffer *buffer;
-	size_t read_data_size;
-	gint32 n_missing_blocks;
-	gint32 n_late_blocks;
-	gint32 last_block_size;
-	gint32 last_packet_id;
-	gint64 last_time_us;
-	guint64 last_timestamp_ns;
-	guint32 statistic_count;
+	guint frame_id;
+
+	gint last_valid_packet;
+
+	guint n_packets;
+	ArvGvStreamPacketData *packet_data;
+
 	gint64 leader_time_us;
 } ArvGvStreamFrameData;
 
@@ -73,7 +78,7 @@ typedef struct {
 	ArvGvStreamPacketResend packet_resend;
 
 	guint64 timestamp_tick_frequency;
-	guint packet_size;
+	guint data_size;
 
 	gboolean cancel;
 
@@ -83,15 +88,18 @@ typedef struct {
 
 	guint n_completed_buffers;
 	guint n_failures;
+	guint n_timeouts;
 	guint n_underruns;
 	guint n_aborteds;
 	guint n_size_mismatch_errors;
 
-	guint n_resent_blocks;
-	guint n_missing_blocks;
-	guint n_late_blocks;
+	guint n_resend_requests;
+	guint n_resent_packets;
+	guint n_missing_packets;
+	guint n_duplicated_packets;
 
 	ArvStatistic *statistic;
+	guint32 statistic_count;
 
 	ArvGvStreamSocketBuffer socket_buffer_option;
 	int socket_buffer_size;
@@ -110,7 +118,7 @@ _send_packet_request (ArvGvStreamThreadData *thread_data,
 	packet = arv_gvcp_packet_new_packet_resend_cmd (frame_id, first_block, last_block,
 							thread_data->packet_count++, &packet_size);
 
-	arv_debug ("stream-thread", "[GvStream::send_packet_request] frame_id = %d (%d - %d)",
+	arv_debug ("stream-thread", "[GvStream::send_packet_request] frame_id = %u (%d - %d)",
 		   frame_id, first_block, last_block);
 
 	arv_gvcp_packet_debug (packet);
@@ -157,16 +165,23 @@ _close_buffer (ArvGvStreamThreadData *thread_data, ArvGvStreamFrameData *frame)
 {
 	GTimeVal current_time;
 	gint64 current_time_us;
+	int i;
+	guint n_missing_packets = 0;
 
 	if (frame->buffer == NULL)
 		return;
 
 	if (frame->buffer->status == ARV_BUFFER_STATUS_FILLING) {
-	       if (frame->read_data_size == frame->buffer->size &&
-		   frame->n_missing_blocks == 0)
-		       frame->buffer->status = ARV_BUFFER_STATUS_SUCCESS;
-	       else
-		       frame->buffer->status = ARV_BUFFER_STATUS_MISSING_BLOCKS;
+		for (i = 0; i < frame->n_packets; i++)
+			if (!frame->packet_data[i].received)
+				n_missing_packets++;
+
+		thread_data->n_missing_packets += n_missing_packets;
+
+		if (n_missing_packets == 0)
+			frame->buffer->status = ARV_BUFFER_STATUS_SUCCESS;
+		else
+			frame->buffer->status = ARV_BUFFER_STATUS_MISSING_PACKETS;
 	}
 
 	if (frame->buffer->status == ARV_BUFFER_STATUS_SUCCESS)
@@ -177,6 +192,9 @@ _close_buffer (ArvGvStreamThreadData *thread_data, ArvGvStreamFrameData *frame)
 	if (frame->buffer->status == ARV_BUFFER_STATUS_ABORTED)
 		thread_data->n_aborteds++;
 
+	if (frame->buffer->status == ARV_BUFFER_STATUS_TIMEOUT)
+		thread_data->n_timeouts++;
+
 	if (frame->buffer->status == ARV_BUFFER_STATUS_SIZE_MISMATCH)
 		thread_data->n_size_mismatch_errors++;
 
@@ -187,25 +205,17 @@ _close_buffer (ArvGvStreamThreadData *thread_data, ArvGvStreamFrameData *frame)
 
 	g_get_current_time (&current_time);
 	current_time_us = current_time.tv_sec * 1000000 + current_time.tv_usec;
-	if (frame->statistic_count > 5) {
-		arv_statistic_fill (thread_data->statistic, 0,
-				    (frame->buffer->timestamp_ns - frame->last_timestamp_ns) /
-				    1000, frame->buffer->frame_id);
+	if (thread_data->statistic_count > 5) {
 		arv_statistic_fill (thread_data->statistic, 1,
-				    current_time_us - frame->last_time_us,
-				    frame->buffer->frame_id);
-		arv_statistic_fill (thread_data->statistic, 2,
 				    current_time_us - frame->leader_time_us,
 				    frame->buffer->frame_id);
 	} else
-		frame->statistic_count++;
-
-	frame->last_time_us = current_time_us;
-	frame->last_timestamp_ns = frame->buffer->timestamp_ns;
+		thread_data->statistic_count++;
 
 	arv_stream_push_output_buffer (thread_data->stream, frame->buffer);
 
 	frame->buffer = NULL;
+	frame->frame_id = 0;
 }
 
 static void
@@ -213,19 +223,18 @@ _process_data_leader (ArvGvStreamThreadData *thread_data,
 		      ArvGvStreamFrameData *frame,
 		      ArvGvspPacket *packet)
 {
-	GTimeVal current_time;
+	guint32 packet_id;
 
-	if (frame->buffer != NULL)
-		_close_buffer (thread_data, frame);
+	if (frame->buffer == NULL)
+		return;
 
-	frame->buffer = arv_stream_pop_input_buffer (thread_data->stream);
-	if (frame->buffer == NULL) {
-		thread_data->n_underruns++;
+	packet_id = arv_gvsp_packet_get_packet_id (packet);
+	if (packet_id != 0) {
+		frame->buffer->status = ARV_BUFFER_STATUS_WRONG_PACKET_ID;
+		_close_buffer (thread_data, frame);
 		return;
 	}
 
-	_update_socket (thread_data, frame->buffer);
-
 	frame->buffer->x_offset = arv_gvsp_packet_get_x_offset (packet);
 	frame->buffer->y_offset = arv_gvsp_packet_get_y_offset (packet);
 	frame->buffer->width = arv_gvsp_packet_get_width (packet);
@@ -236,19 +245,11 @@ _process_data_leader (ArvGvStreamThreadData *thread_data,
 	frame->buffer->timestamp_ns = arv_gvsp_packet_get_timestamp (packet,
 								     thread_data->timestamp_tick_frequency);
 
-	frame->buffer->status = ARV_BUFFER_STATUS_FILLING;
-	frame->read_data_size = 0;
-	frame->n_missing_blocks = 0;
-	frame->last_block_size = 0;
-	frame->last_packet_id = 0;
-
-	g_get_current_time (&current_time);
-	frame->leader_time_us = current_time.tv_sec * 1000000 + current_time.tv_usec;
+	if (frame->packet_data[packet_id].n_requests > 0)
+		thread_data->n_resent_packets++;
 
-	if (thread_data->callback != NULL)
-		thread_data->callback (thread_data->user_data,
-				       ARV_STREAM_CALLBACK_TYPE_START_BUFFER,
-				       frame->buffer);
+	if (frame->last_valid_packet == frame->n_packets - 1)
+		_close_buffer (thread_data, frame);
 }
 
 static void
@@ -266,88 +267,167 @@ _process_data_block (ArvGvStreamThreadData *thread_data,
 	    frame->buffer->status != ARV_BUFFER_STATUS_FILLING)
 		return;
 
-	if (frame->buffer->frame_id != arv_gvsp_packet_get_frame_id (packet)) {
-		thread_data->n_late_blocks ++;
-		return;
-	}
-
 	packet_id = arv_gvsp_packet_get_packet_id (packet);
-	if (packet_id <= frame->last_packet_id) {
-		arv_debug ("stream-thread", "[GvStream::thread] Receive resent packet (%d) frame %d",
-			   packet_id, frame->buffer->frame_id);
-
-		block_size = arv_gvsp_packet_get_data_size (read_count);
-		block_offset = frame->last_block_size * (packet_id - 1);
-		block_end = block_size + block_offset;
-
-		if (block_end  > frame->buffer->size) {
-			arv_gvsp_packet_debug (packet, read_count);
-			frame->buffer->status = ARV_BUFFER_STATUS_SIZE_MISMATCH;
-			return;
-		}
-		memcpy (frame->buffer->data + block_offset, &packet->data, block_size);
-
-		frame->read_data_size += block_size;
-		frame->n_missing_blocks--;
-		thread_data->n_resent_blocks++;
-		return;
-	}
-
-	if (packet_id != (frame->last_packet_id + 1)) {
-		gint32 n_misses;
-
-		n_misses = packet_id - frame->last_packet_id - 1;
-
+	if (packet_id > frame->n_packets - 2) {
 		arv_gvsp_packet_debug (packet, read_count);
-		arv_debug ("stream-thread", "[GvStream::thread] Missing block (expected %d - %d) frame %d",
-			   frame->last_packet_id + 1,
-			   packet_id, frame->buffer->frame_id);
-		thread_data->n_missing_blocks += n_misses;
-		frame->n_missing_blocks += n_misses;
-
-		if (thread_data->packet_resend != ARV_GV_STREAM_PACKET_RESEND_NEVER)
-			_send_packet_request (thread_data, frame->buffer->frame_id,
-					      frame->last_packet_id + 1, packet_id - 1);
+		frame->buffer->status = ARV_BUFFER_STATUS_WRONG_PACKET_ID;
+		_close_buffer (thread_data, frame);
+		return;
 	}
 
 	block_size = arv_gvsp_packet_get_data_size (read_count);
-	block_offset = frame->last_block_size * (packet_id - 1);
+	block_offset = (packet_id - 1) * thread_data->data_size;
 	block_end = block_size + block_offset;
 
-	if (block_end  > frame->buffer->size) {
+	if (block_end > frame->buffer->size) {
 		arv_gvsp_packet_debug (packet, read_count);
 		frame->buffer->status = ARV_BUFFER_STATUS_SIZE_MISMATCH;
+		_close_buffer (thread_data, frame);
 		return;
 	}
+
 	memcpy (frame->buffer->data + block_offset, &packet->data, block_size);
 
-	frame->read_data_size += block_size;
-	frame->last_block_size = block_size;
-	frame->last_packet_id =  packet_id;
+	if (frame->packet_data[packet_id].n_requests > 0)
+		thread_data->n_resent_packets++;
+
+	if (frame->last_valid_packet == frame->n_packets - 1)
+		_close_buffer (thread_data, frame);
 }
 
 static void
-_process_data_trailer (ArvGvStreamThreadData *thread_data, ArvGvStreamFrameData *frame)
+_process_data_trailer (ArvGvStreamThreadData *thread_data,
+		       ArvGvStreamFrameData *frame,
+		       ArvGvspPacket *packet)
 {
+	guint32 packet_id;
+
 	if (frame->buffer == NULL)
 		return;
 
-	if (frame->read_data_size < frame->buffer->size)
+	packet_id = arv_gvsp_packet_get_packet_id (packet);
+	if (packet_id != frame->n_packets - 1) {
+		frame->buffer->status = ARV_BUFFER_STATUS_WRONG_PACKET_ID;
+		_close_buffer (thread_data, frame);
 		return;
+	}
 
-	_close_buffer (thread_data, frame);
+	if (frame->packet_data[packet_id].n_requests > 0)
+		thread_data->n_resent_packets++;
+
+	if (frame->last_valid_packet == frame->n_packets - 1)
+		_close_buffer (thread_data, frame);
+}
+
+static void
+_update_frame_data (ArvGvStreamThreadData *thread_data, ArvGvStreamFrameData *frame,
+		    ArvGvspPacket *packet, size_t read_count)
+{
+	GTimeVal current_time;
+	guint frame_id;
+	guint n_packets;
+	int packet_id;
+	int i;
+
+	frame_id = arv_gvsp_packet_get_frame_id (packet);
+
+	if (frame->buffer != NULL && frame->frame_id != frame_id) {
+		frame->buffer->status = ARV_BUFFER_STATUS_TIMEOUT;
+		_close_buffer (thread_data, frame);
+	}
+
+	if (frame->buffer == NULL) {
+		frame->buffer = arv_stream_pop_input_buffer (thread_data->stream);
+		if (frame->buffer == NULL) {
+			thread_data->n_underruns++;
+			return;
+		}
+
+		_update_socket (thread_data, frame->buffer);
+
+		frame->frame_id = frame_id;
+		frame->last_valid_packet = -1;
+		frame->buffer->status = ARV_BUFFER_STATUS_FILLING;
+
+		g_get_current_time (&current_time);
+		frame->leader_time_us = current_time.tv_sec * 1000000 + current_time.tv_usec;
+
+		n_packets = (frame->buffer->size + thread_data->data_size - 1) / thread_data->data_size + 2;
+		if (frame->n_packets != n_packets) {
+			g_free (frame->packet_data);
+			frame->packet_data = g_new (ArvGvStreamPacketData, n_packets);
+			frame->n_packets = n_packets;
+
+			arv_debug ("stream", "[GvStream::_update_frame_data] n_packets = %d", frame->n_packets);
+		}
+
+		memset (frame->packet_data, 0, sizeof (ArvGvStreamPacketData) * frame->n_packets);
+
+		if (thread_data->callback != NULL)
+			thread_data->callback (thread_data->user_data,
+					       ARV_STREAM_CALLBACK_TYPE_START_BUFFER,
+					       NULL);
+	}
+
+	packet_id = arv_gvsp_packet_get_packet_id (packet);
+	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;
+	}
+
+	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;
+
+	if (packet_id < frame->n_packets) {
+		int first_missing = -1;
+
+		for (i = frame->last_valid_packet + 1; i < packet_id; i++) {
+			if (!frame->packet_data[i].received &&
+			    frame->packet_data[i].n_requests == 0) {
+				if (first_missing < 0)
+					first_missing = i;
+			} else
+				if (first_missing >= 0) {
+					int j;
+
+					_send_packet_request (thread_data, frame->frame_id,
+							      first_missing, i - 1);
+					for (j = first_missing; j < i; j++)
+						frame->packet_data[j].n_requests = 1;
+					thread_data->n_resend_requests += (i - first_missing);
+
+					first_missing = -1;
+				}
+		}
+
+		if (first_missing >= 0) {
+			int j;
+
+			_send_packet_request (thread_data, frame->frame_id,
+					      first_missing, i - 1);
+			for (j = first_missing; j < i; j++)
+				frame->packet_data[j].n_requests = 1;
+			thread_data->n_resend_requests += (i - first_missing);
+		}
+	}
 }
 
 static void *
 arv_gv_stream_thread (void *data)
 {
 	ArvGvStreamThreadData *thread_data = data;
-	ArvGvStreamFrameData frame;
+	ArvGvStreamFrameData frames[ARV_GV_STREAM_THREAD_N_FRAMES];
+	ArvGvStreamFrameData *frame;
 	ArvGvspPacket *packet;
-	GTimeVal current_time;
+	guint frame_id;
 	GPollFD poll_fd;
 	size_t read_count;
 	int n_events;
+	int i;
 
 	if (thread_data->callback != NULL)
 		thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_INIT, NULL);
@@ -358,14 +438,7 @@ arv_gv_stream_thread (void *data)
 
 	packet = g_malloc0 (ARV_GV_STREAM_INCOMING_BUFFER_SIZE);
 
-	frame.buffer = NULL;
-	frame.n_missing_blocks = 0;
-	frame.last_block_size = 0;
-	frame.last_packet_id = 0;
-	frame.statistic_count = 0;
-	g_get_current_time (&current_time);
-	frame.last_time_us = current_time.tv_sec * 1000000 + current_time.tv_usec;
-	frame.last_timestamp_ns = 0;
+	memset (frames, 0, sizeof (ArvGvStreamFrameData) * ARV_GV_STREAM_THREAD_N_FRAMES);
 
 	do {
 		n_events = g_poll (&poll_fd, 1, 1000);
@@ -374,25 +447,33 @@ arv_gv_stream_thread (void *data)
 			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);
+			frame = &frames[frame_id % ARV_GV_STREAM_THREAD_N_FRAMES];
+
+			_update_frame_data (thread_data, frame, packet, read_count);
+
 			switch (arv_gvsp_packet_get_packet_type (packet)) {
 				case ARV_GVSP_PACKET_TYPE_DATA_LEADER:
-					_process_data_leader (thread_data, &frame, packet);
+					_process_data_leader (thread_data, frame, packet);
 					break;
 
 				case ARV_GVSP_PACKET_TYPE_DATA_BLOCK:
-					_process_data_block (thread_data, &frame, packet, read_count);
+					_process_data_block (thread_data, frame, packet, read_count);
 					break;
 
 				case ARV_GVSP_PACKET_TYPE_DATA_TRAILER:
-					_process_data_trailer (thread_data, &frame);
+					_process_data_trailer (thread_data, frame, packet);
 					break;
 			}
 		}
 	} while (!thread_data->cancel);
 
-	if (frame.buffer != NULL) {
-		frame.buffer->status = ARV_BUFFER_STATUS_ABORTED;
-		_close_buffer (thread_data, &frame);
+	for (i = 0; i < ARV_GV_STREAM_THREAD_N_FRAMES; i++) {
+		if (frames[i].buffer != NULL) {
+			frames[i].buffer->status = ARV_BUFFER_STATUS_ABORTED;
+			_close_buffer (thread_data, &frames[i]);
+		}
+		g_free (frames[i].packet_data);
 	}
 
 	if (thread_data->callback != NULL)
@@ -429,7 +510,7 @@ arv_gv_stream_new (GInetAddress *device_address, guint16 port,
 	ArvGvStreamThreadData *thread_data;
 
 	g_return_val_if_fail (G_IS_INET_ADDRESS (device_address), NULL);
-	g_return_val_if_fail (packet_size > 0, NULL);
+	g_return_val_if_fail (packet_size > (20 + 8 + 8) /* FIXME IP + UDP + GVSP headers */, NULL);
 
 	gv_stream = g_object_new (ARV_TYPE_GV_STREAM, NULL);
 
@@ -453,7 +534,7 @@ arv_gv_stream_new (GInetAddress *device_address, guint16 port,
 	thread_data->device_address = g_inet_socket_address_new (device_address, ARV_GVCP_PORT);
 	thread_data->packet_resend = ARV_GV_STREAM_PACKET_RESEND_ALWAYS;
 	thread_data->timestamp_tick_frequency = timestamp_tick_frequency;
-	thread_data->packet_size = packet_size;
+	thread_data->data_size = packet_size - (20 + 8 + 8) /* FIXME IP + UDP + GVSP headers */;
 	thread_data->cancel = FALSE;
 
 	thread_data->packet_count = 1;
@@ -462,16 +543,18 @@ arv_gv_stream_new (GInetAddress *device_address, guint16 port,
 	thread_data->n_failures = 0;
 	thread_data->n_underruns = 0;
 	thread_data->n_size_mismatch_errors = 0;
-	thread_data->n_missing_blocks = 0;
-	thread_data->n_resent_blocks = 0;
-	thread_data->n_late_blocks = 0;
+	thread_data->n_missing_packets = 0;
+	thread_data->n_resent_packets = 0;
+	thread_data->n_resend_requests = 0;
+	thread_data->n_duplicated_packets = 0;
 	thread_data->n_aborteds = 0;
+	thread_data->n_timeouts = 0;
 
-	thread_data->statistic = arv_statistic_new (3, 5000, 200, 0);
+	thread_data->statistic = arv_statistic_new (2, 5000, 200, 0);
+	thread_data->statistic_count = 0;
 
 	arv_statistic_set_name (thread_data->statistic, 0, "Timestamp delta");
-	arv_statistic_set_name (thread_data->statistic, 1, "Local time delta");
-	arv_statistic_set_name (thread_data->statistic, 2, "Buffer reception time");
+	arv_statistic_set_name (thread_data->statistic, 1, "Buffer reception time");
 
 	thread_data->socket_buffer_option = ARV_GV_STREAM_SOCKET_BUFFER_FIXED;
 	thread_data->socket_buffer_size = 0;
@@ -488,9 +571,8 @@ arv_gv_stream_new (GInetAddress *device_address, guint16 port,
 
 void
 arv_gv_stream_get_statistics (ArvGvStream *gv_stream,
-			      guint64 *n_resent_blocks,
-			      guint64 *n_missing_blocks,
-			      guint64 *n_late_blocks)
+			      guint64 *n_resent_packets,
+			      guint64 *n_missing_packets)
 
 {
 	ArvGvStreamThreadData *thread_data;
@@ -499,12 +581,10 @@ arv_gv_stream_get_statistics (ArvGvStream *gv_stream,
 
 	thread_data = gv_stream->thread_data;
 
-	if (n_resent_blocks != NULL)
-		*n_resent_blocks = thread_data->n_resent_blocks;
-	if (n_missing_blocks != NULL)
-		*n_missing_blocks = thread_data->n_missing_blocks;
-	if (n_late_blocks != NULL)
-		*n_late_blocks = thread_data->n_late_blocks;
+	if (n_resent_packets != NULL)
+		*n_resent_packets = thread_data->n_resent_packets;
+	if (n_missing_packets != NULL)
+		*n_missing_packets = thread_data->n_missing_packets;
 }
 
 static void
@@ -589,25 +669,29 @@ arv_gv_stream_finalize (GObject *object)
 
 		thread_data = gv_stream->thread_data;
 
+		thread_data->cancel = TRUE;
+		g_thread_join (gv_stream->thread);
+
 		arv_debug ("stream",
 			   "[GvStream::finalize] n_completed_buffers    = %d", thread_data->n_completed_buffers);
 		arv_debug ("stream",
 			   "[GvStream::finalize] n_failures             = %d", thread_data->n_failures);
 		arv_debug ("stream",
+			   "[GvStream::finalize] n_timeouts             = %d", thread_data->n_timeouts);
+		arv_debug ("stream",
 			   "[GvStream::finalize] n_aborteds             = %d", thread_data->n_aborteds);
 		arv_debug ("stream",
 			   "[GvStream::finalize] n_underruns            = %d", thread_data->n_underruns);
 		arv_debug ("stream",
 			   "[GvStream::finalize] n_size_mismatch_errors = %d", thread_data->n_size_mismatch_errors);
 		arv_debug ("stream",
-			   "[GvStream::finalize] n_missing_blocks       = %d", thread_data->n_missing_blocks);
+			   "[GvStream::finalize] n_missing_packets      = %d", thread_data->n_missing_packets);
 		arv_debug ("stream",
-			   "[GvStream::finalize] n_resent_blocks        = %d", thread_data->n_resent_blocks);
+			   "[GvStream::finalize] n_resend_requests      = %d", thread_data->n_resend_requests);
 		arv_debug ("stream",
-			   "[GvStream::finalize] n_late_blocks          = %d", thread_data->n_late_blocks);
-
-		thread_data->cancel = TRUE;
-		g_thread_join (gv_stream->thread);
+			   "[GvStream::finalize] n_resent_packets       = %d", thread_data->n_resent_packets);
+		arv_debug ("stream",
+			   "[GvStream::finalize] n_duplicated_packets   = %d", thread_data->n_duplicated_packets);
 
 		g_object_unref (thread_data->device_address);
 
diff --git a/src/arvgvstream.h b/src/arvgvstream.h
index f614fb2..257c5c4 100644
--- a/src/arvgvstream.h
+++ b/src/arvgvstream.h
@@ -83,9 +83,8 @@ ArvStream * 	arv_gv_stream_new			(GInetAddress *device_address, guint16 port,
 guint16 	arv_gv_stream_get_port			(ArvGvStream *gv_stream);
 
 void		arv_gv_stream_get_statistics		(ArvGvStream *gv_stream,
-							 guint64 *n_resent_blocks,
-							 guint64 *n_missing_blocks,
-							 guint64 *n_late_blocks);
+							 guint64 *n_resent_packets,
+							 guint64 *n_missing_packets);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]