Hi, there is a leftover (mentioned bellow). Fixed locally. On Thu, Oct 22, 2015 at 04:07:18PM +0200, Victor Toso wrote: > For streaming devices it might be necessary from application to drop > data for different reasons. This patch provides a new callback that it > is called before queueing the most recent iso packages. > > Related: https://bugzilla.redhat.com/show_bug.cgi?id=1264156 > --- > usbredirhost/usbredirhost.c | 63 +++++++++++++++++++++++++++++++++++++++++++-- > usbredirhost/usbredirhost.h | 12 +++++++++ > 2 files changed, 73 insertions(+), 2 deletions(-) > > diff --git a/usbredirhost/usbredirhost.c b/usbredirhost/usbredirhost.c > index ad30722..4c20bff 100644 > --- a/usbredirhost/usbredirhost.c > +++ b/usbredirhost/usbredirhost.c > @@ -23,6 +23,7 @@ > #include <stdio.h> > #include <stdlib.h> > #include <stdarg.h> > +#include <stdbool.h> > #include <string.h> > #include <errno.h> > #include <unistd.h> > @@ -109,6 +110,7 @@ struct usbredirhost { > usbredirparser_read read_func; > usbredirparser_write write_func; > usbredirhost_flush_writes flush_writes_func; > + usbredirhost_can_write_iso can_write_iso_func; > void *func_priv; > int verbose; > libusb_context *ctx; > @@ -130,6 +132,11 @@ struct usbredirhost { > struct usbredirtransfer transfers_head; > struct usbredirfilter_rule *filter_rules; > int filter_rules_count; > + struct { > + uint64_t higher; > + uint64_t lower; > + bool dropping; > + } iso_threshold; > }; > > struct usbredirhost_dev_ids { > @@ -1003,6 +1010,31 @@ static void usbredirhost_send_stream_status(struct usbredirhost *host, > } > } > > +static int usbredirhost_can_write_iso_package(struct usbredirhost *host, > + uint8_t ep) ep is not used. removed. > +{ > + uint64_t size; > + > + if (!host->can_write_iso_func) > + return true; > + > + size = host->can_write_iso_func(host->func_priv); > + if (size >= host->iso_threshold.higher) { > + if (!host->iso_threshold.dropping) > + DEBUG("START dropping isoc packets %lu buffer > %lu hi threshold", > + size, host->iso_threshold.higher); > + host->iso_threshold.dropping = true; > + } else if (size < host->iso_threshold.lower) { > + if (host->iso_threshold.dropping) > + DEBUG("STOP dropping isoc packets %lu buffer < %lu low threshold", > + size, host->iso_threshold.lower); > + > + host->iso_threshold.dropping = false; > + } > + > + return !host->iso_threshold.dropping; > +} > + > static void usbredirhost_send_stream_data(struct usbredirhost *host, > uint64_t id, uint8_t ep, uint8_t status, uint8_t *data, int len) > { > @@ -1028,8 +1060,10 @@ static void usbredirhost_send_stream_data(struct usbredirhost *host, > .status = status, > .length = len, > }; > - usbredirparser_send_iso_packet(host->parser, id, &iso_packet, > - data, len); > + > + if (usbredirhost_can_write_iso_package(host, ep)) > + usbredirparser_send_iso_packet(host->parser, id, &iso_packet, > + data, len); > break; > } > case usb_redir_type_bulk: { > @@ -1120,6 +1154,16 @@ static void usbredirhost_stop_stream(struct usbredirhost *host, > FLUSH(host); > } > > +static void usbredirhost_set_iso_threshold(struct usbredirhost *host, > + uint8_t pkts_per_transfer, uint8_t transfer_count, uint16_t max_packetsize) > +{ > + uint64_t reference = pkts_per_transfer * transfer_count * max_packetsize; > + host->iso_threshold.lower = reference / 2; > + host->iso_threshold.higher = reference * 2; > + DEBUG("higher threshold is %lu bytes | lower threshold is %lu bytes", > + host->iso_threshold.higher, host->iso_threshold.lower); > +} > + > /* Called from both parser read and packet complete callbacks */ > static void usbredirhost_alloc_stream_unlocked(struct usbredirhost *host, > uint64_t id, uint8_t ep, uint8_t type, uint8_t pkts_per_transfer, > @@ -1178,6 +1222,10 @@ static void usbredirhost_alloc_stream_unlocked(struct usbredirhost *host, > host->endpoint[EP2I(ep)].transfer[i], ISO_TIMEOUT); > libusb_set_iso_packet_lengths( > host->endpoint[EP2I(ep)].transfer[i]->transfer, pkt_size); > + > + usbredirhost_set_iso_threshold( > + host, pkts_per_transfer, transfer_count, > + host->endpoint[EP2I(ep)].max_packetsize); > break; > case usb_redir_type_bulk: > libusb_fill_bulk_transfer( > @@ -1358,6 +1406,17 @@ static void usbredirhost_log_data(struct usbredirhost *host, const char *desc, > > /**************************************************************************/ > > +void usbredirhost_set_cb_can_write_iso(struct usbredirhost *host, > + usbredirhost_can_write_iso can_write_iso_func) > +{ > + if (!host) { > + ERROR("invalid usbredirhost"); > + return; > + } > + > + host->can_write_iso_func = can_write_iso_func; > +} > + > /* Return value: > 0 All ok > 1 Packet borked, continue with next packet / urb > diff --git a/usbredirhost/usbredirhost.h b/usbredirhost/usbredirhost.h > index c0042c9..a03b10b 100644 > --- a/usbredirhost/usbredirhost.h > +++ b/usbredirhost/usbredirhost.h > @@ -33,6 +33,8 @@ struct usbredirhost; > > typedef void (*usbredirhost_flush_writes)(void *priv); > > +typedef uint64_t (*usbredirhost_can_write_iso)(void *priv); > + > /* This function creates an usbredirhost instance, including its embedded > libusbredirparser instance and sends the initial usb_redir_hello packet to > the usb-guest. > @@ -114,6 +116,16 @@ void usbredirhost_close(struct usbredirhost *host); > int usbredirhost_set_device(struct usbredirhost *host, > libusb_device_handle *usb_dev_handle); > > +/* Call this function to set a callback in usbredirhost. > + The usbredirhost_can_write_iso callback should return the application's > + buffer size (in bytes) that are handling the isochronous data. > + usbredirhost set two levels of threshold based in the information provided > + by the device; if buffer size is higher then the higher threshold, usbredir > + will drop isochronous packages till it reaches lower threshold. > +*/ > +void usbredirhost_set_cb_can_write_iso(struct usbredirhost *host, > + usbredirhost_can_write_iso can_write_iso_func); > + > /* Call this whenever there is data ready for the usbredirhost to read from > the usb-guest > returns 0 on success, or an error code from the below enum on error. > -- > 2.5.0 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel