[aravis] gv_stream: handle frame ledaer timestamp.



commit d59e863e62f8168f5b9d221b8f26da6a3799f5ca
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Mon May 10 14:48:25 2010 +0200

    gv_stream: handle frame ledaer timestamp.

 src/arvbuffer.h   |    2 ++
 src/arvgvcp.h     |    4 ++++
 src/arvgvdevice.c |   27 ++++++++++++++++++++++++++-
 src/arvgvdevice.h |    4 +++-
 src/arvgvsp.h     |   26 +++++++++++++++++++++++++-
 src/arvgvstream.c |   24 +++++++++++++++++++++---
 src/arvgvstream.h |    3 ++-
 7 files changed, 83 insertions(+), 7 deletions(-)
---
diff --git a/src/arvbuffer.h b/src/arvbuffer.h
index a1b982e..6b8128a 100644
--- a/src/arvbuffer.h
+++ b/src/arvbuffer.h
@@ -62,6 +62,8 @@ struct _ArvBuffer {
 	guint32 width;
 	guint32 height;
 	ArvPixelFormat pixel_format;
+
+	guint64 timestamp_ns;
 };
 
 struct _ArvBufferClass {
diff --git a/src/arvgvcp.h b/src/arvgvcp.h
index e03276f..dd2a55d 100644
--- a/src/arvgvcp.h
+++ b/src/arvgvcp.h
@@ -47,6 +47,10 @@ G_BEGIN_DECLS
 #define ARV_GVBS_SECOND_XML_URL				0x00000400
 #define ARV_GVBS_XML_URL_SIZE				512
 
+#define ARV_GVBS_HEARTBEAT_TIMEOUT			0x00000938
+#define ARV_GVBS_TIMESTAMP_TICK_FREQUENCY_HIGH		0x0000093c
+#define ARV_GVBS_TIMESTAMP_TICK_FREQUENCY_LOW		0x00000940
+
 #define ARV_GVBS_CONTROL_CHANNEL_PRIVILEGE		0x00000a00
 #define ARV_GVBS_FIRST_STREAM_CHANNEL_PORT		0x00000d00
 #define ARV_GVBS_FIRST_STREAM_CHANNEL_PACKET_SIZE	0x00000d04
diff --git a/src/arvgvdevice.c b/src/arvgvdevice.c
index 8baac45..0b1d20a 100644
--- a/src/arvgvdevice.c
+++ b/src/arvgvdevice.c
@@ -301,6 +301,30 @@ arv_gv_device_leave_control (ArvGvDevice *gv_device)
 	return result;
 }
 
+guint64
+arv_gv_device_get_timestamp_tick_frequency (ArvGvDevice *gv_device)
+{
+	guint32 timestamp_tick_frequency_high;
+	guint32 timestamp_tick_frequency_low;
+
+	g_return_val_if_fail (ARV_IS_GV_DEVICE (gv_device), 0);
+
+	if (arv_device_read_register (ARV_DEVICE (gv_device),
+				      ARV_GVBS_TIMESTAMP_TICK_FREQUENCY_HIGH,
+				      &timestamp_tick_frequency_high) &&
+	    arv_device_read_register (ARV_DEVICE (gv_device),
+				      ARV_GVBS_TIMESTAMP_TICK_FREQUENCY_LOW,
+				      &timestamp_tick_frequency_low)) {
+		guint64 timestamp_tick_frequency;
+
+		timestamp_tick_frequency = ((guint64) timestamp_tick_frequency_high << 32) |
+			timestamp_tick_frequency_low;
+		return timestamp_tick_frequency;
+	}
+
+	return 0;
+}
+
 static char *
 _load_genicam (ArvGvDevice *gv_device, guint32 address, size_t  *size)
 {
@@ -419,7 +443,8 @@ arv_gv_device_new_stream (ArvDevice *device, ArvStreamCallback callback, void *u
 	device_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (io_data->device_address));
 	address_bytes = g_inet_address_to_bytes (interface_address);
 
-	stream = arv_gv_stream_new (device_address, 0, callback, user_data);
+	stream = arv_gv_stream_new (device_address, 0, callback, user_data,
+				    arv_gv_device_get_timestamp_tick_frequency (gv_device));
 
 	stream_port = arv_gv_stream_get_port (ARV_GV_STREAM (stream));
 
diff --git a/src/arvgvdevice.h b/src/arvgvdevice.h
index c354aca..e67bb39 100644
--- a/src/arvgvdevice.h
+++ b/src/arvgvdevice.h
@@ -56,7 +56,9 @@ struct _ArvGvDeviceClass {
 
 GType arv_gv_device_get_type (void);
 
-ArvDevice * 		arv_gv_device_new 		(GInetAddress *interface_address, GInetAddress *device_address);
+ArvDevice * 	arv_gv_device_new 	(GInetAddress *interface_address, GInetAddress *device_address);
+
+guint64 	arv_gv_device_get_timestamp_tick_frequency 	(ArvGvDevice *gv_device);
 
 G_END_DECLS
 
diff --git a/src/arvgvsp.h b/src/arvgvsp.h
index 4698db2..124dc1e 100644
--- a/src/arvgvsp.h
+++ b/src/arvgvsp.h
@@ -41,7 +41,8 @@ typedef struct {
 
 typedef struct {
 	guint32 data0;
-	guint64 timestamp;
+	guint32 timestamp_high;
+	guint32 timestamp_low;
 	guint32 pixel_format;
 	guint32 width;
 	guint32 height;
@@ -124,6 +125,29 @@ arv_gvsp_packet_get_pixel_format (const ArvGvspPacket *packet)
 	return g_ntohl (leader->pixel_format);
 }
 
+static inline guint64
+arv_gvsp_packet_get_timestamp (const ArvGvspPacket *packet, guint64 timestamp_tick_frequency)
+{
+	ArvGvspDataLeader *leader;
+	guint64 timestamp_s;
+	guint64 timestamp_ns;
+	guint64 timestamp;
+
+	if (timestamp_tick_frequency < 1)
+		return 0;
+
+	leader = (ArvGvspDataLeader *) &packet->data;
+
+	timestamp = ( (guint64) g_ntohl (leader->timestamp_high) << 32) | g_ntohl (leader->timestamp_low);
+
+	timestamp_s = timestamp / timestamp_tick_frequency;
+	timestamp_ns = ((timestamp % timestamp_tick_frequency) * 1000000000) / timestamp_tick_frequency;
+
+	timestamp_ns += timestamp_s * 1000000000;
+
+	return timestamp_ns;
+}
+
 static inline size_t
 arv_gvsp_packet_get_data_size (size_t packet_size)
 {
diff --git a/src/arvgvstream.c b/src/arvgvstream.c
index d301920..d41e978 100644
--- a/src/arvgvstream.c
+++ b/src/arvgvstream.c
@@ -40,6 +40,8 @@ typedef struct {
 	GSocket *socket;
 	GSocketAddress *device_address;
 
+	guint64 timestamp_tick_frequency;
+
 	gboolean cancel;
 	GAsyncQueue *input_queue;
 	GAsyncQueue *output_queue;
@@ -134,6 +136,7 @@ arv_gv_stream_thread (void *data)
 	GTimeVal current_time;
 	gint64 current_time_us;
 	gint64 last_time_us;
+	guint64 last_timestamp_ns;
 	gboolean statistic_count = 0;
 
 	if (thread_data->callback != NULL)
@@ -147,6 +150,7 @@ arv_gv_stream_thread (void *data)
 
 	g_get_current_time (&current_time);
 	last_time_us = current_time.tv_sec * 1000000 + current_time.tv_usec;
+	last_timestamp_ns = 0;
 
 	do {
 		n_events = g_poll (&poll_fd, 1, 1000);
@@ -173,6 +177,9 @@ arv_gv_stream_thread (void *data)
 					buffer->pixel_format = arv_gvsp_packet_get_pixel_format (packet);
 					buffer->frame_id = arv_gvsp_packet_get_frame_id (packet);
 
+					buffer->timestamp_ns = arv_gvsp_packet_get_timestamp
+						(packet, thread_data->timestamp_tick_frequency);
+
 					buffer->status = ARV_BUFFER_STATUS_FILLING;
 					block_id = 0;
 					offset = 0;
@@ -228,11 +235,17 @@ arv_gv_stream_thread (void *data)
 						g_get_current_time (&current_time);
 						current_time_us = current_time.tv_sec * 1000000 + current_time.tv_usec;
 						statistic_count++;
-						if (statistic_count > 5)
+						if (statistic_count > 5) {
 							arv_statistic_fill (thread_data->statistic,
 									    0, (current_time_us - last_time_us),
 									    buffer->frame_id);
+							arv_statistic_fill (thread_data->statistic,
+									    1,
+									    (buffer->timestamp_ns - last_timestamp_ns) /
+									    1000, buffer->frame_id);
+						}
 						last_time_us = current_time_us;
+						last_timestamp_ns = buffer->timestamp_ns;
 						g_async_queue_push (thread_data->output_queue, buffer);
 						buffer = NULL;
 					}
@@ -288,7 +301,8 @@ arv_gv_stream_set_option (ArvGvStream *gv_stream, ArvGvStreamOption option, int
 
 ArvStream *
 arv_gv_stream_new (GInetAddress *device_address, guint16 port,
-		   ArvStreamCallback callback, void *user_data)
+		   ArvStreamCallback callback, void *user_data,
+		   guint64 timestamp_tick_frequency)
 {
 	ArvGvStream *gv_stream;
 	ArvStream *stream;
@@ -316,6 +330,7 @@ arv_gv_stream_new (GInetAddress *device_address, guint16 port,
 	thread_data->user_data = user_data;
 	thread_data->socket = gv_stream->socket;
 	thread_data->device_address = g_inet_socket_address_new (device_address, ARV_GVCP_PORT);
+	thread_data->timestamp_tick_frequency = timestamp_tick_frequency;
 	thread_data->cancel = FALSE;
 	thread_data->input_queue = stream->input_queue;
 	thread_data->output_queue = stream->output_queue;
@@ -328,7 +343,10 @@ arv_gv_stream_new (GInetAddress *device_address, guint16 port,
 	thread_data->n_size_mismatch_errors = 0;
 	thread_data->n_missing_blocks = 0;
 
-	thread_data->statistic = arv_statistic_new (1, 5000, 200, 0);
+	thread_data->statistic = arv_statistic_new (2, 5000, 200, 0);
+
+	arv_statistic_set_name (thread_data->statistic, 0, "Local time delta");
+	arv_statistic_set_name (thread_data->statistic, 1, "Timestamp delta");
 
 	thread_data->socket_buffer_option = ARV_GV_STREAM_OPTION_SOCKET_BUFFER_FIXED;
 	thread_data->socket_buffer_size = 0;
diff --git a/src/arvgvstream.h b/src/arvgvstream.h
index d45de01..4915bab 100644
--- a/src/arvgvstream.h
+++ b/src/arvgvstream.h
@@ -60,7 +60,8 @@ struct _ArvGvStreamClass {
 GType arv_gv_stream_get_type (void);
 
 ArvStream * 		arv_gv_stream_new		(GInetAddress *device_address, guint16 port,
-							 ArvStreamCallback callback, void *user_data);
+							 ArvStreamCallback callback, void *user_data,
+							 guint64 timestamp_tick_frequency);
 guint16 		arv_gv_stream_get_port		(ArvGvStream *gv_stream);
 void			arv_gv_stream_set_option	(ArvGvStream *gv_stream, ArvGvStreamOption option,
 							 int value);



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