From 296531ad0050fbc38fb1cf7823f6e22f97d502b1 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 19 Sep 2013 14:31:43 +0200 Subject: mixer: minor refactoring Let struct mixer access access MPOpts to simplify some things. Rename some variables and functions. There should be no functional changes. --- mpvcore/mplayer.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'mpvcore') diff --git a/mpvcore/mplayer.c b/mpvcore/mplayer.c index d9715e447f..a2c96bb270 100644 --- a/mpvcore/mplayer.c +++ b/mpvcore/mplayer.c @@ -454,7 +454,7 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) if (mpctx->sh_audio) uninit_audio(mpctx->sh_audio); cleanup_demux_stream(mpctx, STREAM_AUDIO); - mpctx->mixer.afilter = NULL; + mpctx->mixer.af = NULL; } if (mask & INITIALIZED_SUB) { @@ -542,7 +542,7 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) if (mask & INITIALIZED_AO) { mpctx->initialized_flags &= ~INITIALIZED_AO; if (mpctx->mixer.ao) - mixer_uninit(&mpctx->mixer); + mixer_uninit_audio(&mpctx->mixer); mpctx->mixer.ao = NULL; if (mpctx->ao) ao_uninit(mpctx->ao, mpctx->stop_play != AT_END_OF_FILE); @@ -1628,11 +1628,7 @@ static int recreate_audio_filters(struct MPContext *mpctx) return -1; } - mpctx->mixer.afilter = mpctx->sh_audio->afilter; - mpctx->mixer.volstep = opts->volstep; - mpctx->mixer.softvol = opts->softvol; - mpctx->mixer.softvol_max = opts->softvol_max; - mixer_reinit(&mpctx->mixer, mpctx->ao); + mixer_reinit_audio(&mpctx->mixer, mpctx->ao, mpctx->sh_audio->afilter); if (!(mpctx->initialized_flags & INITIALIZED_VOL)) { if (opts->mixer_init_volume >= 0) { mixer_setvolume(&mpctx->mixer, opts->mixer_init_volume, @@ -4859,6 +4855,7 @@ static int mpv_main(int argc, char *argv[]) init_libav(); GetCpuCaps(&gCpuCaps); screenshot_init(mpctx); + mpctx->mixer.opts = opts; // Preparse the command line m_config_preparse_command_line(mpctx->mconfig, argc, argv); -- cgit v1.2.3 From 38b2c97fd6b59b923ad309c19c457cbc0210da17 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 19 Sep 2013 14:32:09 +0200 Subject: mixer: refactor, fix some aspects of --volume handling Refactor how mixer.c does volume/mute restoration and initialization. Move to handling of --volume and --mute to mixer.c. Simplify the implementation of these and hopefully fix bugs/strange behavior related to using them as file-local options (this uses a somewhat dirty trick: the option values are reverted to "auto" after initialization). Put most code related to initialization and volume restoring in probe_softvol() and restore_volume(). Having this code all in one place is less confusing. Instead of trying to detect whether to use softvol at runtime, detect it at initialization time using AOCONTROL_GET_VOLUME (same with mute, AOCONTROL_GET_MUTE). This implies we expect SET_VOLUME/SET_MUTE to work if the GET variants work. Hopefully this is always the case. This is also preparation for being able to change volume/mute settings if audio is disabled, and for allowing restoring value with playback resume. --- mpvcore/mp_core.h | 1 - mpvcore/mplayer.c | 42 +++++++----------------------------------- 2 files changed, 7 insertions(+), 36 deletions(-) (limited to 'mpvcore') diff --git a/mpvcore/mp_core.h b/mpvcore/mp_core.h index 9f3e095110..8f57a65edf 100644 --- a/mpvcore/mp_core.h +++ b/mpvcore/mp_core.h @@ -29,7 +29,6 @@ #define INITIALIZED_VO 1 #define INITIALIZED_AO 2 -#define INITIALIZED_VOL 4 #define INITIALIZED_GETCH2 8 #define INITIALIZED_PLAYBACK 16 #define INITIALIZED_STREAM 64 diff --git a/mpvcore/mplayer.c b/mpvcore/mplayer.c index a2c96bb270..fafb88d022 100644 --- a/mpvcore/mplayer.c +++ b/mpvcore/mplayer.c @@ -443,18 +443,16 @@ static void uninit_subs(struct demuxer *demuxer) void uninit_player(struct MPContext *mpctx, unsigned int mask) { - struct MPOpts *opts = mpctx->opts; - mask &= mpctx->initialized_flags; mp_msg(MSGT_CPLAYER, MSGL_DBG2, "\n*** uninit(0x%X)\n", mask); if (mask & INITIALIZED_ACODEC) { mpctx->initialized_flags &= ~INITIALIZED_ACODEC; + mixer_uninit_audio(&mpctx->mixer); if (mpctx->sh_audio) uninit_audio(mpctx->sh_audio); cleanup_demux_stream(mpctx, STREAM_AUDIO); - mpctx->mixer.af = NULL; } if (mask & INITIALIZED_SUB) { @@ -526,24 +524,8 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) getch2_disable(); } - if (mask & INITIALIZED_VOL) { - mpctx->initialized_flags &= ~INITIALIZED_VOL; - if (mpctx->mixer.ao) { - // Normally the mixer remembers volume, but do it even if the - // volume is set explicitly with --volume=... (so that the same - // volume is restored on reinit) - if (opts->mixer_init_volume >= 0 && mpctx->mixer.user_set_volume) - mixer_getbothvolume(&mpctx->mixer, &opts->mixer_init_volume); - if (opts->mixer_init_mute >= 0 && mpctx->mixer.user_set_mute) - opts->mixer_init_mute = mixer_getmute(&mpctx->mixer); - } - } - if (mask & INITIALIZED_AO) { mpctx->initialized_flags &= ~INITIALIZED_AO; - if (mpctx->mixer.ao) - mixer_uninit_audio(&mpctx->mixer); - mpctx->mixer.ao = NULL; if (mpctx->ao) ao_uninit(mpctx->ao, mpctx->stop_play != AT_END_OF_FILE); mpctx->ao = NULL; @@ -1618,7 +1600,6 @@ static int build_afilter_chain(struct MPContext *mpctx) static int recreate_audio_filters(struct MPContext *mpctx) { - struct MPOpts *opts = mpctx->opts; assert(mpctx->sh_audio); // init audio filters: @@ -1629,15 +1610,6 @@ static int recreate_audio_filters(struct MPContext *mpctx) } mixer_reinit_audio(&mpctx->mixer, mpctx->ao, mpctx->sh_audio->afilter); - if (!(mpctx->initialized_flags & INITIALIZED_VOL)) { - if (opts->mixer_init_volume >= 0) { - mixer_setvolume(&mpctx->mixer, opts->mixer_init_volume, - opts->mixer_init_volume); - } - if (opts->mixer_init_mute >= 0) - mixer_setmute(&mpctx->mixer, opts->mixer_init_mute); - mpctx->initialized_flags |= INITIALIZED_VOL; - } return 0; } @@ -1662,7 +1634,7 @@ void reinit_audio_chain(struct MPContext *mpctx) struct MPOpts *opts = mpctx->opts; init_demux_stream(mpctx, STREAM_AUDIO); if (!mpctx->sh_audio) { - uninit_player(mpctx, INITIALIZED_VOL | INITIALIZED_AO); + uninit_player(mpctx, INITIALIZED_AO); goto no_audio; } @@ -1733,7 +1705,7 @@ void reinit_audio_chain(struct MPContext *mpctx) return; init_error: - uninit_player(mpctx, INITIALIZED_ACODEC | INITIALIZED_AO | INITIALIZED_VOL); + uninit_player(mpctx, INITIALIZED_ACODEC | INITIALIZED_AO); cleanup_demux_stream(mpctx, STREAM_AUDIO); no_audio: mpctx->current_track[STREAM_AUDIO] = NULL; @@ -2040,7 +2012,7 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type, uninit_player(mpctx, INITIALIZED_VCODEC | (mpctx->opts->fixed_vo && track ? 0 : INITIALIZED_VO)); } else if (type == STREAM_AUDIO) { - uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_ACODEC | INITIALIZED_VOL); + uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_ACODEC); } else if (type == STREAM_SUB) { uninit_player(mpctx, INITIALIZED_SUB); } @@ -2280,7 +2252,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx, double endpts) * while displaying video, then doing the output format switch. */ if (!mpctx->opts->gapless_audio) - uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_VOL); + uninit_player(mpctx, INITIALIZED_AO); reinit_audio_chain(mpctx); return -1; } else if (res == ASYNC_PLAY_DONE) @@ -2909,7 +2881,7 @@ static bool timeline_set_part(struct MPContext *mpctx, int i, bool force) enum stop_play_reason orig_stop_play = mpctx->stop_play; if (!mpctx->sh_video && mpctx->stop_play == KEEP_PLAYING) mpctx->stop_play = AT_END_OF_FILE; // let audio uninit drain data - uninit_player(mpctx, INITIALIZED_VCODEC | (mpctx->opts->fixed_vo ? 0 : INITIALIZED_VO) | (mpctx->opts->gapless_audio ? 0 : INITIALIZED_AO) | INITIALIZED_VOL | INITIALIZED_ACODEC | INITIALIZED_SUB); + uninit_player(mpctx, INITIALIZED_VCODEC | (mpctx->opts->fixed_vo ? 0 : INITIALIZED_VO) | (mpctx->opts->gapless_audio ? 0 : INITIALIZED_AO) | INITIALIZED_ACODEC | INITIALIZED_SUB); mpctx->stop_play = orig_stop_play; mpctx->demuxer = n->source; @@ -4855,7 +4827,7 @@ static int mpv_main(int argc, char *argv[]) init_libav(); GetCpuCaps(&gCpuCaps); screenshot_init(mpctx); - mpctx->mixer.opts = opts; + mixer_init(&mpctx->mixer, opts); // Preparse the command line m_config_preparse_command_line(mpctx->mconfig, argc, argv); -- cgit v1.2.3 From b8e42ae13c511855fcba0b6b795d55b37e461665 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 19 Sep 2013 14:32:47 +0200 Subject: mixer: restore volume with playback resume Note that this is intentionally never done if the AO or softvolume is different, or if the current volume control method is thought to control system wide volume (such as ALSA) or otherwise user controllable (such as PulseAudio). The intention is to keep things robust and to avoid messing with the user's audio settings as far as possible, while still providing the ability to resume volume if it makes sense. --- mpvcore/command.c | 16 ++++++++++++++++ mpvcore/mplayer.c | 3 +-- mpvcore/options.c | 1 + mpvcore/options.h | 1 + 4 files changed, 19 insertions(+), 2 deletions(-) (limited to 'mpvcore') diff --git a/mpvcore/command.c b/mpvcore/command.c index dedac9dc10..ea71b9e082 100644 --- a/mpvcore/command.c +++ b/mpvcore/command.c @@ -804,6 +804,21 @@ static int mp_property_mute(m_option_t *prop, int action, void *arg, return M_PROPERTY_NOT_IMPLEMENTED; } +static int mp_property_volrestore(m_option_t *prop, int action, + void *arg, MPContext *mpctx) +{ + switch (action) { + case M_PROPERTY_GET: { + char *s = mixer_get_volume_restore_data(&mpctx->mixer); + *(char **)arg = s; + return s ? M_PROPERTY_OK : M_PROPERTY_UNAVAILABLE; + } + case M_PROPERTY_SET: + return M_PROPERTY_NOT_IMPLEMENTED; + } + return mp_property_generic_option(prop, action, arg, mpctx); +} + /// Audio delay (RW) static int mp_property_audio_delay(m_option_t *prop, int action, void *arg, MPContext *mpctx) @@ -1806,6 +1821,7 @@ static const m_option_t mp_properties[] = { M_OPTION_PROPERTY_CUSTOM("aid", mp_property_audio), { "balance", mp_property_balance, CONF_TYPE_FLOAT, M_OPT_RANGE, -1, 1, NULL }, + M_OPTION_PROPERTY_CUSTOM("volume-restore-data", mp_property_volrestore), // Video M_OPTION_PROPERTY_CUSTOM("fullscreen", mp_property_fullscreen), diff --git a/mpvcore/mplayer.c b/mpvcore/mplayer.c index fafb88d022..00229364e6 100644 --- a/mpvcore/mplayer.c +++ b/mpvcore/mplayer.c @@ -809,8 +809,7 @@ static const char *backup_properties[] = { "speed", "edition", "pause", - //"volume", - //"mute", + "volume-restore-data", "audio-delay", //"balance", "fullscreen", diff --git a/mpvcore/options.c b/mpvcore/options.c index a09a28856f..e3b3137aed 100644 --- a/mpvcore/options.c +++ b/mpvcore/options.c @@ -565,6 +565,7 @@ const m_option_t mp_opts[] = { ({"auto", -1}, {"no", 0}, {"yes", 1}, {"", 1})), + OPT_STRING("volume-restore-data", mixer_restore_volume_data, 0), OPT_FLAG("gapless-audio", gapless_audio, 0), // set screen dimensions (when not detectable or virtual!=visible) diff --git a/mpvcore/options.h b/mpvcore/options.h index 67074de241..d425d0789b 100644 --- a/mpvcore/options.h +++ b/mpvcore/options.h @@ -51,6 +51,7 @@ typedef struct MPOpts { int softvol; float mixer_init_volume; int mixer_init_mute; + char *mixer_restore_volume_data; int volstep; float softvol_max; int gapless_audio; -- cgit v1.2.3 From 327a779a81098b39823f7036eba816b8b4c7245f Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 19 Sep 2013 14:33:12 +0200 Subject: mixer: allow accessing volume and mute property on disabled audio The volume is set as soon as the audio chain is created again. This works only in softvol mode. For system wide volume or otherwise externally user controllable volume, this code is intentionally disabled. It would be extremely weird if changing volume (while audio is not initialized) would do nothing, and then suddenly change it when the audio chain is created. There's another odd corner case: the user-set volume will be thrown away if it's set before the _first_ audio chain initialization. This is because the volume restore logic recognizes a change from nothing to softvol or an AO, and circumventing that would require additional code. Also, we don't even know the start volume before that point. Forcing the volume with --volume will can override the volume set during no-audio mode, depending on the situation. --- mpvcore/command.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'mpvcore') diff --git a/mpvcore/command.c b/mpvcore/command.c index ea71b9e082..cb1bdd9678 100644 --- a/mpvcore/command.c +++ b/mpvcore/command.c @@ -762,10 +762,6 @@ static int mp_property_clock(m_option_t *prop, int action, void *arg, static int mp_property_volume(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - - if (!mpctx->sh_audio) - return M_PROPERTY_UNAVAILABLE; - switch (action) { case M_PROPERTY_GET: mixer_getbothvolume(&mpctx->mixer, arg); @@ -789,10 +785,6 @@ static int mp_property_volume(m_option_t *prop, int action, void *arg, static int mp_property_mute(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - - if (!mpctx->sh_audio) - return M_PROPERTY_UNAVAILABLE; - switch (action) { case M_PROPERTY_SET: mixer_setmute(&mpctx->mixer, *(int *) arg); -- cgit v1.2.3 From 01622717257673d424debfa762536f998d97a4dd Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 19 Sep 2013 14:33:26 +0200 Subject: mixer: make struct opaque Also remove stray include statements from ao_alsa and ao_oss. --- mpvcore/command.c | 20 ++++++++++---------- mpvcore/mp_core.h | 3 +-- mpvcore/mplayer.c | 6 +++--- 3 files changed, 14 insertions(+), 15 deletions(-) (limited to 'mpvcore') diff --git a/mpvcore/command.c b/mpvcore/command.c index cb1bdd9678..a2de363b3d 100644 --- a/mpvcore/command.c +++ b/mpvcore/command.c @@ -764,17 +764,17 @@ static int mp_property_volume(m_option_t *prop, int action, void *arg, { switch (action) { case M_PROPERTY_GET: - mixer_getbothvolume(&mpctx->mixer, arg); + mixer_getbothvolume(mpctx->mixer, arg); return M_PROPERTY_OK; case M_PROPERTY_SET: - mixer_setvolume(&mpctx->mixer, *(float *) arg, *(float *) arg); + mixer_setvolume(mpctx->mixer, *(float *) arg, *(float *) arg); return M_PROPERTY_OK; case M_PROPERTY_SWITCH: { struct m_property_switch_arg *sarg = arg; if (sarg->inc <= 0) - mixer_decvolume(&mpctx->mixer); + mixer_decvolume(mpctx->mixer); else - mixer_incvolume(&mpctx->mixer); + mixer_incvolume(mpctx->mixer); return M_PROPERTY_OK; } } @@ -787,10 +787,10 @@ static int mp_property_mute(m_option_t *prop, int action, void *arg, { switch (action) { case M_PROPERTY_SET: - mixer_setmute(&mpctx->mixer, *(int *) arg); + mixer_setmute(mpctx->mixer, *(int *) arg); return M_PROPERTY_OK; case M_PROPERTY_GET: - *(int *)arg = mixer_getmute(&mpctx->mixer); + *(int *)arg = mixer_getmute(mpctx->mixer); return M_PROPERTY_OK; } return M_PROPERTY_NOT_IMPLEMENTED; @@ -801,7 +801,7 @@ static int mp_property_volrestore(m_option_t *prop, int action, { switch (action) { case M_PROPERTY_GET: { - char *s = mixer_get_volume_restore_data(&mpctx->mixer); + char *s = mixer_get_volume_restore_data(mpctx->mixer); *(char **)arg = s; return s ? M_PROPERTY_OK : M_PROPERTY_UNAVAILABLE; } @@ -906,11 +906,11 @@ static int mp_property_balance(m_option_t *prop, int action, void *arg, switch (action) { case M_PROPERTY_GET: - mixer_getbalance(&mpctx->mixer, arg); + mixer_getbalance(mpctx->mixer, arg); return M_PROPERTY_OK; case M_PROPERTY_PRINT: { char **str = arg; - mixer_getbalance(&mpctx->mixer, &bal); + mixer_getbalance(mpctx->mixer, &bal); if (bal == 0.f) *str = talloc_strdup(NULL, "center"); else if (bal == -1.f) @@ -925,7 +925,7 @@ static int mp_property_balance(m_option_t *prop, int action, void *arg, return M_PROPERTY_OK; } case M_PROPERTY_SET: - mixer_setbalance(&mpctx->mixer, *(float *)arg); + mixer_setbalance(mpctx->mixer, *(float *)arg); return M_PROPERTY_OK; } return M_PROPERTY_NOT_IMPLEMENTED; diff --git a/mpvcore/mp_core.h b/mpvcore/mp_core.h index 8f57a65edf..98096aa5fe 100644 --- a/mpvcore/mp_core.h +++ b/mpvcore/mp_core.h @@ -22,7 +22,6 @@ #include #include "mpvcore/options.h" -#include "audio/mixer.h" #include "demux/demux.h" // definitions used internally by the core player code @@ -179,7 +178,7 @@ typedef struct MPContext { // demuxer defines metadata), or special purpose demuxers like TV. struct demuxer *master_demuxer; - mixer_t mixer; + struct mixer *mixer; struct ao *ao; struct vo *video_out; diff --git a/mpvcore/mplayer.c b/mpvcore/mplayer.c index 00229364e6..dc4322d4e3 100644 --- a/mpvcore/mplayer.c +++ b/mpvcore/mplayer.c @@ -449,7 +449,7 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) if (mask & INITIALIZED_ACODEC) { mpctx->initialized_flags &= ~INITIALIZED_ACODEC; - mixer_uninit_audio(&mpctx->mixer); + mixer_uninit_audio(mpctx->mixer); if (mpctx->sh_audio) uninit_audio(mpctx->sh_audio); cleanup_demux_stream(mpctx, STREAM_AUDIO); @@ -1608,7 +1608,7 @@ static int recreate_audio_filters(struct MPContext *mpctx) return -1; } - mixer_reinit_audio(&mpctx->mixer, mpctx->ao, mpctx->sh_audio->afilter); + mixer_reinit_audio(mpctx->mixer, mpctx->ao, mpctx->sh_audio->afilter); return 0; } @@ -4826,7 +4826,7 @@ static int mpv_main(int argc, char *argv[]) init_libav(); GetCpuCaps(&gCpuCaps); screenshot_init(mpctx); - mixer_init(&mpctx->mixer, opts); + mpctx->mixer = mixer_init(mpctx, opts); // Preparse the command line m_config_preparse_command_line(mpctx->mconfig, argc, argv); -- cgit v1.2.3