[vlc-devel] [PATCH 2/4] aout: keep the requested aout-mode across several inputs

Thomas Guillem thomas at gllm.fr
Fri Mar 30 13:57:10 CEST 2018


This also fixes the aout-mode being forgotten when the decoder thread reload
its decoder module and aout.

If the requested aout-mode is not available, fallback to the default one, but
keep this mode for next inputs.
---
 src/audio_output/aout_internal.h |  2 +-
 src/audio_output/dec.c           |  3 --
 src/audio_output/output.c        | 69 +++++++++++++++++++++++++---------------
 3 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h
index a2c982cde3..96f83618cc 100644
--- a/src/audio_output/aout_internal.h
+++ b/src/audio_output/aout_internal.h
@@ -84,7 +84,7 @@ typedef struct
         bool discontinuity;
     } sync;
 
-    int initial_output_mode; /**< Initial output mode set by options */
+    int requested_output_mode; /**< Requested output mode set by the user */
 
     audio_sample_format_t input_format;
     audio_sample_format_t mixer_format;
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
index bdfcbab8fd..2c5706876a 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -84,9 +84,6 @@ int aout_DecNew( audio_output_t *p_aout,
     owner->mixer_format = owner->input_format;
     owner->request_vout = *p_request_vout;
 
-    var_Change (p_aout, "aout-mode", VLC_VAR_SETVALUE,
-                &(vlc_value_t) { .i_int = owner->initial_output_mode }, NULL);
-
     owner->filters_cfg = AOUT_FILTERS_CFG_INIT;
     if (aout_OutputNew (p_aout, &owner->mixer_format, &owner->filters_cfg))
         goto error;
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index 1b32113b47..6f16ebe66d 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -177,6 +177,11 @@ static int AoutModeCallback (vlc_object_t *obj, const char *varname,
     audio_output_t *aout = (audio_output_t *)obj;
     (void)varname; (void)oldval; (void)newval; (void)data;
 
+    aout_owner_t *owner = aout_owner (aout);
+    vlc_mutex_lock (&owner->lock);
+    owner->requested_output_mode = newval.i_int;
+    vlc_mutex_unlock (&owner->lock);
+
     aout_RestartRequest (aout, AOUT_RESTART_OUTPUTMODE);
     return 0;
 }
@@ -338,7 +343,7 @@ audio_output_t *aout_New (vlc_object_t *parent)
 
     /* Stereo mode */
     var_Create (aout, "aout-mode", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
-    owner->initial_output_mode = var_GetInteger (aout, "aout-mode");
+    owner->requested_output_mode = var_GetInteger (aout, "aout-mode");
 
     var_AddCallback (aout, "aout-mode", AoutModeCallback, NULL);
     vlc_value_t txt;
@@ -404,14 +409,18 @@ static void aout_PrepareOutputMode (audio_output_t *aout,
                                     audio_sample_format_t *restrict fmt,
                                     aout_filters_cfg_t *filters_cfg,
                                     audio_channel_type_t input_chan_type,
-                                    unsigned i_nb_input_channels,
-                                    int i_forced_output_mode)
+                                    unsigned i_nb_input_channels)
 {
+    aout_owner_t *owner = aout_owner (aout);
+
     /* Fill Stereo mode choices */
     var_Change (aout, "aout-mode", VLC_VAR_CLEARCHOICES, NULL, NULL);
-    vlc_value_t val, txt, default_val = { .i_int = AOUT_VAR_CHAN_UNSET };
+    vlc_value_t val, txt;
     val.i_int = 0;
 
+    int i_output_mode = owner->requested_output_mode;
+    int i_default_mode = AOUT_VAR_CHAN_UNSET;
+
     if (!AOUT_FMT_LINEAR(fmt))
         return;
 
@@ -442,7 +451,10 @@ static void aout_PrepareOutputMode (audio_output_t *aout,
 
     if (i_nb_input_channels == 2)
     {
-        default_val.i_int = val.i_int; /* Stereo or Dolby Surround */
+        if (fmt->i_chan_mode & AOUT_CHANMODE_DUALMONO)
+            i_default_mode = AOUT_VAR_CHAN_LEFT;
+        else
+            i_default_mode = val.i_int; /* Stereo or Dolby Surround */
 
         val.i_int = AOUT_VAR_CHAN_LEFT;
         txt.psz_string = _("Left");
@@ -463,18 +475,29 @@ static void aout_PrepareOutputMode (audio_output_t *aout,
         txt.psz_string = _("Headphones");
         var_Change (aout, "aout-mode", VLC_VAR_ADDCHOICE, &val, &txt);
 
-        if (i_forced_output_mode == AOUT_VAR_CHAN_UNSET
-         && aout->current_sink_info.headphones)
+        if (aout->current_sink_info.headphones)
+            i_default_mode = AOUT_VAR_CHAN_HEADPHONES;
+    }
+
+    bool mode_available = false;
+    if (i_output_mode != AOUT_VAR_CHAN_UNSET)
+    {
+        vlc_value_t vals;
+        if (!var_Change(aout, "aout-mode", VLC_VAR_GETCHOICES, &vals, NULL))
         {
-            i_forced_output_mode = AOUT_VAR_CHAN_HEADPHONES;
-            default_val.i_int = val.i_int;
-            var_Change (aout, "aout-mode", VLC_VAR_SETVALUE, &default_val,
-                        NULL);
+            for (int i = 0; !mode_available && i < vals.p_list->i_count; ++i)
+            {
+                if (vals.p_list->p_values[i].i_int == i_output_mode)
+                    mode_available = true;
+            }
+            var_FreeList(&vals, NULL);
         }
     }
+    if (!mode_available)
+        i_output_mode = i_default_mode;
 
     /* The user may have selected a different channels configuration. */
-    switch (i_forced_output_mode)
+    switch (i_output_mode)
     {
         case AOUT_VAR_CHAN_RSTEREO:
             filters_cfg->remap[AOUT_CHANIDX_LEFT] = AOUT_CHANIDX_RIGHT;
@@ -500,16 +523,11 @@ static void aout_PrepareOutputMode (audio_output_t *aout,
                 filters_cfg->remap[i] = AOUT_CHANIDX_LEFT;
             break;
         default:
-            if (i_nb_input_channels == 2
-             && fmt->i_chan_mode & AOUT_CHANMODE_DUALMONO)
-            {   /* Go directly to the left channel. */
-                filters_cfg->remap[AOUT_CHANIDX_RIGHT] = AOUT_CHANIDX_DISABLE;
-                default_val.i_int = val.i_int = AOUT_VAR_CHAN_LEFT;
-            }
-            var_Change (aout, "aout-mode", VLC_VAR_SETVALUE, &default_val,
-                        NULL);
             break;
     }
+
+    var_Change(aout, "aout-mode", VLC_VAR_SETVALUE,
+               &(vlc_value_t) { .i_int = i_output_mode }, NULL);
 }
 
 /**
@@ -520,10 +538,10 @@ static void aout_PrepareOutputMode (audio_output_t *aout,
 int aout_OutputNew (audio_output_t *aout, audio_sample_format_t *restrict fmt,
                     aout_filters_cfg_t *filters_cfg)
 {
+    aout_owner_t *owner = aout_owner (aout);
     aout_OutputAssertLocked (aout);
 
     audio_channel_type_t input_chan_type = fmt->channel_type;
-    int i_forced_output_mode = AOUT_VAR_CHAN_UNSET;
     unsigned i_nb_input_channels = fmt->i_channels;
 
     /* Ideally, the audio filters would be created before the audio output,
@@ -551,11 +569,10 @@ int aout_OutputNew (audio_output_t *aout, audio_sample_format_t *restrict fmt,
         fmt->i_format = (fmt->i_bitspersample > 16) ? VLC_CODEC_FL32
                                                     : VLC_CODEC_S16N;
 
-        i_forced_output_mode = var_GetInteger (aout, "aout-mode");
-        if (i_forced_output_mode != AOUT_VAR_CHAN_UNSET)
+        if (owner->requested_output_mode != AOUT_VAR_CHAN_UNSET)
         {
-            if (i_forced_output_mode == AOUT_VAR_CHAN_LEFT
-             || i_forced_output_mode == AOUT_VAR_CHAN_RIGHT)
+            if (owner->requested_output_mode == AOUT_VAR_CHAN_LEFT
+             || owner->requested_output_mode == AOUT_VAR_CHAN_RIGHT)
                 fmt->i_physical_channels = AOUT_CHAN_CENTER;
             else
                 fmt->i_physical_channels = AOUT_CHANS_STEREO;
@@ -574,7 +591,7 @@ int aout_OutputNew (audio_output_t *aout, audio_sample_format_t *restrict fmt,
     }
 
     aout_PrepareOutputMode (aout, fmt, filters_cfg, input_chan_type,
-                            i_nb_input_channels, i_forced_output_mode);
+                            i_nb_input_channels);
 
     aout_FormatPrepare (fmt);
     assert (fmt->i_bytes_per_frame > 0 && fmt->i_frame_length > 0);
-- 
2.11.0



More information about the vlc-devel mailing list