diff options
-rw-r--r-- | player/core.h | 2 | ||||
-rw-r--r-- | player/playloop.c | 20 | ||||
-rw-r--r-- | player/sub.c | 16 |
3 files changed, 32 insertions, 6 deletions
diff --git a/player/core.h b/player/core.h index 5e97b6d868..c44868cecd 100644 --- a/player/core.h +++ b/player/core.h @@ -132,6 +132,8 @@ struct track { char *external_filename; bool auto_loaded; + bool demuxer_ready; // if more packets should be read (subtitles only) + struct demuxer *demuxer; // Invariant: !stream || stream->demuxer == demuxer struct sh_stream *stream; diff --git a/player/playloop.c b/player/playloop.c index bf903e54f7..12239d69ab 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -803,6 +803,22 @@ int get_cache_buffering_percentage(struct MPContext *mpctx) return mpctx->demuxer ? mpctx->cache_buffer : -1; } +static void handle_update_subtitles(struct MPContext *mpctx) +{ + if (mpctx->video_status == STATUS_EOF) { + update_subtitles(mpctx, mpctx->playback_pts); + return; + } + + for (int n = 0; n < mpctx->num_tracks; n++) { + struct track *track = mpctx->tracks[n]; + if (track->type == STREAM_SUB && !track->demuxer_ready) { + update_subtitles(mpctx, mpctx->playback_pts); + break; + } + } +} + static void handle_cursor_autohide(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; @@ -1233,8 +1249,8 @@ void run_playloop(struct MPContext *mpctx) handle_dummy_ticks(mpctx); update_osd_msg(mpctx); - if (mpctx->video_status == STATUS_EOF) - update_subtitles(mpctx, mpctx->playback_pts); + + handle_update_subtitles(mpctx); handle_each_frame_screenshot(mpctx); diff --git a/player/sub.c b/player/sub.c index 998b88d620..65e5732e23 100644 --- a/player/sub.c +++ b/player/sub.c @@ -224,10 +224,18 @@ void reinit_sub(struct MPContext *mpctx, struct track *track) osd_set_sub(mpctx->osd, order, track->d_sub); // When paused we have to wait for packets to be available. - // So just retry until we get a packet in this case. - if (mpctx->playback_initialized) - while (!update_subtitles(mpctx, mpctx->playback_pts) && - mpctx->paused && !mpctx->paused_for_cache); + // Retry on a timeout until we get a packet. If still not successful, + // then queue it for later in the playloop (but this will have a delay). + if (mpctx->playback_initialized) { + track->demuxer_ready = false; + int64_t end = mp_time_ns() + MP_TIME_MS_TO_NS(50); + while (!track->demuxer_ready && mp_time_ns() < end) + track->demuxer_ready = update_subtitles(mpctx, mpctx->playback_pts) || + !mpctx->paused; + if (!track->demuxer_ready) + mp_wakeup_core(mpctx); + + } } void reinit_sub_all(struct MPContext *mpctx) |