diff --git a/demux/demux.c b/demux/demux.c index f198cfc9af..575ccc227d 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -864,7 +864,8 @@ static void wakeup_ds(struct demux_stream *ds) } static void update_stream_selection_state(struct demux_internal *in, - struct demux_stream *ds) + struct demux_stream *ds, + bool paused) { ds->eof = false; ds->refreshing = false; @@ -886,8 +887,8 @@ static void update_stream_selection_state(struct demux_internal *in, } // Subtitles are only eagerly read if there are no other eagerly read - // streams. - if (any_av_streams) { + // streams or the player is paused. + if (any_av_streams && !paused) { for (int n = 0; n < in->num_streams; n++) { struct demux_stream *s = in->streams[n]->ds; @@ -1002,7 +1003,7 @@ static void demux_add_sh_stream_locked(struct demux_internal *in, sh->ds->queue = in->current_range->streams[sh->ds->index]; } - update_stream_selection_state(in, sh->ds); + update_stream_selection_state(in, sh->ds, false); switch (ds->type) { case STREAM_AUDIO: @@ -3961,7 +3962,7 @@ static void initiate_refresh_seek(struct demux_internal *in, // ref_pts is used only if the stream is enabled. Then it serves as approximate // start pts for this stream (in the worst case it is ignored). void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream, - double ref_pts, bool selected) + double ref_pts, bool selected, bool paused) { struct demux_internal *in = demuxer->in; struct demux_stream *ds = stream->ds; @@ -3971,7 +3972,7 @@ void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream, if (ds->selected != selected) { MP_VERBOSE(in, "%sselect track %d\n", selected ? "" : "de", stream->index); ds->selected = selected; - update_stream_selection_state(in, ds); + update_stream_selection_state(in, ds, paused); in->tracks_switched = true; if (ds->selected) { if (in->back_demuxing) @@ -3991,7 +3992,7 @@ void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream, // Execute a refresh seek on the given stream. // ref_pts has the same meaning as with demuxer_select_track() void demuxer_refresh_track(struct demuxer *demuxer, struct sh_stream *stream, - double ref_pts) + double ref_pts, bool paused) { struct demux_internal *in = demuxer->in; struct demux_stream *ds = stream->ds; @@ -3999,7 +4000,7 @@ void demuxer_refresh_track(struct demuxer *demuxer, struct sh_stream *stream, ref_pts = MP_ADD_PTS(ref_pts, -in->ts_offset); if (ds->selected) { MP_VERBOSE(in, "refresh track %d\n", stream->index); - update_stream_selection_state(in, ds); + update_stream_selection_state(in, ds, paused); if (in->back_demuxing) ds->back_seek_pos = ref_pts; if (!in->after_seek) diff --git a/demux/demux.h b/demux/demux.h index 08904f26cc..4582c544e7 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -319,9 +319,9 @@ void demux_get_reader_state(struct demuxer *demuxer, struct demux_reader_state * void demux_block_reading(struct demuxer *demuxer, bool block); void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream, - double ref_pts, bool selected); + double ref_pts, bool selected, bool paused); void demuxer_refresh_track(struct demuxer *demuxer, struct sh_stream *stream, - double ref_pts); + double ref_pts, bool paused); int demuxer_help(struct mp_log *log, const m_option_t *opt, struct bstr name); diff --git a/demux/demux_disc.c b/demux/demux_disc.c index 3dfff45403..5f8885e5e8 100644 --- a/demux/demux_disc.c +++ b/demux/demux_disc.c @@ -59,7 +59,7 @@ static void reselect_streams(demuxer_t *demuxer) for (int n = 0; n < MPMIN(num_slave, p->num_streams); n++) { if (p->streams[n]) { demuxer_select_track(p->slave, demux_get_stream(p->slave, n), - MP_NOPTS_VALUE, demux_stream_is_selected(p->streams[n])); + MP_NOPTS_VALUE, demux_stream_is_selected(p->streams[n]), false); } } } diff --git a/demux/demux_timeline.c b/demux/demux_timeline.c index 5572fb53bf..21fdcdbe5b 100644 --- a/demux/demux_timeline.c +++ b/demux/demux_timeline.c @@ -170,7 +170,7 @@ static void reselect_streams(struct demuxer *demuxer) if (!src->current || seg->d != src->current->d) selected = false; struct sh_stream *sh = demux_get_stream(seg->d, i); - demuxer_select_track(seg->d, sh, MP_NOPTS_VALUE, selected); + demuxer_select_track(seg->d, sh, MP_NOPTS_VALUE, selected, false); update_slave_stats(demuxer, seg->d); } diff --git a/player/loadfile.c b/player/loadfile.c index 7fe7284e77..521a20d459 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -381,9 +381,9 @@ void reselect_demux_stream(struct MPContext *mpctx, struct track *track, pts -= 10.0; } if (refresh_only) - demuxer_refresh_track(track->demuxer, track->stream, pts); + demuxer_refresh_track(track->demuxer, track->stream, pts, mpctx->paused); else - demuxer_select_track(track->demuxer, track->stream, pts, track->selected); + demuxer_select_track(track->demuxer, track->stream, pts, track->selected, mpctx->paused); } static void enable_demux_thread(struct MPContext *mpctx, struct demuxer *demux) @@ -1178,7 +1178,7 @@ static void *open_demux_thread(void *ctx) int num_streams = demux_get_num_stream(demux); for (int n = 0; n < num_streams; n++) { struct sh_stream *sh = demux_get_stream(demux, n); - demuxer_select_track(demux, sh, MP_NOPTS_VALUE, true); + demuxer_select_track(demux, sh, MP_NOPTS_VALUE, true, mpctx->paused); } demux_set_wakeup_cb(demux, wakeup_demux, mpctx); diff --git a/player/playloop.c b/player/playloop.c index 7a1c13f4ad..61d374a589 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -180,6 +180,15 @@ void set_pause_state(struct MPContext *mpctx, bool user_pause) } else { (void)get_relative_time(mpctx); // ignore time that passed during pause } + + if (mpctx->demuxer) { + double pts = get_current_time(mpctx); + for (int n = 0; n < num_ptracks[STREAM_SUB]; n++) { + struct track *track = mpctx->current_track[n][STREAM_SUB]; + if (track) + demuxer_refresh_track(mpctx->demuxer, track->stream, pts, mpctx->paused); + } + } } update_core_idle_state(mpctx); diff --git a/player/sub.c b/player/sub.c index 7dd1f2ccb6..91627d8c22 100644 --- a/player/sub.c +++ b/player/sub.c @@ -100,7 +100,7 @@ static bool update_subtitle(struct MPContext *mpctx, double video_pts, sub_preload(dec_sub); } - if (!sub_read_packets(dec_sub, video_pts, mpctx->paused)) + if (!sub_read_packets(dec_sub, video_pts)) return false; // Handle displaying subtitles on terminal; never done for secondary subs diff --git a/sub/dec_sub.c b/sub/dec_sub.c index dc26aa027e..84c6b7bfbe 100644 --- a/sub/dec_sub.c +++ b/sub/dec_sub.c @@ -269,7 +269,7 @@ static bool is_new_segment(struct dec_sub *sub, struct demux_packet *p) // Read packets from the demuxer stream passed to sub_create(). Return true if // enough packets were read, false if the player should wait until the demuxer // signals new packets available (and then should retry). -bool sub_read_packets(struct dec_sub *sub, double video_pts, bool force) +bool sub_read_packets(struct dec_sub *sub, double video_pts) { bool r = true; pthread_mutex_lock(&sub->lock); @@ -291,7 +291,7 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts, bool force) break; // (Use this mechanism only if sub_delay matters to avoid corner cases.) - double min_pts = sub->opts->sub_delay < 0 || force ? video_pts : MP_NOPTS_VALUE; + double min_pts = sub->opts->sub_delay < 0 ? video_pts : MP_NOPTS_VALUE; struct demux_packet *pkt; int st = demux_read_packet_async_until(sub->sh, min_pts, &pkt); diff --git a/sub/dec_sub.h b/sub/dec_sub.h index 96b8c29807..c2b75f308a 100644 --- a/sub/dec_sub.h +++ b/sub/dec_sub.h @@ -43,7 +43,7 @@ void sub_destroy(struct dec_sub *sub); bool sub_can_preload(struct dec_sub *sub); void sub_preload(struct dec_sub *sub); -bool sub_read_packets(struct dec_sub *sub, double video_pts, bool force); +bool sub_read_packets(struct dec_sub *sub, double video_pts); struct sub_bitmaps *sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, int format, double pts); char *sub_get_text(struct dec_sub *sub, double pts, enum sd_text_type type);