0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 03:52:22 +02:00

f_decoder_wrapper: make decoder thread responsive while filling queue

The mp_filter_run() invocation blocks as long as the demuxer provides
packets and the queue can be filled. That means it may block quite a
long time of the decoder queue size is large (since we use libavcodec in
a blocking manner; it regrettably does not have an async. API).

This made the main thread freeze in certain situations, because it has
to wait on the decoder thread.

Other than I suspected (I wrote that code, but that doesn't mean I know
how the hell it works), this did not freeze during seeking: seek resets
flushed the queue, which also prevented the decoder thread from adding
more frames to it, thus stopping decoding and responding to the main
thread in time. But it does fix the issue that exiting the player waited
for the decoder to finish filling the queue when stopping playback.
(This happened because it called mp_decoder_wrapper_set_play_dir()
before any resets. Related to the somewhat messy way play_dir is
generally set. But it affects all "synchronous" decoder wrapper API
calls.)

This uses pretty weird mechanisms in filter.h and dispatch.h. The
resulting durr hurr interactions are probably hard to follow, and this
whole thing is a sin. On the other hand, this is a _very_ user visible
issue, and I'm happy that it can be fixed in such an unintrusive way.
This commit is contained in:
wm4 2020-03-05 21:30:21 +01:00
parent 12375f67b4
commit c5eb2f2ac4
2 changed files with 8 additions and 3 deletions

View File

@ -4521,9 +4521,6 @@ Cache
affecting the playback logic). In other situations, it will simply make
seeking slower and use significantly more memory.
In specific situations, this still makes the player wait on the decoder,
such as seeking, switching hardware decoding modes, and more.
The queue size is restricted by the other ``--vd-queue-...`` options. The
final queue size is the minimum as indicated by the option with the lowest
limit. Each decoder/track has its own queue that may use the full configured

View File

@ -1141,6 +1141,13 @@ static void wakeup_dec_thread(void *ptr)
mp_dispatch_interrupt(p->dec_dispatch);
}
static void onlock_dec_thread(void *ptr)
{
struct priv *p = ptr;
mp_filter_graph_interrupt(p->dec_root_filter);
}
struct mp_decoder_wrapper *mp_decoder_wrapper_create(struct mp_filter *parent,
struct sh_stream *src)
{
@ -1185,6 +1192,7 @@ struct mp_decoder_wrapper *mp_decoder_wrapper_create(struct mp_filter *parent,
p->dec_dispatch = mp_dispatch_create(p);
p->dec_root_filter = mp_filter_create_root(public_f->global);
mp_filter_root_set_wakeup_cb(p->dec_root_filter, wakeup_dec_thread, p);
mp_dispatch_set_onlock_fn(p->dec_dispatch, onlock_dec_thread, p);
struct mp_stream_info *sinfo = mp_filter_find_stream_info(parent);
if (sinfo) {