changeset 31971:910579aafc61

Time-based PTS recalculation. Patch by P«”sztor Szil«”rd, bartosteka freemail hu
author cehoyos
date Tue, 07 Sep 2010 16:14:56 +0000
parents 7779efdd10a7
children 96559880e475
files mp_core.h mplayer.c
diffstat 2 files changed, 24 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mp_core.h	Tue Sep 07 02:08:31 2010 +0000
+++ b/mp_core.h	Tue Sep 07 16:14:56 2010 +0000
@@ -93,6 +93,8 @@
     int startup_decode_retry;
     // how long until we need to display the "current" frame
     float time_frame;
+    // flag to indicate that we've found a correctly timed video frame PTS
+    int framestep_found;
 
     // AV sync: the next frame should be shown when the audio out has this
     // much (in seconds) buffered data left. Increased when more data is
--- a/mplayer.c	Tue Sep 07 02:08:31 2010 +0000
+++ b/mplayer.c	Tue Sep 07 16:14:56 2010 +0000
@@ -2452,6 +2452,28 @@
 	frame_time = sh_video->pts - sh_video->last_pts;
 	sh_video->last_pts = sh_video->pts;
 	sh_video->timer += frame_time;
+	// Time-based PTS recalculation.
+	// The key to maintaining A-V sync is to not touch PTS until the proper frame is reached
+	if (sh_video->pts != MP_NOPTS_VALUE) {
+	    if (sh_video->last_pts != MP_NOPTS_VALUE) {
+		double pts = sh_video->last_pts + frame_time;
+		double ptsdiff = fabs(pts - sh_video->pts);
+
+		// Allow starting PTS recalculation at the appropriate frame only
+		mpctx->framestep_found |= (ptsdiff <= frame_time * 1.5);
+
+		// replace PTS only if we're not too close and not too far
+		// and a correctly timed frame has been found, otherwise
+		// keep pts to eliminate rounding errors or catch up with stream
+		if (ptsdiff > frame_time * 20)
+		    mpctx->framestep_found = 0;
+		if (ptsdiff * 10 > frame_time && mpctx->framestep_found)
+		    sh_video->pts = pts;
+		else
+		    mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"Keeping PTS at %6.2f\n", sh_video->pts);
+	    }
+	    sh_video->last_pts = sh_video->pts;
+	}
 	if(mpctx->sh_audio)
 	    mpctx->delay -= frame_time;
 	*blit_frame = res > 0;