On 04/02/2026 14:39, Marc-André Lureau wrote:
> Hi
>
> On Wed, Feb 4, 2026 at 3:33 PM Mark Cave-Ayland
> <mark.caveayland@nutanix.com> wrote:
>>
>> On 23/01/2026 07:49, marcandre.lureau@redhat.com wrote:
>>
>>> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>
>>> Now "audio_driver" is a detail implementation of AudioMixengBackend and
>>> not required to implement an AudioBackend.
>>>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> ---
>>> 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 7e23a63d401..f6896229cfb 100644
>>> --- a/audio/audio.c
>>> +++ b/audio/audio.c
>>> @@ -1561,24 +1561,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) {
>>> @@ -1600,7 +1592,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,
>>> @@ -1643,6 +1654,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;
>>> }
>>
>> I'm wondering if an AudioBackendClass realize() method is the right way
>> to handle this, and if instead an object_property_set() function could
>> be used to set a "driver" property?
>>
>
> By the end of the refactoring, "driver" is gone. Effectively, each
> (current) backend will inherit from AudioMixengBe.
(goes and looks)
I see, so this happens in part 2 of the series. If the property were
exposed directly to callers then I'd prefer to use an object setter to
bind the Audiodev to the backend. However in this case it's all nicely
tucked away in audio_be_new() so it doesn't really matter. Hence:
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
ATB,
Mark.