Commit 649bb721 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

aout: use atomic ops for (deferred) restart

parent 2cdfae96
...@@ -70,9 +70,6 @@ struct aout_input_t ...@@ -70,9 +70,6 @@ struct aout_input_t
/* Mixer information */ /* Mixer information */
audio_replay_gain_t replay_gain; audio_replay_gain_t replay_gain;
/* If b_restart == 1, the input pipeline will be re-created. */
bool b_restart;
/* If b_error == 1, there is no input pipeline. */ /* If b_error == 1, there is no input pipeline. */
bool b_error; bool b_error;
...@@ -112,7 +109,7 @@ typedef struct ...@@ -112,7 +109,7 @@ typedef struct
filter_t *filters[AOUT_MAX_FILTERS]; filter_t *filters[AOUT_MAX_FILTERS];
int nb_filters; int nb_filters;
bool need_restart; vlc_atomic_t restart;
} aout_owner_t; } aout_owner_t;
typedef struct typedef struct
...@@ -137,7 +134,6 @@ int aout_InputNew(audio_output_t *, const audio_sample_format_t *, ...@@ -137,7 +134,6 @@ int aout_InputNew(audio_output_t *, const audio_sample_format_t *,
int aout_InputDelete( audio_output_t * p_aout, aout_input_t * p_input ); int aout_InputDelete( audio_output_t * p_aout, aout_input_t * p_input );
block_t *aout_InputPlay( audio_output_t *p_aout, aout_input_t *p_input, block_t *aout_InputPlay( audio_output_t *p_aout, aout_input_t *p_input,
block_t *p_buffer, int i_input_rate, date_t * ); block_t *p_buffer, int i_input_rate, date_t * );
void aout_InputRequestRestart( audio_output_t *p_aout );
/* From filters.c : */ /* From filters.c : */
int aout_FiltersCreatePipeline( vlc_object_t *, filter_t **, int *, int aout_FiltersCreatePipeline( vlc_object_t *, filter_t **, int *,
...@@ -195,6 +191,9 @@ void aout_DecChangePause(audio_output_t *, bool b_paused, mtime_t i_date); ...@@ -195,6 +191,9 @@ void aout_DecChangePause(audio_output_t *, bool b_paused, mtime_t i_date);
void aout_DecFlush(audio_output_t *); void aout_DecFlush(audio_output_t *);
bool aout_DecIsEmpty(audio_output_t *); bool aout_DecIsEmpty(audio_output_t *);
void aout_InputRequestRestart(audio_output_t *);
void aout_RequestRestart(audio_output_t *);
/* Audio output locking */ /* Audio output locking */
#if !defined (NDEBUG) \ #if !defined (NDEBUG) \
......
...@@ -31,9 +31,9 @@ ...@@ -31,9 +31,9 @@
#include <assert.h> #include <assert.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_aout.h> #include <vlc_aout.h>
#include <vlc_input.h> #include <vlc_input.h>
#include <vlc_atomic.h>
#include "aout_internal.h" #include "aout_internal.h"
#include "libvlc.h" #include "libvlc.h"
...@@ -97,6 +97,7 @@ int aout_DecNew( audio_output_t *p_aout, ...@@ -97,6 +97,7 @@ int aout_DecNew( audio_output_t *p_aout,
/* Recreate the output using the new format. */ /* Recreate the output using the new format. */
owner->input_format = *p_format; owner->input_format = *p_format;
vlc_atomic_set (&owner->restart, 0);
if( aout_OutputNew( p_aout, p_format ) < 0 ) if( aout_OutputNew( p_aout, p_format ) < 0 )
goto error; goto error;
...@@ -144,6 +145,8 @@ void aout_DecDelete( audio_output_t * p_aout ) ...@@ -144,6 +145,8 @@ void aout_DecDelete( audio_output_t * p_aout )
free (input); free (input);
} }
#define AOUT_RESTART_OUTPUT 1
#define AOUT_RESTART_INPUT 2
static void aout_CheckRestart (audio_output_t *aout) static void aout_CheckRestart (audio_output_t *aout)
{ {
aout_owner_t *owner = aout_owner (aout); aout_owner_t *owner = aout_owner (aout);
...@@ -151,24 +154,29 @@ static void aout_CheckRestart (audio_output_t *aout) ...@@ -151,24 +154,29 @@ static void aout_CheckRestart (audio_output_t *aout)
aout_assert_locked (aout); aout_assert_locked (aout);
if (likely(!owner->need_restart)) int restart = vlc_atomic_swap (&owner->restart, 0);
if (likely(restart == 0))
return; return;
owner->need_restart = false;
/* Reinitializes the output */ assert (restart & AOUT_RESTART_INPUT);
aout_InputDelete (aout, owner->input); aout_InputDelete (aout, input);
aout_MixerDelete (owner->volume.mixer);
owner->volume.mixer = NULL;
aout_OutputDelete (aout);
if (aout_OutputNew (aout, &owner->input_format)) /* Reinitializes the output */
if (restart & AOUT_RESTART_OUTPUT)
{ {
input->b_error = true; aout_MixerDelete (owner->volume.mixer);
return; /* we are officially screwed */ owner->volume.mixer = NULL;
aout_OutputDelete (aout);
if (aout_OutputNew (aout, &owner->input_format))
{
input->b_error = true;
return; /* we are officially screwed */
}
owner->volume.mixer = aout_MixerNew (aout,
owner->mixer_format.i_format);
} }
owner->volume.mixer = aout_MixerNew (aout, owner->mixer_format.i_format);
if (aout_InputNew (aout, &owner->input_format, &owner->mixer_format, input, if (aout_InputNew (aout, &owner->input_format, &owner->mixer_format, input,
&input->request_vout)) &input->request_vout))
assert (input->b_error); assert (input->b_error);
...@@ -177,22 +185,15 @@ static void aout_CheckRestart (audio_output_t *aout) ...@@ -177,22 +185,15 @@ static void aout_CheckRestart (audio_output_t *aout)
} }
/** /**
* Restarts the audio filter chain if needed. * Marks the audio output for restart, to update any parameter of the output
* plug-in (e.g. output device or channel mapping).
*/ */
static void aout_InputCheckAndRestart (audio_output_t *aout) void aout_RequestRestart (audio_output_t *aout)
{ {
aout_owner_t *owner = aout_owner (aout); aout_owner_t *owner = aout_owner (aout);
aout_input_t *input = owner->input;
aout_assert_locked (aout);
if (!input->b_restart)
return;
input->b_restart = false;
aout_InputDelete (aout, input); /* DO NOT remove AOUT_RESTART_INPUT. You need to change the atomic ops. */
aout_InputNew (aout, &owner->input_format, &owner->mixer_format, vlc_atomic_set (&owner->restart, AOUT_RESTART_OUTPUT|AOUT_RESTART_INPUT);
input, &input->request_vout);
} }
/** /**
...@@ -201,10 +202,9 @@ static void aout_InputCheckAndRestart (audio_output_t *aout) ...@@ -201,10 +202,9 @@ static void aout_InputCheckAndRestart (audio_output_t *aout)
*/ */
void aout_InputRequestRestart (audio_output_t *aout) void aout_InputRequestRestart (audio_output_t *aout)
{ {
aout_lock (aout); aout_owner_t *owner = aout_owner (aout);
if (aout_owner (aout)->input != NULL)
aout_owner (aout)->input->b_restart = true; vlc_atomic_compare_swap (&owner->restart, 0, AOUT_RESTART_INPUT);
aout_unlock (aout);
} }
...@@ -264,7 +264,6 @@ int aout_DecPlay (audio_output_t *p_aout, block_t *p_buffer, int i_input_rate) ...@@ -264,7 +264,6 @@ int aout_DecPlay (audio_output_t *p_aout, block_t *p_buffer, int i_input_rate)
} }
aout_CheckRestart( p_aout ); aout_CheckRestart( p_aout );
aout_InputCheckAndRestart (p_aout);
/* Input */ /* Input */
p_buffer = aout_InputPlay (p_aout, p_input, p_buffer, i_input_rate, p_buffer = aout_InputPlay (p_aout, p_input, p_buffer, i_input_rate,
......
...@@ -233,20 +233,6 @@ int aout_SetMute (vlc_object_t *obj, audio_volume_t *volp, bool mute) ...@@ -233,20 +233,6 @@ int aout_SetMute (vlc_object_t *obj, audio_volume_t *volp, bool mute)
* Pipelines management * Pipelines management
*/ */
/**
* Marks the audio output for restart, to update any parameter of the output
* plug-in (e.g. output device or channel mapping).
*/
static void aout_Restart (audio_output_t *aout)
{
aout_owner_t *owner = aout_owner (aout);
aout_lock (aout);
if (owner->input != NULL)
owner->need_restart = true;
aout_unlock (aout);
}
/***************************************************************************** /*****************************************************************************
* aout_ChannelsRestart : change the audio device or channels and restart * aout_ChannelsRestart : change the audio device or channels and restart
*****************************************************************************/ *****************************************************************************/
...@@ -263,7 +249,7 @@ int aout_ChannelsRestart( vlc_object_t * p_this, const char * psz_variable, ...@@ -263,7 +249,7 @@ int aout_ChannelsRestart( vlc_object_t * p_this, const char * psz_variable,
* rebuilding the channel choices. */ * rebuilding the channel choices. */
var_Destroy( p_aout, "audio-channels" ); var_Destroy( p_aout, "audio-channels" );
} }
aout_Restart( p_aout ); aout_RequestRestart (p_aout);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment