player: fix --lavfi-complex freeze

Commit 0e0b87b6f3 fixed that dropped packets did not trigger further
work correctly. But it also made trivial --lavfi-complex freeze. The
reason is that the meaning if DATA_AGAIN was overloaded: the decoders
meant that they should be called again, while lavfi.c meant that other
outputs needed to be checked again. Rename the latter meaning to
DATA_STARVE, which means that the current input will deliver no more
data, until "other" work has been done (like reading other outputs, or
feeding input).

The decoders never return DATA_STARVE, because they don't get input from
the player core (instead, they get it from the demuxer directly, which
is why they still can return DATA_WAIT).

Also document the DATA_* semantics in the enum.

Fixes #4746.
This commit is contained in:
wm4 2017-08-11 21:28:01 +02:00
parent 8b1d4b978d
commit c391640645
4 changed files with 13 additions and 9 deletions

View File

@ -59,10 +59,11 @@ enum stream_type {
}; };
enum { enum {
DATA_OK = 1, DATA_OK = 1, // data is actually being returned
DATA_WAIT = 0, DATA_WAIT = 0, // async wait: check state again after next wakeup
DATA_AGAIN = -1, DATA_AGAIN = -2, // repeat request (internal progress was made)
DATA_EOF = -2, DATA_STARVE = -1, // need input (might require to drain other outputs)
DATA_EOF = -3, // no more data available
}; };
extern const char mpv_version[]; extern const char mpv_version[];

View File

@ -51,6 +51,7 @@ enum {
AD_NEW_FMT = -3, AD_NEW_FMT = -3,
AD_WAIT = -4, AD_WAIT = -4,
AD_NO_PROGRESS = -5, AD_NO_PROGRESS = -5,
AD_STARVE = -6,
}; };
// Use pitch correction only for speed adjustments by the user, not minor sync // Use pitch correction only for speed adjustments by the user, not minor sync
@ -846,6 +847,7 @@ static int decode_new_frame(struct ao_chain *ao_c)
case DATA_OK: return AD_OK; case DATA_OK: return AD_OK;
case DATA_WAIT: return AD_WAIT; case DATA_WAIT: return AD_WAIT;
case DATA_AGAIN: return AD_NO_PROGRESS; case DATA_AGAIN: return AD_NO_PROGRESS;
case DATA_STARVE: return AD_STARVE;
case DATA_EOF: return AD_EOF; case DATA_EOF: return AD_EOF;
default: abort(); default: abort();
} }
@ -880,7 +882,7 @@ static int filter_audio(struct MPContext *mpctx, struct mp_audio_buffer *outbuf,
res = decode_new_frame(ao_c); res = decode_new_frame(ao_c);
if (res == AD_NO_PROGRESS) if (res == AD_NO_PROGRESS)
continue; continue;
if (res == AD_WAIT) if (res == AD_WAIT || res == AD_STARVE)
break; break;
if (res < 0) { if (res < 0) {
// drain filters first (especially for true EOF case) // drain filters first (especially for true EOF case)

View File

@ -716,12 +716,12 @@ static int lavfi_request_frame(struct lavfi_pad *pad)
} else if (pad->main->all_waiting) { } else if (pad->main->all_waiting) {
return DATA_WAIT; return DATA_WAIT;
} }
return DATA_AGAIN; return DATA_STARVE;
} }
// Try to read a new frame from an output pad. Returns one of the following: // Try to read a new frame from an output pad. Returns one of the following:
// DATA_OK: a frame is returned // DATA_OK: a frame is returned
// DATA_AGAIN: needs more input data // DATA_STARVE: needs more input data
// DATA_WAIT: needs more input data, and all inputs in LAVFI_WAIT state // DATA_WAIT: needs more input data, and all inputs in LAVFI_WAIT state
// DATA_EOF: no more data // DATA_EOF: no more data
int lavfi_request_frame_a(struct lavfi_pad *pad, struct mp_audio **out_aframe) int lavfi_request_frame_a(struct lavfi_pad *pad, struct mp_audio **out_aframe)
@ -750,7 +750,7 @@ bool lavfi_needs_input(struct lavfi_pad *pad)
// A filter user is supposed to call lavfi_needs_input(), and if that returns // A filter user is supposed to call lavfi_needs_input(), and if that returns
// true, send either a new status or a frame. A status can be one of: // true, send either a new status or a frame. A status can be one of:
// DATA_AGAIN: a new frame/status will come, caller will retry // DATA_STARVE: a new frame/status will come, caller will retry
// DATA_WAIT: a new frame/status will come, but caller goes to sleep // DATA_WAIT: a new frame/status will come, but caller goes to sleep
// DATA_EOF: no more input possible (in near time) // DATA_EOF: no more input possible (in near time)
// If you have a new frame, use lavfi_send_frame_ instead. // If you have a new frame, use lavfi_send_frame_ instead.
@ -764,7 +764,7 @@ void lavfi_send_status(struct lavfi_pad *pad, int status)
assert(!pad->pending_v && !pad->pending_a); assert(!pad->pending_v && !pad->pending_a);
pad->input_waiting = status == DATA_WAIT || status == DATA_EOF; pad->input_waiting = status == DATA_WAIT || status == DATA_EOF;
pad->input_again = status == DATA_AGAIN; pad->input_again = status == DATA_STARVE;
pad->input_eof = status == DATA_EOF; pad->input_eof = status == DATA_EOF;
} }

View File

@ -617,6 +617,7 @@ static int decode_image(struct MPContext *mpctx)
switch (res) { switch (res) {
case DATA_WAIT: return VD_WAIT; case DATA_WAIT: return VD_WAIT;
case DATA_OK: case DATA_OK:
case DATA_STARVE:
case DATA_AGAIN: return VD_PROGRESS; case DATA_AGAIN: return VD_PROGRESS;
case DATA_EOF: return VD_EOF; case DATA_EOF: return VD_EOF;
default: abort(); default: abort();