mirror of
https://github.com/mpv-player/mpv
synced 2025-01-01 20:32:13 +00:00
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.
This commit is contained in:
parent
e285e22143
commit
5085cf295f
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user