summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/options.rst11
-rw-r--r--core/cfg-mplayer.h2
-rw-r--r--core/defaultopts.c1
-rw-r--r--core/mp_core.h2
-rw-r--r--core/mplayer.c44
-rw-r--r--core/options.h1
-rw-r--r--stream/cache2.c9
-rw-r--r--stream/stream.h1
8 files changed, 66 insertions, 5 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index b5a2b02537..a7aa700786 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -261,9 +261,18 @@
from slow media, but can also have negative effects, especially with file
formats that require a lot of seeking, such as mp4. See also ``--no-cache``.
+--cache-pause=<no|percentage>
+ If the cache percentage goes below the specified value, pause and wait
+ until the percentage set by ``--cache-min`` is reached, then resume
+ playback (default: 10). If ``no`` is specified, this behavior is disabled.
+
+ When the player is paused this way, the status line shows ``Buffering``
+ instead of ``Paused``, and the OSD uses a clock symbol instead of the
+ normal paused symbol.
+
--cache-min=<percentage>
Playback will start when the cache has been filled up to <percentage> of
- the total.
+ the total (default: 20).
--cache-seek-min=<percentage>
If a seek is to be made to a position within <percentage> of the cache
diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h
index b1c693a5a9..03432c8e04 100644
--- a/core/cfg-mplayer.h
+++ b/core/cfg-mplayer.h
@@ -329,6 +329,8 @@ const m_option_t common_opts[] = {
OPT_FLOATRANGE("cache-min", stream_cache_min_percent, 0, 0, 99),
OPT_FLOATRANGE("cache-seek-min", stream_cache_seek_min_percent, 0, 0, 99),
+ OPT_CHOICE_OR_INT("cache-pause", stream_cache_pause, 0,
+ 0, 40, ({"no", -1})),
#endif /* CONFIG_STREAM_CACHE */
{"cdrom-device", &cdrom_device, CONF_TYPE_STRING, 0, 0, 0, NULL},
#ifdef CONFIG_DVDREAD
diff --git a/core/defaultopts.c b/core/defaultopts.c
index 1c179a74a1..9f746b3dc1 100644
--- a/core/defaultopts.c
+++ b/core/defaultopts.c
@@ -32,6 +32,7 @@ void set_default_mplayer_options(struct MPOpts *opts)
.chapter_merge_threshold = 100,
.stream_cache_min_percent = 20.0,
.stream_cache_seek_min_percent = 50.0,
+ .stream_cache_pause = 10.0,
.chapterrange = {-1, -1},
.edition_id = -1,
.user_correct_pts = -1,
diff --git a/core/mp_core.h b/core/mp_core.h
index dac4dd26d0..f633f3481f 100644
--- a/core/mp_core.h
+++ b/core/mp_core.h
@@ -257,6 +257,8 @@ typedef struct MPContext {
// step this many frames, then pause
int step_frames;
+ bool paused_for_cache;
+
// Set after showing warning about decoding being too slow for realtime
// playback rate. Used to avoid showing it multiple times.
bool drop_message_shown;
diff --git a/core/mplayer.c b/core/mplayer.c
index e60c7e173c..04ea0e2597 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -1051,6 +1051,14 @@ static int get_cache_percent(struct MPContext *mpctx)
return -1;
}
+static bool get_cache_idle(struct MPContext *mpctx)
+{
+ int idle = 0;
+ if (mpctx->stream)
+ stream_control(mpctx->stream, STREAM_CTRL_GET_CACHE_IDLE, &idle);
+ return idle;
+}
+
/**
* \brief append a formatted string
* \param buf buffer to print into
@@ -1131,8 +1139,12 @@ static void print_status(struct MPContext *mpctx)
line[0] = '\0';
// Playback status
- if (mpctx->paused)
+ if (mpctx->paused_for_cache) {
+ saddf(line, width, "(Buffering) ");
+ } else if (mpctx->paused) {
saddf(line, width, "(Paused) ");
+ }
+
if (mpctx->sh_audio)
saddf(line, width, "A");
if (mpctx->sh_video)
@@ -1458,8 +1470,15 @@ static void sadd_osd_status(char *buffer, int len, struct MPContext *mpctx,
{
bool fractions = mpctx->opts.osd_fractions;
int sym = mpctx->osd_function;
- if (!sym)
- sym = mpctx->paused || mpctx->step_frames ? OSD_PAUSE : OSD_PLAY;
+ if (!sym) {
+ if (mpctx->paused_for_cache) {
+ sym = OSD_CLOCK;
+ } else if (mpctx->paused || mpctx->step_frames) {
+ sym = OSD_PAUSE;
+ } else {
+ sym = OSD_PLAY;
+ }
+ }
saddf_osd_function_sym(buffer, len, sym);
sadd_hhmmssff(buffer, len, get_current_time(mpctx), fractions);
if (full) {
@@ -2579,6 +2598,7 @@ void unpause_player(struct MPContext *mpctx)
return;
mpctx->paused = 0;
mpctx->osd_function = 0;
+ mpctx->paused_for_cache = false;
if (mpctx->ao && mpctx->sh_audio)
ao_resume(mpctx->ao);
@@ -3070,6 +3090,22 @@ static void update_avsync(struct MPContext *mpctx)
}
}
+static void handle_pause_on_low_cache(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ int cache = get_cache_percent(mpctx);
+ bool idle = 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_pause && !idle) {
+ pause_player(mpctx);
+ mpctx->paused_for_cache = true;
+ }
+ }
+}
+
static void run_playloop(struct MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
@@ -3390,6 +3426,8 @@ static void run_playloop(struct MPContext *mpctx)
//================= Keyboard events, SEEKing ====================
+ handle_pause_on_low_cache(mpctx);
+
mp_cmd_t *cmd;
while ((cmd = mp_input_get_cmd(mpctx->input, 0, 1)) != NULL) {
/* Allow running consecutive seek commands to combine them,
diff --git a/core/options.h b/core/options.h
index 47f4593b9b..2847637bcc 100644
--- a/core/options.h
+++ b/core/options.h
@@ -55,6 +55,7 @@ typedef struct MPOpts {
int stream_cache_size;
float stream_cache_min_percent;
float stream_cache_seek_min_percent;
+ int stream_cache_pause;
int chapterrange[2];
int edition_id;
int correct_pts;
diff --git a/stream/cache2.c b/stream/cache2.c
index 8b35150321..7744f2cba9 100644
--- a/stream/cache2.c
+++ b/stream/cache2.c
@@ -93,6 +93,7 @@ typedef struct {
volatile int control_res;
volatile double stream_time_length;
volatile double stream_time_pos;
+ volatile int idle;
} cache_vars_t;
static void cache_wakeup(stream_t *s)
@@ -420,6 +421,7 @@ static void cache_mainloop(cache_vars_t *s) {
#endif
do {
if (!cache_fill(s)) {
+ s->idle = 1;
#if FORKED_CACHE
// Let signal wake us up, we cannot leave this
// enabled since we do not handle EINTR in most places.
@@ -436,8 +438,10 @@ static void cache_mainloop(cache_vars_t *s) {
sa.sa_handler = SIG_IGN;
sigaction(SIGUSR1, &sa, NULL);
#endif
- } else
+ } else {
sleep_count = 0;
+ s->idle = 0;
+ }
} while (cache_execute_control(s));
}
@@ -624,6 +628,9 @@ int cache_do_control(stream_t *stream, int cmd, void *arg) {
case STREAM_CTRL_GET_CACHE_FILL:
*(int64_t *)arg = s->max_filepos - s->read_filepos;
return STREAM_OK;
+ case STREAM_CTRL_GET_CACHE_IDLE:
+ *(int *)arg = s->idle;
+ return STREAM_OK;
case STREAM_CTRL_SEEK_TO_TIME:
s->control_double_arg = *(double *)arg;
s->control = cmd;
diff --git a/stream/stream.h b/stream/stream.h
index a112b0f3f6..9f2be2f817 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -100,6 +100,7 @@
#define STREAM_CTRL_GET_CURRENT_TITLE 14
#define STREAM_CTRL_GET_CACHE_SIZE 15
#define STREAM_CTRL_GET_CACHE_FILL 16
+#define STREAM_CTRL_GET_CACHE_IDLE 17
struct stream_lang_req {
int type; // STREAM_AUDIO, STREAM_SUB