[PATCH 15/18] audio: Be more strict during audio backend initialisation

Daniel P. Berrangé berrange at redhat.com
Mon Apr 25 14:16:27 UTC 2022


On Mon, Apr 25, 2022 at 10:21:58AM +0200, Martin Kletzander wrote:
> Now that audiodev= is required and audio_init() will not be called
> without and AudioDev we can remove the fallback functionality and error
> out in case audio drivers fail initialisation or when the driver does
> not exist.
> 
> Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
> ---
>  audio/audio.c                   | 146 ++++++--------------------------
>  docs/about/deprecated.rst       |   8 --
>  docs/about/removed-features.rst |   8 ++
>  3 files changed, 34 insertions(+), 128 deletions(-)
> 
> diff --git a/audio/audio.c b/audio/audio.c
> index 97eb645764c1..c944cf817cf9 100644
> --- a/audio/audio.c
> +++ b/audio/audio.c
> @@ -87,6 +87,8 @@ audio_driver *audio_driver_lookup(const char *name)
>          }
>      }
>  
> +    error_setg(&error_fatal, "Unknown audio driver `%s'", name);
> +    /* Avoid compiler complaining that we do not return in non-void function */
>      return NULL;
>  }

I'd be inclined to plumb in 'Error **errp' here and in the next two
callers up, and pass &error_fatal from softmmu/vl.c

>  
> @@ -104,8 +106,6 @@ const struct mixeng_volume nominal_volume = {
>  #endif
>  };
>  
> -static bool legacy_config = true;
> -
>  int audio_bug (const char *funcname, int cond)
>  {
>      if (cond) {
> @@ -1532,31 +1532,27 @@ size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size)
>      return total;
>  }
>  
> -static int audio_driver_init(AudioState *s, struct audio_driver *drv,
> -                             bool msg, Audiodev *dev)
> +static void audio_driver_init(AudioState *s, struct audio_driver *drv,
> +                              Audiodev *dev)
>  {
>      s->drv_opaque = drv->init(dev);
>  
> -    if (s->drv_opaque) {
> -        if (!drv->pcm_ops->get_buffer_in) {
> -            drv->pcm_ops->get_buffer_in = audio_generic_get_buffer_in;
> -            drv->pcm_ops->put_buffer_in = audio_generic_put_buffer_in;
> -        }
> -        if (!drv->pcm_ops->get_buffer_out) {
> -            drv->pcm_ops->get_buffer_out = audio_generic_get_buffer_out;
> -            drv->pcm_ops->put_buffer_out = audio_generic_put_buffer_out;
> -        }
> +    if (!s->drv_opaque) {
> +        error_setg(&error_fatal, "Could not init `%s' audio driver", drv->name);
> +    }
>  
> -        audio_init_nb_voices_out(s, drv);
> -        audio_init_nb_voices_in(s, drv);
> -        s->drv = drv;
> -        return 0;
> -    } else {
> -        if (msg) {
> -            dolog("Could not init `%s' audio driver\n", drv->name);
> -        }
> -        return -1;
> +    if (!drv->pcm_ops->get_buffer_in) {
> +        drv->pcm_ops->get_buffer_in = audio_generic_get_buffer_in;
> +        drv->pcm_ops->put_buffer_in = audio_generic_put_buffer_in;
>      }
> +    if (!drv->pcm_ops->get_buffer_out) {
> +        drv->pcm_ops->get_buffer_out = audio_generic_get_buffer_out;
> +        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);
> +    s->drv = drv;
>  }
>  
>  static void audio_vm_change_state_handler (void *opaque, bool running,
> @@ -1661,79 +1657,19 @@ static const VMStateDescription vmstate_audio = {
>  
>  static void audio_validate_opts(Audiodev *dev, Error **errp);
>  
> -static AudiodevListEntry *audiodev_find(
> -    AudiodevListHead *head, const char *drvname)
> -{
> -    AudiodevListEntry *e;
> -    QSIMPLEQ_FOREACH(e, head, next) {
> -        if (strcmp(AudiodevDriver_str(e->dev->driver), drvname) == 0) {
> -            return e;
> -        }
> -    }
> -
> -    return NULL;
> -}
> -
> -/*
> - * if we have dev, this function was called because of an -audiodev argument =>
> - *   initialize a new state with it
> - * 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)
>  {
>      static bool atexit_registered;
> -    size_t i;
> -    int done = 0;
>      const char *drvname = NULL;
>      VMChangeStateEntry *e;
>      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);
> +    if (!dev) {
> +        error_setg(&error_abort, "Mandatory audiodev parameter required");
>      }
>  
> +    drvname = AudiodevDriver_str(dev->driver);
> +
>      s = g_new0(AudioState, 1);
>      s->dev = dev;
>  
> @@ -1763,37 +1699,7 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
>          s->nb_hw_voices_in = 0;
>      }
>  
> -    if (drvname) {
> -        driver = audio_driver_lookup(drvname);
> -        if (driver) {
> -            done = !audio_driver_init(s, driver, true, dev);
> -        } else {
> -            dolog ("Unknown audio driver `%s'\n", drvname);
> -        }
> -    } 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;
> -                }
> -            }
> -        }
> -    }
> -    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");
> -    }
> +    audio_driver_init(s, audio_driver_lookup(drvname), dev);
>  
>      if (dev->timer_period <= 0) {
>          s->period_ticks = 1;
> @@ -2120,7 +2026,7 @@ void audio_init_audiodevs(void)
>      AudiodevListEntry *e;
>  
>      QSIMPLEQ_FOREACH(e, &audiodevs, next) {
> -        audio_init(e->dev, NULL);
> +        audio_init(e->dev);
>      }
>  }
>  
> @@ -2133,7 +2039,7 @@ static void audio_init_dummy(const char *id)
>      dev->id = g_strdup(id);
>  
>      audio_validate_opts(dev, &error_abort);
> -    audio_init(dev, NULL);
> +    audio_init(dev);
>  
>      e->dev = dev;
>      QSIMPLEQ_INSERT_TAIL(&audiodevs, e, next);
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index 7ba71ebd3435..b2255319e347 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -31,14 +31,6 @@ backend settings instead of environment variables.  To ease migration to
>  the new format, the ``-audiodev-help`` option can be used to convert
>  the current values of the environment variables to ``-audiodev`` options.
>  
> -Creating sound card devices and vnc without ``audiodev=`` property (since 4.2)
> -''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
> -
> -When not using the deprecated legacy audio config, each sound card
> -should specify an ``audiodev=`` property.  Additionally, when using
> -vnc, you should specify an ``audiodev=`` property if you plan to
> -transmit audio through the VNC protocol.
> -
>  ``-chardev`` backend aliases ``tty`` and ``parport`` (since 6.0)
>  ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
>  
> diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
> index 086ba3edb042..f9eea4dda327 100644
> --- a/docs/about/removed-features.rst
> +++ b/docs/about/removed-features.rst
> @@ -346,6 +346,14 @@ needs two devices (``-device intel-hda -device hda-duplex``) and
>  pcspk-audiodev=<name>``.  And ``AC97`` and ``ES1370`` now have to be
>  specified in uppercase.
>  
> +Creating sound card devices and vnc without ``audiodev=`` property (removed in 7.1)
> +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
> +
> +When not using the deprecated legacy audio config, each sound card
> +should specify an ``audiodev=`` property.  Additionally, when using
> +vnc, you should specify an ``audiodev=`` property if you plan to
> +transmit audio through the VNC protocol.
> +
>  
>  QEMU Machine Protocol (QMP) commands
>  ------------------------------------
> -- 
> 2.35.1
> 

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


More information about the libvir-list mailing list