[vlc-devel] [PATCH V2 1/8] aout: add exclusive argument in plugins start cb

Thomas Guillem thomas at gllm.fr
Fri Nov 8 18:13:07 CET 2019


No exclusive implementation in this commit. The wasapi exclusive mode is added
in a next commit. The macOS and PulseAudio one should be implemented as well
later.
---
 include/vlc_aout.h                      | 8 +++++++-
 modules/audio_output/adummy.c           | 5 +++--
 modules/audio_output/alsa.c             | 5 +++--
 modules/audio_output/amem.c             | 5 +++--
 modules/audio_output/audiotrack.c       | 9 +++++++--
 modules/audio_output/audiounit_ios.m    | 6 ++++--
 modules/audio_output/auhal.c            | 5 +++--
 modules/audio_output/directsound.c      | 9 +++++----
 modules/audio_output/file.c             | 5 +++--
 modules/audio_output/jack.c             | 5 +++--
 modules/audio_output/kai.c              | 5 +++--
 modules/audio_output/mmdevice.c         | 6 +++++-
 modules/audio_output/opensles_android.c | 6 ++++--
 modules/audio_output/oss.c              | 5 +++--
 modules/audio_output/pulse.c            | 6 +++++-
 modules/audio_output/sndio.c            | 5 +++--
 modules/audio_output/waveout.c          | 5 +++--
 modules/audio_output/winstore.c         | 6 +++++-
 modules/video_output/decklink.cpp       | 5 +++--
 src/audio_output/output.c               | 2 +-
 20 files changed, 76 insertions(+), 37 deletions(-)

diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index 49527f30fb5..46022e98625 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -142,7 +142,8 @@ struct audio_output
 
     void *sys; /**< Private data for callbacks */
 
-    int (*start)(audio_output_t *, audio_sample_format_t *fmt);
+    int (*start)(audio_output_t *, audio_sample_format_t *fmt,
+                 bool exclusive);
     /**< Starts a new stream (mandatory, cannot be NULL).
       *
       * This callback changes the audio output from stopped to playing state
@@ -151,6 +152,11 @@ struct audio_output
       *
       * \param fmt input stream sample format upon entry,
       *            output stream sample format upon return [IN/OUT]
+      * \param exclusive true if the stream should be configured as exclusive.
+      * If the module can't handle the exclusive mode, it should return
+      * VLC_EGENERIC. In exclusive mode, the module can still adapt its fmt to
+      * match the audio enpoint format.
+
       * \return VLC_SUCCESS on success, non-zero on failure
       *
       * \note This callback can only be called while the audio output is in
diff --git a/modules/audio_output/adummy.c b/modules/audio_output/adummy.c
index 4a3fe6ca0d6..293f27a06d1 100644
--- a/modules/audio_output/adummy.c
+++ b/modules/audio_output/adummy.c
@@ -96,9 +96,10 @@ static void Flush(audio_output_t *aout)
     sys->length = 0;
 }
 
-static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
+static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt,
+                 bool exclusive)
 {
-    (void) aout;
+    (void) aout; (void) exclusive;
 
     switch (fmt->i_format)
     {
diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c
index 63056de5228..24a29b66634 100644
--- a/modules/audio_output/alsa.c
+++ b/modules/audio_output/alsa.c
@@ -297,14 +297,15 @@ static void Flush (audio_output_t *);
 static void Drain (audio_output_t *);
 
 /** Initializes an ALSA playback stream */
-static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt)
+static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt,
+                  bool exclusive)
 {
     aout_sys_t *sys = aout->sys;
     snd_pcm_format_t pcm_format; /* ALSA sample format */
     unsigned channels;
     int passthrough = PASSTHROUGH_NONE;
 
-    if (aout_FormatNbChannels(fmt) == 0)
+    if (aout_FormatNbChannels(fmt) == 0 || exclusive)
         return VLC_EGENERIC;
 
     switch (fmt->i_format)
diff --git a/modules/audio_output/amem.c b/modules/audio_output/amem.c
index 9d21412f072..1c7e477f1d0 100644
--- a/modules/audio_output/amem.c
+++ b/modules/audio_output/amem.c
@@ -192,13 +192,14 @@ static void Stop (audio_output_t *aout)
     vlc_mutex_unlock(&sys->lock);
 }
 
-static int Start (audio_output_t *aout, audio_sample_format_t *fmt)
+static int Start (audio_output_t *aout, audio_sample_format_t *fmt,
+                  bool exclusive)
 {
     aout_sys_t *sys = aout->sys;
     char format[5] = "S16N";
     unsigned channels;
 
-    if (aout_FormatNbChannels(fmt) == 0)
+    if (aout_FormatNbChannels(fmt) == 0 || exclusive)
         return VLC_EGENERIC;
 
     vlc_mutex_lock(&sys->lock);
diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c
index 3fcd79c7a50..3dab5f24014 100644
--- a/modules/audio_output/audiotrack.c
+++ b/modules/audio_output/audiotrack.c
@@ -43,7 +43,8 @@
 static int  Open( vlc_object_t * );
 static void Close( vlc_object_t * );
 static void Stop( audio_output_t * );
-static int Start( audio_output_t *, audio_sample_format_t * );
+static int Start( audio_output_t *, audio_sample_format_t *,
+                  enum vlc_aout_exclusive_mode );
 static void *AudioTrack_Thread( void * );
 
 /* There is an undefined behavior when configuring AudioTrack with SPDIF or
@@ -1292,7 +1293,8 @@ StartPCM( JNIEnv *env, audio_output_t *p_aout, unsigned i_max_channels )
 }
 
 static int
-Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt )
+Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt
+       enum vlc_aout_exclusive_mode exclusive )
 {
     aout_sys_t *p_sys = p_aout->sys;
     JNIEnv *env;
@@ -1300,6 +1302,9 @@ Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt )
     bool b_try_passthrough;
     unsigned i_max_channels;
 
+    if( exclusive )
+        return VLC_EGENERIC;
+
     if( p_sys->at_dev == AT_DEV_ENCODED )
     {
         b_try_passthrough = true;
diff --git a/modules/audio_output/audiounit_ios.m b/modules/audio_output/audiounit_ios.m
index 072de41534a..5a807ad983f 100644
--- a/modules/audio_output/audiounit_ios.m
+++ b/modules/audio_output/audiounit_ios.m
@@ -462,14 +462,16 @@ Stop(audio_output_t *p_aout)
 }
 
 static int
-Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
+Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt,
+      bool exclusive)
 {
     aout_sys_t *p_sys = p_aout->sys;
     OSStatus err;
     OSStatus status;
     AudioChannelLayout *layout = NULL;
 
-    if (aout_FormatNbChannels(fmt) == 0 || AOUT_FMT_HDMI(fmt))
+    if (aout_FormatNbChannels(fmt) == 0 || AOUT_FMT_HDMI(fmt)
+     || exclusive)
         return VLC_EGENERIC;
 
     /* XXX: No more passthrough since iOS 11 */
diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c
index b56e609bc39..03c9f8817d7 100644
--- a/modules/audio_output/auhal.c
+++ b/modules/audio_output/auhal.c
@@ -1495,7 +1495,8 @@ Stop(audio_output_t *p_aout)
 }
 
 static int
-Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
+Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt,
+      bool exclusive)
 {
     UInt32                  i_param_size = 0;
     aout_sys_t              *p_sys = NULL;
@@ -1504,7 +1505,7 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
      * property size */
     int                     b_alive = false;
 
-    if (AOUT_FMT_HDMI(fmt))
+    if (AOUT_FMT_HDMI(fmt) || exclusive)
         return VLC_EGENERIC;
 
     p_sys = p_aout->sys;
diff --git a/modules/audio_output/directsound.c b/modules/audio_output/directsound.c
index f4d7efea6da..70eebb2efa5 100644
--- a/modules/audio_output/directsound.c
+++ b/modules/audio_output/directsound.c
@@ -588,9 +588,10 @@ static void OutputStop( audio_output_t *aout )
 }
 
 static HRESULT Start( vlc_object_t *obj, aout_stream_sys_t *sys,
-                      audio_sample_format_t *restrict pfmt )
+                      audio_sample_format_t *restrict pfmt,
+                      bool exclusive)
 {
-    if( aout_FormatNbChannels( pfmt ) == 0 )
+    if( aout_FormatNbChannels( pfmt ) == 0 || exclusive )
         return E_FAIL;
 
 #if !VLC_WINSTORE_APP
@@ -858,7 +859,7 @@ static HRESULT StreamStart( aout_stream_t *s,
 
     sys->p_dsobject = pv;
 
-    hr = Start( VLC_OBJECT(s), sys, fmt );
+    hr = Start( VLC_OBJECT(s), sys, fmt, false );
     if( FAILED(hr) )
         goto error;
 
@@ -974,7 +975,7 @@ static int OutputStart( audio_output_t *p_aout,
     }
 
     aout_sys_t *sys = p_aout->sys;
-    HRESULT hr = Start( VLC_OBJECT(p_aout), &sys->s, fmt );
+    HRESULT hr = Start( VLC_OBJECT(p_aout), &sys->s, fmt, false );
     if( FAILED(hr) )
         return -1;
 
diff --git a/modules/audio_output/file.c b/modules/audio_output/file.c
index 283b8415c97..771379cc907 100644
--- a/modules/audio_output/file.c
+++ b/modules/audio_output/file.c
@@ -128,13 +128,14 @@ vlc_module_begin ()
     set_callback( Open )
 vlc_module_end ()
 
-static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
+static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt,
+                  enum vlc_aout_exclusive_mode exclusive )
 {
     char * psz_name, * psz_format;
     const char * const * ppsz_compare = format_list;
     int i_channels, i = 0;
 
-    if( aout_FormatNbChannels( fmt ) == 0 )
+    if( aout_FormatNbChannels( fmt ) == 0 || exclusive )
         return VLC_EGENERIC;
 
     psz_name = var_InheritString( p_aout, "audiofile-file" );
diff --git a/modules/audio_output/jack.c b/modules/audio_output/jack.c
index d21150f2a41..a0ab086351d 100644
--- a/modules/audio_output/jack.c
+++ b/modules/audio_output/jack.c
@@ -112,7 +112,8 @@ vlc_module_begin ()
 vlc_module_end ()
 
 
-static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
+static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt,
+                  enum vlc_aout_exclusive_mode exclusive )
 {
     char *psz_name;
     aout_sys_t *p_sys = p_aout->sys;
@@ -120,7 +121,7 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
     unsigned int i;
     int i_error;
 
-    if( aout_FormatNbChannels( fmt ) == 0 )
+    if( aout_FormatNbChannels( fmt ) == 0 || exclusive )
         return VLC_EGENERIC;
 
     p_sys->latency = 0;
diff --git a/modules/audio_output/kai.c b/modules/audio_output/kai.c
index dd75e367d8a..839b029da03 100644
--- a/modules/audio_output/kai.c
+++ b/modules/audio_output/kai.c
@@ -124,7 +124,8 @@ vlc_module_end ()
 /*****************************************************************************
  * Open: open the audio device
  *****************************************************************************/
-static int Start ( audio_output_t *p_aout, audio_sample_format_t *fmt )
+static int Start ( audio_output_t *p_aout, audio_sample_format_t *fmt,
+                   enum vlc_aout_exclusive_mode exclusive )
 {
     aout_sys_t *p_sys = p_aout->sys;
     char *psz_mode;
@@ -135,7 +136,7 @@ static int Start ( audio_output_t *p_aout, audio_sample_format_t *fmt )
     vlc_value_t val, text;
     audio_sample_format_t format = *fmt;
 
-    if( aout_FormatNbChannels( fmt ) == 0 )
+    if( aout_FormatNbChannels( fmt ) == 0 || exclusive )
         return VLC_EGENERIC;
 
     psz_mode = var_InheritString( p_aout, "kai-audio-device" );
diff --git a/modules/audio_output/mmdevice.c b/modules/audio_output/mmdevice.c
index bf1d2958bd7..3c78423845e 100644
--- a/modules/audio_output/mmdevice.c
+++ b/modules/audio_output/mmdevice.c
@@ -1104,10 +1104,14 @@ static int aout_stream_Start(void *func, bool forced, va_list ap)
     return SUCCEEDED(*hr) ? VLC_SUCCESS : VLC_EGENERIC;
 }
 
-static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
+static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt,
+                 bool exclusive)
 {
     aout_sys_t *sys = aout->sys;
 
+    if (exclusive)
+        return -1;
+
     const bool b_spdif = AOUT_FMT_SPDIF(fmt);
     const bool b_hdmi = AOUT_FMT_HDMI(fmt);
     if (b_spdif || b_hdmi)
diff --git a/modules/audio_output/opensles_android.c b/modules/audio_output/opensles_android.c
index b1c2a0d9851..86d5101de62 100644
--- a/modules/audio_output/opensles_android.c
+++ b/modules/audio_output/opensles_android.c
@@ -374,9 +374,11 @@ static int aout_get_native_sample_rate(audio_output_t *aout)
 /*****************************************************************************
  *
  *****************************************************************************/
-static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
+static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt,
+                 bool exclusive)
 {
-    if (aout_FormatNbChannels(fmt) == 0 || !AOUT_FMT_LINEAR(fmt))
+    if (aout_FormatNbChannels(fmt) == 0 || !AOUT_FMT_LINEAR(fmt)
+     || exclusive)
         return VLC_EGENERIC;
 
     SLresult       result;
diff --git a/modules/audio_output/oss.c b/modules/audio_output/oss.c
index 5bada6857d5..14e6a44e134 100644
--- a/modules/audio_output/oss.c
+++ b/modules/audio_output/oss.c
@@ -92,11 +92,12 @@ static void Play(audio_output_t *, block_t *, vlc_tick_t);
 static void Pause (audio_output_t *, bool, vlc_tick_t);
 static void Flush (audio_output_t *);
 
-static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt)
+static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt,
+                  bool exclusive)
 {
     aout_sys_t* sys = aout->sys;
 
-    if (aout_FormatNbChannels(fmt) == 0)
+    if (aout_FormatNbChannels(fmt) == 0 || exclusive)
         return VLC_EGENERIC;
 
     /* Open the device */
diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c
index fba8fd68408..fa5278e505f 100644
--- a/modules/audio_output/pulse.c
+++ b/modules/audio_output/pulse.c
@@ -707,10 +707,14 @@ static const char *str_map(const char *key, const char *const table[][2],
 /**
  * Create a PulseAudio playback stream, a.k.a. a sink input.
  */
-static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
+static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt,
+                 bool exclusive)
 {
     aout_sys_t *sys = aout->sys;
 
+    if (exclusive)
+        return VLC_EGENERIC;
+
     /* Sample format specification */
     struct pa_sample_spec ss = { .format = PA_SAMPLE_INVALID };
     pa_encoding_t encoding = PA_ENCODING_PCM;
diff --git a/modules/audio_output/sndio.c b/modules/audio_output/sndio.c
index 642113a4872..d21192dc173 100644
--- a/modules/audio_output/sndio.c
+++ b/modules/audio_output/sndio.c
@@ -62,11 +62,12 @@ typedef struct
 } aout_sys_t;
 
 /** Initializes an sndio playback stream */
-static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt)
+static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt,
+                  bool exclusive)
 {
     aout_sys_t *sys = aout->sys;
 
-    if (aout_FormatNbChannels(fmt) == 0)
+    if (aout_FormatNbChannels(fmt) == 0 || exclusive)
         return VLC_EGENERIC;
 
     sys->hdl = sio_open (NULL, SIO_PLAY, 0 /* blocking */);
diff --git a/modules/audio_output/waveout.c b/modules/audio_output/waveout.c
index 990b1e8b8d8..29f8e423acd 100644
--- a/modules/audio_output/waveout.c
+++ b/modules/audio_output/waveout.c
@@ -167,9 +167,10 @@ vlc_module_end ()
  *****************************************************************************
  * This function opens and setups Win32 waveOut
  *****************************************************************************/
-static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
+static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt,
+                  enum vlc_aout_exclusive_mode exclusive )
 {
-    if( aout_FormatNbChannels( fmt ) == 0 )
+    if( aout_FormatNbChannels( fmt ) == 0 || exclusive )
         return VLC_EGENERIC;
 
     p_aout->time_get = WaveOutTimeGet;
diff --git a/modules/audio_output/winstore.c b/modules/audio_output/winstore.c
index 5a6f873ae20..3b469fd226b 100644
--- a/modules/audio_output/winstore.c
+++ b/modules/audio_output/winstore.c
@@ -219,11 +219,15 @@ static int aout_stream_Start(void *func, bool forced, va_list ap)
     return SUCCEEDED(*hr) ? VLC_SUCCESS : VLC_EGENERIC;
 }
 
-static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
+static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt,
+                 bool exclusive)
 {
     aout_sys_t *sys = aout->sys;
     HRESULT hr;
 
+    if (exclusive)
+        return -1;
+
     aout_stream_t *s = vlc_object_create(aout, sizeof (*s));
     if (unlikely(s == NULL))
         return -1;
diff --git a/modules/video_output/decklink.cpp b/modules/video_output/decklink.cpp
index f4d01fb81d4..78b61d29388 100644
--- a/modules/video_output/decklink.cpp
+++ b/modules/video_output/decklink.cpp
@@ -858,11 +858,12 @@ static int TimeGet(audio_output_t *, vlc_tick_t* restrict)
     return -1;
 }
 
-static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
+static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt,
+                 bool exclusive)
 {
     decklink_sys_t *sys = (decklink_sys_t *) aout->sys;
 
-    if (sys->i_rate == 0)
+    if (sys->i_rate == 0 || exclusive)
         return VLC_EGENERIC;
 
     fmt->i_format = VLC_CODEC_S16N;
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index fe782d6e1d7..4177b3bfe03 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -600,7 +600,7 @@ int aout_OutputNew (audio_output_t *aout)
     for (size_t i = 0; formats[i] != 0 && ret != VLC_SUCCESS; ++i)
     {
         filter_fmt->i_format = fmt->i_format = formats[i];
-        ret = aout->start(aout, fmt);
+        ret = aout->start(aout, fmt, owner->exclusive_mode);
     }
     vlc_mutex_unlock(&owner->lock);
     if (ret)
-- 
2.20.1



More information about the vlc-devel mailing list