diff options
author | Kővágó, Zoltán <dirty.ice.hu@gmail.com> | 2019-10-13 21:58:04 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2019-10-18 08:14:05 +0200 |
commit | 2c6a740f6b0bafc59d7008bf1138c163fb541d6b (patch) | |
tree | fef2ec1be5f5c2a7b651729c5a3b48ac9b06cd4e /hw/usb/dev-audio.c | |
parent | b5c7db3eefeba1cb661c86b2e530ea387319db1d (diff) |
usb-audio: do not count on avail bytes actually available
This assumption is no longer true when mixeng is turned off.
Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Message-id: d63f4d39a0ee7a2e4e7e4a2eb005ba79120eaf1d.1570996490.git.DirtY.iCE.hu@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb/dev-audio.c')
-rw-r--r-- | hw/usb/dev-audio.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index ae42e5a2f1..74c99b1f12 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -319,30 +319,31 @@ static int streambuf_put(struct streambuf *buf, USBPacket *p) { uint32_t free = buf->size - (buf->prod - buf->cons); - if (!free) { + if (free < USBAUDIO_PACKET_SIZE) { return 0; } if (p->iov.size != USBAUDIO_PACKET_SIZE) { return 0; } - assert(free >= USBAUDIO_PACKET_SIZE); + usb_packet_copy(p, buf->data + (buf->prod % buf->size), USBAUDIO_PACKET_SIZE); buf->prod += USBAUDIO_PACKET_SIZE; return USBAUDIO_PACKET_SIZE; } -static uint8_t *streambuf_get(struct streambuf *buf) +static uint8_t *streambuf_get(struct streambuf *buf, size_t *len) { uint32_t used = buf->prod - buf->cons; uint8_t *data; if (!used) { + *len = 0; return NULL; } - assert(used >= USBAUDIO_PACKET_SIZE); data = buf->data + (buf->cons % buf->size); - buf->cons += USBAUDIO_PACKET_SIZE; + *len = MIN(buf->prod - buf->cons, + buf->size - (buf->cons % buf->size)); return data; } @@ -374,16 +375,21 @@ static void output_callback(void *opaque, int avail) USBAudioState *s = opaque; uint8_t *data; - for (;;) { - if (avail < USBAUDIO_PACKET_SIZE) { + while (avail) { + size_t written, len; + + data = streambuf_get(&s->out.buf, &len); + if (!data) { return; } - data = streambuf_get(&s->out.buf); - if (!data) { + + written = AUD_write(s->out.voice, data, len); + avail -= written; + s->out.buf.cons += written; + + if (written < len) { return; } - AUD_write(s->out.voice, data, USBAUDIO_PACKET_SIZE); - avail -= USBAUDIO_PACKET_SIZE; } } |