summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-12-05 00:29:10 +0100
committerwm4 <wm4@nowhere>2013-12-05 00:31:55 +0100
commit84cfe0d8b24aaa104a4f607d3f1b0b32c225349b (patch)
treee83dc2d26af271cd68c71d5db078dce1377cb724
parented024aadb6e7be6c3d910045a64db53a6c95e98f (diff)
downloadmpv-84cfe0d8b24aaa104a4f607d3f1b0b32c225349b.tar.bz2
mpv-84cfe0d8b24aaa104a4f607d3f1b0b32c225349b.tar.xz
audio: flush remaining data from the filter chain on EOF
This can be reproduced with: mpv short.wav -af 'lavfi="aecho=0.8:0.9:5000|6800:0.3|0.25"' An audio file that is just 1-2 seconds long should play for 8-9 seconds, which audible echo towards the end. The code assumes that when playing with AF_FILTER_FLAG_EOF, the filter will either produce output, or has all remaining data flushed. I'm not really sure whether this really works if there are multiple filters with EOF handling in the chain. To handle it correctly, af_lavfi should retry filtering if 1. EOF flag is set, 2. there were input samples, and 3. no output samples were produced. But currently it seems to work well enough anyway.
-rw-r--r--audio/decode/dec_audio.c6
-rw-r--r--audio/filter/af_lavfi.c4
2 files changed, 7 insertions, 3 deletions
diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c
index b004664474..6f07b4729d 100644
--- a/audio/decode/dec_audio.c
+++ b/audio/decode/dec_audio.c
@@ -275,10 +275,14 @@ static int filter_n_bytes(struct dec_audio *da, struct mp_audio_buffer *outbuf,
filter_data.rate = da->afilter->input.rate; // due to playback speed change
len = MPMIN(filter_data.samples, len);
filter_data.samples = len;
+ bool eof = filter_data.samples == 0 && error < 0;
- if (af_filter(da->afilter, &filter_data, 0) < 0)
+ if (af_filter(da->afilter, &filter_data, eof ? AF_FILTER_FLAG_EOF : 0) < 0)
return -1;
+
mp_audio_buffer_append(outbuf, &filter_data);
+ if (eof && filter_data.samples > 0)
+ error = 0; // don't end playback yet
// remove processed data from decoder buffer:
mp_audio_buffer_skip(da->decode_buffer, len);
diff --git a/audio/filter/af_lavfi.c b/audio/filter/af_lavfi.c
index 7f0aad2c36..ab5b8d5495 100644
--- a/audio/filter/af_lavfi.c
+++ b/audio/filter/af_lavfi.c
@@ -210,7 +210,7 @@ static int filter(struct af_instance *af, struct mp_audio *data, int flags)
{
struct priv *p = af->priv;
struct mp_audio *r = af->data;
-
+ bool eof = data->samples == 0 && (flags & AF_FILTER_FLAG_EOF);
AVFilterLink *l_in = p->in->outputs[0];
AVFrame *frame = av_frame_alloc();
@@ -229,7 +229,7 @@ static int filter(struct af_instance *af, struct mp_audio *data, int flags)
frame->data[n] = data->planes[n];
frame->linesize[0] = frame->nb_samples * data->sstride;
- if (av_buffersrc_add_frame(p->in, frame) < 0) {
+ if (av_buffersrc_add_frame(p->in, eof ? NULL : frame) < 0) {
av_frame_free(&frame);
return -1;
}