summaryrefslogtreecommitdiffstats
path: root/player/lavfi.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-02-08 17:53:34 +0100
committerwm4 <wm4@nowhere>2017-02-08 20:29:38 +0100
commit5085cf295f9de28d22004b6356219eeeadcf01c1 (patch)
tree09d690694d68c9b3352f8724678e1f4f9d4092eb /player/lavfi.c
parente285e2214333e7d625fb5bac3022c3cfb57b7f1e (diff)
downloadmpv-5085cf295f9de28d22004b6356219eeeadcf01c1.tar.bz2
mpv-5085cf295f9de28d22004b6356219eeeadcf01c1.tar.xz
lavfi: slightly better disconnected output handling
If we have a disconnected output, read data only passively (and don't cause input to be written). Otherwise, we're in danger of making libavfilter queue too many frames on other outputs which are connected to the same input, but don't read as quickly. Also don't set pad->output_needed in this specific case, because it would nonsensically make lavfi_process() return true, even if nothing is going on. This commit breaks if there is a simple filter chain with a connected input, but a disconnected output, like --lavfi-complex='[aid1] copy [ao]' and the audio output didn't initialize correctly. This will eventually starve video as the audio packet queue get full (it will print a warning, and then assume video EOF and exit). But whatever. Probably fixes #4118.
Diffstat (limited to 'player/lavfi.c')
-rw-r--r--player/lavfi.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/player/lavfi.c b/player/lavfi.c
index 50c2fd8fc2..d01f166b63 100644
--- a/player/lavfi.c
+++ b/player/lavfi.c
@@ -43,6 +43,11 @@
#include "lavfi.h"
+#if LIBAVFILTER_VERSION_MICRO < 100
+#define av_buffersink_get_frame_flags(a, b, c) av_buffersink_get_frame(a, b)
+#define AV_BUFFERSINK_FLAG_NO_REQUEST 0
+#endif
+
struct lavfi {
struct mp_log *log;
char *graph_string;
@@ -266,6 +271,10 @@ enum stream_type lavfi_pad_type(struct lavfi_pad *pad)
void lavfi_set_connected(struct lavfi_pad *pad, bool connected)
{
pad->connected = connected;
+ if (!pad->connected) {
+ pad->output_needed = false;
+ drop_pad_data(pad);
+ }
}
bool lavfi_get_connected(struct lavfi_pad *pad)
@@ -545,19 +554,17 @@ static void read_output_pads(struct lavfi *c)
if (pad->dir != LAVFI_OUT)
continue;
- // If disconnected, read and discard everything.
- if (!pad->pending_v && !pad->pending_a && !pad->connected)
- pad->output_needed = true;
-
- if (!pad->output_needed)
+ // If disconnected, read and discard everything (passively).
+ if (pad->connected && !pad->output_needed)
continue;
assert(pad->buffer);
assert(!pad->pending_v && !pad->pending_a);
+ int flags = pad->output_needed ? 0 : AV_BUFFERSINK_FLAG_NO_REQUEST;
int r = AVERROR_EOF;
if (!pad->buffer_is_eof)
- r = av_buffersink_get_frame(pad->buffer, pad->tmp_frame);
+ r = av_buffersink_get_frame_flags(pad->buffer, pad->tmp_frame, flags);
if (r >= 0) {
pad->output_needed = false;
double pts = mp_pts_from_av(pad->tmp_frame->pts, &pad->timebase);
@@ -583,6 +590,7 @@ static void read_output_pads(struct lavfi *c)
// input pads (via av_buffersrc_get_nb_failed_requests()).
pad->output_eof = false;
} else if (r == AVERROR_EOF) {
+ pad->output_needed = false;
pad->buffer_is_eof = true;
if (!c->draining_recover_eof && !c->draining_new_format)
pad->output_eof = true;