summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@nand.wakku.to>2015-03-25 22:40:10 +0100
committerNiklas Haas <git@nand.wakku.to>2015-03-25 22:40:10 +0100
commit62d3c953679b2dc32e47d9f81b9f877eb1a5c804 (patch)
treee5ea96697be4b23863d054686d26d28ef3a8f252
parent72308256e45e9184bb1578ad2cd40830e091ce13 (diff)
downloadmpv-62d3c953679b2dc32e47d9f81b9f877eb1a5c804.tar.bz2
mpv-62d3c953679b2dc32e47d9f81b9f877eb1a5c804.tar.xz
vo_opengl: correct OSD PTS when using interpolation
-rw-r--r--video/out/gl_video.c23
1 files changed, 22 insertions, 1 deletions
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.