Mercurial > mplayer.hg
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; }