Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging

* fix from optionrom build
* fix for KVM on Apple M2
* introduce machine property "audiodev"
* ui/vnc: Require audiodev= to enable audio
* audio: remove QEMU_AUDIO_* and -audio-help support
* audio: forbid using default audiodev backend with -audiodev and -nodefaults
* remove compatibility code for old machine types
* make-release: do not ship dtc sources
* build system cleanups

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmUb0QgUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroOpnAf9EFXfGkXpqQ5Q8ZbVlVc5GQKofMHW
# OZwamTBlp/c07+QcQiMxwLhIW0iyDhrfdCjoFSUaTA8O10FM1YrFv4SkUryYb9B3
# bmoTl4NeLvmkxpC47GEeaaBfjyM0G/9Ip9Zsuqx3u+gSzwTbkEstA2u7gcsN0tL9
# VlhMSiV82uHhRC/DJYLxr+8bRYSIm1AeuI8K/O1yags85Kztf3UiQUhePIKLznMH
# BdORjD+i46xM1dE8ifpdsunm462cDWz/faAnIH0YVKBlshnQHXKTO+GDA/Fbfl51
# wFfupZXo93wwgawS7elAUzI+gwaKCPRHA8NDcukeO91hTzk6i14y04u5SQ==
# =nv64
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 03 Oct 2023 04:30:00 EDT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (24 commits)
  audio: forbid default audiodev backend with -nodefaults
  audio: propagate Error * out of audio_init
  vt82c686 machines: Support machine-default audiodev with fallback
  hw/ppc: Support machine-default audiodev with fallback
  hw/arm: Support machine-default audiodev with fallback
  Introduce machine property "audiodev"
  audio: remove QEMU_AUDIO_* and -audio-help support
  audio: simplify flow in audio_init
  audio: commonize voice initialization
  audio: return Error ** from audio_state_by_name
  audio: allow returning an error from the driver init
  audio: Require AudioState in AUD_add_capture
  ui/vnc: Require audiodev= to enable audio
  crypto: only include tls-cipher-suites in emulators
  scsi-disk: ensure that FORMAT UNIT commands are terminated
  esp: restrict non-DMA transfer length to that of available data
  esp: use correct type for esp_dma_enable() in sysbus_esp_gpio_demux()
  Makefile: build plugins before running TCG tests
  meson: clean up static_library keyword arguments
  make-release: do not ship dtc sources
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2023-10-03 07:43:44 -04:00
76 changed files with 515 additions and 958 deletions
+28 -4
View File
@@ -2851,7 +2851,13 @@ bool kvm_cpu_check_are_resettable(void)
static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
{
if (!cpu->vcpu_dirty) {
kvm_arch_get_registers(cpu);
int ret = kvm_arch_get_registers(cpu);
if (ret) {
error_report("Failed to get registers: %s", strerror(-ret));
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
vm_stop(RUN_STATE_INTERNAL_ERROR);
}
cpu->vcpu_dirty = true;
}
}
@@ -2865,7 +2871,13 @@ void kvm_cpu_synchronize_state(CPUState *cpu)
static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
{
kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
if (ret) {
error_report("Failed to put registers after reset: %s", strerror(-ret));
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
vm_stop(RUN_STATE_INTERNAL_ERROR);
}
cpu->vcpu_dirty = false;
}
@@ -2876,7 +2888,12 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu)
static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
{
kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
if (ret) {
error_report("Failed to put registers after init: %s", strerror(-ret));
exit(1);
}
cpu->vcpu_dirty = false;
}
@@ -2969,7 +2986,14 @@ int kvm_cpu_exec(CPUState *cpu)
MemTxAttrs attrs;
if (cpu->vcpu_dirty) {
kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
if (ret) {
error_report("Failed to put registers after init: %s",
strerror(-ret));
ret = -1;
break;
}
cpu->vcpu_dirty = false;
}
+1 -2
View File
@@ -904,7 +904,7 @@ static void alsa_init_per_direction(AudiodevAlsaPerDirectionOptions *apdo)
}
}
static void *alsa_audio_init(Audiodev *dev)
static void *alsa_audio_init(Audiodev *dev, Error **errp)
{
AudiodevAlsaOptions *aopts;
assert(dev->driver == AUDIODEV_DRIVER_ALSA);
@@ -960,7 +960,6 @@ static struct audio_driver alsa_audio_driver = {
.init = alsa_audio_init,
.fini = alsa_audio_fini,
.pcm_ops = &alsa_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof (ALSAVoiceOut),
+4 -2
View File
@@ -26,6 +26,7 @@
#include "audio/audio.h"
#include "monitor/hmp.h"
#include "monitor/monitor.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
@@ -65,10 +66,11 @@ void hmp_wavcapture(Monitor *mon, const QDict *qdict)
int nchannels = qdict_get_try_int(qdict, "nchannels", 2);
const char *audiodev = qdict_get_str(qdict, "audiodev");
CaptureState *s;
AudioState *as = audio_state_by_name(audiodev);
Error *local_err = NULL;
AudioState *as = audio_state_by_name(audiodev, &local_err);
if (!as) {
monitor_printf(mon, "Audiodev '%s' not found\n", audiodev);
error_report_err(local_err);
return;
}
+116 -130
View File
@@ -32,7 +32,9 @@
#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-visit-audio.h"
#include "qapi/qapi-commands-audio.h"
#include "qapi/qmp/qdict.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/help_option.h"
@@ -61,19 +63,22 @@ const char *audio_prio_list[] = {
"spice",
CONFIG_AUDIO_DRIVERS
"none",
"wav",
NULL
};
static QLIST_HEAD(, audio_driver) audio_drivers;
static AudiodevListHead audiodevs = QSIMPLEQ_HEAD_INITIALIZER(audiodevs);
static AudiodevListHead audiodevs =
QSIMPLEQ_HEAD_INITIALIZER(audiodevs);
static AudiodevListHead default_audiodevs =
QSIMPLEQ_HEAD_INITIALIZER(default_audiodevs);
void audio_driver_register(audio_driver *drv)
{
QLIST_INSERT_HEAD(&audio_drivers, drv, next);
}
audio_driver *audio_driver_lookup(const char *name)
static audio_driver *audio_driver_lookup(const char *name)
{
struct audio_driver *d;
Error *local_err = NULL;
@@ -111,8 +116,6 @@ const struct mixeng_volume nominal_volume = {
#endif
};
static bool legacy_config = true;
int audio_bug (const char *funcname, int cond)
{
if (cond) {
@@ -1553,9 +1556,11 @@ size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size)
}
static int audio_driver_init(AudioState *s, struct audio_driver *drv,
bool msg, Audiodev *dev)
Audiodev *dev, Error **errp)
{
s->drv_opaque = drv->init(dev);
Error *local_err = NULL;
s->drv_opaque = drv->init(dev, &local_err);
if (s->drv_opaque) {
if (!drv->pcm_ops->get_buffer_in) {
@@ -1567,13 +1572,15 @@ static int audio_driver_init(AudioState *s, struct audio_driver *drv,
drv->pcm_ops->put_buffer_out = audio_generic_put_buffer_out;
}
audio_init_nb_voices_out(s, drv);
audio_init_nb_voices_in(s, drv);
audio_init_nb_voices_out(s, drv, 1);
audio_init_nb_voices_in(s, drv, 0);
s->drv = drv;
return 0;
} else {
if (msg) {
dolog("Could not init `%s' audio driver\n", drv->name);
if (local_err) {
error_propagate(errp, local_err);
} else {
error_setg(errp, "Could not init `%s' audio driver", drv->name);
}
return -1;
}
@@ -1681,17 +1688,45 @@ static const VMStateDescription vmstate_audio = {
static void audio_validate_opts(Audiodev *dev, Error **errp);
static AudiodevListEntry *audiodev_find(
AudiodevListHead *head, const char *drvname)
static void audio_create_default_audiodevs(void)
{
AudiodevListEntry *e;
QSIMPLEQ_FOREACH(e, head, next) {
if (strcmp(AudiodevDriver_str(e->dev->driver), drvname) == 0) {
return e;
}
const char *drvname = getenv("QEMU_AUDIO_DRV");
if (!defaults_enabled()) {
return;
}
return NULL;
/* QEMU_AUDIO_DRV=none is used by libqtest. */
if (drvname && !g_str_equal(drvname, "none")) {
error_report("Please use -audiodev instead of QEMU_AUDIO_*");
exit(1);
}
for (int i = 0; audio_prio_list[i]; i++) {
if (drvname && !g_str_equal(drvname, audio_prio_list[i])) {
continue;
}
if (audio_driver_lookup(audio_prio_list[i])) {
QDict *dict = qdict_new();
Audiodev *dev = NULL;
AudiodevListEntry *e;
Visitor *v;
qdict_put_str(dict, "driver", audio_prio_list[i]);
qdict_put_str(dict, "id", "#default");
v = qobject_input_visitor_new_keyval(QOBJECT(dict));
qobject_unref(dict);
visit_type_Audiodev(v, NULL, &dev, &error_fatal);
visit_free(v);
audio_validate_opts(dev, &error_abort);
e = g_new0(AudiodevListEntry, 1);
e->dev = dev;
QSIMPLEQ_INSERT_TAIL(&default_audiodevs, e, next);
}
}
}
/*
@@ -1700,62 +1735,16 @@ static AudiodevListEntry *audiodev_find(
* if dev == NULL => legacy implicit initialization, return the already created
* state or create a new one
*/
static AudioState *audio_init(Audiodev *dev, const char *name)
static AudioState *audio_init(Audiodev *dev, Error **errp)
{
static bool atexit_registered;
size_t i;
int done = 0;
const char *drvname = NULL;
const char *drvname;
VMChangeStateEntry *vmse;
AudioState *s;
struct audio_driver *driver;
/* 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");
if (driver) {
driver->can_be_default = 1;
}
}
if (dev) {
/* -audiodev option */
legacy_config = false;
drvname = AudiodevDriver_str(dev->driver);
} else if (!QTAILQ_EMPTY(&audio_states)) {
if (!legacy_config) {
dolog("Device %s: audiodev default parameter is deprecated, please "
"specify audiodev=%s\n", name,
QTAILQ_FIRST(&audio_states)->dev->id);
}
return QTAILQ_FIRST(&audio_states);
} else {
/* legacy implicit initialization */
head = audio_handle_legacy_opts();
/*
* In case of legacy initialization, all Audiodevs in the list will have
* the same configuration (except the driver), so it doesn't matter which
* one we chose. We need an Audiodev to set up AudioState before we can
* init a driver. Also note that dev at this point is still in the
* list.
*/
dev = QSIMPLEQ_FIRST(&head)->dev;
audio_validate_opts(dev, &error_abort);
}
s = g_new0(AudioState, 1);
s->dev = dev;
QLIST_INIT (&s->hw_head_out);
QLIST_INIT (&s->hw_head_in);
@@ -1767,56 +1756,35 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
s->nb_hw_voices_out = audio_get_pdo_out(dev)->voices;
s->nb_hw_voices_in = audio_get_pdo_in(dev)->voices;
if (s->nb_hw_voices_out < 1) {
dolog ("Bogus number of playback voices %d, setting to 1\n",
s->nb_hw_voices_out);
s->nb_hw_voices_out = 1;
}
if (s->nb_hw_voices_in < 0) {
dolog ("Bogus number of capture voices %d, setting to 0\n",
s->nb_hw_voices_in);
s->nb_hw_voices_in = 0;
}
if (drvname) {
if (dev) {
/* -audiodev option */
s->dev = dev;
drvname = AudiodevDriver_str(dev->driver);
driver = audio_driver_lookup(drvname);
if (driver) {
done = !audio_driver_init(s, driver, true, dev);
done = !audio_driver_init(s, driver, dev, errp);
} else {
dolog ("Unknown audio driver `%s'\n", drvname);
error_setg(errp, "Unknown audio driver `%s'\n", drvname);
}
if (!done) {
free_audio_state(s);
return NULL;
goto out;
}
} else {
for (i = 0; audio_prio_list[i]; i++) {
AudiodevListEntry *e = audiodev_find(&head, audio_prio_list[i]);
driver = audio_driver_lookup(audio_prio_list[i]);
if (e && driver) {
s->dev = dev = e->dev;
audio_validate_opts(dev, &error_abort);
done = !audio_driver_init(s, driver, false, dev);
if (done) {
e->dev = NULL;
break;
}
for (;;) {
AudiodevListEntry *e = QSIMPLEQ_FIRST(&default_audiodevs);
if (!e) {
error_setg(errp, "no default audio driver available");
goto out;
}
s->dev = dev = e->dev;
drvname = AudiodevDriver_str(dev->driver);
driver = audio_driver_lookup(drvname);
if (!audio_driver_init(s, driver, dev, NULL)) {
break;
}
QSIMPLEQ_REMOVE_HEAD(&default_audiodevs, next);
}
}
audio_free_audiodev_list(&head);
if (!done) {
driver = audio_driver_lookup("none");
done = !audio_driver_init(s, driver, false, dev);
assert(done);
dolog("warning: Using timer based audio emulation\n");
}
if (dev->timer_period <= 0) {
s->period_ticks = 1;
@@ -1834,27 +1802,50 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
QLIST_INIT (&s->card_head);
vmstate_register (NULL, 0, &vmstate_audio, s);
return s;
out:
free_audio_state(s);
return NULL;
}
void audio_free_audiodev_list(AudiodevListHead *head)
{
AudiodevListEntry *e;
while ((e = QSIMPLEQ_FIRST(head))) {
QSIMPLEQ_REMOVE_HEAD(head, next);
qapi_free_Audiodev(e->dev);
g_free(e);
}
}
void AUD_register_card (const char *name, QEMUSoundCard *card)
bool AUD_register_card (const char *name, QEMUSoundCard *card, Error **errp)
{
if (!card->state) {
card->state = audio_init(NULL, name);
if (!QTAILQ_EMPTY(&audio_states)) {
/*
* FIXME: once it is possible to create an arbitrary
* default device via -audio DRIVER,OPT=VALUE (no "model"),
* replace this special case with the default AudioState*,
* storing it in a separate global. For now, keep the
* warning to encourage moving off magic use of the first
* -audiodev.
*/
if (QSIMPLEQ_EMPTY(&default_audiodevs)) {
dolog("Device %s: audiodev default parameter is deprecated, please "
"specify audiodev=%s\n", name,
QTAILQ_FIRST(&audio_states)->dev->id);
}
card->state = QTAILQ_FIRST(&audio_states);
} else {
if (QSIMPLEQ_EMPTY(&default_audiodevs)) {
audio_create_default_audiodevs();
}
card->state = audio_init(NULL, errp);
if (!card->state) {
if (!QSIMPLEQ_EMPTY(&audiodevs)) {
error_append_hint(errp, "Perhaps you wanted to set audiodev=%s?",
QSIMPLEQ_FIRST(&audiodevs)->dev->id);
}
return false;
}
}
}
card->name = g_strdup (name);
memset (&card->entries, 0, sizeof (card->entries));
QLIST_INSERT_HEAD(&card->state->card_head, card, entries);
return true;
}
void AUD_remove_card (QEMUSoundCard *card)
@@ -1876,10 +1867,8 @@ CaptureVoiceOut *AUD_add_capture(
struct capture_callback *cb;
if (!s) {
if (!legacy_config) {
dolog("Capturing without setting an audiodev is deprecated\n");
}
s = audio_init(NULL, NULL);
error_report("Capturing without setting an audiodev is not supported");
abort();
}
if (!audio_get_pdo_out(s->dev)->mixing_engine) {
@@ -2183,17 +2172,13 @@ void audio_define(Audiodev *dev)
QSIMPLEQ_INSERT_TAIL(&audiodevs, e, next);
}
bool audio_init_audiodevs(void)
void audio_init_audiodevs(void)
{
AudiodevListEntry *e;
QSIMPLEQ_FOREACH(e, &audiodevs, next) {
if (!audio_init(e->dev, NULL)) {
return false;
}
audio_init(e->dev, &error_fatal);
}
return true;
}
audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo)
@@ -2255,7 +2240,7 @@ int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo,
audioformat_bytes_per_sample(as->fmt);
}
AudioState *audio_state_by_name(const char *name)
AudioState *audio_state_by_name(const char *name, Error **errp)
{
AudioState *s;
QTAILQ_FOREACH(s, &audio_states, list) {
@@ -2264,6 +2249,7 @@ AudioState *audio_state_by_name(const char *name)
return s;
}
}
error_setg(errp, "audiodev '%s' not found", name);
return NULL;
}
+3 -4
View File
@@ -94,7 +94,7 @@ typedef struct QEMUAudioTimeStamp {
void AUD_vlog (const char *cap, const char *fmt, va_list ap) G_GNUC_PRINTF(2, 0);
void AUD_log (const char *cap, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
void AUD_register_card (const char *name, QEMUSoundCard *card);
bool AUD_register_card (const char *name, QEMUSoundCard *card, Error **errp);
void AUD_remove_card (QEMUSoundCard *card);
CaptureVoiceOut *AUD_add_capture(
AudioState *s,
@@ -170,11 +170,10 @@ void audio_sample_from_uint64(void *samples, int pos,
void audio_define(Audiodev *audio);
void audio_parse_option(const char *opt);
bool audio_init_audiodevs(void);
void audio_init_audiodevs(void);
void audio_help(void);
void audio_legacy_help(void);
AudioState *audio_state_by_name(const char *name);
AudioState *audio_state_by_name(const char *name, Error **errp);
const char *audio_get_id(QEMUSoundCard *card);
#define DEFINE_AUDIO_PROPERTIES(_s, _f) \
+1 -6
View File
@@ -140,13 +140,12 @@ typedef struct audio_driver audio_driver;
struct audio_driver {
const char *name;
const char *descr;
void *(*init) (Audiodev *);
void *(*init) (Audiodev *, Error **);
void (*fini) (void *);
#ifdef CONFIG_GIO
void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *manager, bool p2p);
#endif
struct audio_pcm_ops *pcm_ops;
int can_be_default;
int max_voices_out;
int max_voices_in;
size_t voice_size_out;
@@ -243,7 +242,6 @@ extern const struct mixeng_volume nominal_volume;
extern const char *audio_prio_list[];
void audio_driver_register(audio_driver *drv);
audio_driver *audio_driver_lookup(const char *name);
void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
@@ -297,9 +295,6 @@ typedef struct AudiodevListEntry {
} AudiodevListEntry;
typedef QSIMPLEQ_HEAD(, AudiodevListEntry) AudiodevListHead;
AudiodevListHead audio_handle_legacy_opts(void);
void audio_free_audiodev_list(AudiodevListHead *head);
void audio_create_pdos(Audiodev *dev);
AudiodevPerDirectionOptions *audio_get_pdo_in(Audiodev *dev);
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -37,11 +37,12 @@
#endif
static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
struct audio_driver *drv)
struct audio_driver *drv, int min_voices)
{
int max_voices = glue (drv->max_voices_, TYPE);
size_t voice_size = glue(drv->voice_size_, TYPE);
glue (s->nb_hw_voices_, TYPE) = glue(audio_get_pdo_, TYPE)(s->dev)->voices;
if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
if (!max_voices) {
#ifdef DAC
@@ -56,6 +57,12 @@ static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
glue (s->nb_hw_voices_, TYPE) = max_voices;
}
if (glue (s->nb_hw_voices_, TYPE) < min_voices) {
dolog ("Bogus number of " NAME " voices %d, setting to %d\n",
glue (s->nb_hw_voices_, TYPE),
min_voices);
}
if (audio_bug(__func__, !voice_size && max_voices)) {
dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
drv->name, max_voices);
+1 -2
View File
@@ -644,7 +644,7 @@ static void coreaudio_enable_out(HWVoiceOut *hw, bool enable)
update_device_playback_state(core);
}
static void *coreaudio_audio_init(Audiodev *dev)
static void *coreaudio_audio_init(Audiodev *dev, Error **errp)
{
return dev;
}
@@ -673,7 +673,6 @@ static struct audio_driver coreaudio_audio_driver = {
.init = coreaudio_audio_init,
.fini = coreaudio_audio_fini,
.pcm_ops = &coreaudio_pcm_ops,
.can_be_default = 1,
.max_voices_out = 1,
.max_voices_in = 0,
.voice_size_out = sizeof (coreaudioVoiceOut),
+1 -2
View File
@@ -395,7 +395,7 @@ dbus_enable_in(HWVoiceIn *hw, bool enable)
}
static void *
dbus_audio_init(Audiodev *dev)
dbus_audio_init(Audiodev *dev, Error **errp)
{
DBusAudio *da = g_new0(DBusAudio, 1);
@@ -676,7 +676,6 @@ static struct audio_driver dbus_audio_driver = {
.fini = dbus_audio_fini,
.set_dbus_server = dbus_audio_set_server,
.pcm_ops = &dbus_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(DBusVoiceOut),
+1 -2
View File
@@ -619,7 +619,7 @@ static void dsound_audio_fini (void *opaque)
g_free(s);
}
static void *dsound_audio_init(Audiodev *dev)
static void *dsound_audio_init(Audiodev *dev, Error **errp)
{
int err;
HRESULT hr;
@@ -721,7 +721,6 @@ static struct audio_driver dsound_audio_driver = {
.init = dsound_audio_init,
.fini = dsound_audio_fini,
.pcm_ops = &dsound_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = 1,
.voice_size_out = sizeof (DSoundVoiceOut),
+1 -2
View File
@@ -645,7 +645,7 @@ static int qjack_thread_creator(jack_native_thread_t *thread,
}
#endif
static void *qjack_init(Audiodev *dev)
static void *qjack_init(Audiodev *dev, Error **errp)
{
assert(dev->driver == AUDIODEV_DRIVER_JACK);
return dev;
@@ -676,7 +676,6 @@ static struct audio_driver jack_driver = {
.init = qjack_init,
.fini = qjack_fini,
.pcm_ops = &jack_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(QJackOut),
-1
View File
@@ -1,7 +1,6 @@
system_ss.add([spice_headers, files('audio.c')])
system_ss.add(files(
'audio-hmp-cmds.c',
'audio_legacy.c',
'mixeng.c',
'noaudio.c',
'wavaudio.c',
+1 -2
View File
@@ -104,7 +104,7 @@ static void no_enable_in(HWVoiceIn *hw, bool enable)
}
}
static void *no_audio_init(Audiodev *dev)
static void *no_audio_init(Audiodev *dev, Error **errp)
{
return &no_audio_init;
}
@@ -135,7 +135,6 @@ static struct audio_driver no_audio_driver = {
.init = no_audio_init,
.fini = no_audio_fini,
.pcm_ops = &no_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof (NoVoiceOut),
+8 -4
View File
@@ -28,6 +28,7 @@
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/host-utils.h"
#include "qapi/error.h"
#include "audio.h"
#include "trace.h"
@@ -736,7 +737,7 @@ static void oss_init_per_direction(AudiodevOssPerDirectionOptions *opdo)
}
}
static void *oss_audio_init(Audiodev *dev)
static void *oss_audio_init(Audiodev *dev, Error **errp)
{
AudiodevOssOptions *oopts;
assert(dev->driver == AUDIODEV_DRIVER_OSS);
@@ -745,8 +746,12 @@ static void *oss_audio_init(Audiodev *dev)
oss_init_per_direction(oopts->in);
oss_init_per_direction(oopts->out);
if (access(oopts->in->dev ?: "/dev/dsp", R_OK | W_OK) < 0 ||
access(oopts->out->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
if (access(oopts->in->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
error_setg_errno(errp, errno, "%s not accessible", oopts->in->dev ?: "/dev/dsp");
return NULL;
}
if (access(oopts->out->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
error_setg_errno(errp, errno, "%s not accessible", oopts->out->dev ?: "/dev/dsp");
return NULL;
}
return dev;
@@ -779,7 +784,6 @@ static struct audio_driver oss_audio_driver = {
.init = oss_audio_init,
.fini = oss_audio_fini,
.pcm_ops = &oss_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof (OSSVoiceOut),
+5 -3
View File
@@ -3,7 +3,7 @@
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "audio.h"
#include "qapi/opts-visitor.h"
#include "qapi/error.h"
#include <pulse/pulseaudio.h>
@@ -818,7 +818,7 @@ fail:
return NULL;
}
static void *qpa_audio_init(Audiodev *dev)
static void *qpa_audio_init(Audiodev *dev, Error **errp)
{
paaudio *g;
AudiodevPaOptions *popts = &dev->u.pa;
@@ -834,10 +834,12 @@ static void *qpa_audio_init(Audiodev *dev)
runtime = getenv("XDG_RUNTIME_DIR");
if (!runtime) {
error_setg(errp, "XDG_RUNTIME_DIR not set");
return NULL;
}
snprintf(pidfile, sizeof(pidfile), "%s/pulse/pid", runtime);
if (stat(pidfile, &st) != 0) {
error_setg_errno(errp, errno, "could not stat pidfile %s", pidfile);
return NULL;
}
}
@@ -867,6 +869,7 @@ static void *qpa_audio_init(Audiodev *dev)
}
if (!g->conn) {
g_free(g);
error_setg(errp, "could not connect to PulseAudio server");
return NULL;
}
@@ -928,7 +931,6 @@ static struct audio_driver pa_audio_driver = {
.init = qpa_audio_init,
.fini = qpa_audio_fini,
.pcm_ops = &qpa_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof (PAVoiceOut),
+9 -8
View File
@@ -13,6 +13,7 @@
#include "audio.h"
#include <errno.h>
#include "qemu/error-report.h"
#include "qapi/error.h"
#include <spa/param/audio/format-utils.h>
#include <spa/utils/ringbuffer.h>
#include <spa/utils/result.h>
@@ -736,7 +737,7 @@ static const struct pw_core_events core_events = {
};
static void *
qpw_audio_init(Audiodev *dev)
qpw_audio_init(Audiodev *dev, Error **errp)
{
g_autofree pwaudio *pw = g_new0(pwaudio, 1);
@@ -748,19 +749,19 @@ qpw_audio_init(Audiodev *dev)
pw->dev = dev;
pw->thread_loop = pw_thread_loop_new("PipeWire thread loop", NULL);
if (pw->thread_loop == NULL) {
error_report("Could not create PipeWire loop: %s", g_strerror(errno));
error_setg_errno(errp, errno, "Could not create PipeWire loop");
goto fail;
}
pw->context =
pw_context_new(pw_thread_loop_get_loop(pw->thread_loop), NULL, 0);
if (pw->context == NULL) {
error_report("Could not create PipeWire context: %s", g_strerror(errno));
error_setg_errno(errp, errno, "Could not create PipeWire context");
goto fail;
}
if (pw_thread_loop_start(pw->thread_loop) < 0) {
error_report("Could not start PipeWire loop: %s", g_strerror(errno));
error_setg_errno(errp, errno, "Could not start PipeWire loop");
goto fail;
}
@@ -769,13 +770,13 @@ qpw_audio_init(Audiodev *dev)
pw->core = pw_context_connect(pw->context, NULL, 0);
if (pw->core == NULL) {
pw_thread_loop_unlock(pw->thread_loop);
goto fail;
goto fail_error;
}
if (pw_core_add_listener(pw->core, &pw->core_listener,
&core_events, pw) < 0) {
pw_thread_loop_unlock(pw->thread_loop);
goto fail;
goto fail_error;
}
if (wait_resync(pw) < 0) {
pw_thread_loop_unlock(pw->thread_loop);
@@ -785,8 +786,9 @@ qpw_audio_init(Audiodev *dev)
return g_steal_pointer(&pw);
fail_error:
error_setg(errp, "Failed to initialize PW context");
fail:
AUD_log(AUDIO_CAP, "Failed to initialize PW context");
if (pw->thread_loop) {
pw_thread_loop_stop(pw->thread_loop);
}
@@ -841,7 +843,6 @@ static struct audio_driver pw_audio_driver = {
.init = qpw_audio_init,
.fini = qpw_audio_fini,
.pcm_ops = &qpw_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(PWVoiceOut),
+3 -3
View File
@@ -26,6 +26,7 @@
#include <SDL.h>
#include <SDL_thread.h>
#include "qemu/module.h"
#include "qapi/error.h"
#include "audio.h"
#ifndef _WIN32
@@ -449,10 +450,10 @@ static void sdl_enable_in(HWVoiceIn *hw, bool enable)
SDL_PauseAudioDevice(sdl->devid, !enable);
}
static void *sdl_audio_init(Audiodev *dev)
static void *sdl_audio_init(Audiodev *dev, Error **errp)
{
if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
sdl_logerr ("SDL failed to initialize audio subsystem\n");
error_setg(errp, "SDL failed to initialize audio subsystem");
return NULL;
}
@@ -493,7 +494,6 @@ static struct audio_driver sdl_audio_driver = {
.init = sdl_audio_init,
.fini = sdl_audio_fini,
.pcm_ops = &sdl_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(SDLVoiceOut),
+1 -2
View File
@@ -518,7 +518,7 @@ static void sndio_fini_in(HWVoiceIn *hw)
sndio_fini(self);
}
static void *sndio_audio_init(Audiodev *dev)
static void *sndio_audio_init(Audiodev *dev, Error **errp)
{
assert(dev->driver == AUDIODEV_DRIVER_SNDIO);
return dev;
@@ -550,7 +550,6 @@ static struct audio_driver sndio_audio_driver = {
.init = sndio_audio_init,
.fini = sndio_audio_fini,
.pcm_ops = &sndio_pcm_ops,
.can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(SndioVoice),
+4 -1
View File
@@ -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;
}

Some files were not shown because too many files have changed in this diff Show More