1
0
mirror of https://github.com/mpv-player/mpv synced 2025-03-01 11:50:48 +00:00

core: don't let cache pause handling and user pausing conflict

The core pauses and unpauses automatically to wait for the network
cache (also known as buffering). This conflicted with user pause
control, and was perceived as if the player was unresponsive and/or
the cache just overturned the user's decisions.

Change it so that the actual pause state and the pause state as
intended by the user never conflict. If the user toggles pause, the
pause state will be in the expected state as soon as the cache is
loaded.
This commit is contained in:
wm4 2013-04-25 19:07:47 +02:00
parent 848542a513
commit e1fccfdcd8
3 changed files with 25 additions and 10 deletions

View File

@ -527,7 +527,7 @@ static int mp_property_pause(m_option_t *prop, int action, void *arg,
}
return M_PROPERTY_OK;
case M_PROPERTY_GET:
*(int *)arg = mpctx->paused;
*(int *)arg = mpctx->paused_user;
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
@ -2303,7 +2303,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
pause_player(mpctx);
break;
case 3: // "pausing_toggle"
if (mpctx->paused)
if (mpctx->paused_user)
unpause_player(mpctx);
else
pause_player(mpctx);

View File

@ -272,7 +272,7 @@ typedef struct MPContext {
int max_frames;
bool playing_msg_shown;
bool paused_for_cache;
bool paused_for_cache, paused_user;
// Set after showing warning about decoding being too slow for realtime
// playback rate. Used to avoid showing it multiple times.

View File

@ -1065,7 +1065,7 @@ static void print_status(struct MPContext *mpctx)
char *line = NULL;
// Playback status
if (mpctx->paused_for_cache) {
if (mpctx->paused_for_cache && !mpctx->paused_user) {
saddf(&line, "(Buffering) ");
} else if (mpctx->paused) {
saddf(&line, "(Paused) ");
@ -1429,7 +1429,7 @@ static void sadd_osd_status(char **buffer, struct MPContext *mpctx, bool full)
bool fractions = mpctx->opts.osd_fractions;
int sym = mpctx->osd_function;
if (!sym) {
if (mpctx->paused_for_cache) {
if (mpctx->paused_for_cache && !mpctx->paused_user) {
sym = OSD_CLOCK;
} else if (mpctx->paused || mpctx->step_frames) {
sym = OSD_PAUSE;
@ -2638,12 +2638,15 @@ static double update_video(struct MPContext *mpctx, double endpts)
void pause_player(struct MPContext *mpctx)
{
mpctx->paused_user = true;
if (mpctx->paused)
return;
mpctx->paused = 1;
mpctx->step_frames = 0;
mpctx->time_frame -= get_relative_time(mpctx);
mpctx->osd_function = 0;
mpctx->paused_for_cache = false;
if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok)
vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL);
@ -2661,11 +2664,15 @@ void pause_player(struct MPContext *mpctx)
void unpause_player(struct MPContext *mpctx)
{
mpctx->paused_user = false;
if (!mpctx->paused)
return;
// Don't actually unpause while cache is loading.
if (mpctx->paused_for_cache)
return;
mpctx->paused = 0;
mpctx->osd_function = 0;
mpctx->paused_for_cache = false;
if (mpctx->ao && mpctx->sh_audio)
ao_resume(mpctx->ao);
@ -3192,12 +3199,17 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
int cache = mp_get_cache_percent(mpctx);
bool idle = mp_get_cache_idle(mpctx);
if (mpctx->paused && mpctx->paused_for_cache) {
if (cache < 0 || cache >= opts->stream_cache_min_percent || idle)
unpause_player(mpctx);
} else if (!mpctx->paused) {
if (cache < 0 || cache >= opts->stream_cache_min_percent || idle) {
mpctx->paused_for_cache = false;
if (!mpctx->paused_user)
unpause_player(mpctx);
}
} else {
if (cache >= 0 && cache <= opts->stream_cache_pause && !idle) {
mpctx->paused_for_cache = true;
bool prev_paused_user = mpctx->paused_user;
pause_player(mpctx);
mpctx->paused_for_cache = true;
mpctx->paused_user = prev_paused_user;
}
}
}
@ -4244,6 +4256,9 @@ goto_enable_cache: ;
mpctx->seek = (struct seek_params){ 0 };
get_relative_time(mpctx); // reset current delta
mpctx->paused = mpctx->paused_user;
mpctx->paused_for_cache = false;
// Make sure VO knows current pause state
if (mpctx->sh_video)
vo_control(mpctx->video_out,