X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=audio%2Fspiceaudio.c;h=7f02f7285cf29e8680201fb0956035af32e4fd87;hb=8fa379170c2a12476021f5f50d6cf3f672e79e7b;hp=999bfbde47c5401f5447585bf663ff209fdbdec3;hpb=a2893c8303e05dda92291487949b611aa361a039;p=qmiga%2Fqemu.git diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 999bfbde47..7f02f7285c 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -22,6 +22,7 @@ #include "qemu/module.h" #include "qemu/error-report.h" #include "qemu/timer.h" +#include "qapi/error.h" #include "ui/qemu-spice.h" #define AUDIO_CAP "spice" @@ -71,11 +72,13 @@ static const SpiceRecordInterface record_sif = { .base.minor_version = SPICE_INTERFACE_RECORD_MINOR, }; -static void *spice_audio_init(Audiodev *dev) +static void *spice_audio_init(Audiodev *dev, Error **errp) { if (!using_spice) { + error_setg(errp, "Cannot use spice audio without -spice"); return NULL; } + return &spice_audio_init; } @@ -120,6 +123,13 @@ static void line_out_fini (HWVoiceOut *hw) spice_server_remove_interface (&out->sin.base); } +static size_t line_out_get_free(HWVoiceOut *hw) +{ + SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw); + + return audio_rate_peek_bytes(&out->rate, &hw->info); +} + static void *line_out_get_buffer(HWVoiceOut *hw, size_t *size) { SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw); @@ -133,8 +143,6 @@ static void *line_out_get_buffer(HWVoiceOut *hw, size_t *size) *size = MIN((out->fsize - out->fpos) << 2, *size); } - *size = audio_rate_get_bytes(&hw->info, &out->rate, *size); - return out->frame + out->fpos; } @@ -142,6 +150,8 @@ static size_t line_out_put_buffer(HWVoiceOut *hw, void *buf, size_t size) { SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw); + audio_rate_add_bytes(&out->rate, size); + if (buf) { assert(buf == out->frame + out->fpos && out->fpos <= out->fsize); out->fpos += size >> 2; @@ -232,10 +242,13 @@ static void line_in_fini (HWVoiceIn *hw) static size_t line_in_read(HWVoiceIn *hw, void *buf, size_t len) { SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); - uint64_t to_read = audio_rate_get_bytes(&hw->info, &in->rate, len) >> 2; + uint64_t to_read = audio_rate_get_bytes(&in->rate, &hw->info, len) >> 2; size_t ready = spice_server_record_get_samples(&in->sin, buf, to_read); - /* XXX: do we need this? */ + /* + * If the client didn't send new frames, it most likely disconnected. + * Generate silence in this case to avoid a stalled audio stream. + */ if (ready == 0) { memset(buf, 0, to_read << 2); ready = to_read; @@ -282,6 +295,7 @@ static struct audio_pcm_ops audio_callbacks = { .init_out = line_out_init, .fini_out = line_out_fini, .write = audio_generic_write, + .buffer_get_free = line_out_get_free, .get_buffer_out = line_out_get_buffer, .put_buffer_out = line_out_put_buffer, .enable_out = line_out_enable, @@ -317,3 +331,5 @@ static void register_audio_spice(void) audio_driver_register(&spice_audio_driver); } type_init(register_audio_spice); + +module_dep("ui-spice-core");