player: show subtitles on VO if --force-window is used

If a VO is created, but no video is playing (i.e. --force-window is
used), then until now no subtitles were shown. This is because VO
subtitle display normally depends on video frame timing. If there are no
video frames, there can be no subtitles.

Change this and add some code to handle this situation specifically. Set
a subtitle PTS manually and request VO redrawing manually, which gets
the subtitles rendered somehow.

This is kind of shaky. The subtitles are essentially sampled at
arbitrary times (such as when new audio data is decoded and pushed to
the AO, or on user interaction). To make a it slightly more consistent,
force a completely arbitrary minimum FPS of 10.

Other solutions (such as creating fake video) would be more intrusive or
would require VO-level API changes.

Fixes #3684.
This commit is contained in:
wm4
2016-10-26 20:43:03 +02:00
parent fc4318d23e
commit 90b968a67a
6 changed files with 39 additions and 1 deletions

View File

@@ -1095,7 +1095,7 @@ void run_playloop(struct MPContext *mpctx)
handle_dummy_ticks(mpctx);
update_osd_msg(mpctx);
if (!mpctx->video_out)
if (!mpctx->vo_chain)
update_subtitles(mpctx, mpctx->playback_pts);
handle_eof(mpctx);

View File

@@ -112,6 +112,19 @@ static bool update_subtitle(struct MPContext *mpctx, double video_pts,
if (mpctx->current_track[0][STREAM_SUB] == track && !mpctx->video_out)
term_osd_set_subs(mpctx, sub_get_text(dec_sub, video_pts));
// Handle displaying subtitles on VO with no video being played. This is
// quite differently, because normally subtitles are redrawn on new video
// frames, using the video frames' timestamps.
if (mpctx->video_out && !mpctx->vo_chain) {
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);
}
return true;
}

View File

@@ -482,6 +482,9 @@ int reinit_video_chain_src(struct MPContext *mpctx, struct lavfi_pad *src)
update_window_title(mpctx, true);
// Undo what the subtitle path does if mpctx->vo_chain is unset.
osd_set_force_video_pts(mpctx->osd, MP_NOPTS_VALUE);
struct vo_chain *vo_c = talloc_zero(NULL, struct vo_chain);
mpctx->vo_chain = vo_c;
vo_c->log = mpctx->log;