Mercurial > mplayer.hg
comparison mplayer.c @ 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 | 7862aea6a387 |
children | a80db7629478 |
comparison
equal
deleted
inserted
replaced
26227:85c37eab722b | 26228:089dc00275b6 |
---|---|
1706 { | 1706 { |
1707 return written_audio_pts(sh_audio, d_audio) - playback_speed * | 1707 return written_audio_pts(sh_audio, d_audio) - playback_speed * |
1708 audio_out->get_delay(); | 1708 audio_out->get_delay(); |
1709 } | 1709 } |
1710 | 1710 |
1711 static int check_framedrop(double frame_time) { | |
1712 // check for frame-drop: | |
1713 current_module = "check_framedrop"; | |
1714 if (mpctx->sh_audio && !mpctx->d_audio->eof) { | |
1715 static int dropped_frames; | |
1716 float delay = playback_speed*mpctx->audio_out->get_delay(); | |
1717 float d = delay-mpctx->delay; | |
1718 ++total_frame_cnt; | |
1719 // we should avoid dropping too many frames in sequence unless we | |
1720 // are too late. and we allow 100ms A-V delay here: | |
1721 if (d < -dropped_frames*frame_time-0.100 && | |
1722 mpctx->osd_function != OSD_PAUSE) { | |
1723 ++drop_frame_cnt; | |
1724 ++dropped_frames; | |
1725 return frame_dropping; | |
1726 } else | |
1727 dropped_frames = 0; | |
1728 } | |
1729 return 0; | |
1730 } | |
1731 | |
1711 static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_video) | 1732 static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_video) |
1712 { | 1733 { |
1713 unsigned char *start; | 1734 unsigned char *start; |
1714 int in_size; | 1735 int in_size; |
1715 int hit_eof=0; | 1736 int hit_eof=0; |
1716 double pts; | 1737 double pts; |
1717 | 1738 |
1718 while (1) { | 1739 while (1) { |
1740 int drop_frame = check_framedrop(sh_video->frametime); | |
1719 void *decoded_frame; | 1741 void *decoded_frame; |
1720 current_module = "decode video"; | 1742 current_module = "decode video"; |
1721 // XXX Time used in this call is not counted in any performance | 1743 // XXX Time used in this call is not counted in any performance |
1722 // timer now, OSD is not updated correctly for filter-added frames | 1744 // timer now, OSD is not updated correctly for filter-added frames |
1723 if (vf_output_queued_frame(sh_video->vfilter)) | 1745 if (vf_output_queued_frame(sh_video->vfilter)) |
1731 hit_eof = 1; | 1753 hit_eof = 1; |
1732 } | 1754 } |
1733 if (in_size > max_framesize) | 1755 if (in_size > max_framesize) |
1734 max_framesize = in_size; | 1756 max_framesize = in_size; |
1735 current_module = "decode video"; | 1757 current_module = "decode video"; |
1736 decoded_frame = decode_video(sh_video, start, in_size, 0, pts); | 1758 decoded_frame = decode_video(sh_video, start, in_size, drop_frame, pts); |
1737 if (decoded_frame) { | 1759 if (decoded_frame) { |
1738 update_subtitles(sh_video, mpctx->d_sub, 0); | 1760 update_subtitles(sh_video, mpctx->d_sub, 0); |
1739 update_teletext(sh_video, mpctx->demuxer, 0); | 1761 update_teletext(sh_video, mpctx->demuxer, 0); |
1740 update_osd_msg(); | 1762 update_osd_msg(); |
1741 current_module = "filter video"; | 1763 current_module = "filter video"; |
1742 if (filter_video(sh_video, decoded_frame, sh_video->pts)) | 1764 if (filter_video(sh_video, decoded_frame, sh_video->pts)) |
1743 break; | 1765 break; |
1744 } | 1766 } else if (drop_frame) |
1767 return -1; | |
1745 if (hit_eof) | 1768 if (hit_eof) |
1746 return 0; | 1769 return 0; |
1747 } | 1770 } |
1748 return 1; | 1771 return 1; |
1749 } | 1772 } |
2251 sh_video->timer += frame_time; | 2274 sh_video->timer += frame_time; |
2252 if (mpctx->sh_audio) | 2275 if (mpctx->sh_audio) |
2253 mpctx->delay -= frame_time; | 2276 mpctx->delay -= frame_time; |
2254 // video_read_frame can change fps (e.g. for ASF video) | 2277 // video_read_frame can change fps (e.g. for ASF video) |
2255 vo_fps = sh_video->fps; | 2278 vo_fps = sh_video->fps; |
2256 // check for frame-drop: | 2279 drop_frame = check_framedrop(frame_time); |
2257 current_module = "check_framedrop"; | |
2258 if (mpctx->sh_audio && !mpctx->d_audio->eof) { | |
2259 static int dropped_frames; | |
2260 float delay = playback_speed*mpctx->audio_out->get_delay(); | |
2261 float d = delay-mpctx->delay; | |
2262 // we should avoid dropping too many frames in sequence unless we | |
2263 // are too late. and we allow 100ms A-V delay here: | |
2264 if (d < -dropped_frames*frame_time-0.100 && | |
2265 mpctx->osd_function != OSD_PAUSE) { | |
2266 drop_frame = frame_dropping; | |
2267 ++drop_frame_cnt; | |
2268 ++dropped_frames; | |
2269 } else | |
2270 drop_frame = dropped_frames = 0; | |
2271 ++total_frame_cnt; | |
2272 } | |
2273 update_subtitles(sh_video, mpctx->d_sub, 0); | 2280 update_subtitles(sh_video, mpctx->d_sub, 0); |
2274 update_teletext(sh_video, mpctx->demuxer, 0); | 2281 update_teletext(sh_video, mpctx->demuxer, 0); |
2275 update_osd_msg(); | 2282 update_osd_msg(); |
2276 current_module = "decode_video"; | 2283 current_module = "decode_video"; |
2277 #ifdef USE_DVDNAV | 2284 #ifdef USE_DVDNAV |
2288 current_module = "filter_video"; | 2295 current_module = "filter_video"; |
2289 *blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame, | 2296 *blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame, |
2290 sh_video->pts)); | 2297 sh_video->pts)); |
2291 } | 2298 } |
2292 else { | 2299 else { |
2293 if (!generate_video_frame(sh_video, mpctx->d_video)) | 2300 int res = generate_video_frame(sh_video, mpctx->d_video); |
2301 if (!res) | |
2294 return -1; | 2302 return -1; |
2295 ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, | 2303 ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, |
2296 VFCTRL_GET_PTS, &sh_video->pts); | 2304 VFCTRL_GET_PTS, &sh_video->pts); |
2297 if (sh_video->pts == MP_NOPTS_VALUE) { | 2305 if (sh_video->pts == MP_NOPTS_VALUE) { |
2298 mp_msg(MSGT_CPLAYER, MSGL_ERR, "pts after filters MISSING\n"); | 2306 mp_msg(MSGT_CPLAYER, MSGL_ERR, "pts after filters MISSING\n"); |
2307 frame_time = sh_video->pts - sh_video->last_pts; | 2315 frame_time = sh_video->pts - sh_video->last_pts; |
2308 sh_video->last_pts = sh_video->pts; | 2316 sh_video->last_pts = sh_video->pts; |
2309 sh_video->timer += frame_time; | 2317 sh_video->timer += frame_time; |
2310 if(mpctx->sh_audio) | 2318 if(mpctx->sh_audio) |
2311 mpctx->delay -= frame_time; | 2319 mpctx->delay -= frame_time; |
2312 *blit_frame = 1; | 2320 *blit_frame = res > 0; |
2313 } | 2321 } |
2314 return frame_time; | 2322 return frame_time; |
2315 } | 2323 } |
2316 | 2324 |
2317 static void pause_loop(void) | 2325 static void pause_loop(void) |