[Spice-commits] src/channel-usbredir.c src/usb-device-manager.c src/usb-device-manager-priv.h

Marc-André Lureau elmarco at kemper.freedesktop.org
Fri Oct 7 08:15:29 UTC 2016


 src/channel-usbredir.c        |   10 ++++++++++
 src/usb-device-manager-priv.h |    1 +
 src/usb-device-manager.c      |   38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+)

New commits:
commit de2ee1a84d9dfa4463d7a43824c26a02014aa61a
Author: Snir Sheriber <ssheribe at redhat.com>
Date:   Thu Oct 6 18:13:42 2016 +0300

    Avoid compression of isochronous devices
    
    Device is considered isochronous if one of its endpoints is
    defined as isochronous transfer, in that case data transfer
    over the usbredir channel will not be compressed
    (it is assumed that there is a strong correlation between
    isochronous devices and devices which their data is usually
    compressed)
    
    E.g.
    Camera/mic device will usually be recognised as isochronous
    while storage devices won't
    
    Message-Id: <1475766822-26809-2-git-send-email-ssheribe at redhat.com>
    Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>

diff --git a/src/channel-usbredir.c b/src/channel-usbredir.c
index dd17e6c..94a5050 100644
--- a/src/channel-usbredir.c
+++ b/src/channel-usbredir.c
@@ -544,6 +544,12 @@ void spice_usbredir_channel_disconnect_device_async(SpiceUsbredirChannel *channe
     g_object_unref(task);
 }
 
+static SpiceUsbDevice *
+spice_usbredir_channel_get_spice_usb_device(SpiceUsbredirChannel *channel)
+{
+    return channel->priv->spice_device;
+}
+
 G_GNUC_INTERNAL
 libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel)
 {
@@ -673,6 +679,10 @@ static int try_write_compress_LZ4(SpiceUsbredirChannel *channel, uint8_t *data,
         /* No server compression capability - data will not be compressed */
         return FALSE;
     }
+    if (spice_usb_device_is_isochronous(spice_usbredir_channel_get_spice_usb_device(channel))) {
+        /* Don't compress - one of the device endpoints is isochronous */
+        return FALSE;
+    }
     bound = LZ4_compressBound(count);
     if (bound == 0) {
         /* Invalid bound - data will not be compressed */
diff --git a/src/usb-device-manager-priv.h b/src/usb-device-manager-priv.h
index b6fa9c9..83884d7 100644
--- a/src/usb-device-manager-priv.h
+++ b/src/usb-device-manager-priv.h
@@ -40,6 +40,7 @@ guint8 spice_usb_device_get_busnum(const SpiceUsbDevice *device);
 guint8 spice_usb_device_get_devaddr(const SpiceUsbDevice *device);
 guint16 spice_usb_device_get_vid(const SpiceUsbDevice *device);
 guint16 spice_usb_device_get_pid(const SpiceUsbDevice *device);
+gboolean spice_usb_device_is_isochronous(const SpiceUsbDevice *device);
 
 #endif
 
diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index f076967..feba468 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -153,6 +153,7 @@ typedef struct _SpiceUsbDeviceInfo {
     guint8  devaddr;
     guint16 vid;
     guint16 pid;
+    gboolean isochronous;
 #ifdef G_OS_WIN32
     guint8  state;
 #else
@@ -2017,6 +2018,33 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *for
 
 
 #ifdef USE_USBREDIR
+static gboolean probe_isochronous_endpoint(libusb_device *libdev)
+{
+    struct libusb_config_descriptor *conf_desc;
+    gboolean isoc_found = FALSE;
+    gint i, j, k;
+
+    g_return_val_if_fail(libdev != NULL, FALSE);
+
+    if (!libusb_get_active_config_descriptor(libdev, &conf_desc)) {
+        g_return_val_if_reached(FALSE);
+    }
+
+    for (i = 0; !isoc_found && i < conf_desc->bNumInterfaces; i++) {
+        for (j = 0; !isoc_found && j < conf_desc->interface[i].num_altsetting; j++) {
+            for (k = 0; !isoc_found && k < conf_desc->interface[i].altsetting[j].bNumEndpoints;k++) {
+                gint attributes = conf_desc->interface[i].altsetting[j].endpoint[k].bmAttributes;
+                gint type = attributes & LIBUSB_TRANSFER_TYPE_MASK;
+                if (type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
+                    isoc_found = TRUE;
+            }
+        }
+    }
+
+    libusb_free_config_descriptor(conf_desc);
+    return isoc_found;
+}
+
 /*
  * SpiceUsbDeviceInfo
  */
@@ -2042,6 +2070,7 @@ static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev)
     info->vid = vid;
     info->pid = pid;
     info->ref = 1;
+    info->isochronous = probe_isochronous_endpoint(libdev);
 #ifndef G_OS_WIN32
     info->libdev = libusb_ref_device(libdev);
 #endif
@@ -2085,6 +2114,15 @@ guint16 spice_usb_device_get_pid(const SpiceUsbDevice *device)
     return info->pid;
 }
 
+gboolean spice_usb_device_is_isochronous(const SpiceUsbDevice *device)
+{
+    const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
+
+    g_return_val_if_fail(info != NULL, 0);
+
+    return info->isochronous;
+}
+
 #ifdef G_OS_WIN32
 void spice_usb_device_set_state(SpiceUsbDevice *device, guint8 state)
 {


More information about the Spice-commits mailing list