[aravis/wip/emmanuel/usb3vision] wip: some live USB images in viewer!



commit e7ed6151da0612a7e61929783aeb3f1f0d5b6395
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Sat Jun 11 17:42:04 2016 +0200

    wip: some live USB images in viewer!

 src/Makefile.am   |    6 ++-
 src/arvuvcp.c     |    2 -
 src/arvuvcp.h     |    2 +
 src/arvuvdevice.c |   56 ++++++++++++++------
 src/arvuvsp.c     |  140 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/arvuvsp.h     |  153 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/arvuvstream.c |   76 +++++++++++++++++++++++++-
 src/arvuvstream.h |    2 +-
 8 files changed, 413 insertions(+), 24 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 346d406..cb6ed41 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -163,7 +163,8 @@ ARAVIS_SRCS +=                                      \
        arvuvstream.c
 
 ARAVIS_SRCS_NO_INTRO +=                                \
-       arvuvcp.c
+       arvuvcp.c                               \
+       arvuvsp.c
 
 ARAVIS_HDRS +=                                 \
        arvuvinterface.h                        \
@@ -171,7 +172,8 @@ ARAVIS_HDRS +=                                      \
        arvuvstream.h
 
 ARAVIS_HDRS_NO_INTRO +=                                \
-       arvuvcp.h
+       arvuvcp.h                               \
+       arvuvsp.h
 endif
 
 arv_fake_cameradir = $(aravis_datadir)
diff --git a/src/arvuvcp.c b/src/arvuvcp.c
index b2fe9db..2c102ee 100644
--- a/src/arvuvcp.c
+++ b/src/arvuvcp.c
@@ -31,8 +31,6 @@
 #include <arvstr.h>
 #include <string.h>
 
-#define ARV_UVCP_MAGIC 0x43563355
-
 void
 arv_uvcp_packet_free (ArvUvcpPacket *packet)
 {
diff --git a/src/arvuvcp.h b/src/arvuvcp.h
index 9d98f19..86ccc0f 100644
--- a/src/arvuvcp.h
+++ b/src/arvuvcp.h
@@ -28,6 +28,8 @@
 
 G_BEGIN_DECLS
 
+#define ARV_UVCP_MAGIC 0x43563355
+
 #define ARV_ABRM_GENCP_VERSION                 0x0000
 #define ARV_ABRM_MANUFACTURER_NAME             0x0004
 #define ARV_ABRM_MODEL_NAME                    0x0044
diff --git a/src/arvuvdevice.c b/src/arvuvdevice.c
index 414932b..5fbebca 100644
--- a/src/arvuvdevice.c
+++ b/src/arvuvdevice.c
@@ -63,9 +63,10 @@ struct _ArvUvDevicePrivate {
 static ArvStream *
 arv_uv_device_create_stream (ArvDevice *device, ArvStreamCallback callback, void *user_data)
 {
+       ArvUvDevice *uv_device = ARV_UV_DEVICE (device);
        ArvStream *stream;
 
-       stream = arv_uv_stream_new (callback, user_data);
+       stream = arv_uv_stream_new (uv_device->priv->usb, uv_device->priv->usb_device, callback, user_data);
 
        return stream;
 }
@@ -97,12 +98,10 @@ _read_memory (ArvUvDevice *uv_device, guint32 address, guint32 size, void *buffe
 
                arv_uvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);
 
-               g_assert (libusb_claim_interface (uv_device->priv->usb_device, 0) >= 0);
                g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x04 | LIBUSB_ENDPOINT_OUT),
                                                (guchar *) packet, packet_size, &transferred, 0) >= 0);
                g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x84 | LIBUSB_ENDPOINT_IN),
                                                (guchar *) read_packet, read_packet_size, &transferred, 0) >= 
0);
-               g_assert (libusb_release_interface (uv_device->priv->usb_device, 0) >= 0);
                success = TRUE;
 
                memcpy (buffer, arv_uvcp_packet_get_read_memory_ack_data (read_packet), size);
@@ -173,12 +172,10 @@ _write_memory (ArvUvDevice *uv_device, guint32 address, guint32 size, void *buff
 
                arv_uvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);
 
-               g_assert (libusb_claim_interface (uv_device->priv->usb_device, 0) >= 0);
                g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x04 | LIBUSB_ENDPOINT_OUT),
                                                (guchar *) packet, packet_size, &transferred, 0) >= 0);
                g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x84 | LIBUSB_ENDPOINT_IN),
                                                (guchar *) read_packet, read_packet_size, &transferred, 0) >= 
0);
-               g_assert (libusb_release_interface (uv_device->priv->usb_device, 0) >= 0);
                success = TRUE;
 
                arv_uvcp_packet_debug (read_packet, ARV_DEBUG_LEVEL_LOG);
@@ -243,11 +240,18 @@ _bootstrap (ArvUvDevice *uv_device)
        guint32 max_ack_transfer;
        guint32 u3vcp_capability;
        guint64 sirm_offset;
-       guint32 si_control;
        guint32 si_info;
-       guint32 req_payload_size;
-       guint32 req_leader_size;
-       guint32 req_trailer_size;
+       guint32 si_control;
+       guint64 si_req_payload_size;
+       guint32 si_req_leader_size;
+       guint32 si_req_trailer_size;
+       guint32 si_max_leader_size;
+       guint32 si_payload_size;
+       guint32 si_payload_count;
+       guint32 si_transfer1_size;
+       guint32 si_transfer2_size;
+       guint32 si_max_trailer_size;
+
        guint64 manifest_n_entries;
        ArvUvcpManifestEntry entry;
        GString *string;
@@ -275,17 +279,29 @@ _bootstrap (ArvUvDevice *uv_device)
        g_message ("MAX_ACK_TRANSFER =         0x%08x", max_ack_transfer);
        g_message ("SIRM_OFFSET =              0x%016lx", sirm_offset);
 
-       arv_device_read_memory (device, sirm_offset + ARV_SI_INFO, sizeof (guint64), &si_info, NULL);
-       arv_device_read_memory (device, sirm_offset + ARV_SI_CONTROL, sizeof (guint64), &si_control, NULL);
-       arv_device_read_memory (device, sirm_offset + ARV_SI_REQ_PAYLOAD_SIZE, sizeof (guint64), 
&req_payload_size, NULL);
-       arv_device_read_memory (device, sirm_offset + ARV_SI_REQ_LEADER_SIZE, sizeof (guint64), 
&req_leader_size, NULL);
-       arv_device_read_memory (device, sirm_offset + ARV_SI_REQ_TRAILER_SIZE, sizeof (guint64), 
&req_trailer_size, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_INFO, sizeof (si_info), &si_info, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_CONTROL, sizeof (si_control), &si_control, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_REQ_PAYLOAD_SIZE, sizeof (si_req_payload_size), 
&si_req_payload_size, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_REQ_LEADER_SIZE, sizeof (si_req_leader_size), 
&si_req_leader_size, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_REQ_TRAILER_SIZE, sizeof (si_req_trailer_size), 
&si_req_trailer_size, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_MAX_LEADER_SIZE, sizeof (si_max_leader_size), 
&si_max_leader_size, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_PAYLOAD_SIZE, sizeof (si_payload_size), 
&si_payload_size, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_PAYLOAD_COUNT, sizeof (si_payload_count), 
&si_payload_count, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_TRANSFER1_SIZE, sizeof (si_transfer1_size), 
&si_transfer1_size, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_TRANSFER2_SIZE, sizeof (si_transfer2_size), 
&si_transfer2_size, NULL);
+       arv_device_read_memory (device, sirm_offset + ARV_SI_MAX_TRAILER_SIZE, sizeof (si_max_trailer_size), 
&si_max_trailer_size, NULL);
 
        g_message ("SI_INFO =                  0x%08x", si_info);
        g_message ("SI_CONTROL =               0x%08x", si_control);
-       g_message ("REQ_PAYLOAD_SIZE =         0x%08x", req_payload_size);
-       g_message ("REQ_LEADER_SIZE =          0x%08x", req_leader_size);
-       g_message ("REQ_TRAILER_SIZE =         0x%08x", req_trailer_size);
+       g_message ("SI_REQ_PAYLOAD_SIZE =      0x%016lx", si_req_payload_size);
+       g_message ("SI_REQ_LEADER_SIZE =       0x%08x", si_req_leader_size);
+       g_message ("SI_REQ_TRAILER_SIZE =      0x%08x", si_req_trailer_size);
+       g_message ("SI_MAX_LEADER_SIZE =       0x%08x", si_max_leader_size);
+       g_message ("SI_PAYLOAD_SIZE =          0x%08x", si_payload_size);
+       g_message ("SI_PAYLOAD_COUNT =         0x%08x", si_payload_count);
+       g_message ("SI_TRANSFER1_SIZE =        0x%08x", si_transfer1_size);
+       g_message ("SI_TRANSFER2_SIZE =        0x%08x", si_transfer2_size);
+       g_message ("SI_MAX_TRAILER_SIZE =      0x%08x", si_max_trailer_size);
 
        arv_device_read_memory (device, manifest_table_address, sizeof (guint64), &manifest_n_entries, NULL);
        arv_device_read_memory (device, manifest_table_address + 0x08, sizeof (entry), &entry, NULL);
@@ -435,9 +451,13 @@ arv_uv_device_new (const char *vendor, const char *product, const char *serial_n
 
        _open_usb_device (uv_device);
 
+       g_assert (libusb_claim_interface (uv_device->priv->usb_device, 0) >= 0);
+
        _bootstrap (uv_device);
 
        if (!ARV_IS_GC (uv_device->priv->genicam)) {
+               g_assert (libusb_release_interface (uv_device->priv->usb_device, 0) >= 0);
+
                arv_warning_device ("[UvDevice::new] Failed to load genicam data");
                g_object_unref (uv_device);
                return NULL;
@@ -458,6 +478,8 @@ arv_uv_device_finalize (GObject *object)
 {
        ArvUvDevice *uv_device = ARV_UV_DEVICE (object);
 
+       g_assert (libusb_release_interface (uv_device->priv->usb_device, 0) >= 0);
+
        g_object_unref (uv_device->priv->genicam);
 
        g_clear_pointer (&uv_device->priv->vendor, g_free);
diff --git a/src/arvuvsp.c b/src/arvuvsp.c
new file mode 100644
index 0000000..c40c72d
--- /dev/null
+++ b/src/arvuvsp.c
@@ -0,0 +1,140 @@
+/* Aravis - Digital camera library
+ *
+ * Copyright © 2009-2016 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <arvuvsp.h>
+#include <arvstr.h>
+#include <arvmisc.h>
+
+/**
+ * arv_uvsp_packet_to_string:
+ * @packet: a #ArvUvspPacket
+ *
+ * Converts @packet into a human readable string.
+ *
+ * return value: (transfer full): A newly allocated string.
+ */
+
+char *
+arv_uvsp_packet_to_string (const ArvUvspPacket *packet)
+{
+       ArvUvspLeader *leader = (ArvUvspLeader *) packet;
+       ArvUvspTrailer *trailer = (ArvUvspTrailer *) packet;
+       GString *string;
+       char *c_string;
+
+       g_return_val_if_fail (packet != NULL, NULL);
+
+       string = g_string_new ("");
+
+       switch (GUINT32_FROM_LE (packet->header.magic)) {
+               case ARV_UVSP_LEADER_MAGIC:
+                       g_string_append (string, "packet_type  = leader\n");
+                       g_string_append_printf (string, "size         = %d\n", GUINT16_FROM_LE 
(packet->header.size));
+                       g_string_append_printf (string, "frame id     = %" G_GUINT64_FORMAT "\n",
+                                               GUINT64_FROM_LE (packet->header.frame_id));
+                       switch (leader->infos.payload_type) {
+                               case ARV_UVSP_PAYLOAD_TYPE_IMAGE:
+                                       g_string_append (string, "payload_type = image\n");
+                                       break;
+                               case ARV_UVSP_PAYLOAD_TYPE_CHUNK:
+                                       g_string_append (string, "payload_type = chunk\n");
+                                       break;
+                               case ARV_UVSP_PAYLOAD_TYPE_EXTENDED_CHUNK:
+                                       g_string_append (string, "payload_type = extended chunk\n");
+                                       break;
+                               default:
+                                       g_string_append (string, "payload_type = unknown\n");
+                                       break;
+                       }
+                       g_string_append_printf (string, "pixel format = %s\n",
+                                               arv_pixel_format_to_gst_caps_string (GUINT32_FROM_LE 
(leader->infos.pixel_format)));
+                       g_string_append_printf (string, "width        = %d\n",
+                                               GUINT16_FROM_LE (leader->infos.width));
+                       g_string_append_printf (string, "height       = %d\n",
+                                               GUINT16_FROM_LE (leader->infos.height));
+                       g_string_append_printf (string, "x_offset     = %d\n",
+                                               GUINT16_FROM_LE (leader->infos.x_offset));
+                       g_string_append_printf (string, "y_offset     = %d\n",
+                                               GUINT16_FROM_LE (leader->infos.y_offset));
+                       break;
+               case ARV_UVSP_TRAILER_MAGIC:
+                       g_string_append (string, "packet_type  = trailer\n");
+                       g_string_append_printf (string, "size         = %d\n", GUINT16_FROM_LE 
(packet->header.size));
+                       g_string_append_printf (string, "frame id     = %" G_GUINT64_FORMAT "\n",
+                                               GUINT64_FROM_LE (packet->header.frame_id));
+                       g_string_append_printf (string, "payload_size = %" G_GUINT64_FORMAT "\n",
+                                               GUINT64_FROM_LE (trailer->infos.payload_size));
+                       break;
+               default:
+                       g_string_append (string, "packet_type  = image\n");
+                       break;
+       }
+
+#if 0
+       {
+               size_t packet_size;
+
+               packet_size = sizeof (ArvUvspHeader) + GUINT16_FROM_LE (packet->header.size);
+
+               arv_g_string_append_hex_dump (string, packet, packet_size);
+       }
+#endif
+
+       c_string = string->str;
+
+       g_string_free (string, FALSE);
+
+       return c_string;
+}
+
+/**
+ * arv_uvsp_packet_debug:
+ * @packet: a #ArvUvspPacket
+ * @level: debug level
+ *
+ * Dumps the content of @packet if level is lower or equal to the current debug level for the gvcp debug 
category. See arv_debug_enable().
+ */
+
+void
+arv_uvsp_packet_debug (const ArvUvspPacket *packet, ArvDebugLevel level)
+{
+       char *string;
+
+       if (!arv_debug_check (&arv_debug_category_gvcp, level))
+               return;
+
+       string = arv_uvsp_packet_to_string (packet);
+       switch (level) {
+               case ARV_DEBUG_LEVEL_LOG:
+                       arv_log_gvcp ("%s", string);
+                       break;
+               case ARV_DEBUG_LEVEL_DEBUG:
+                       arv_debug_gvcp ("%s", string);
+                       break;
+               case ARV_DEBUG_LEVEL_WARNING:
+                       arv_warning_gvcp ("%s", string);
+                       break;
+               default:
+                       break;
+       }
+       g_free (string);
+}
diff --git a/src/arvuvsp.h b/src/arvuvsp.h
new file mode 100644
index 0000000..6d146a6
--- /dev/null
+++ b/src/arvuvsp.h
@@ -0,0 +1,153 @@
+/* Aravis - Digital camera library
+ *
+ * Copyright © 2009-2016 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef ARV_UVSP_H
+#define ARV_UVSP_H
+
+#include <arvtypes.h>
+#include <arvdebug.h>
+
+G_BEGIN_DECLS
+
+#define ARV_UVSP_LEADER_MAGIC  0x4C563355
+#define ARV_UVSP_TRAILER_MAGIC 0x54563355
+
+/**
+ * ArvUvspPacketType:
+ * @ARV_UVSP_PACKET_TYPE_UNKNOWN: unknown packet
+ * @ARV_UVSP_PACKET_TYPE_LEADER: leader packet
+ * @ARV_UVSP_PACKET_TYPE_TRAILER: trailer packet
+ * @ARV_UVSP_PACKET_TYPE_DATA: data packet
+ */
+
+typedef enum {
+       ARV_UVSP_PACKET_TYPE_UNKNOWN,
+       ARV_UVSP_PACKET_TYPE_LEADER,
+       ARV_UVSP_PACKET_TYPE_TRAILER,
+       ARV_UVSP_PACKET_TYPE_DATA
+} ArvUvspPacketType;
+
+typedef enum {
+       ARV_UVSP_PAYLOAD_TYPE_IMAGE =                   0x0001,
+       ARV_UVSP_PAYLOAD_TYPE_CHUNK =                   0x4000,
+       ARV_UVSP_PAYLOAD_TYPE_EXTENDED_CHUNK =          0x4001
+} ArvUvspPayloadType;
+
+#define ARAVIS_PACKED_STRUCTURE __attribute__((__packed__))
+
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       guint32 magic;
+       guint16 unknown0;
+       guint16 size;
+       guint64 frame_id;
+} ArvUvspHeader;
+
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       ArvUvspHeader header;
+       void *data;
+} ArvUvspPacket;
+
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       guint16 unknown0;
+       guint16 payload_type;
+       guint64 timestamp;
+       guint32 pixel_format;
+       guint32 width;
+       guint32 height;
+       guint32 x_offset;
+       guint32 y_offset;
+       guint16 x_padding;
+       guint16 unknown1;
+} ArvUvspLeaderInfos;
+
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       ArvUvspHeader header;
+       ArvUvspLeaderInfos infos;
+} ArvUvspLeader;
+
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       guint32 unknown0;
+       guint64 payload_size; 
+} ArvUvspTrailerInfos;
+
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       ArvUvspHeader header;
+       ArvUvspTrailerInfos infos;
+} ArvUvspTrailer;
+
+#undef ARAVIS_PACKED_STRUCTURE
+
+char *                         arv_uvsp_packet_to_string               (const ArvUvspPacket *packet);
+void                   arv_uvsp_packet_debug                   (const ArvUvspPacket *packet, ArvDebugLevel 
level);
+
+static inline ArvUvspPacketType
+arv_uvsp_packet_get_packet_type        (const ArvUvspPacket *packet)
+{
+       if (packet == NULL)
+               return ARV_UVSP_PACKET_TYPE_UNKNOWN;
+       else if (GUINT32_FROM_LE (packet->header.magic) == ARV_UVSP_LEADER_MAGIC)
+               return ARV_UVSP_PACKET_TYPE_LEADER;
+       else if (GUINT32_FROM_LE (packet->header.magic) == ARV_UVSP_TRAILER_MAGIC)
+               return ARV_UVSP_PACKET_TYPE_TRAILER;
+       else
+               return ARV_UVSP_PACKET_TYPE_DATA;
+}
+
+static inline guint64
+arv_uvsp_packet_get_frame_id (ArvUvspPacket *packet)
+{
+       if (packet == NULL)
+               return 0;
+
+       return (GUINT64_FROM_LE (packet->header.frame_id));
+}
+
+static inline void
+arv_uvsp_packet_get_region (ArvUvspPacket *packet, guint32 *width, guint32 *height, guint32 *x_offset, 
guint32 *y_offset)
+{
+       ArvUvspLeader *leader;
+
+       if (packet == NULL)
+               return;
+
+       leader = (ArvUvspLeader *)packet;
+       *width = GUINT32_FROM_LE (leader->infos.width);
+       *height = GUINT32_FROM_LE (leader->infos.height);
+       *x_offset = GUINT32_FROM_LE (leader->infos.x_offset);
+       *y_offset = GUINT32_FROM_LE (leader->infos.y_offset);
+}
+
+static inline guint64
+arv_uvsp_packet_get_timestamp (ArvUvspPacket *packet)
+{
+       ArvUvspLeader *leader;
+
+       if (packet == NULL)
+               return 0;
+
+       leader = (ArvUvspLeader *)packet;
+       return GUINT64_FROM_LE (leader->infos.timestamp);
+}
+
+G_END_DECLS
+
+#endif
diff --git a/src/arvuvstream.c b/src/arvuvstream.c
index 67c4269..515da19 100644
--- a/src/arvuvstream.c
+++ b/src/arvuvstream.c
@@ -26,10 +26,13 @@
  */
 
 #include <arvuvstream.h>
+#include <arvuvsp.h>
 #include <arvstreamprivate.h>
 #include <arvbufferprivate.h>
 #include <arvdebug.h>
 #include <arvmisc.h>
+#include <libusb.h>
+#include <string.h>
 
 static GObjectClass *parent_class = NULL;
 
@@ -46,6 +49,9 @@ typedef struct {
        ArvStreamCallback callback;
        void *user_data;
 
+       libusb_context *usb;
+       libusb_device_handle *usb_device;
+
        gboolean cancel;
 
        /* Statistics */
@@ -59,19 +65,83 @@ static void *
 arv_uv_stream_thread (void *data)
 {
        ArvUvStreamThreadData *thread_data = data;
+       ArvUvspPacket *packet;
+       ArvBuffer *buffer = NULL;
+       guint64 offset;
+       int transferred;
 
        arv_log_stream_thread ("[UvStream::thread] Start");
 
+       packet = g_malloc (65536);
+
        if (thread_data->callback != NULL)
                thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_INIT, NULL);
 
+       offset = 0;
+
        while (!thread_data->cancel) {
-               g_usleep (1000000);
+               g_assert (libusb_bulk_transfer (thread_data->usb_device, (0x81 | LIBUSB_ENDPOINT_IN),
+                                               (guchar *) packet, 65536, &transferred, 1000) >= 0);
+
+               if (transferred > 0) {
+                       ArvUvspPacketType packet_type;
+
+                       arv_uvsp_packet_debug (packet, ARV_DEBUG_LEVEL_WARNING);
+
+                       packet_type = arv_uvsp_packet_get_packet_type (packet);
+                       switch (packet_type) {
+                               case ARV_UVSP_PACKET_TYPE_LEADER:
+                                       if (buffer != NULL) {
+                                               buffer->priv->status = ARV_BUFFER_STATUS_MISSING_PACKETS;
+                                               arv_stream_push_output_buffer (thread_data->stream, buffer);
+                                               thread_data->n_failures++;
+                                               buffer = NULL;
+                                       }
+                                       buffer = arv_stream_pop_input_buffer (thread_data->stream);
+                                       if (buffer != NULL) {
+                                               buffer->priv->status = ARV_BUFFER_STATUS_FILLING;
+                                               buffer->priv->gvsp_payload_type = ARV_GVSP_PAYLOAD_TYPE_IMAGE;
+                                               arv_uvsp_packet_get_region (packet,
+                                                                           &buffer->priv->width,
+                                                                           &buffer->priv->height,
+                                                                           &buffer->priv->x_offset,
+                                                                           &buffer->priv->y_offset);
+                                               buffer->priv->frame_id = arv_uvsp_packet_get_frame_id 
(packet);
+                                               buffer->priv->timestamp_ns = arv_uvsp_packet_get_timestamp 
(packet);
+                                               offset = 0;
+                                       } else
+                                               thread_data->n_underruns++;
+                                       break;
+                               case ARV_UVSP_PACKET_TYPE_TRAILER:
+                                       if (buffer != NULL) {
+                                               g_message ("Received %" G_GUINT64_FORMAT " bytes - expected 
%" G_GUINT64_FORMAT,
+                                                          offset, buffer->priv->size);
+                                               buffer->priv->status = ARV_BUFFER_STATUS_SUCCESS;
+                                               arv_stream_push_output_buffer (thread_data->stream, buffer);
+                                               thread_data->n_completed_buffers++;
+                                               buffer = NULL;
+                                       }
+                                       break;
+                               case ARV_UVSP_PACKET_TYPE_DATA:
+                                       if (buffer != NULL && buffer->priv->status == 
ARV_BUFFER_STATUS_FILLING) {
+                                               if (offset + transferred < buffer->priv->size) {
+                                                       memcpy (((char *) buffer->priv->data) + offset, 
packet, transferred);
+                                                       offset += transferred;
+                                               } else
+                                                       buffer->priv->status = 
ARV_BUFFER_STATUS_SIZE_MISMATCH;
+                                       }
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
        }
 
        if (thread_data->callback != NULL)
                thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_EXIT, NULL);
 
+       g_free (packet);
+
        arv_log_stream_thread ("[UvStream::thread] Stop");
 
        return NULL;
@@ -89,7 +159,7 @@ arv_uv_stream_thread (void *data)
  */
 
 ArvStream *
-arv_uv_stream_new (ArvStreamCallback callback, void *user_data)
+arv_uv_stream_new (void *usb, void *usb_device, ArvStreamCallback callback, void *user_data)
 {
        ArvUvStream *uv_stream;
        ArvUvStreamThreadData *thread_data;
@@ -100,6 +170,8 @@ arv_uv_stream_new (ArvStreamCallback callback, void *user_data)
        stream = ARV_STREAM (uv_stream);
 
        thread_data = g_new (ArvUvStreamThreadData, 1);
+       thread_data->usb = usb;
+       thread_data->usb_device = usb_device;
        thread_data->stream = stream;
        thread_data->callback = callback;
        thread_data->user_data = user_data;
diff --git a/src/arvuvstream.h b/src/arvuvstream.h
index a88572c..92f9fc2 100644
--- a/src/arvuvstream.h
+++ b/src/arvuvstream.h
@@ -50,7 +50,7 @@ struct _ArvUvStreamClass {
 
 GType arv_uv_stream_get_type (void);
 
-ArvStream *    arv_uv_stream_new       (ArvStreamCallback callback, void *user_data);
+ArvStream *    arv_uv_stream_new       (void *usb, void *usb_device, ArvStreamCallback callback, void 
*user_data);
 
 G_END_DECLS
 


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