From 62d3c953679b2dc32e47d9f81b9f877eb1a5c804 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Wed, 25 Mar 2015 22:40:10 +0100 Subject: vo_opengl: correct OSD PTS when using interpolation --- video/out/gl_video.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'video') diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 7b6976685f..3837da82ad 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -131,6 +131,7 @@ struct scaler { struct fbosurface { struct fbotex fbotex; int64_t pts; + double vpts; // used for synchronizing subtitles only }; #define FBOSURFACES_MAX 10 @@ -492,8 +493,10 @@ void gl_video_set_debug(struct gl_video *p, bool enable) static void gl_video_reset_surfaces(struct gl_video *p) { - for (int i = 0; i < FBOSURFACES_MAX; i++) + for (int i = 0; i < FBOSURFACES_MAX; i++) { p->surfaces[i].pts = 0; + p->surfaces[i].vpts = MP_NOPTS_VALUE; + } p->surface_idx = 0; p->surface_now = 0; } @@ -1734,6 +1737,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, int fbo, finish_pass_fbo(p, &p->surfaces[p->surface_now].fbotex, vp_w, vp_h, 0, fuzz); p->surfaces[p->surface_now].pts = t ? t->pts : 0; + p->surfaces[p->surface_now].vpts = p->image.mpi->pts; p->surface_idx = p->surface_now; } @@ -1769,6 +1773,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, int fbo, finish_pass_fbo(p, &p->surfaces[surface_dst].fbotex, vp_w, vp_h, 0, fuzz); p->surfaces[surface_dst].pts = t->pts; + p->surfaces[surface_dst].vpts = p->image.mpi->pts; p->surface_idx = surface_dst; } @@ -1788,6 +1793,22 @@ static void gl_video_interpolate_frame(struct gl_video *p, int fbo, } } + // Update OSD PTS to synchronize subtitles with the displayed frame + if (t) { + double vpts_now = p->surfaces[surface_now].vpts, + vpts_nxt = p->surfaces[surface_nxt].vpts, + vpts_new = p->image.mpi->pts; + if (vpts_now != MP_NOPTS_VALUE && + vpts_nxt != MP_NOPTS_VALUE && + vpts_new != MP_NOPTS_VALUE) + { + // Round to nearest neighbour + double vpts_vsync = (t->next_vsync - t->pts)/1e6 + vpts_new; + p->osd_pts = fabs(vpts_vsync-vpts_now) < fabs(vpts_vsync-vpts_nxt) + ? vpts_now : vpts_nxt; + } + } + // Finally, draw the right mix of frames to the screen. if (!t || !valid) { // surface_now is guaranteed to be valid, so we can safely use it. -- cgit v1.2.3