summaryrefslogtreecommitdiffstats
path: root/src/channel-usbredir.c
diff options
context:
space:
mode:
authorVictor Toso <victortoso@redhat.com>2015-09-29 07:53:45 +0200
committerVictor Toso <victortoso@redhat.com>2015-10-30 15:47:44 +0100
commit36c7db9a38cc5335727c2abbe7968112eb6667e0 (patch)
treefa82ab9cf7bc672db11356f12bb774c0b8e5ef8b /src/channel-usbredir.c
parentaa6f1cd7a233d2a17948d0817d4b6a3bb63a93a4 (diff)
downloadspice-gtk-36c7db9a38cc5335727c2abbe7968112eb6667e0.tar.gz
spice-gtk-36c7db9a38cc5335727c2abbe7968112eb6667e0.tar.xz
spice-gtk-36c7db9a38cc5335727c2abbe7968112eb6667e0.zip
channel-usbredir: drop isoc packets on low bandwidth
When channel wants to send much more data then the wire can handle, the queue grows fast. This patch does not limit the queue growth but introduces an internal API to check if queue size is too big. This internal API is used in usbredir_buffered_output_size_callback which is called before any isoc pacaket is queued in usbredir. The usbredir implements the logic to: - only drop isoc packets - while dropping packtes does still give us video frames from and above 10fps streams An easy way to test locally is sharing and webcam and with tc: tc qdisc add dev lo root netem delay 100ms tc qdisc change dev lo root netem delay 1000ms tc qdisc del dev lo root netem Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1264156
Diffstat (limited to 'src/channel-usbredir.c')
-rw-r--r--src/channel-usbredir.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/channel-usbredir.c b/src/channel-usbredir.c
index c236ee7..0be72ba 100644
--- a/src/channel-usbredir.c
+++ b/src/channel-usbredir.c
@@ -91,6 +91,9 @@ static void usbredir_log(void *user_data, int level, const char *msg);
static int usbredir_read_callback(void *user_data, uint8_t *data, int count);
static int usbredir_write_callback(void *user_data, uint8_t *data, int count);
static void usbredir_write_flush_callback(void *user_data);
+#if USBREDIR_VERSION >= 0x000701
+static uint64_t usbredir_buffered_output_size_callback(void *user_data);
+#endif
static void *usbredir_alloc_lock(void);
static void usbredir_lock_lock(void *user_data);
@@ -224,6 +227,10 @@ void spice_usbredir_channel_set_context(SpiceUsbredirChannel *channel,
usbredirhost_fl_write_cb_owns_buffer);
if (!priv->host)
g_error("Out of memory allocating usbredirhost");
+
+#if USBREDIR_VERSION >= 0x000701
+ usbredirhost_set_buffered_output_size_cb(priv->host, usbredir_buffered_output_size_callback);
+#endif
}
static gboolean spice_usbredir_channel_open_device(
@@ -461,6 +468,14 @@ void spice_usbredir_channel_get_guest_filter(
/* ------------------------------------------------------------------ */
/* callbacks (any context) */
+#if USBREDIR_VERSION >= 0x000701
+static uint64_t usbredir_buffered_output_size_callback(void *user_data)
+{
+ g_return_val_if_fail(SPICE_IS_USBREDIR_CHANNEL(user_data), 0);
+ return spice_channel_get_queue_size(SPICE_CHANNEL(user_data));
+}
+#endif
+
/* Note that this function must be re-entrant safe, as it can get called
from both the main thread as well as from the usb event handling thread */
static void usbredir_write_flush_callback(void *user_data)