From 6e63d9ad4fd12798c14a466ddfd3eb426e1dd3bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= <remi@remlab.net>
Date: Thu, 12 May 2022 18:42:49 +0300
Subject: [PATCH] alsa: reorder to avoid forward declarations

---
 modules/audio_output/alsa.c | 391 ++++++++++++++++++------------------
 1 file changed, 191 insertions(+), 200 deletions(-)

diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c
index 9e0a00d28562..68a3c4aa2326 100644
--- a/modules/audio_output/alsa.c
+++ b/modules/audio_output/alsa.c
@@ -39,75 +39,6 @@
 #include <alsa/asoundlib.h>
 #include <alsa/version.h>
 
-/** Private data for an ALSA PCM playback stream */
-typedef struct
-{
-    snd_pcm_t *pcm;
-    unsigned rate; /**< Sample rate */
-    vlc_fourcc_t format; /**< Sample format */
-    uint8_t chans_table[AOUT_CHAN_MAX]; /**< Channels order table */
-    uint8_t chans_to_reorder; /**< Number of channels to reorder */
-
-    bool soft_mute;
-    float soft_gain;
-    char *device;
-} aout_sys_t;
-
-enum {
-    PASSTHROUGH_NONE,
-    PASSTHROUGH_SPDIF,
-    PASSTHROUGH_HDMI,
-};
-
-#include "audio_output/volume.h"
-
-#define A52_FRAME_NB 1536
-
-static int Open (vlc_object_t *);
-static void Close (vlc_object_t *);
-static int EnumDevices(char const *, char ***, char ***);
-
-#define AUDIO_DEV_TEXT N_("Audio output device")
-#define AUDIO_DEV_LONGTEXT N_("Audio output device (using ALSA syntax).")
-
-#define AUDIO_CHAN_TEXT N_("Audio output channels")
-#define AUDIO_CHAN_LONGTEXT N_("Channels available for audio output. " \
-    "If the input has more channels than the output, it will be down-mixed. " \
-    "This parameter is ignored when digital pass-through is active.")
-static const int channels[] = {
-    AOUT_CHAN_CENTER, AOUT_CHANS_STEREO, AOUT_CHANS_4_0, AOUT_CHANS_4_1,
-    AOUT_CHANS_5_0, AOUT_CHANS_5_1, AOUT_CHANS_7_1,
-};
-static const char *const channels_text[] = {
-    N_("Mono"), N_("Stereo"), N_("Surround 4.0"), N_("Surround 4.1"),
-    N_("Surround 5.0"), N_("Surround 5.1"), N_("Surround 7.1"),
-};
-
-#define PASSTHROUGH_TEXT N_("Audio passthrough mode")
-static const int passthrough_modes[] = {
-    PASSTHROUGH_NONE, PASSTHROUGH_SPDIF, PASSTHROUGH_HDMI,
-};
-static const char *const passthrough_modes_text[] = {
-    N_("None"), N_("S/PDIF"), N_("HDMI"),
-};
-
-vlc_module_begin ()
-    set_shortname( "ALSA" )
-    set_description( N_("ALSA audio output") )
-    set_subcategory( SUBCAT_AUDIO_AOUT )
-    add_string ("alsa-audio-device", "default",
-                AUDIO_DEV_TEXT, AUDIO_DEV_LONGTEXT)
-    add_integer ("alsa-audio-channels", AOUT_CHANS_FRONT,
-                 AUDIO_CHAN_TEXT, AUDIO_CHAN_LONGTEXT)
-        change_integer_list (channels, channels_text)
-    add_integer("alsa-passthrough", PASSTHROUGH_NONE, PASSTHROUGH_TEXT,
-                NULL)
-        change_integer_list(passthrough_modes, passthrough_modes_text)
-    add_sw_gain ()
-    set_capability( "audio output", 150 )
-    set_callbacks( Open, Close )
-vlc_module_end ()
-
 /** Helper for ALSA -> VLC debugging output */
 static void Dump (vlc_object_t *obj, const char *msg,
                   int (*cb)(void *, snd_output_t *), void *p)
@@ -159,6 +90,149 @@ static void DumpDeviceStatus (vlc_object_t *obj, snd_pcm_t *pcm)
 }
 #define DumpDeviceStatus(o, p) DumpDeviceStatus(VLC_OBJECT(o), p)
 
+/** Private data for an ALSA PCM playback stream */
+typedef struct
+{
+    snd_pcm_t *pcm;
+    unsigned rate; /**< Sample rate */
+    vlc_fourcc_t format; /**< Sample format */
+    uint8_t chans_table[AOUT_CHAN_MAX]; /**< Channels order table */
+    uint8_t chans_to_reorder; /**< Number of channels to reorder */
+
+    bool soft_mute;
+    float soft_gain;
+    char *device;
+} aout_sys_t;
+
+#include "audio_output/volume.h"
+
+static int TimeGet(audio_output_t *aout, vlc_tick_t *restrict delay)
+{
+    aout_sys_t *sys = aout->sys;
+    snd_pcm_sframes_t frames;
+
+    int val = snd_pcm_delay(sys->pcm, &frames);
+    if (val)
+    {
+        msg_Err(aout, "cannot estimate delay: %s", snd_strerror(val));
+        return -1;
+    }
+    *delay = vlc_tick_from_samples(frames, sys->rate);
+    return 0;
+}
+
+/**
+ * Queues one audio buffer to the hardware.
+ */
+static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
+{
+    aout_sys_t *sys = aout->sys;
+
+    if (sys->chans_to_reorder != 0)
+        aout_ChannelReorder(block->p_buffer, block->i_buffer,
+                            sys->chans_to_reorder, sys->chans_table,
+                            sys->format);
+
+    snd_pcm_t *pcm = sys->pcm;
+
+    /* TODO: better overflow handling */
+    /* TODO: no period wake ups */
+
+    while (block->i_nb_samples > 0)
+    {
+        snd_pcm_sframes_t frames;
+
+        frames = snd_pcm_writei(pcm, block->p_buffer, block->i_nb_samples);
+        if (frames >= 0)
+        {
+            size_t bytes = snd_pcm_frames_to_bytes(pcm, frames);
+            block->i_nb_samples -= frames;
+            block->p_buffer += bytes;
+            block->i_buffer -= bytes;
+            // pts, length
+        }
+        else
+        {
+            int val = snd_pcm_recover(pcm, frames, 1);
+            if (val)
+            {
+                msg_Err(aout, "cannot recover playback stream: %s",
+                        snd_strerror (val));
+                DumpDeviceStatus(aout, pcm);
+                break;
+            }
+            msg_Warn(aout, "cannot write samples: %s", snd_strerror(frames));
+        }
+    }
+    block_Release(block);
+    (void) date;
+}
+
+static void PauseDummy(audio_output_t *aout, bool pause, vlc_tick_t date)
+{
+    aout_sys_t *p_sys = aout->sys;
+    snd_pcm_t *pcm = p_sys->pcm;
+
+    /* Stupid device cannot pause. Discard samples. */
+    if (pause)
+        snd_pcm_drop(pcm);
+    else
+        snd_pcm_prepare(pcm);
+    (void) date;
+}
+
+/**
+ * Pauses/resumes the audio playback.
+ */
+static void Pause(audio_output_t *aout, bool pause, vlc_tick_t date)
+{
+    aout_sys_t *p_sys = aout->sys;
+    snd_pcm_t *pcm = p_sys->pcm;
+
+    int val = snd_pcm_pause(pcm, pause);
+    if (unlikely(val))
+        PauseDummy(aout, pause, date);
+}
+
+/**
+ * Flushes the audio playback buffer.
+ */
+static void Flush (audio_output_t *aout)
+{
+    aout_sys_t *p_sys = aout->sys;
+    snd_pcm_t *pcm = p_sys->pcm;
+
+    snd_pcm_drop(pcm);
+    snd_pcm_prepare(pcm);
+}
+
+/**
+ * Drains the audio playback buffer.
+ */
+static void Drain (audio_output_t *aout)
+{
+    aout_sys_t *p_sys = aout->sys;
+    snd_pcm_t *pcm = p_sys->pcm;
+
+    /* XXX: Synchronous drain, not interruptible. */
+    snd_pcm_drain(pcm);
+    snd_pcm_prepare(pcm);
+
+    aout_DrainedReport(aout);
+}
+
+/**
+ * Releases the audio output.
+ */
+static void Stop (audio_output_t *aout)
+{
+    aout_sys_t *sys = aout->sys;
+    snd_pcm_t *pcm = sys->pcm;
+
+    snd_pcm_drop(pcm);
+    snd_pcm_close(pcm);
+}
+
 #if (SND_LIB_VERSION >= 0x01001B)
 static const uint16_t vlc_chans[] = {
     [SND_CHMAP_MONO] = AOUT_CHAN_CENTER,
@@ -288,12 +362,13 @@ out:
 # define SetupChannels(obj, pcm, mask, tab) (0)
 #endif
 
-static int TimeGet (audio_output_t *aout, vlc_tick_t *);
-static void Play(audio_output_t *, block_t *, vlc_tick_t);
-static void Pause (audio_output_t *, bool, vlc_tick_t);
-static void PauseDummy (audio_output_t *, bool, vlc_tick_t);
-static void Flush (audio_output_t *);
-static void Drain (audio_output_t *);
+enum {
+    PASSTHROUGH_NONE,
+    PASSTHROUGH_SPDIF,
+    PASSTHROUGH_HDMI,
+};
+
+#define A52_FRAME_NB 1536
 
 /** Initializes an ALSA playback stream */
 static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt)
@@ -631,131 +706,6 @@ error:
     return VLC_EGENERIC;
 }
 
-static int TimeGet (audio_output_t *aout, vlc_tick_t *restrict delay)
-{
-    aout_sys_t *sys = aout->sys;
-    snd_pcm_sframes_t frames;
-
-    int val = snd_pcm_delay (sys->pcm, &frames);
-    if (val)
-    {
-        msg_Err (aout, "cannot estimate delay: %s", snd_strerror (val));
-        return -1;
-    }
-    *delay = vlc_tick_from_samples(frames, sys->rate);
-    return 0;
-}
-
-/**
- * Queues one audio buffer to the hardware.
- */
-static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
-{
-    aout_sys_t *sys = aout->sys;
-
-    if (sys->chans_to_reorder != 0)
-        aout_ChannelReorder(block->p_buffer, block->i_buffer,
-                           sys->chans_to_reorder, sys->chans_table, sys->format);
-
-    snd_pcm_t *pcm = sys->pcm;
-
-    /* TODO: better overflow handling */
-    /* TODO: no period wake ups */
-
-    while (block->i_nb_samples > 0)
-    {
-        snd_pcm_sframes_t frames;
-
-        frames = snd_pcm_writei (pcm, block->p_buffer, block->i_nb_samples);
-        if (frames >= 0)
-        {
-            size_t bytes = snd_pcm_frames_to_bytes (pcm, frames);
-            block->i_nb_samples -= frames;
-            block->p_buffer += bytes;
-            block->i_buffer -= bytes;
-            // pts, length
-        }
-        else  
-        {
-            int val = snd_pcm_recover (pcm, frames, 1);
-            if (val)
-            {
-                msg_Err (aout, "cannot recover playback stream: %s",
-                         snd_strerror (val));
-                DumpDeviceStatus (aout, pcm);
-                break;
-            }
-            msg_Warn (aout, "cannot write samples: %s", snd_strerror (frames));
-        }
-    }
-    block_Release (block);
-    (void) date;
-}
-
-/**
- * Pauses/resumes the audio playback.
- */
-static void Pause (audio_output_t *aout, bool pause, vlc_tick_t date)
-{
-    aout_sys_t *p_sys = aout->sys;
-    snd_pcm_t *pcm = p_sys->pcm;
-
-    int val = snd_pcm_pause (pcm, pause);
-    if (unlikely(val))
-        PauseDummy (aout, pause, date);
-}
-
-static void PauseDummy (audio_output_t *aout, bool pause, vlc_tick_t date)
-{
-    aout_sys_t *p_sys = aout->sys;
-    snd_pcm_t *pcm = p_sys->pcm;
-
-    /* Stupid device cannot pause. Discard samples. */
-    if (pause)
-        snd_pcm_drop (pcm);
-    else
-        snd_pcm_prepare (pcm);
-    (void) date;
-}
-
-/**
- * Flushes the audio playback buffer.
- */
-static void Flush (audio_output_t *aout)
-{
-    aout_sys_t *p_sys = aout->sys;
-    snd_pcm_t *pcm = p_sys->pcm;
-    snd_pcm_drop (pcm);
-    snd_pcm_prepare (pcm);
-}
-
-/**
- * Drains the audio playback buffer.
- */
-static void Drain (audio_output_t *aout)
-{
-    aout_sys_t *p_sys = aout->sys;
-    snd_pcm_t *pcm = p_sys->pcm;
-
-    /* XXX: Synchronous drain, not interruptible. */
-    snd_pcm_drain (pcm);
-    snd_pcm_prepare (pcm);
-
-    aout_DrainedReport(aout);
-}
-
-/**
- * Releases the audio output.
- */
-static void Stop (audio_output_t *aout)
-{
-    aout_sys_t *sys = aout->sys;
-    snd_pcm_t *pcm = sys->pcm;
-
-    snd_pcm_drop (pcm);
-    snd_pcm_close (pcm);
-}
-
 /**
  * Enumerates ALSA output devices.
  */
@@ -884,3 +834,44 @@ static void Close(vlc_object_t *obj)
     free (sys->device);
     free (sys);
 }
+
+#define AUDIO_DEV_TEXT N_("Audio output device")
+#define AUDIO_DEV_LONGTEXT N_("Audio output device (using ALSA syntax).")
+
+#define AUDIO_CHAN_TEXT N_("Audio output channels")
+#define AUDIO_CHAN_LONGTEXT N_("Channels available for audio output. " \
+    "If the input has more channels than the output, it will be down-mixed. " \
+    "This parameter is ignored when digital pass-through is active.")
+static const int channels[] = {
+    AOUT_CHAN_CENTER, AOUT_CHANS_STEREO, AOUT_CHANS_4_0, AOUT_CHANS_4_1,
+    AOUT_CHANS_5_0, AOUT_CHANS_5_1, AOUT_CHANS_7_1,
+};
+static const char *const channels_text[] = {
+    N_("Mono"), N_("Stereo"), N_("Surround 4.0"), N_("Surround 4.1"),
+    N_("Surround 5.0"), N_("Surround 5.1"), N_("Surround 7.1"),
+};
+
+#define PASSTHROUGH_TEXT N_("Audio passthrough mode")
+static const int passthrough_modes[] = {
+    PASSTHROUGH_NONE, PASSTHROUGH_SPDIF, PASSTHROUGH_HDMI,
+};
+static const char *const passthrough_modes_text[] = {
+    N_("None"), N_("S/PDIF"), N_("HDMI"),
+};
+
+vlc_module_begin()
+    set_shortname("ALSA")
+    set_description(N_("ALSA audio output"))
+    set_subcategory(SUBCAT_AUDIO_AOUT)
+    add_string("alsa-audio-device", "default",
+               AUDIO_DEV_TEXT, AUDIO_DEV_LONGTEXT)
+    add_integer("alsa-audio-channels", AOUT_CHANS_FRONT,
+                AUDIO_CHAN_TEXT, AUDIO_CHAN_LONGTEXT)
+        change_integer_list (channels, channels_text)
+    add_integer("alsa-passthrough", PASSTHROUGH_NONE, PASSTHROUGH_TEXT,
+                NULL)
+        change_integer_list(passthrough_modes, passthrough_modes_text)
+    add_sw_gain()
+    set_capability("audio output", 150)
+    set_callbacks(Open, Close)
+vlc_module_end()
-- 
GitLab