From: Marc-André Lureau <[email protected]> Now "audio_driver" is a detail implementation of AudioBEDriver and not required to implement an AudioBE.
Signed-off-by: Marc-André Lureau <[email protected]> --- include/qemu/audio.h | 1 + audio/audio.c | 38 +++++++++++++++++++++++++------------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/include/qemu/audio.h b/include/qemu/audio.h index f83f8326ab..3abf1037f8 100644 --- a/include/qemu/audio.h +++ b/include/qemu/audio.h @@ -51,6 +51,7 @@ typedef struct AudioBackend { typedef struct AudioBackendClass { ObjectClass parent_class; + bool (*realize)(AudioBackend *be, Audiodev *dev, Error **errp); const char *(*get_id)(AudioBackend *be); #ifdef CONFIG_GIO bool (*set_dbus_server)(AudioBackend *be, diff --git a/audio/audio.c b/audio/audio.c index 1693563c62..31459f9707 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -1563,23 +1563,15 @@ size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size) return total; } -static AudioBackend *audio_be_new(Audiodev *dev, Error **errp) +static bool audio_be_driver_realize(AudioBackend *abe, Audiodev *dev, Error **errp) { - const char *drvname = AudiodevDriver_str(dev->driver); - struct audio_driver *drv = audio_driver_lookup(drvname); - - if (!drv) { - error_setg(errp, "Unknown audio driver `%s'", drvname); - return NULL; - } + AudioDriver *d = AUDIO_DRIVER(abe); + audio_driver *drv = AUDIO_DRIVER_GET_CLASS(d)->driver; - AudioDriver *d = AUDIO_DRIVER(object_new(TYPE_AUDIO_DRIVER)); d->dev = dev; - d->drv_opaque = drv->init(d->dev, errp); if (!d->drv_opaque) { - object_unref(OBJECT(d)); - return NULL; + return false; } if (!drv->pcm_ops->get_buffer_in) { @@ -1601,7 +1593,26 @@ static AudioBackend *audio_be_new(Audiodev *dev, Error **errp) d->period_ticks = d->dev->timer_period * (int64_t)SCALE_US; } - return AUDIO_BACKEND(d); + return true; +} + +static AudioBackend *audio_be_new(Audiodev *dev, Error **errp) +{ + const char *drvname = AudiodevDriver_str(dev->driver); + g_autofree char *type = g_strconcat("audio-", drvname, NULL); + AudioBackend *be = AUDIO_BACKEND(object_new(type)); + + if (!be) { + error_setg(errp, "Unknown audio driver `%s'", drvname); + return NULL; + } + + if (!AUDIO_BACKEND_GET_CLASS(be)->realize(be, dev, errp)) { + object_unref(OBJECT(be)); + return NULL; + } + + return be; } static void audio_vm_change_state_handler (void *opaque, bool running, @@ -1645,6 +1656,7 @@ static void audio_driver_class_init(ObjectClass *klass, const void *data) { AudioBackendClass *be = AUDIO_BACKEND_CLASS(klass); + be->realize = audio_be_driver_realize; be->get_id = audio_driver_get_id; } -- 2.51.1
