summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-07-22 14:43:58 +0200
committerwm4 <wm4@nowhere>2013-07-22 15:11:03 +0200
commit3b8dfddb4cb6e9431da659b10c5b31a9f17c81b5 (patch)
treeb087f6551fa96a6fbe0f1f2b7f0f951f331eb552 /core
parent221ef23d0d4454af974b08e68fad6b898d1d8e12 (diff)
downloadmpv-3b8dfddb4cb6e9431da659b10c5b31a9f17c81b5.tar.bz2
mpv-3b8dfddb4cb6e9431da659b10c5b31a9f17c81b5.tar.xz
audio/filter: use new option API
Make the VF/VO/AO option parser available to audio filters. No audio filter uses this yet, but it's still a quite intrusive change. In particular, the commands for manipulating filters at runtime completely change. We delete the old code, and use the same infrastructure as for video filters. (This forces complete reinitialization of the filter chain, which hopefully isn't a problem for any use cases. The old code forced reinitialization too, but it could potentially allow a filter to cache things; e.g. consider loaded ladspa plugins and such.)
Diffstat (limited to 'core')
-rw-r--r--core/command.c101
-rw-r--r--core/input/input.c6
-rw-r--r--core/input/input.h6
-rw-r--r--core/mp_core.h1
-rw-r--r--core/mplayer.c85
-rw-r--r--core/options.c4
-rw-r--r--core/options.h1
7 files changed, 101 insertions, 103 deletions
diff --git a/core/command.c b/core/command.c
index 4cf508d5e7..32479784e9 100644
--- a/core/command.c
+++ b/core/command.c
@@ -1914,43 +1914,72 @@ static const char *property_error_string(int error_value)
return "UNKNOWN";
}
-static void change_video_filters(MPContext *mpctx, const char *cmd,
- const char *arg)
+static bool reinit_filters(MPContext *mpctx, enum stream_type mediatype)
+{
+ switch (mediatype) {
+ case STREAM_VIDEO:
+ return reinit_video_filters(mpctx) >= 0;
+ case STREAM_AUDIO:
+ return reinit_audio_filters(mpctx) >= 0;
+ }
+ return false;
+}
+
+static void change_filters(MPContext *mpctx, enum stream_type mediatype,
+ const char *cmd, const char *arg)
{
struct MPOpts *opts = &mpctx->opts;
struct m_config *conf = mpctx->mconfig;
- struct m_obj_settings *old_vf_settings = NULL;
+ struct m_obj_settings *old_settings = NULL;
bool success = false;
bool need_refresh = false;
+ const char *option;
+ struct m_obj_settings **list;
+
+ switch (mediatype) {
+ case STREAM_VIDEO:
+ option = "vf";
+ list = &opts->vf_settings;
+ break;
+ case STREAM_AUDIO:
+ option = "af";
+ list = &opts->af_settings;
+ break;
+ }
// The option parser is used to modify the filter list itself.
char optname[20];
- snprintf(optname, sizeof(optname), "vf-%s", cmd);
+ snprintf(optname, sizeof(optname), "%s-%s", option, cmd);
const struct m_option *type = m_config_get_option(conf, bstr0(optname));
// Backup old settings, in case it fails
- m_option_copy(type, &old_vf_settings, &opts->vf_settings);
+ m_option_copy(type, &old_settings, list);
if (m_config_set_option0(conf, optname, arg) >= 0) {
need_refresh = true;
- success = reinit_video_filters(mpctx) >= 0;
+ success = reinit_filters(mpctx, mediatype);
}
if (!success) {
- m_option_copy(type, &opts->vf_settings, &old_vf_settings);
+ m_option_copy(type, list, &old_settings);
if (need_refresh)
- reinit_video_filters(mpctx);
+ reinit_filters(mpctx, mediatype);
}
- m_option_free(type, &old_vf_settings);
+ m_option_free(type, &old_settings);
- if (need_refresh)
+ if (need_refresh && mediatype == STREAM_VIDEO)
mp_force_video_refresh(mpctx);
}
+static void change_video_filters(MPContext *mpctx, const char *cmd,
+ const char *arg)
+{
+ change_filters(mpctx, STREAM_VIDEO, cmd, arg);
+}
+
void run_command(MPContext *mpctx, mp_cmd_t *cmd)
{
struct MPOpts *opts = &mpctx->opts;
- sh_audio_t *const sh_audio = mpctx->sh_audio;
sh_video_t *const sh_video = mpctx->sh_video;
int osd_duration = opts->osd_duration;
bool auto_osd = cmd->on_osd == MP_ON_OSD_AUTO;
@@ -2467,54 +2496,10 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
}
break;
- case MP_CMD_AF_SWITCH:
- if (sh_audio) {
- af_uninit(mpctx->mixer.afilter);
- af_init(mpctx->mixer.afilter);
- }
- /* fallthrough */
- case MP_CMD_AF_ADD:
- case MP_CMD_AF_DEL: {
- if (!sh_audio)
- break;
- char *af_args = strdup(cmd->args[0].v.s);
- bstr af_commands = bstr0(af_args);
- struct af_instance *af;
- while (af_commands.len) {
- bstr af_command;
- bstr_split_tok(af_commands, ",", &af_command, &af_commands);
- char *af_command0 = bstrdup0(NULL, af_command);
- if (cmd->id == MP_CMD_AF_DEL) {
- af = af_get(mpctx->mixer.afilter, af_command0);
- if (af != NULL)
- af_remove(mpctx->mixer.afilter, af);
- } else
- af_add(mpctx->mixer.afilter, af_command0);
- talloc_free(af_command0);
- }
- reinit_audio_chain(mpctx);
- free(af_args);
- break;
- }
- case MP_CMD_AF_CLR:
- if (!sh_audio)
- break;
- af_uninit(mpctx->mixer.afilter);
- af_init(mpctx->mixer.afilter);
- reinit_audio_chain(mpctx);
- break;
- case MP_CMD_AF_CMDLINE:
- if (sh_audio) {
- struct af_instance *af = af_get(sh_audio->afilter, cmd->args[0].v.s);
- if (!af) {
- mp_msg(MSGT_CPLAYER, MSGL_WARN,
- "Filter '%s' not found in chain.\n", cmd->args[0].v.s);
- break;
- }
- af->control(af, AF_CONTROL_COMMAND_LINE, cmd->args[1].v.s);
- af_reinit(sh_audio->afilter);
- }
+ case MP_CMD_AF:
+ change_filters(mpctx, STREAM_AUDIO, cmd->args[0].v.s, cmd->args[1].v.s);
break;
+
case MP_CMD_VF:
change_video_filters(mpctx, cmd->args[0].v.s, cmd->args[1].v.s);
break;
diff --git a/core/input/input.c b/core/input/input.c
index 66d78b48c6..467f6d6299 100644
--- a/core/input/input.c
+++ b/core/input/input.c
@@ -210,11 +210,7 @@ static const mp_cmd_t mp_cmds[] = {
}},
{ MP_CMD_DISABLE_INPUT_SECTION, "disable_section", { ARG_STRING } },
- { MP_CMD_AF_SWITCH, "af_switch", { ARG_STRING } },
- { MP_CMD_AF_ADD, "af_add", { ARG_STRING } },
- { MP_CMD_AF_DEL, "af_del", { ARG_STRING } },
- { MP_CMD_AF_CLR, "af_clr", },
- { MP_CMD_AF_CMDLINE, "af_cmdline", { ARG_STRING, ARG_STRING } },
+ { MP_CMD_AF, "af", { ARG_STRING, ARG_STRING } },
{ MP_CMD_VF, "vf", { ARG_STRING, ARG_STRING } },
diff --git a/core/input/input.h b/core/input/input.h
index 1a0f2529ce..f4f5621e9f 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -77,11 +77,7 @@ enum mp_command_type {
MP_CMD_DVB_SET_CHANNEL = 5101,
/// Audio Filter commands
- MP_CMD_AF_SWITCH,
- MP_CMD_AF_ADD,
- MP_CMD_AF_DEL,
- MP_CMD_AF_CLR,
- MP_CMD_AF_CMDLINE,
+ MP_CMD_AF,
/// Video filter commands
MP_CMD_VF,
diff --git a/core/mp_core.h b/core/mp_core.h
index f7e6786b60..6bbe18c71e 100644
--- a/core/mp_core.h
+++ b/core/mp_core.h
@@ -296,6 +296,7 @@ double playing_audio_pts(struct MPContext *mpctx);
struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename, int noerr);
int reinit_video_chain(struct MPContext *mpctx);
int reinit_video_filters(struct MPContext *mpctx);
+int reinit_audio_filters(struct MPContext *mpctx);
void pause_player(struct MPContext *mpctx);
void unpause_player(struct MPContext *mpctx);
void add_step_frame(struct MPContext *mpctx, int dir);
diff --git a/core/mplayer.c b/core/mplayer.c
index e54b55444f..d9c03dace5 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -1185,11 +1185,6 @@ static int build_afilter_chain(struct MPContext *mpctx)
struct ao *ao = mpctx->ao;
struct MPOpts *opts = &mpctx->opts;
int new_srate;
- int result;
- if (!sh_audio) {
- mpctx->mixer.afilter = NULL;
- return 0;
- }
if (af_control_any_rev(sh_audio->afilter,
AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET,
&opts->playback_speed))
@@ -1205,10 +1200,8 @@ static int build_afilter_chain(struct MPContext *mpctx)
opts->playback_speed = (float)new_srate / sh_audio->samplerate;
}
}
- result = init_audio_filters(sh_audio, new_srate,
- &ao->samplerate, &ao->channels, &ao->format);
- mpctx->mixer.afilter = sh_audio->afilter;
- return result;
+ return init_audio_filters(sh_audio, new_srate,
+ &ao->samplerate, &ao->channels, &ao->format);
}
@@ -1572,6 +1565,51 @@ static void update_osd_msg(struct MPContext *mpctx)
}
}
+static int recreate_audio_filters(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ assert(mpctx->sh_audio);
+
+ // init audio filters:
+ if (!build_afilter_chain(mpctx)) {
+ mp_tmsg(MSGT_CPLAYER, MSGL_ERR,
+ "Couldn't find matching filter/ao format!\n");
+ 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);
+ 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;
+}
+
+int reinit_audio_filters(struct MPContext *mpctx)
+{
+ struct sh_audio *sh_audio = mpctx->sh_audio;
+ if (!sh_audio)
+ return -2;
+
+ af_uninit(mpctx->sh_audio->afilter);
+ if (af_init(mpctx->sh_audio->afilter) < 0)
+ return -1;
+ if (recreate_audio_filters(mpctx) < 0)
+ return -1;
+
+ return 0;
+}
+
void reinit_audio_chain(struct MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
@@ -1603,7 +1641,9 @@ void reinit_audio_chain(struct MPContext *mpctx)
}
}
- // first init to detect best values
+ // Determine what the filter chain outputs. build_afilter_chain() also
+ // needs this for testing whether playback speed is changed by resampling
+ // or using a special filter.
if (!init_audio_filters(mpctx->sh_audio, // preliminary init
// input:
mpctx->sh_audio->samplerate,
@@ -1638,25 +1678,9 @@ void reinit_audio_chain(struct MPContext *mpctx)
ao->driver->info->comment);
}
- // init audio filters:
- if (!build_afilter_chain(mpctx)) {
- mp_tmsg(MSGT_CPLAYER, MSGL_ERR,
- "Couldn't find matching filter/ao format!\n");
+ if (recreate_audio_filters(mpctx) < 0)
goto init_error;
- }
- mpctx->mixer.volstep = opts->volstep;
- mpctx->mixer.softvol = opts->softvol;
- mpctx->mixer.softvol_max = opts->softvol_max;
- mixer_reinit(&mpctx->mixer, mpctx->ao);
- 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;
- }
+
mpctx->syncing_audio = true;
return;
@@ -4512,11 +4536,6 @@ static bool handle_help_options(struct MPContext *mpctx)
talloc_free(list);
opt_exit = 1;
}
- if (af_cfg.list && strcmp(af_cfg.list[0], "help") == 0) {
- af_help();
- mp_msg(MSGT_CPLAYER, MSGL_INFO, "\n");
- opt_exit = 1;
- }
#ifdef CONFIG_X11
if (opts->vo.fstype_list && strcmp(opts->vo.fstype_list[0], "help") == 0) {
fstype_help();
diff --git a/core/options.c b/core/options.c
index cce36b90bb..03acdc570b 100644
--- a/core/options.c
+++ b/core/options.c
@@ -182,6 +182,7 @@ extern char *dvd_device, *cdrom_device;
extern double mf_fps;
extern char * mf_type;
extern const struct m_obj_list vf_obj_list;
+extern const struct m_obj_list af_obj_list;
extern const struct m_obj_list vo_obj_list;
extern const struct m_obj_list ao_obj_list;
@@ -436,8 +437,7 @@ const m_option_t mp_opts[] = {
// ------------------------- codec/vfilter options --------------------
- {"af*", &af_cfg.list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
-
+ OPT_SETTINGSLIST("af*", af_settings, 0, &af_obj_list),
OPT_SETTINGSLIST("vf*", vf_settings, 0, &vf_obj_list),
OPT_STRING("ad", audio_decoders, 0),
diff --git a/core/options.h b/core/options.h
index e7f04b548c..fcb8002a42 100644
--- a/core/options.h
+++ b/core/options.h
@@ -162,6 +162,7 @@ typedef struct MPOpts {
int dtshd;
float playback_speed;
struct m_obj_settings *vf_settings;
+ struct m_obj_settings *af_settings;
float movie_aspect;
int flip;
int field_dominance;