mirror of https://github.com/xemu-project/xemu.git
audio: various buffering fixes.
audio: build spiceaudio as module. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCgAGBQJfaxDaAAoJEEy22O7T6HE4CNEP/ibm5gDvhzdQVzALSQWPCZNF MqWm1PK4AzSCa+hXfk0PvEGkiCvybw6D2jNmzvQCDHcMDUk3TiQjFBHIiNdVQcAZ U4ZbYcDsiHiJub9ePDf30Vjyq8D6JNuhv4hB4YTAYEpXst3CdnXWBb+wf3KeJ28z gYxJ2wSQeEwOGa53Ttlbx3MrQ2GtsWUAIszNIU6xQ61kfP15/N86+0x5J/0NATmI Kb3Qiha0A06xWG67bYdIr9+MRqcBv/34O2G2t5U+1Di7AMe3elqBwGYQ3qiOoYz2 DKl6rvJfBisisvTyqLwaMvEVpus1N83vkGNKEpSSlHfIqqnZ3roikKKHMLZWubO5 QMr5f7ZmrAc1PUrhoKfcBclbumavlpdKiyDMGbdZS4iOhhlcUgE31dhlpnkYJBfg HFjKEVQB5qXEnhalaKsgr/Ux50/+ctGTo5vX7/kpLGO58V8Rtej558vXd1DIIS9P V0FUUbxwkROd3Mvb+NQYpaRJwaMXaHsCRWHXJRGM2CmarUdRGObEPbhAhdOuOTUB ejdv0MrgHtDYM62Ed2UB73YlSLtWJbW2uNHjRpro5rQ4F4lVk5q/b5K6yp5l7CCv YvPEmiXng0VYWtu9im4EN9lqVNxJdtZ1ihzWsdd3qUu5s/ur2FraQgMIAF4Q7ZIY BEA7cutPwME/XvLO07F1 =bdMY -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
1bd5556f66
|
@ -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;
|
||||
|
||||
memcpy(dst, buf, copy_size);
|
||||
return hw->pcm_ops->put_buffer_out(hw, dst, copy_size);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -29,7 +29,6 @@ extern int using_spice;
|
|||
|
||||
void qemu_spice_init(void);
|
||||
void qemu_spice_input_init(void);
|
||||
void qemu_spice_audio_init(void);
|
||||
void qemu_spice_display_init(void);
|
||||
int qemu_spice_display_add_client(int csock, int skipauth, int tls);
|
||||
int qemu_spice_add_interface(SpiceBaseInstance *sin);
|
||||
|
|
|
@ -804,7 +804,6 @@ void qemu_spice_init(void)
|
|||
qemu_spice_add_interface(&spice_migrate.base);
|
||||
|
||||
qemu_spice_input_init();
|
||||
qemu_spice_audio_init();
|
||||
|
||||
qemu_add_vm_change_state_handler(vm_change_state_handler, NULL);
|
||||
qemu_spice_display_stop();
|
||||
|
|
Loading…
Reference in New Issue