summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-04-12 18:03:20 +0200
committerwm4 <wm4@nowhere>2015-04-12 18:06:23 +0200
commite466a735a39203f81d31d61acc4bfddcb6fb4695 (patch)
tree9caf6685c8a065382d98ac1e7b634af928925863
parenta8e8176ab1be38a156bcefc74b75d06dee0ba721 (diff)
downloadmpv-e466a735a39203f81d31d61acc4bfddcb6fb4695.tar.bz2
mpv-e466a735a39203f81d31d61acc4bfddcb6fb4695.tar.xz
audio/filter: fully renegotiate audio formats on every reconfig
It could happen that a lavrresample filter would keep its old output format when the decoder changed its output format. This simply happened because the output format was never reset. Normally, this was not an issue, because lavrresample filters only inserted for format conversion were removed on format changes. But if --no-audio-pitch-correction is set and playback speed is changed, then there is a "permanent" lavrresample filter in the filter chain, which shows this behavior. Fix by explicitly resetting output formats for all filters which support it. Note: this can crash with libswresample in some cases. I'm not sure if this is mpv's fault or libswresample's, but since it works with libavresample, I'm going to assume it's not our's.
-rw-r--r--audio/filter/af.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/audio/filter/af.c b/audio/filter/af.c
index 8d29e332a8..7b957c16bd 100644
--- a/audio/filter/af.c
+++ b/audio/filter/af.c
@@ -505,6 +505,15 @@ static int af_fix_rate(struct af_stream *s, struct af_instance **p_af,
return AF_OK;
}
+static void reset_formats(struct af_stream *s)
+{
+ for (struct af_instance *af = s->first; af; af = af->next) {
+ af->control(af, AF_CONTROL_SET_RESAMPLE_RATE, &(int){0});
+ af->control(af, AF_CONTROL_SET_CHANNELS, &(struct mp_chmap){0});
+ af->control(af, AF_CONTROL_SET_FORMAT, &(int){0});
+ }
+}
+
// Return AF_OK on success or AF_ERROR on failure.
// Warning:
// A failed af_reinit() leaves the audio chain behind in a useless, broken
@@ -515,6 +524,7 @@ static int af_reinit(struct af_stream *s)
{
remove_auto_inserted_filters(s);
af_chain_forget_frames(s);
+ reset_formats(s);
s->first->fmt_in = s->first->fmt_out = s->input;
// Start with the second filter, as the first filter is the special input
// filter which needs no initialization.