From f798bc3c2542b4c3e7b4cb1483d41ce309b4fb51 Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 3 Jan 2018 21:48:42 +0100 Subject: [PATCH] player: add --cache-pause-initial option to start in buffering state Reasons why you'd want this see manpage additions. Disabled by default, because it would increase latency of live streams by default. (Or well, at least it would be another problem when trying getting lower latency.) --- DOCS/man/options.rst | 14 ++++++++++++++ options/options.c | 1 + options/options.h | 1 + player/playloop.c | 11 +++++++++++ 4 files changed, 27 insertions(+) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 3d1c2ade2d..20f48ebc93 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -3865,6 +3865,20 @@ Cache ends before that for some other reason (like file end), playback resumes earlier. +``--cache-pause-initial=`` + Enter "buffering" mode before starting playback (default: no). This can be + used to ensure playback starts smoothly, in exchange for waiting some time + to prefetch network data (as controlled by ``--cache-pause-wait``). For + example, some common behavior is that playback starts, but network caches + immediately underrun when trying to decode more data as playback progresses. + + Another thing that can happen is that the network prefetching is so CPU + demanding (due to demuxing in the background) that playback drops frames + at first. In these cases, it helps enabling this option, and setting + ``--cache-secs`` and ``--cache-pause-wait`` to roughly the same value. + + This option also triggers when playback is restarted after seeking. + Network ------- diff --git a/options/options.c b/options/options.c index 030ba6f9e6..08cb9be3cf 100644 --- a/options/options.c +++ b/options/options.c @@ -451,6 +451,7 @@ const m_option_t mp_opts[] = { OPT_FLAG("demuxer-thread", demuxer_thread, 0), OPT_FLAG("prefetch-playlist", prefetch_open, 0), OPT_FLAG("cache-pause", cache_pausing, 0), + OPT_FLAG("cache-pause-initial", cache_pause_initial, 0), OPT_FLOAT("cache-pause-wait", cache_pause_wait, M_OPT_MIN, .min = 0), OPT_DOUBLE("mf-fps", mf_fps, 0), diff --git a/options/options.h b/options/options.h index 3774b7b343..96f19a2ee5 100644 --- a/options/options.h +++ b/options/options.h @@ -263,6 +263,7 @@ typedef struct MPOpts { char *sub_demuxer_name; int cache_pausing; + int cache_pause_initial; float cache_pause_wait; struct image_writer_opts *screenshot_image_opts; diff --git a/player/playloop.c b/player/playloop.c index 632ccd0999..e9d9112588 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -950,6 +950,17 @@ 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); + } + if (mpctx->video_status == STATUS_READY) { mpctx->video_status = STATUS_PLAYING; get_relative_time(mpctx);