summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst14
-rw-r--r--options/options.c1
-rw-r--r--options/options.h1
-rw-r--r--player/playloop.c11
4 files changed, 27 insertions, 0 deletions
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=<yes|no>``
+ 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);