Просмотр исходного кода

audio: add driver registry

Add registry for audio drivers, using the existing audio_driver struct.
Make all drivers register themself.  The old list of audio_driver struct
pointers is now a list of audio driver names, specifying the priority
(aka probe order) in case no driver is explicitly asked for.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20180306074053.22856-2-kraxel@redhat.com
Gerd Hoffmann 7 лет назад
Родитель
Сommit
d3893a39eb
12 измененных файлов с 106 добавлено и 45 удалено
  1. 7 1
      audio/alsaaudio.c
  2. 37 26
      audio/audio.c
  3. 5 9
      audio/audio_int.h
  4. 7 1
      audio/coreaudio.c
  5. 7 1
      audio/dsoundaudio.c
  6. 7 1
      audio/noaudio.c
  7. 7 1
      audio/ossaudio.c
  8. 7 1
      audio/paaudio.c
  9. 7 1
      audio/sdlaudio.c
  10. 7 1
      audio/spiceaudio.c
  11. 7 1
      audio/wavaudio.c
  12. 1 1
      scripts/create_config

+ 7 - 1
audio/alsaaudio.c

@@ -1213,7 +1213,7 @@ static struct audio_pcm_ops alsa_pcm_ops = {
     .ctl_in   = alsa_ctl_in,
     .ctl_in   = alsa_ctl_in,
 };
 };
 
 
-struct audio_driver alsa_audio_driver = {
+static struct audio_driver alsa_audio_driver = {
     .name           = "alsa",
     .name           = "alsa",
     .descr          = "ALSA http://www.alsa-project.org",
     .descr          = "ALSA http://www.alsa-project.org",
     .options        = alsa_options,
     .options        = alsa_options,
@@ -1226,3 +1226,9 @@ struct audio_driver alsa_audio_driver = {
     .voice_size_out = sizeof (ALSAVoiceOut),
     .voice_size_out = sizeof (ALSAVoiceOut),
     .voice_size_in  = sizeof (ALSAVoiceIn)
     .voice_size_in  = sizeof (ALSAVoiceIn)
 };
 };
+
+static void register_audio_alsa(void)
+{
+    audio_driver_register(&alsa_audio_driver);
+}
+type_init(register_audio_alsa);

+ 37 - 26
audio/audio.c

@@ -45,15 +45,32 @@
    The 1st one is the one used by default, that is the reason
    The 1st one is the one used by default, that is the reason
     that we generate the list.
     that we generate the list.
 */
 */
-static struct audio_driver *drvtab[] = {
-#ifdef CONFIG_SPICE
-    &spice_audio_driver,
-#endif
+static const char *audio_prio_list[] = {
+    "spice",
     CONFIG_AUDIO_DRIVERS
     CONFIG_AUDIO_DRIVERS
-    &no_audio_driver,
-    &wav_audio_driver
+    "none",
+    "wav",
 };
 };
 
 
+static QLIST_HEAD(, audio_driver) audio_drivers;
+
+void audio_driver_register(audio_driver *drv)
+{
+    QLIST_INSERT_HEAD(&audio_drivers, drv, next);
+}
+
+audio_driver *audio_driver_lookup(const char *name)
+{
+    struct audio_driver *d;
+
+    QLIST_FOREACH(d, &audio_drivers, next) {
+        if (strcmp(name, d->name) == 0) {
+            return d;
+        }
+    }
+    return NULL;
+}
+
 struct fixed_settings {
 struct fixed_settings {
     int enabled;
     int enabled;
     int nb_voices;
     int nb_voices;
@@ -1656,11 +1673,10 @@ static void audio_pp_nb_voices (const char *typ, int nb)
 
 
 void AUD_help (void)
 void AUD_help (void)
 {
 {
-    size_t i;
+    struct audio_driver *d;
 
 
     audio_process_options ("AUDIO", audio_options);
     audio_process_options ("AUDIO", audio_options);
-    for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
-        struct audio_driver *d = drvtab[i];
+    QLIST_FOREACH(d, &audio_drivers, next) {
         if (d->options) {
         if (d->options) {
             audio_process_options (d->name, d->options);
             audio_process_options (d->name, d->options);
         }
         }
@@ -1672,8 +1688,7 @@ void AUD_help (void)
 
 
     printf ("Available drivers:\n");
     printf ("Available drivers:\n");
 
 
-    for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
-        struct audio_driver *d = drvtab[i];
+    QLIST_FOREACH(d, &audio_drivers, next) {
 
 
         printf ("Name: %s\n", d->name);
         printf ("Name: %s\n", d->name);
         printf ("Description: %s\n", d->descr);
         printf ("Description: %s\n", d->descr);
@@ -1807,6 +1822,7 @@ static void audio_init (void)
     const char *drvname;
     const char *drvname;
     VMChangeStateEntry *e;
     VMChangeStateEntry *e;
     AudioState *s = &glob_audio_state;
     AudioState *s = &glob_audio_state;
+    struct audio_driver *driver;
 
 
     if (s->drv) {
     if (s->drv) {
         return;
         return;
@@ -1842,32 +1858,27 @@ static void audio_init (void)
     }
     }
 
 
     if (drvname) {
     if (drvname) {
-        int found = 0;
-
-        for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
-            if (!strcmp (drvname, drvtab[i]->name)) {
-                done = !audio_driver_init (s, drvtab[i]);
-                found = 1;
-                break;
-            }
-        }
-
-        if (!found) {
+        driver = audio_driver_lookup(drvname);
+        if (driver) {
+            done = !audio_driver_init(s, driver);
+        } else {
             dolog ("Unknown audio driver `%s'\n", drvname);
             dolog ("Unknown audio driver `%s'\n", drvname);
             dolog ("Run with -audio-help to list available drivers\n");
             dolog ("Run with -audio-help to list available drivers\n");
         }
         }
     }
     }
 
 
     if (!done) {
     if (!done) {
-        for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) {
-            if (drvtab[i]->can_be_default) {
-                done = !audio_driver_init (s, drvtab[i]);
+        for (i = 0; !done && i < ARRAY_SIZE(audio_prio_list); i++) {
+            driver = audio_driver_lookup(audio_prio_list[i]);
+            if (driver && driver->can_be_default) {
+                done = !audio_driver_init(s, driver);
             }
             }
         }
         }
     }
     }
 
 
     if (!done) {
     if (!done) {
-        done = !audio_driver_init (s, &no_audio_driver);
+        driver = audio_driver_lookup("none");
+        done = !audio_driver_init(s, driver);
         assert(done);
         assert(done);
         dolog("warning: Using timer based audio emulation\n");
         dolog("warning: Using timer based audio emulation\n");
     }
     }

+ 5 - 9
audio/audio_int.h

@@ -141,6 +141,7 @@ struct SWVoiceIn {
     QLIST_ENTRY (SWVoiceIn) entries;
     QLIST_ENTRY (SWVoiceIn) entries;
 };
 };
 
 
+typedef struct audio_driver audio_driver;
 struct audio_driver {
 struct audio_driver {
     const char *name;
     const char *name;
     const char *descr;
     const char *descr;
@@ -154,6 +155,7 @@ struct audio_driver {
     int voice_size_out;
     int voice_size_out;
     int voice_size_in;
     int voice_size_in;
     int ctl_caps;
     int ctl_caps;
+    QLIST_ENTRY(audio_driver) next;
 };
 };
 
 
 struct audio_pcm_ops {
 struct audio_pcm_ops {
@@ -203,17 +205,11 @@ struct AudioState {
     int vm_running;
     int vm_running;
 };
 };
 
 
-extern struct audio_driver no_audio_driver;
-extern struct audio_driver oss_audio_driver;
-extern struct audio_driver sdl_audio_driver;
-extern struct audio_driver wav_audio_driver;
-extern struct audio_driver alsa_audio_driver;
-extern struct audio_driver coreaudio_audio_driver;
-extern struct audio_driver dsound_audio_driver;
-extern struct audio_driver pa_audio_driver;
-extern struct audio_driver spice_audio_driver;
 extern const struct mixeng_volume nominal_volume;
 extern const struct mixeng_volume nominal_volume;
 
 
+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_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);
 void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
 
 

+ 7 - 1
audio/coreaudio.c

@@ -722,7 +722,7 @@ static struct audio_pcm_ops coreaudio_pcm_ops = {
     .ctl_out  = coreaudio_ctl_out
     .ctl_out  = coreaudio_ctl_out
 };
 };
 
 
-struct audio_driver coreaudio_audio_driver = {
+static struct audio_driver coreaudio_audio_driver = {
     .name           = "coreaudio",
     .name           = "coreaudio",
     .descr          = "CoreAudio http://developer.apple.com/audio/coreaudio.html",
     .descr          = "CoreAudio http://developer.apple.com/audio/coreaudio.html",
     .options        = coreaudio_options,
     .options        = coreaudio_options,
@@ -735,3 +735,9 @@ struct audio_driver coreaudio_audio_driver = {
     .voice_size_out = sizeof (coreaudioVoiceOut),
     .voice_size_out = sizeof (coreaudioVoiceOut),
     .voice_size_in  = 0
     .voice_size_in  = 0
 };
 };
+
+static void register_audio_coreaudio(void)
+{
+    audio_driver_register(&coreaudio_audio_driver);
+}
+type_init(register_audio_coreaudio);

+ 7 - 1
audio/dsoundaudio.c

@@ -890,7 +890,7 @@ static struct audio_pcm_ops dsound_pcm_ops = {
     .ctl_in   = dsound_ctl_in
     .ctl_in   = dsound_ctl_in
 };
 };
 
 
-struct audio_driver dsound_audio_driver = {
+static struct audio_driver dsound_audio_driver = {
     .name           = "dsound",
     .name           = "dsound",
     .descr          = "DirectSound http://wikipedia.org/wiki/DirectSound",
     .descr          = "DirectSound http://wikipedia.org/wiki/DirectSound",
     .options        = dsound_options,
     .options        = dsound_options,
@@ -903,3 +903,9 @@ struct audio_driver dsound_audio_driver = {
     .voice_size_out = sizeof (DSoundVoiceOut),
     .voice_size_out = sizeof (DSoundVoiceOut),
     .voice_size_in  = sizeof (DSoundVoiceIn)
     .voice_size_in  = sizeof (DSoundVoiceIn)
 };
 };
+
+static void register_audio_dsound(void)
+{
+    audio_driver_register(&dsound_audio_driver);
+}
+type_init(register_audio_dsound);

+ 7 - 1
audio/noaudio.c

@@ -160,7 +160,7 @@ static struct audio_pcm_ops no_pcm_ops = {
     .ctl_in   = no_ctl_in
     .ctl_in   = no_ctl_in
 };
 };
 
 
-struct audio_driver no_audio_driver = {
+static struct audio_driver no_audio_driver = {
     .name           = "none",
     .name           = "none",
     .descr          = "Timer based audio emulation",
     .descr          = "Timer based audio emulation",
     .options        = NULL,
     .options        = NULL,
@@ -173,3 +173,9 @@ struct audio_driver no_audio_driver = {
     .voice_size_out = sizeof (NoVoiceOut),
     .voice_size_out = sizeof (NoVoiceOut),
     .voice_size_in  = sizeof (NoVoiceIn)
     .voice_size_in  = sizeof (NoVoiceIn)
 };
 };
+
+static void register_audio_none(void)
+{
+    audio_driver_register(&no_audio_driver);
+}
+type_init(register_audio_none);

+ 7 - 1
audio/ossaudio.c

@@ -922,7 +922,7 @@ static struct audio_pcm_ops oss_pcm_ops = {
     .ctl_in   = oss_ctl_in
     .ctl_in   = oss_ctl_in
 };
 };
 
 
-struct audio_driver oss_audio_driver = {
+static struct audio_driver oss_audio_driver = {
     .name           = "oss",
     .name           = "oss",
     .descr          = "OSS http://www.opensound.com",
     .descr          = "OSS http://www.opensound.com",
     .options        = oss_options,
     .options        = oss_options,
@@ -935,3 +935,9 @@ struct audio_driver oss_audio_driver = {
     .voice_size_out = sizeof (OSSVoiceOut),
     .voice_size_out = sizeof (OSSVoiceOut),
     .voice_size_in  = sizeof (OSSVoiceIn)
     .voice_size_in  = sizeof (OSSVoiceIn)
 };
 };
+
+static void register_audio_oss(void)
+{
+    audio_driver_register(&oss_audio_driver);
+}
+type_init(register_audio_oss);

+ 7 - 1
audio/paaudio.c

@@ -937,7 +937,7 @@ static struct audio_pcm_ops qpa_pcm_ops = {
     .ctl_in   = qpa_ctl_in
     .ctl_in   = qpa_ctl_in
 };
 };
 
 
-struct audio_driver pa_audio_driver = {
+static struct audio_driver pa_audio_driver = {
     .name           = "pa",
     .name           = "pa",
     .descr          = "http://www.pulseaudio.org/",
     .descr          = "http://www.pulseaudio.org/",
     .options        = qpa_options,
     .options        = qpa_options,
@@ -951,3 +951,9 @@ struct audio_driver pa_audio_driver = {
     .voice_size_in  = sizeof (PAVoiceIn),
     .voice_size_in  = sizeof (PAVoiceIn),
     .ctl_caps       = VOICE_VOLUME_CAP
     .ctl_caps       = VOICE_VOLUME_CAP
 };
 };
+
+static void register_audio_pa(void)
+{
+    audio_driver_register(&pa_audio_driver);
+}
+type_init(register_audio_pa);

+ 7 - 1
audio/sdlaudio.c

@@ -500,7 +500,7 @@ static struct audio_pcm_ops sdl_pcm_ops = {
     .ctl_out  = sdl_ctl_out,
     .ctl_out  = sdl_ctl_out,
 };
 };
 
 
-struct audio_driver sdl_audio_driver = {
+static struct audio_driver sdl_audio_driver = {
     .name           = "sdl",
     .name           = "sdl",
     .descr          = "SDL http://www.libsdl.org",
     .descr          = "SDL http://www.libsdl.org",
     .options        = sdl_options,
     .options        = sdl_options,
@@ -513,3 +513,9 @@ struct audio_driver sdl_audio_driver = {
     .voice_size_out = sizeof (SDLVoiceOut),
     .voice_size_out = sizeof (SDLVoiceOut),
     .voice_size_in  = 0
     .voice_size_in  = 0
 };
 };
+
+static void register_audio_sdl(void)
+{
+    audio_driver_register(&sdl_audio_driver);
+}
+type_init(register_audio_sdl);

+ 7 - 1
audio/spiceaudio.c

@@ -391,7 +391,7 @@ static struct audio_pcm_ops audio_callbacks = {
     .ctl_in   = line_in_ctl,
     .ctl_in   = line_in_ctl,
 };
 };
 
 
-struct audio_driver spice_audio_driver = {
+static struct audio_driver spice_audio_driver = {
     .name           = "spice",
     .name           = "spice",
     .descr          = "spice audio driver",
     .descr          = "spice audio driver",
     .options        = audio_options,
     .options        = audio_options,
@@ -411,3 +411,9 @@ void qemu_spice_audio_init (void)
 {
 {
     spice_audio_driver.can_be_default = 1;
     spice_audio_driver.can_be_default = 1;
 }
 }
+
+static void register_audio_spice(void)
+{
+    audio_driver_register(&spice_audio_driver);
+}
+type_init(register_audio_spice);

+ 7 - 1
audio/wavaudio.c

@@ -278,7 +278,7 @@ static struct audio_pcm_ops wav_pcm_ops = {
     .ctl_out  = wav_ctl_out,
     .ctl_out  = wav_ctl_out,
 };
 };
 
 
-struct audio_driver wav_audio_driver = {
+static struct audio_driver wav_audio_driver = {
     .name           = "wav",
     .name           = "wav",
     .descr          = "WAV renderer http://wikipedia.org/wiki/WAV",
     .descr          = "WAV renderer http://wikipedia.org/wiki/WAV",
     .options        = wav_options,
     .options        = wav_options,
@@ -291,3 +291,9 @@ struct audio_driver wav_audio_driver = {
     .voice_size_out = sizeof (WAVVoiceOut),
     .voice_size_out = sizeof (WAVVoiceOut),
     .voice_size_in  = 0
     .voice_size_in  = 0
 };
 };
+
+static void register_audio_wav(void)
+{
+    audio_driver_register(&wav_audio_driver);
+}
+type_init(register_audio_wav);

+ 1 - 1
scripts/create_config

@@ -36,7 +36,7 @@ case $line in
     drivers=${line#*=}
     drivers=${line#*=}
     echo "#define CONFIG_AUDIO_DRIVERS \\"
     echo "#define CONFIG_AUDIO_DRIVERS \\"
     for drv in $drivers; do
     for drv in $drivers; do
-      echo "    &${drv}_audio_driver,\\"
+      echo "    \"${drv}\",\\"
     done
     done
     echo ""
     echo ""
     ;;
     ;;