From: Marc-André Lureau <[email protected]> Now "audio_driver" is a detail implementation of AudioMixengBackend and not required to implement an AudioBackend.
Reviewed-by: Mark Cave-Ayland <[email protected]> Reviewed-by: Akihiko Odaki <[email protected]> Signed-off-by: Marc-André Lureau <[email protected]> --- include/qemu/audio.h | 1 + audio/audio.c | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/include/qemu/audio.h b/include/qemu/audio.h index 474d761f0be..1eeead2a722 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 5d0f5ad2145..72949fe27f5 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -1562,24 +1562,16 @@ 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_mixeng_backend_realize(AudioBackend *abe, + Audiodev *dev, Error **errp) { - const char *drvname = AudiodevDriver_str(dev->driver); - struct audio_driver *drv = audio_driver_lookup(drvname); + AudioMixengBackend *be = AUDIO_MIXENG_BACKEND(abe); + audio_driver *drv = AUDIO_MIXENG_BACKEND_GET_CLASS(be)->driver; - if (!drv) { - error_setg(errp, "Unknown audio driver `%s'", drvname); - qapi_free_Audiodev(dev); - return NULL; - } - - AudioMixengBackend *be = AUDIO_MIXENG_BACKEND(object_new(TYPE_AUDIO_MIXENG_BACKEND)); be->dev = dev; - be->drv_opaque = drv->init(be->dev, errp); if (!be->drv_opaque) { - object_unref(OBJECT(be)); - return NULL; + return false; } if (!drv->pcm_ops->get_buffer_in) { @@ -1601,7 +1593,26 @@ static AudioBackend *audio_be_new(Audiodev *dev, Error **errp) be->period_ticks = be->dev->timer_period * (int64_t)SCALE_US; } - return AUDIO_BACKEND(be); + 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, @@ -1644,6 +1655,7 @@ static void audio_mixeng_backend_class_init(ObjectClass *klass, const void *data { AudioBackendClass *be = AUDIO_BACKEND_CLASS(klass); + be->realize = audio_mixeng_backend_realize; be->get_id = audio_mixeng_backend_get_id; } -- 2.53.0
