[aravis] gv_stream: handle frame ledaer timestamp.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [aravis] gv_stream: handle frame ledaer timestamp.
- Date: Mon, 10 May 2010 12:50:13 +0000 (UTC)
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,
+ ×tamp_tick_frequency_high) &&
+ arv_device_read_register (ARV_DEVICE (gv_device),
+ ARV_GVBS_TIMESTAMP_TICK_FREQUENCY_LOW,
+ ×tamp_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 (¤t_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 (¤t_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]