1
mirror of https://code.videolan.org/videolan/vlc synced 2024-09-12 13:44:56 +02:00

aout: remove intricate volume/mute transaction system

Volume and mute states are now independant. There is no need to
update them together in a single transaction.

Furthermore, other processes can change the volume and/or mute state
of VLC playback streams asynchronously. Thus volume-up/volume-down
and mute-toggle are not atomic operations even when protected by the
volume lock. We would need to have toggle and up/down provided by the
to the output plugins. That is probably impossible and overkill.
So accept the small race condition and simplify the code.
This commit is contained in:
Rémi Denis-Courmont 2012-07-02 23:35:48 +03:00
parent f6d9780ee5
commit b7797c07e2
4 changed files with 63 additions and 113 deletions

View File

@ -36,13 +36,20 @@ VLC_API int aout_VolumeSet( vlc_object_t *, float );
VLC_API int aout_VolumeUp( vlc_object_t *, int, float * );
#define aout_VolumeUp(a, b, c) aout_VolumeUp(VLC_OBJECT(a), b, c)
#define aout_VolumeDown(a, b, c) aout_VolumeUp(a, -(b), c)
VLC_API int aout_MuteToggle( vlc_object_t * );
#define aout_MuteToggle(a) aout_MuteToggle(VLC_OBJECT(a))
VLC_API int aout_MuteSet( vlc_object_t *, bool );
#define aout_MuteSet(a, b) aout_MuteSet(VLC_OBJECT(a), b)
VLC_API int aout_MuteGet( vlc_object_t * );
#define aout_MuteGet(a) aout_MuteGet(VLC_OBJECT(a))
static inline int aout_MuteToggle (vlc_object_t *obj)
{
int val = aout_MuteGet (obj);
if (val >= 0)
val = aout_MuteSet (obj, !val);
return val;
}
#define aout_MuteToggle(a) aout_MuteToggle(VLC_OBJECT(a))
VLC_API void aout_EnableFilter( vlc_object_t *, const char *, bool );
#define aout_EnableFilter( o, n, b ) \
aout_EnableFilter( VLC_OBJECT(o), n, b )

View File

@ -60,74 +60,6 @@ static audio_output_t *findAout (vlc_object_t *obj)
}
#define findAout(o) findAout(VLC_OBJECT(o))
/** Start a volume change transaction. */
static void prepareVolume (vlc_object_t *obj, audio_output_t **aoutp,
float *vol, bool *mute)
{
audio_output_t *aout = findAout (obj);
/* FIXME: we need interlocking even if aout does not exist! */
*aoutp = aout;
if (aout != NULL)
{
obj = VLC_OBJECT(aout); /* use aout volume if aout exists */
aout_lock_volume (aout);
}
if (vol != NULL)
*vol = var_InheritInteger (obj, "volume") / (float)AOUT_VOLUME_DEFAULT;
if (mute != NULL)
*mute = var_InheritBool (obj, "mute");
}
/** Commit a volume change transaction. */
static int commitVolume (vlc_object_t *obj, audio_output_t *aout,
float vol, bool mute)
{
long volume = lroundf (vol * AOUT_VOLUME_DEFAULT);
int ret = 0;
if (aout != NULL)
{
/* apply volume to the pipeline */
aout_lock (aout);
if (aout->mute_set != NULL)
ret = aout->mute_set (aout, mute);
else
ret = -1;
if (ret == 0 && aout->volume_set != NULL)
ret = aout->volume_set (aout, vol);
aout_unlock (aout);
if (ret == 0)
{ /* update aout volume if it maintains its own */
var_SetInteger (aout, "volume", volume);
var_SetBool (aout, "mute", mute);
}
aout_unlock_volume (aout);
vlc_object_release (aout);
}
if (ret == 0)
{ /* update caller (input manager) volume */
var_SetInteger (obj, "volume", volume);
var_SetBool (obj, "mute", mute);
if (var_InheritBool (obj, "volume-save"))
config_PutInt (obj, "volume", volume);
}
return ret;
}
/** Cancel a volume change transaction. */
static void cancelVolume (vlc_object_t *obj, audio_output_t *aout)
{
(void) obj;
if (aout != NULL)
{
aout_unlock_volume (aout);
vlc_object_release (aout);
}
}
#undef aout_VolumeGet
/**
* Gets the volume of the output device (independent of mute).
@ -136,26 +68,42 @@ static void cancelVolume (vlc_object_t *obj, audio_output_t *aout)
*/
float aout_VolumeGet (vlc_object_t *obj)
{
audio_output_t *aout;
float vol;
audio_output_t *aout = findAout (obj);
if (aout == NULL)
return -1.f;
prepareVolume (obj, &aout, &vol, NULL);
cancelVolume (obj, aout);
return vol;
long l = var_InheritInteger (aout, "volume");
vlc_object_release (aout);
return l / (float)AOUT_VOLUME_DEFAULT;
}
#undef aout_VolumeSet
/**
* Sets the volume of the output device.
* The mute status is not changed.
* \note The mute status is not changed.
*/
int aout_VolumeSet (vlc_object_t *obj, float vol)
{
audio_output_t *aout;
bool mute;
long volume = lroundf (vol * AOUT_VOLUME_DEFAULT);
int ret = -1;
prepareVolume (obj, &aout, NULL, &mute);
return commitVolume (obj, aout, vol, mute);
audio_output_t *aout = findAout (obj);
if (aout != NULL)
{
aout_lock (aout);
if (aout->volume_set != NULL)
ret = aout->volume_set (aout, vol);
aout_unlock (aout);
vlc_object_release (aout);
}
if (ret == 0)
{ /* update caller (input manager) volume */
var_SetInteger (obj, "volume", volume);
if (var_InheritBool (obj, "volume-save"))
config_PutInt (obj, "volume", volume);
}
return ret;
}
#undef aout_VolumeUp
@ -166,38 +114,21 @@ int aout_VolumeSet (vlc_object_t *obj, float vol)
*/
int aout_VolumeUp (vlc_object_t *obj, int value, float *volp)
{
audio_output_t *aout;
int ret;
float vol;
bool mute;
value *= var_InheritInteger (obj, "volume-step");
prepareVolume (obj, &aout, &vol, &mute);
float vol = aout_VolumeGet (obj);
if (vol < 0.)
return -1;
vol += value / (float)AOUT_VOLUME_DEFAULT;
if (vol < 0.)
vol = 0.;
if (vol > (AOUT_VOLUME_MAX / AOUT_VOLUME_DEFAULT))
vol = AOUT_VOLUME_MAX / AOUT_VOLUME_DEFAULT;
ret = commitVolume (obj, aout, vol, mute);
if (vol > 2.)
vol = 2.;
if (volp != NULL)
*volp = vol;
return ret;
}
#undef aout_MuteToggle
/**
* Toggles the mute state.
*/
int aout_MuteToggle (vlc_object_t *obj)
{
audio_output_t *aout;
float vol;
bool mute;
prepareVolume (obj, &aout, &vol, &mute);
mute = !mute;
return commitVolume (obj, aout, vol, mute);
return aout_VolumeSet (obj, vol);
}
#undef aout_MuteGet
@ -207,11 +138,12 @@ int aout_MuteToggle (vlc_object_t *obj)
*/
int aout_MuteGet (vlc_object_t *obj)
{
audio_output_t *aout;
bool mute;
audio_output_t *aout = findAout (obj);
if (aout == NULL)
return -1.f;
prepareVolume (obj, &aout, NULL, &mute);
cancelVolume (obj, aout);
bool mute = var_InheritBool (aout, "mute");
vlc_object_release (aout);
return mute;
}
@ -221,11 +153,21 @@ int aout_MuteGet (vlc_object_t *obj)
*/
int aout_MuteSet (vlc_object_t *obj, bool mute)
{
audio_output_t *aout;
float vol;
int ret = -1;
prepareVolume (obj, &aout, &vol, NULL);
return commitVolume (obj, aout, vol, mute);
audio_output_t *aout = findAout (obj);
if (aout != NULL)
{
aout_lock (aout);
if (aout->mute_set != NULL)
ret = aout->mute_set (aout, mute);
aout_unlock (aout);
vlc_object_release (aout);
}
if (ret == 0)
var_SetBool (obj, "mute", mute);
return ret;
}

View File

@ -347,6 +347,7 @@ static int aout_SoftVolumeSet (audio_output_t *aout, float volume)
* formula, be sure to update the aout_VolumeHardInit()-based plugins also.
*/
owner->volume.amp = volume * volume * volume;
aout_VolumeReport (aout, volume);
return 0;
}
@ -356,6 +357,7 @@ static int aout_SoftMuteSet (audio_output_t *aout, bool mute)
aout_assert_locked (aout);
owner->volume.mute = mute;
aout_MuteReport (aout, mute);
return 0;
}

View File

@ -17,7 +17,6 @@ aout_MixerRun
aout_VolumeGet
aout_VolumeSet
aout_VolumeUp
aout_MuteToggle
aout_MuteSet
aout_MuteGet
aout_VolumeSoftInit