diff options
Diffstat (limited to '')
-rw-r--r-- | player/sub.c | 83 |
1 files changed, 57 insertions, 26 deletions
diff --git a/player/sub.c b/player/sub.c index f3e42fe..65e5732 100644 --- a/player/sub.c +++ b/player/sub.c @@ -54,6 +54,19 @@ static void reset_subtitles(struct MPContext *mpctx, struct track *track) term_osd_set_subs(mpctx, NULL); } +// Only matters for subs on an image. +void redraw_subs(struct MPContext *mpctx) +{ + for (int n = 0; n < num_ptracks[STREAM_SUB]; n++) { + if (mpctx->current_track[n][STREAM_SUB] && + mpctx->current_track[n][STREAM_SUB]->d_sub) + { + mpctx->redraw_subs = true; + break; + } + } +} + void reset_subtitle_state(struct MPContext *mpctx) { for (int n = 0; n < mpctx->num_tracks; n++) @@ -100,33 +113,43 @@ static bool update_subtitle(struct MPContext *mpctx, double video_pts, sub_preload(dec_sub); } - if (!sub_read_packets(dec_sub, video_pts, mpctx->paused)) - return false; + bool packets_read = false; + bool sub_updated = false; + sub_read_packets(dec_sub, video_pts, mpctx->paused, &packets_read, &sub_updated); - // Handle displaying subtitles on terminal; never done for secondary subs - if (mpctx->current_track[0][STREAM_SUB] == track && !mpctx->video_out) { - char *text = sub_get_text(dec_sub, video_pts, SD_TEXT_TYPE_PLAIN); - term_osd_set_subs(mpctx, text); - talloc_free(text); - } + double osd_pts = osd_get_force_video_pts(mpctx->osd); + + // Check if we need to update subtitles for these special cases. Always + // update on discontinuities like seeking or a new file. + if (sub_updated || mpctx->redraw_subs || osd_pts == MP_NOPTS_VALUE) { + // Always force a redecode of all packets if we have a refresh. + if (mpctx->redraw_subs) + sub_redecode_cached_packets(dec_sub); + + // Handle displaying subtitles on terminal; never done for secondary subs + if (mpctx->current_track[0][STREAM_SUB] == track && !mpctx->video_out) { + char *text = sub_get_text(dec_sub, video_pts, SD_TEXT_TYPE_PLAIN); + term_osd_set_subs(mpctx, text); + talloc_free(text); + } - // Handle displaying subtitles on VO with no video being played. This is - // quite different, because normally subtitles are redrawn on new video - // frames, using the video frames' timestamps. - if (mpctx->video_out && mpctx->video_status == STATUS_EOF && - (mpctx->opts->subs_rend->sub_past_video_end || - !mpctx->current_track[0][STREAM_VIDEO] || - mpctx->current_track[0][STREAM_VIDEO]->image)) { - if (osd_get_force_video_pts(mpctx->osd) != video_pts) { - osd_set_force_video_pts(mpctx->osd, video_pts); - osd_query_and_reset_want_redraw(mpctx->osd); - vo_redraw(mpctx->video_out); - // Force an arbitrary minimum FPS - mp_set_timeout(mpctx, 0.1); + // Handle displaying subtitles on VO with no video being played. This is + // quite different, because normally subtitles are redrawn on new video + // frames, using the video frames' timestamps. + if (mpctx->video_out && mpctx->video_status == STATUS_EOF && + (mpctx->opts->subs_rend->sub_past_video_end || + !mpctx->current_track[0][STREAM_VIDEO] || + mpctx->current_track[0][STREAM_VIDEO]->image)) { + if (osd_pts != video_pts) { + osd_set_force_video_pts(mpctx->osd, video_pts); + osd_query_and_reset_want_redraw(mpctx->osd); + vo_redraw(mpctx->video_out); + } } } - return true; + mpctx->redraw_subs = false; + return packets_read; } // Return true if the subtitles for the given PTS are ready; false if the player @@ -199,12 +222,20 @@ void reinit_sub(struct MPContext *mpctx, struct track *track) sub_select(track->d_sub, true); int order = get_order(mpctx, track); osd_set_sub(mpctx->osd, order, track->d_sub); - sub_control(track->d_sub, SD_CTRL_SET_TOP, &order); // 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); + // 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) |