summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2012-04-09 22:11:49 +0300
committerUoti Urpala <uau@mplayer2.org>2012-04-11 03:52:34 +0300
commit9624f10aa85039c73d4bdb70e8062daeabaa90c6 (patch)
tree7303f5d0011c5f7a320f0e24d74c42d8e5e2eb3f
parente29cb8f323031b32369bc2104ea1fd4422dd2945 (diff)
downloadmpv-9624f10aa85039c73d4bdb70e8062daeabaa90c6.tar.bz2
mpv-9624f10aa85039c73d4bdb70e8062daeabaa90c6.tar.xz
audio: fix unmute-at-end logic
The player tried to disable mute before exiting, so that if mute is emulated by setting volume to 0 and the volume setting is a system-global one, we don't leave it at 0. However, the logic doing this at process exit was flawed, as volume settings are handled by audio output instances and the audio output that set the mute state may have been closed earlier. Trying to write reliably working logic that restores volume at exit only would be tricky, so change the code to always unmute an audio driver before closing it and restore mute status if one is opened again later.
-rw-r--r--command.c4
-rw-r--r--mixer.c28
-rw-r--r--mixer.h1
-rw-r--r--mp_core.h2
-rw-r--r--mplayer.c6
5 files changed, 29 insertions, 12 deletions
diff --git a/command.c b/command.c
index e4ce53f87a..d511e52c4a 100644
--- a/command.c
+++ b/command.c
@@ -719,8 +719,6 @@ static int mp_property_volume(m_option_t *prop, int action, void *arg,
return M_PROPERTY_NOT_IMPLEMENTED;
}
- mpctx->user_muted = 0;
-
switch (action) {
case M_PROPERTY_SET:
if (!arg)
@@ -757,12 +755,10 @@ static int mp_property_mute(m_option_t *prop, int action, void *arg,
if (!arg)
return M_PROPERTY_ERROR;
mixer_setmute(&mpctx->mixer, *(int *) arg);
- mpctx->user_muted = mpctx->mixer.muted;
return M_PROPERTY_OK;
case M_PROPERTY_STEP_UP:
case M_PROPERTY_STEP_DOWN:
mixer_setmute(&mpctx->mixer, !mixer_getmute(&mpctx->mixer));
- mpctx->user_muted = mpctx->mixer.muted;
return M_PROPERTY_OK;
default:
return m_property_flag_ro(prop, action, arg,
diff --git a/mixer.c b/mixer.c
index e694253b11..793a6ac58e 100644
--- a/mixer.c
+++ b/mixer.c
@@ -235,10 +235,32 @@ void mixer_reinit(struct mixer *mixer, struct ao *ao)
const char *restore_reason = mixer->softvol ? "softvol" :
mixer->ao->driver->info->short_name;
if (mixer->restore_volume && !strcmp(mixer->restore_volume,
- restore_reason)) {
+ restore_reason))
mixer_setvolume(mixer, left, right);
- mixer_setmute(mixer, muted);
- }
+ mixer_setmute(mixer, muted);
if (mixer->balance != 0)
mixer_setbalance(mixer, mixer->balance);
}
+
+/* Called before uninitializing the audio output. The main purpose is to
+ * turn off mute, in case it's a global/persistent setting which might
+ * otherwise be left enabled even after this player instance exits.
+ */
+void mixer_uninit(struct mixer *mixer)
+{
+ checkvolume(mixer);
+ if (mixer->muted) {
+ /* Current audio output API combines playing the remaining buffered
+ * audio and uninitializing the AO into one operation, even though
+ * ideally unmute would happen between those two steps. We can't do
+ * volume changes after uninitialization, but we don't want the
+ * remaining audio to play at full volume either. Thus this
+ * workaround to drop remaining audio first. */
+ ao_reset(mixer->ao);
+ mixer_setmute(mixer, false);
+ /* We remember mute status and re-enable it if we play more audio
+ * in the same process. */
+ mixer->muted = true;
+ }
+ mixer->ao = NULL;
+}
diff --git a/mixer.h b/mixer.h
index e626237539..c1903750f1 100644
--- a/mixer.h
+++ b/mixer.h
@@ -39,6 +39,7 @@ typedef struct mixer {
} mixer_t;
void mixer_reinit(struct mixer *mixer, struct ao *ao);
+void mixer_uninit(struct mixer *mixer);
void mixer_getvolume(mixer_t *mixer, float *l, float *r);
void mixer_setvolume(mixer_t *mixer, float l, float r);
void mixer_incvolume(mixer_t *mixer);
diff --git a/mp_core.h b/mp_core.h
index 621a5cc1d2..4481e61469 100644
--- a/mp_core.h
+++ b/mp_core.h
@@ -188,8 +188,6 @@ typedef struct MPContext {
float begin_skip; ///< start time of the current skip while on edlout mode
- short user_muted; ///< Stores whether user wanted muted mode.
-
int global_sub_size; // this encompasses all subtitle sources
int global_sub_pos; // this encompasses all subtitle sources
int set_of_sub_pos;
diff --git a/mplayer.c b/mplayer.c
index 9140b16bca..f3a9cbdc10 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -681,8 +681,10 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
if (mask & INITIALIZED_AO) {
mpctx->initialized_flags &= ~INITIALIZED_AO;
current_module = "uninit_ao";
- if (mpctx->ao)
+ if (mpctx->ao) {
+ mixer_uninit(&mpctx->mixer);
ao_uninit(mpctx->ao, mpctx->stop_play != AT_END_OF_FILE);
+ }
mpctx->ao = NULL;
}
@@ -691,8 +693,6 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
void exit_player_with_rc(struct MPContext *mpctx, enum exit_reason how, int rc)
{
- if (mpctx->user_muted)
- mixer_setmute(&mpctx->mixer, false);
uninit_player(mpctx, INITIALIZED_ALL);
#if defined(__MINGW32__) || defined(__CYGWIN__)
timeEndPeriod(1);