diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-09-24 17:22:17 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-09-24 17:22:17 +0100 |
commit | 1bd5556f6686365e76f7ff67fe67260c449e8345 (patch) | |
tree | c302198da685f9aedb1ed6a6a2208d290e63fcd1 /audio | |
parent | f7f1d916b22306c35ab9c090aab5233a91b4b7f9 (diff) | |
parent | 5e626fa7364bc2d7db5f6c8e59150dee1689b98a (diff) |
Merge remote-tracking branch 'remotes/kraxel/tags/audio-20200923-pull-request' into staging
audio: various buffering fixes.
audio: build spiceaudio as module.
# gpg: Signature made Wed 23 Sep 2020 10:09:46 BST
# gpg: using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138
* remotes/kraxel/tags/audio-20200923-pull-request:
audio: build spiceaudio as module
audio: remove qemu_spice_audio_init()
audio: run downstream playback queue unconditionally
audio: align audio_generic_write with audio_pcm_hw_run_out
audio: remove unnecessary calls to put_buffer_in
audio: align audio_generic_read with audio_pcm_hw_run_in
audio/spiceaudio: always rate limit playback stream
audio/audio: fix video playback slowdown with spiceaudio
audio: handle buf == NULL in put_buffer_out()
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'audio')
-rw-r--r-- | audio/audio.c | 80 | ||||
-rw-r--r-- | audio/meson.build | 4 | ||||
-rw-r--r-- | audio/spiceaudio.c | 26 |
3 files changed, 80 insertions, 30 deletions
diff --git a/audio/audio.c b/audio/audio.c index 1a68cfaafb..46578e4a58 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -34,6 +34,7 @@ #include "qemu/module.h" #include "sysemu/replay.h" #include "sysemu/runstate.h" +#include "ui/qemu-spice.h" #include "trace.h" #define AUDIO_CAP "audio" @@ -1089,14 +1090,18 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) size_t clipped = 0; while (live) { - size_t size, decr, proc; + size_t size = live * hw->info.bytes_per_frame; + size_t decr, proc; void *buf = hw->pcm_ops->get_buffer_out(hw, &size); - if (!buf || size == 0) { + + if (size == 0) { break; } decr = MIN(size / hw->info.bytes_per_frame, live); - audio_pcm_hw_clip_out(hw, buf, decr); + if (buf) { + audio_pcm_hw_clip_out(hw, buf, decr); + } proc = hw->pcm_ops->put_buffer_out(hw, buf, decr * hw->info.bytes_per_frame) / hw->info.bytes_per_frame; @@ -1182,6 +1187,9 @@ static void audio_run_out (AudioState *s) } } } + if (hw->pcm_ops->run_buffer_out) { + hw->pcm_ops->run_buffer_out(hw); + } continue; } @@ -1257,7 +1265,6 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) assert(size % hw->info.bytes_per_frame == 0); if (size == 0) { - hw->pcm_ops->put_buffer_in(hw, buf, size); break; } @@ -1481,22 +1488,54 @@ size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size) size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size) { - size_t dst_size, copy_size; - void *dst = hw->pcm_ops->get_buffer_out(hw, &dst_size); - copy_size = MIN(size, dst_size); + size_t total = 0; + + while (total < size) { + size_t dst_size = size - total; + size_t copy_size, proc; + void *dst = hw->pcm_ops->get_buffer_out(hw, &dst_size); + + if (dst_size == 0) { + break; + } + + copy_size = MIN(size - total, dst_size); + if (dst) { + memcpy(dst, (char *)buf + total, copy_size); + } + proc = hw->pcm_ops->put_buffer_out(hw, dst, copy_size); + total += proc; + + if (proc == 0 || proc < copy_size) { + break; + } + } - memcpy(dst, buf, copy_size); - return hw->pcm_ops->put_buffer_out(hw, dst, copy_size); + if (hw->pcm_ops->run_buffer_out) { + hw->pcm_ops->run_buffer_out(hw); + } + + return total; } size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size) { - void *src = hw->pcm_ops->get_buffer_in(hw, &size); + size_t total = 0; - memcpy(buf, src, size); - hw->pcm_ops->put_buffer_in(hw, src, size); + while (total < size) { + size_t src_size = size - total; + void *src = hw->pcm_ops->get_buffer_in(hw, &src_size); - return size; + if (src_size == 0) { + break; + } + + memcpy((char *)buf + total, src, src_size); + hw->pcm_ops->put_buffer_in(hw, src, src_size); + total += src_size; + } + + return total; } static int audio_driver_init(AudioState *s, struct audio_driver *drv, @@ -1658,6 +1697,21 @@ static AudioState *audio_init(Audiodev *dev, const char *name) /* silence gcc warning about uninitialized variable */ AudiodevListHead head = QSIMPLEQ_HEAD_INITIALIZER(head); + if (using_spice) { + /* + * When using spice allow the spice audio driver being picked + * as default. + * + * Temporary hack. Using audio devices without explicit + * audiodev= property is already deprecated. Same goes for + * the -soundhw switch. Once this support gets finally + * removed we can also drop the concept of a default audio + * backend and this can go away. + */ + driver = audio_driver_lookup("spice"); + driver->can_be_default = 1; + } + if (dev) { /* -audiodev option */ legacy_config = false; diff --git a/audio/meson.build b/audio/meson.build index 15c06ba045..18a831129e 100644 --- a/audio/meson.build +++ b/audio/meson.build @@ -7,7 +7,6 @@ softmmu_ss.add(files( 'wavcapture.c', )) -softmmu_ss.add(when: [spice, 'CONFIG_SPICE'], if_true: files('spiceaudio.c')) softmmu_ss.add(when: [coreaudio, 'CONFIG_AUDIO_COREAUDIO'], if_true: files('coreaudio.c')) softmmu_ss.add(when: [dsound, 'CONFIG_AUDIO_DSOUND'], if_true: files('dsoundaudio.c')) softmmu_ss.add(when: ['CONFIG_AUDIO_WIN_INT'], if_true: files('audio_win_int.c')) @@ -18,7 +17,8 @@ foreach m : [ ['CONFIG_AUDIO_OSS', 'oss', oss, 'ossaudio.c'], ['CONFIG_AUDIO_PA', 'pa', pulse, 'paaudio.c'], ['CONFIG_AUDIO_SDL', 'sdl', sdl, 'sdlaudio.c'], - ['CONFIG_AUDIO_JACK', 'jack', jack, 'jackaudio.c'] + ['CONFIG_AUDIO_JACK', 'jack', jack, 'jackaudio.c'], + ['CONFIG_SPICE', 'spice', spice, 'spiceaudio.c'] ] if config_host.has_key(m[0]) module_ss = ss.source_set() diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index b6b5da4812..ed6dff1dcc 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -130,12 +130,11 @@ static void *line_out_get_buffer(HWVoiceOut *hw, size_t *size) } if (out->frame) { - *size = audio_rate_get_bytes( - &hw->info, &out->rate, - (out->fsize - out->fpos) * hw->info.bytes_per_frame); - } else { - audio_rate_start(&out->rate); + *size = MIN((out->fsize - out->fpos) << 2, *size); } + + *size = audio_rate_get_bytes(&hw->info, &out->rate, *size); + return out->frame + out->fpos; } @@ -143,12 +142,14 @@ static size_t line_out_put_buffer(HWVoiceOut *hw, void *buf, size_t size) { SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw); - assert(buf == out->frame + out->fpos && out->fpos <= out->fsize); - out->fpos += size >> 2; + if (buf) { + assert(buf == out->frame + out->fpos && out->fpos <= out->fsize); + out->fpos += size >> 2; - if (out->fpos == out->fsize) { /* buffer full */ - spice_server_playback_put_samples(&out->sin, out->frame); - out->frame = NULL; + if (out->fpos == out->fsize) { /* buffer full */ + spice_server_playback_put_samples(&out->sin, out->frame); + out->frame = NULL; + } } return size; @@ -310,11 +311,6 @@ static struct audio_driver spice_audio_driver = { .voice_size_in = sizeof (SpiceVoiceIn), }; -void qemu_spice_audio_init (void) -{ - spice_audio_driver.can_be_default = 1; -} - static void register_audio_spice(void) { audio_driver_register(&spice_audio_driver); |