summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--player/playloop.c2
-rw-r--r--player/sub.c13
-rw-r--r--player/video.c3
-rw-r--r--sub/osd.c19
-rw-r--r--sub/osd.h2
-rw-r--r--sub/osd_state.h1
6 files changed, 39 insertions, 1 deletions
diff --git a/player/playloop.c b/player/playloop.c
index aa3eb637ee..2a4509ab95 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -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);
diff --git a/player/sub.c b/player/sub.c
index c4a24fe011..04af1e1e15 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -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;
}
diff --git a/player/video.c b/player/video.c
index 21babe016e..7a76f4dc8e 100644
--- a/player/video.c
+++ b/player/video.c
@@ -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;
diff --git a/sub/osd.c b/sub/osd.c
index dfe75b7698..bf6233a0b1 100644
--- a/sub/osd.c
+++ b/sub/osd.c
@@ -119,6 +119,7 @@ struct osd_state *osd_create(struct mpv_global *global)
.opts = global->opts,
.global = global,
.log = mp_log_new(osd, global->log, "osd"),
+ .force_video_pts = MP_NOPTS_VALUE,
};
pthread_mutex_init(&osd->lock, NULL);
@@ -190,6 +191,21 @@ void osd_set_render_subs_in_filter(struct osd_state *osd, bool s)
pthread_mutex_unlock(&osd->lock);
}
+void osd_set_force_video_pts(struct osd_state *osd, double video_pts)
+{
+ pthread_mutex_lock(&osd->lock);
+ osd->force_video_pts = video_pts;
+ pthread_mutex_unlock(&osd->lock);
+}
+
+double osd_get_force_video_pts(struct osd_state *osd)
+{
+ pthread_mutex_lock(&osd->lock);
+ double pts = osd->force_video_pts;
+ pthread_mutex_unlock(&osd->lock);
+ return pts;
+}
+
void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s)
{
pthread_mutex_lock(&osd->lock);
@@ -288,6 +304,9 @@ void osd_draw(struct osd_state *osd, struct mp_osd_res res,
{
pthread_mutex_lock(&osd->lock);
+ if (osd->force_video_pts != MP_NOPTS_VALUE)
+ video_pts = osd->force_video_pts;
+
if (draw_flags & OSD_DRAW_SUB_FILTER)
draw_flags |= OSD_DRAW_SUB_ONLY;
diff --git a/sub/osd.h b/sub/osd.h
index cf66392904..755aca9969 100644
--- a/sub/osd.h
+++ b/sub/osd.h
@@ -155,6 +155,8 @@ void osd_set_sub(struct osd_state *osd, int index, struct dec_sub *dec_sub);
bool osd_get_render_subs_in_filter(struct osd_state *osd);
void osd_set_render_subs_in_filter(struct osd_state *osd, bool s);
+void osd_set_force_video_pts(struct osd_state *osd, double video_pts);
+double osd_get_force_video_pts(struct osd_state *osd);
struct osd_progbar_state {
int type; // <0: disabled, 1-255: symbol, else: no symbol
diff --git a/sub/osd_state.h b/sub/osd_state.h
index fbccd85e70..cce415a1b9 100644
--- a/sub/osd_state.h
+++ b/sub/osd_state.h
@@ -67,6 +67,7 @@ struct osd_state {
struct osd_object *objs[MAX_OSD_PARTS];
bool render_subs_in_filter;
+ double force_video_pts;
bool want_redraw;
bool want_redraw_notification;