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.
This commit is contained in:
wm4 2013-11-18 13:45:35 +01:00
parent b78d11d328
commit 8f1151a00e
3 changed files with 12 additions and 1 deletions

View File

@ -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)

View File

@ -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)
break;
reinit_audio_buffer(sh);
error = -2;
break;
}
@ -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;
}

View File

@ -695,9 +695,11 @@ struct af_instance *af_add(struct af_stream *s, char *name, char **args)
struct mp_audio *af_play(struct af_stream *s, struct mp_audio *data)
{
struct af_instance *af = s->first;
assert(mp_audio_config_equals(af->data, data));
// Iterate through all filters
do {
data = af->play(af, data);
assert(mp_audio_config_equals(af->data, data));
af = af->next;
} while (af && data);
return data;