changeset 26228:089dc00275b6

Experimental support for -framedrop with -correct-pts. The code is not really correct, but it is very little and works "well enough" to be useful in my tests.
author reimar
date Mon, 17 Mar 2008 20:21:16 +0000
parents 85c37eab722b
children 10bd2e6eee6a
files DOCS/man/en/mplayer.1 mplayer.c
diffstat 2 files changed, 31 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/man/en/mplayer.1	Mon Mar 17 20:15:22 2008 +0000
+++ b/DOCS/man/en/mplayer.1	Mon Mar 17 20:21:16 2008 +0000
@@ -840,7 +840,7 @@
 xmga, xv, xvidix and dfbmga.
 .
 .TP
-.B \-framedrop (also see \-hardframedrop, only works with \-no\-correct\-pts)
+.B \-framedrop (also see \-hardframedrop, experimental without \-no\-correct\-pts)
 Skip displaying some frames to maintain A/V sync on slow systems.
 Video filters are not applied to such frames.
 For B-frames even decoding is skipped completely.
@@ -856,7 +856,7 @@
 Show short summary of options.
 .
 .TP
-.B \-hardframedrop (only works with \-no\-correct\-pts)
+.B \-hardframedrop (experimental without \-no\-correct\-pts)
 More intense frame dropping (breaks decoding).
 Leads to image distortion!
 Note that especially the libmpeg2 decoder may crash with this, 
--- a/mplayer.c	Mon Mar 17 20:15:22 2008 +0000
+++ b/mplayer.c	Mon Mar 17 20:21:16 2008 +0000
@@ -1708,6 +1708,27 @@
 	audio_out->get_delay();
 }
 
+static int check_framedrop(double frame_time) {
+	// check for frame-drop:
+	current_module = "check_framedrop";
+	if (mpctx->sh_audio && !mpctx->d_audio->eof) {
+	    static int dropped_frames;
+	    float delay = playback_speed*mpctx->audio_out->get_delay();
+	    float d = delay-mpctx->delay;
+	    ++total_frame_cnt;
+	    // we should avoid dropping too many frames in sequence unless we
+	    // are too late. and we allow 100ms A-V delay here:
+	    if (d < -dropped_frames*frame_time-0.100 &&
+				mpctx->osd_function != OSD_PAUSE) {
+		++drop_frame_cnt;
+		++dropped_frames;
+		return frame_dropping;
+	    } else
+		dropped_frames = 0;
+	}
+	return 0;
+}
+
 static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_video)
 {
     unsigned char *start;
@@ -1716,6 +1737,7 @@
     double pts;
 
     while (1) {
+	int drop_frame = check_framedrop(sh_video->frametime);
 	void *decoded_frame;
 	current_module = "decode video";
 	// XXX Time used in this call is not counted in any performance
@@ -1733,7 +1755,7 @@
 	if (in_size > max_framesize)
 	    max_framesize = in_size;
 	current_module = "decode video";
-	decoded_frame = decode_video(sh_video, start, in_size, 0, pts);
+	decoded_frame = decode_video(sh_video, start, in_size, drop_frame, pts);
 	if (decoded_frame) {
 	    update_subtitles(sh_video, mpctx->d_sub, 0);
 	    update_teletext(sh_video, mpctx->demuxer, 0);
@@ -1741,7 +1763,8 @@
 	    current_module = "filter video";
 	    if (filter_video(sh_video, decoded_frame, sh_video->pts))
 		break;
-	}
+	} else if (drop_frame)
+	    return -1;
 	if (hit_eof)
 	    return 0;
     }
@@ -2253,23 +2276,7 @@
 	    mpctx->delay -= frame_time;
 	// video_read_frame can change fps (e.g. for ASF video)
 	vo_fps = sh_video->fps;
-	// check for frame-drop:
-	current_module = "check_framedrop";
-	if (mpctx->sh_audio && !mpctx->d_audio->eof) {
-	    static int dropped_frames;
-	    float delay = playback_speed*mpctx->audio_out->get_delay();
-	    float d = delay-mpctx->delay;
-	    // we should avoid dropping too many frames in sequence unless we
-	    // are too late. and we allow 100ms A-V delay here:
-	    if (d < -dropped_frames*frame_time-0.100 &&
-				mpctx->osd_function != OSD_PAUSE) {
-		drop_frame = frame_dropping;
-		++drop_frame_cnt;
-		++dropped_frames;
-	    } else
-		drop_frame = dropped_frames = 0;
-	    ++total_frame_cnt;
-	}
+	drop_frame = check_framedrop(frame_time);
 	update_subtitles(sh_video, mpctx->d_sub, 0);
 	update_teletext(sh_video, mpctx->demuxer, 0);
 	update_osd_msg();
@@ -2290,7 +2297,8 @@
 						    sh_video->pts));
     }
     else {
-	if (!generate_video_frame(sh_video, mpctx->d_video))
+	int res = generate_video_frame(sh_video, mpctx->d_video);
+	if (!res)
 	    return -1;
 	((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter,
 					    VFCTRL_GET_PTS, &sh_video->pts);
@@ -2309,7 +2317,7 @@
 	sh_video->timer += frame_time;
 	if(mpctx->sh_audio)
 	    mpctx->delay -= frame_time;
-	*blit_frame = 1;
+	*blit_frame = res > 0;
     }
     return frame_time;
 }