From c3916406451cddfb9daa42699dcd2163bff1a0eb Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 11 Aug 2017 21:28:01 +0200 Subject: player: fix --lavfi-complex freeze Commit 0e0b87b6f3297 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. --- player/audio.c | 4 +++- player/lavfi.c | 8 ++++---- player/video.c | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'player') diff --git a/player/audio.c b/player/audio.c index 62a5ddb5d6..7891116c7e 100644 --- a/player/audio.c +++ b/player/audio.c @@ -51,6 +51,7 @@ enum { AD_NEW_FMT = -3, AD_WAIT = -4, AD_NO_PROGRESS = -5, + AD_STARVE = -6, }; // 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_WAIT: return AD_WAIT; case DATA_AGAIN: return AD_NO_PROGRESS; + case DATA_STARVE: return AD_STARVE; case DATA_EOF: return AD_EOF; default: abort(); } @@ -880,7 +882,7 @@ static int filter_audio(struct MPContext *mpctx, struct mp_audio_buffer *outbuf, res = decode_new_frame(ao_c); if (res == AD_NO_PROGRESS) continue; - if (res == AD_WAIT) + if (res == AD_WAIT || res == AD_STARVE) break; if (res < 0) { // drain filters first (especially for true EOF case) diff --git a/player/lavfi.c b/player/lavfi.c index 5183b0e690..c597387937 100644 --- a/player/lavfi.c +++ b/player/lavfi.c @@ -716,12 +716,12 @@ static int lavfi_request_frame(struct lavfi_pad *pad) } else if (pad->main->all_waiting) { return DATA_WAIT; } - return DATA_AGAIN; + return DATA_STARVE; } // Try to read a new frame from an output pad. Returns one of the following: // 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_EOF: no more data 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 // 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_EOF: no more input possible (in near time) // 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); 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; } diff --git a/player/video.c b/player/video.c index 108d65a35b..414629c3c2 100644 --- a/player/video.c +++ b/player/video.c @@ -617,6 +617,7 @@ static int decode_image(struct MPContext *mpctx) switch (res) { case DATA_WAIT: return VD_WAIT; case DATA_OK: + case DATA_STARVE: case DATA_AGAIN: return VD_PROGRESS; case DATA_EOF: return VD_EOF; default: abort(); -- cgit v1.2.3