summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-01-06 15:49:32 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-01-07 05:03:15 -0800
commitebe0f5d31356422e72ade81cf43794116f32c12d (patch)
tree6d85ce8b3f454e18a62638f10a23f447bbd7057e
parentb1a11191fdda06f737ce6d9b25e21fbcc6bb16d1 (diff)
downloadmpv-ebe0f5d31356422e72ade81cf43794116f32c12d.tar.bz2
mpv-ebe0f5d31356422e72ade81cf43794116f32c12d.tar.xz
player: slightly refactor/simplify cache pausing logic
The underlying logic is still the same (basically pausing if the demuxer cache underruns), but clean up the higher level logic a bit. It goes from 3 levels of nested if statements to 1. Also remove the code duplication for the --cache-pause-initial logic. In addition, make sure an earlier buffering state has no influence on the new state after a seek (this is also why some of the state resetting can be removed from loadfile.c). Initialize cache_buffer always to 100. It basically means we start out assuming all buffers are filled enough. This actually matters for verbose messages only, but removes some weird special casing.
-rw-r--r--player/loadfile.c2
-rw-r--r--player/playloop.c74
2 files changed, 37 insertions, 39 deletions
diff --git a/player/loadfile.c b/player/loadfile.c
index daea9149e7..edba9caa1b 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -1163,8 +1163,6 @@ static void play_current_file(struct MPContext *mpctx)
mpctx->last_chapter_pts = MP_NOPTS_VALUE;
mpctx->last_chapter = -2;
mpctx->paused = false;
- mpctx->paused_for_cache = false;
- mpctx->cache_buffer = -1;
mpctx->playing_msg_shown = false;
mpctx->max_frames = -1;
mpctx->video_speed = mpctx->audio_speed = opts->playback_speed;
diff --git a/player/playloop.c b/player/playloop.c
index 1184e94ad9..2e714823f9 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -237,11 +237,14 @@ void reset_playback_state(struct MPContext *mpctx)
mpctx->step_frames = 0;
mpctx->ab_loop_clip = true;
mpctx->restart_complete = false;
+ mpctx->paused_for_cache = false;
+ mpctx->cache_buffer = 100;
#if HAVE_ENCODING
encode_lavc_discontinuity(mpctx->encode_lavc_ctx);
#endif
+ update_internal_pause_state(mpctx);
update_core_idle_state(mpctx);
}
@@ -614,30 +617,38 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s);
int cache_buffer = 100;
- bool use_pause_on_low_cache = c.size > 0 || mpctx->demuxer->is_network;
-
- if (mpctx->restart_complete && use_pause_on_low_cache) {
- if (mpctx->paused && mpctx->paused_for_cache) {
- if (!s.underrun && (!opts->cache_pause || s.idle ||
- s.ts_duration >= opts->cache_pause_wait))
- {
- mpctx->paused_for_cache = false;
- update_internal_pause_state(mpctx);
- force_update = true;
- }
- mp_set_timeout(mpctx, 0.2);
- } else {
- if (opts->cache_pause && s.underrun) {
- mpctx->paused_for_cache = true;
- update_internal_pause_state(mpctx);
- mpctx->cache_stop_time = now;
- force_update = true;
- }
- }
- if (mpctx->paused_for_cache) {
- cache_buffer =
- 100 * MPCLAMP(s.ts_duration / opts->cache_pause_wait, 0, 0.99);
- }
+ bool use_pause_on_low_cache = (c.size > 0 || mpctx->demuxer->is_network) &&
+ opts->cache_pause;
+
+ if (!mpctx->restart_complete) {
+ // Audio or video is restarting, and initial buffering is enabled. Make
+ // sure we actually restart them in paused mode, so no audio gets
+ // dropped and video technically doesn't start yet.
+ use_pause_on_low_cache &= opts->cache_pause_initial &&
+ (mpctx->video_status == STATUS_READY ||
+ mpctx->audio_status == STATUS_READY);
+ }
+
+ bool is_low = use_pause_on_low_cache && !s.idle &&
+ s.ts_duration < opts->cache_pause_wait;
+
+ // Enter buffering state only if there actually was an underrun (or if
+ // initial caching before playback restart is used).
+ if (is_low && !mpctx->paused_for_cache && mpctx->restart_complete)
+ is_low = s.underrun;
+
+ if (mpctx->paused_for_cache != is_low) {
+ mpctx->paused_for_cache = is_low;
+ update_internal_pause_state(mpctx);
+ force_update = true;
+ if (is_low)
+ mpctx->cache_stop_time = now;
+ }
+
+ if (mpctx->paused_for_cache) {
+ cache_buffer =
+ 100 * MPCLAMP(s.ts_duration / opts->cache_pause_wait, 0, 0.99);
+ mp_set_timeout(mpctx, 0.2);
}
// Also update cache properties.
@@ -652,9 +663,7 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
}
if (mpctx->cache_buffer != cache_buffer) {
- if (mpctx->cache_buffer >= 0 &&
- (mpctx->cache_buffer == 100) != (cache_buffer == 100))
- {
+ if ((mpctx->cache_buffer == 100) != (cache_buffer == 100)) {
if (cache_buffer < 100) {
MP_VERBOSE(mpctx, "Enter buffering.\n");
} else {
@@ -950,16 +959,7 @@ static void handle_playback_restart(struct MPContext *mpctx)
mpctx->video_status < STATUS_READY)
return;
- if (opts->cache_pause_initial && (mpctx->video_status == STATUS_READY ||
- mpctx->audio_status == STATUS_READY))
- {
- // Audio or video is restarting, and initial buffering is enabled. Make
- // sure we actually restart them in paused mode, so no audio gets
- // dropped and video technically doesn't start yet.
- mpctx->paused_for_cache = true;
- mpctx->cache_buffer = 0;
- update_internal_pause_state(mpctx);
- }
+ handle_pause_on_low_cache(mpctx);
if (mpctx->video_status == STATUS_READY) {
mpctx->video_status = STATUS_PLAYING;