[Spice-devel] [PATCH 2/2] Usbredir: Avoid compression of isochronous devices
Snir Sheriber
ssheribe at redhat.com
Sun Jul 10 16:18:23 UTC 2016
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
Signed-off-by: Snir Sheriber <ssheribe at redhat.com>
---
src/channel-usbredir.c | 9 +++++++++
src/usb-device-manager-priv.h | 1 +
src/usb-device-manager.c | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/src/channel-usbredir.c b/src/channel-usbredir.c
index d420a96..ca8ed99 100644
--- a/src/channel-usbredir.c
+++ b/src/channel-usbredir.c
@@ -544,6 +544,11 @@ 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)
{
@@ -672,6 +677,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 53505fa..2cb265b 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,32 @@ 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;
+
+ if(libdev != NULL) {
+ if(!libusb_get_active_config_descriptor(libdev, &conf_desc)) {
+ for(int i=0;i<conf_desc->bNumInterfaces;i++) {
+ for(int j=0;j<conf_desc->interface[i].num_altsetting;j++) {
+ for(int k=0;k < conf_desc->interface[i].altsetting[j].bNumEndpoints;k++) {
+ if ((conf_desc->interface[i].altsetting[j].endpoint[k].bmAttributes &
+ LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
+ isoc_found = TRUE;
+ goto done;
+ }
+ }
+ }
+ }
+ }
+ }
+ isoc_found = FALSE;
+done:
+ libusb_free_config_descriptor(conf_desc);
+ return isoc_found;
+}
+
/*
* SpiceUsbDeviceInfo
*/
@@ -2042,6 +2069,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 +2113,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)
{
--
2.5.5
More information about the Spice-devel
mailing list