summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2010-12-14 20:20:30 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-12-14 22:33:11 +0200
commit2ba074e613d79600023128974ea60a75251480b5 (patch)
tree0f432c04ef103909dc54e3fcc06bb6ae23139a96 /mplayer.c
parent188fbb6622cdc0429f7f966e239354cc054cd077 (diff)
downloadmpv-2ba074e613d79600023128974ea60a75251480b5.tar.bz2
mpv-2ba074e613d79600023128974ea60a75251480b5.tar.xz
core: timing: add special handling of long frame intervals
Add separate handling for the case where the time to flip the next frame on the VO is more than 50 ms away. In that case don't update OSD contents yet, but wait for possible changes until 50 ms before the frame. Sleep until that time in mp_input_get_cmd(), so the sleep is done in select() and input events can be responded to immediately. Also raise the limit on audio out delay used to limit sleep.
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c71
1 files changed, 36 insertions, 35 deletions
diff --git a/mplayer.c b/mplayer.c
index 16726c7b0a..8274d936ff 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -2280,11 +2280,11 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
return 1;
}
-static int sleep_until_update(struct MPContext *mpctx, float *time_frame,
- float *aq_sleep_time)
+static int sleep_until_near_frame(struct MPContext *mpctx, float *time_frame,
+ float *aq_sleep_time)
{
struct MPOpts *opts = &mpctx->opts;
- int frame_time_remaining = 0;
+ double audio_limit = 2;
current_module="calc_sleep_time";
*time_frame -= get_relative_time(mpctx); // reset timer
@@ -2309,17 +2309,11 @@ static int sleep_until_update(struct MPContext *mpctx, float *time_frame,
}
*time_frame = delay - mpctx->delay / opts->playback_speed;
- *time_frame -= mpctx->video_out->flip_queue_offset;
// delay = amount of audio buffered in soundcard/driver
- if (delay > 0.25) delay=0.25; else
- if (delay < 0.10) delay=0.10;
-
- if (*time_frame > delay*0.6) {
- // sleep time too big - may cause audio drops (buffer underrun)
- frame_time_remaining = 1;
- *time_frame = delay*0.5;
- }
+ delay = FFMIN(delay, 0.5);
+ delay = FFMAX(delay, 0.1);
+ audio_limit = delay;
} else {
// If we're lagging more than 200 ms behind the right playback rate,
// don't try to "catch up".
@@ -2327,19 +2321,19 @@ static int sleep_until_update(struct MPContext *mpctx, float *time_frame,
// without sleeping.
if (*time_frame < -0.2 || opts->benchmark)
*time_frame = 0;
- *time_frame -= mpctx->video_out->flip_queue_offset;
}
- *aq_sleep_time += *time_frame;
+ double t = *time_frame - mpctx->video_out->flip_queue_offset;
+ if (t <= 0.05)
+ return 0;
- //============================== SLEEP: ===================================
-
- // flag 256 means: libvo driver does its timing (dvb card)
- if (*time_frame > 0.001 && !(mpctx->sh_video->output_flags&256))
- *time_frame = timing_sleep(mpctx, *time_frame);
- *time_frame += mpctx->video_out->flip_queue_offset;
- return frame_time_remaining;
+ t -= 0.05;
+ if (t > audio_limit * 0.6)
+ t = audio_limit * 0.5;
+ *aq_sleep_time += t;
+ mp_input_get_cmd(mpctx->input, t * 1000 + 1, 1);
+ return 1;
}
int reinit_video_chain(struct MPContext *mpctx)
@@ -3089,17 +3083,6 @@ static void run_playloop(struct MPContext *mpctx)
mpctx->stop_play = PT_NEXT_ENTRY;
return;
}
- if (blit_frame) {
- struct sh_video *sh_video = mpctx->sh_video;
- update_subtitles(mpctx, &mpctx->opts, sh_video, sh_video->pts,
- mpctx->video_offset, mpctx->d_sub, 0);
- update_teletext(sh_video, mpctx->demuxer, 0);
- update_osd_msg(mpctx);
- struct vf_instance *vf = mpctx->sh_video->vfilter;
- vf->control(vf, VFCTRL_DRAW_EOSD, NULL);
- vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd);
- vo_osd_changed(0);
- }
if (frame_time < 0)
mpctx->stop_play = AT_END_OF_FILE;
else if (!mpctx->restart_playback) {
@@ -3138,14 +3121,32 @@ static void run_playloop(struct MPContext *mpctx)
}
}
- bool frame_time_remaining = sleep_until_update(mpctx,
- &mpctx->time_frame,
- &aq_sleep_time);
+ bool frame_time_remaining = sleep_until_near_frame(mpctx,
+ &mpctx->time_frame,
+ &aq_sleep_time);
//====================== FLIP PAGE (VIDEO BLT): =========================
current_module = "flip_page";
if (!frame_time_remaining && blit_frame) {
+ struct sh_video *sh_video = mpctx->sh_video;
+ update_subtitles(mpctx, &mpctx->opts, sh_video, sh_video->pts,
+ mpctx->video_offset, mpctx->d_sub, 0);
+ update_teletext(sh_video, mpctx->demuxer, 0);
+ update_osd_msg(mpctx);
+ struct vf_instance *vf = sh_video->vfilter;
+ vf->control(vf, VFCTRL_DRAW_EOSD, NULL);
+ vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd);
+ vo_osd_changed(0);
+
+ mpctx->time_frame -= mpctx->video_out->flip_queue_offset;
+ aq_sleep_time += mpctx->time_frame;
+ // flag 256 means: libvo driver does its timing (dvb card)
+ if (mpctx->time_frame > 0.001
+ && !(mpctx->sh_video->output_flags&256))
+ mpctx->time_frame = timing_sleep(mpctx, mpctx->time_frame);
+ mpctx->time_frame += mpctx->video_out->flip_queue_offset;
+
unsigned int t2 = GetTimer();
unsigned int pts_us = mpctx->last_time + mpctx->time_frame * 1e6;
int duration = -1;