path: root/audio/decode
diff options
authorwm4 <wm4@nowhere>2013-11-18 13:45:35 +0100
committerwm4 <wm4@nowhere>2013-11-18 14:20:59 +0100
commit8f1151a00edf3aac78baa6779284eede3e9ee872 (patch)
treeb68ed8dddb5e0aa5342bfb9d86eee9a7a976d3f5 /audio/decode
parentb78d11d3282b118287901bd4f9a220880e27084b (diff)
audio: fix mid-stream audio reconfiguration
Commit 22b3f522 not only redid major aspects of audio decoding, but also attempted to fix audio format change handling. Before that commit, data that was already decoded but not yet filtered was thrown away on a format change. After that commit, data was supposed to finish playing before rebuilding filters and so on. It was still buggy, though: the decoder buffer was initialized to the new format too early, triggering an assertion failure. Move the reinit call below filtering to fix this. ad_mpg123.c needs to be adjusted so that it doesn't decode new data before the format change is actually executed. Add some more assertions to af_play() (audio filtering) to make sure input data and configured format don't mismatch. This will also catch filters which don't set the format on their output data correctly. Regression due to planar_audio branch.
Diffstat (limited to 'audio/decode')
2 files changed, 10 insertions, 1 deletions
diff --git a/audio/decode/ad_mpg123.c b/audio/decode/ad_mpg123.c
index 777c20c2c9..8ea06dd5ab 100644
--- a/audio/decode/ad_mpg123.c
+++ b/audio/decode/ad_mpg123.c
@@ -310,6 +310,11 @@ static int decode_audio(sh_audio_t *sh, struct mp_audio *buffer, int maxlen)
return -1;
+ if (sh->samplerate != buffer->rate ||
+ !mp_chmap_equals(&sh->channels, &buffer->channels) ||
+ sh->sample_format != buffer->format)
+ return 0;
size_t got_now = 0;
ret = mpg123_replace_buffer(con->handle, buf, maxlen * con->sample_size);
if (ret != MPG123_OK)
diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c
index 0aee681def..c79e4ffc42 100644
--- a/audio/decode/dec_audio.c
+++ b/audio/decode/dec_audio.c
@@ -267,7 +267,6 @@ static int filter_n_bytes(sh_audio_t *sh, struct mp_audio_buffer *outbuf,
// first, and don't signal a format change to the caller yet.
if (mp_audio_buffer_samples(sh->decode_buffer) > 0)
- reinit_audio_buffer(sh);
error = -2;
@@ -288,6 +287,11 @@ static int filter_n_bytes(sh_audio_t *sh, struct mp_audio_buffer *outbuf,
// remove processed data from decoder buffer:
mp_audio_buffer_skip(sh->decode_buffer, len);
+ // Assume the filter chain is drained from old data at this point.
+ // (If not, the remaining old data is discarded.)
+ if (error == -2)
+ reinit_audio_buffer(sh);
return error;