[vlc-commits] [Git][videolan/vlc][master] 5 commits: aout: volume: fix data-race

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Wed Mar 30 07:51:13 UTC 2022



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
060a321d by Thomas Guillem at 2022-03-30T07:31:07+00:00
aout: volume: fix data-race

 - output_factor is read from aout_volume_Amplify(), called from the
input/decoder.c DecoderThread.

 - output_factor is written from aout_volume_SetVolume(). It is either
   called  from the same thread via the start cb (OK in that case) or
   from any threads via the volume_set cb.

- - - - -
4f5d4765 by Thomas Guillem at 2022-03-30T07:31:07+00:00
aout: volume: add missing atomic initialisation

- - - - -
8908b373 by Thomas Guillem at 2022-03-30T07:31:07+00:00
aout: volume: specify the mem order

Relaxed because we don't need synchronisation with other variables.

gain_factor and output_factor are write from different threads, so a
sequentially consistent ordering won't help.

- - - - -
2fe7c0a3 by Thomas Guillem at 2022-03-30T07:31:07+00:00
aout: volume: move NULL check

It's really weird to call functions with a NULL pointer...

- - - - -
aeedea5a by Thomas Guillem at 2022-03-30T07:31:07+00:00
aout: dec: move volume configuration

volume is valid only if !bitexact.

- - - - -


2 changed files:

- src/audio_output/dec.c
- src/audio_output/volume.c


Changes:

=====================================
src/audio_output/dec.c
=====================================
@@ -148,12 +148,14 @@ vlc_aout_stream * vlc_aout_stream_New(audio_output_t *p_aout,
     if (aout_OutputNew(p_aout, stream, &stream->mixer_format, stream->input_profile,
                        &stream->filter_format, &stream->filters_cfg))
         goto error;
-    aout_volume_SetFormat (stream->volume, stream->mixer_format.i_format);
 
     vlc_audio_meter_Reset(&owner->meter, &stream->mixer_format);
 
     if (!owner->bitexact)
     {
+        if (stream->volume != NULL)
+            aout_volume_SetFormat(stream->volume, stream->mixer_format.i_format);
+
         /* Create the audio filtering "input" pipeline */
         stream->filters = aout_FiltersNewWithClock(VLC_OBJECT(p_aout), clock,
                                                    &stream->filter_format,
@@ -165,8 +167,8 @@ vlc_aout_stream * vlc_aout_stream_New(audio_output_t *p_aout,
             vlc_audio_meter_Reset(&owner->meter, NULL);
 
 error:
-            aout_volume_Delete (stream->volume);
-            stream->volume = NULL;
+            if (stream->volume != NULL)
+                aout_volume_Delete(stream->volume);
             free(stream);
             return NULL;
         }
@@ -202,7 +204,8 @@ void vlc_aout_stream_Delete (vlc_aout_stream *stream)
             aout_FiltersDelete (aout, stream->filters);
         aout_OutputDelete (aout);
     }
-    aout_volume_Delete (stream->volume);
+    if (stream->volume != NULL)
+        aout_volume_Delete(stream->volume);
     free(stream);
 }
 
@@ -232,8 +235,9 @@ static int stream_CheckReady (vlc_aout_stream *stream)
             if (aout_OutputNew(aout, stream, &stream->mixer_format, stream->input_profile,
                                &stream->filter_format, &stream->filters_cfg))
                 stream->mixer_format.i_format = 0;
-            aout_volume_SetFormat (stream->volume,
-                                   stream->mixer_format.i_format);
+            if (stream->volume != NULL)
+                aout_volume_SetFormat(stream->volume,
+                                      stream->mixer_format.i_format);
 
             /* Notify the decoder that the aout changed in order to try a new
              * suitable codec (like an HDMI audio format). However, keep the
@@ -528,7 +532,8 @@ int vlc_aout_stream_Play(vlc_aout_stream *stream, block_t *block)
     stream->original_pts = VLC_TICK_INVALID;
 
     /* Software volume */
-    aout_volume_Amplify(stream->volume, block);
+    if (stream->volume != NULL)
+        aout_volume_Amplify(stream->volume, block);
 
     /* Update delay */
     if (stream->sync.request_delay != stream->sync.delay)
@@ -647,7 +652,8 @@ void vlc_aout_stream_Flush(vlc_aout_stream *stream)
 
 void vlc_aout_stream_NotifyGain(vlc_aout_stream *stream, float gain)
 {
-    aout_volume_SetVolume(stream->volume, gain);
+    if (stream->volume != NULL)
+        aout_volume_SetVolume(stream->volume, gain);
 }
 
 void vlc_aout_stream_NotifyDrained(vlc_aout_stream *stream)


=====================================
src/audio_output/volume.c
=====================================
@@ -39,7 +39,7 @@ struct aout_volume
     audio_volume_t object;
     audio_replay_gain_t replay_gain;
     _Atomic float gain_factor;
-    float output_factor;
+    _Atomic float output_factor;
     module_t *module;
 };
 
@@ -58,7 +58,8 @@ aout_volume_t *aout_volume_New(vlc_object_t *parent,
     if (unlikely(vol == NULL))
         return NULL;
     vol->module = NULL;
-    vol->output_factor = 1.f;
+    atomic_init(&vol->gain_factor, 1.f);
+    atomic_init(&vol->output_factor, 1.f);
 
     //audio_volume_t *obj = &vol->object;
 
@@ -80,9 +81,6 @@ aout_volume_t *aout_volume_New(vlc_object_t *parent,
  */
 int aout_volume_SetFormat(aout_volume_t *vol, vlc_fourcc_t format)
 {
-    if (unlikely(vol == NULL))
-        return -1;
-
     audio_volume_t *obj = &vol->object;
     if (vol->module != NULL)
     {
@@ -107,9 +105,6 @@ int aout_volume_SetFormat(aout_volume_t *vol, vlc_fourcc_t format)
  */
 void aout_volume_Delete(aout_volume_t *vol)
 {
-    if (vol == NULL)
-        return;
-
     audio_volume_t *obj = &vol->object;
 
     if (vol->module != NULL)
@@ -121,10 +116,7 @@ void aout_volume_Delete(aout_volume_t *vol)
 
 void aout_volume_SetVolume(aout_volume_t *vol, float factor)
 {
-    if (unlikely(vol == NULL))
-        return;
-
-    vol->output_factor = factor;
+    atomic_store_explicit(&vol->output_factor, factor, memory_order_relaxed);
 }
 
 /**
@@ -132,10 +124,11 @@ void aout_volume_SetVolume(aout_volume_t *vol, float factor)
  */
 int aout_volume_Amplify(aout_volume_t *vol, block_t *block)
 {
-    if (unlikely(vol == NULL) || vol->module == NULL)
+    if (vol->module == NULL)
         return -1;
 
-    float amp = vol->output_factor * atomic_load(&vol->gain_factor);
+    float amp = atomic_load_explicit(&vol->output_factor, memory_order_relaxed)
+              * atomic_load_explicit(&vol->gain_factor, memory_order_relaxed);
 
     vol->object.amplify(&vol->object, block, amp);
     return 0;
@@ -197,7 +190,7 @@ static int ReplayGainCallback (vlc_object_t *obj, char const *var,
     aout_volume_t *vol = data;
     float multiplier = aout_ReplayGainSelect(obj, val.psz_string,
                                              &vol->replay_gain);
-    atomic_store(&vol->gain_factor, multiplier);
+    atomic_store_explicit(&vol->gain_factor, multiplier, memory_order_relaxed);
     VLC_UNUSED(var); VLC_UNUSED(oldval);
     return VLC_SUCCESS;
 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b18dda38130cbc8c384ba3b202852858495461c9...aeedea5abf9f4031964bf95dee5034bc2219c501

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b18dda38130cbc8c384ba3b202852858495461c9...aeedea5abf9f4031964bf95dee5034bc2219c501
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list