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)