1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-12 18:02:36 +00:00

f_decoder_wapper: trust frame return over error code

lavc_process() calls the receive/send callbacks, which mirror
libavcodec's send/receive API. The receive API in particular can return
both a status code and a frame. Normally, libavcodec is pretty explicit
that it can't return both a frame and an error. But the receive callback
does more stuff in addition (vd_lavc does hardware decoding fallbacks
etc.). The previous commit shows an instance where this happened, and
where it leaked a frame in this case.

For robustness, check whether the frame is set first, i.e. trust it over
the status code. Before this, it checked for an EOF status first.

Hopefully is of no consequence otherwise. I made this change after
testing everything (can someone implement a test suite which tests this
exhaustively).
This commit is contained in:
wm4 2019-10-25 21:50:10 +02:00
parent edc6075fa3
commit 52536aaa7b

View File

@ -824,13 +824,13 @@ void lavc_process(struct mp_filter *f, struct lavc_state *state,
struct mp_frame frame = {0};
int ret_recv = receive(f, &frame);
if (ret_recv == AVERROR_EOF) {
if (frame.type) {
state->eof_returned = false;
mp_pin_in_write(f->ppins[1], frame);
} else if (ret_recv == AVERROR_EOF) {
if (!state->eof_returned)
mp_pin_in_write(f->ppins[1], MP_EOF_FRAME);
state->eof_returned = true;
} else if (frame.type) {
state->eof_returned = false;
mp_pin_in_write(f->ppins[1], frame);
} else if (ret_recv == AVERROR(EAGAIN)) {
// Need to feed a packet.
frame = mp_pin_out_read(f->ppins[0]);
@ -856,7 +856,7 @@ void lavc_process(struct mp_filter *f, struct lavc_state *state,
talloc_free(pkt);
mp_filter_internal_mark_progress(f);
} else {
// Just try again.
// Decoding error? Just try again.
mp_filter_internal_mark_progress(f);
}
}