diff options
-rw-r--r-- | DOCS/man/en/options.rst | 11 | ||||
-rw-r--r-- | core/cfg-mplayer.h | 2 | ||||
-rw-r--r-- | core/defaultopts.c | 1 | ||||
-rw-r--r-- | core/mp_core.h | 2 | ||||
-rw-r--r-- | core/mplayer.c | 44 | ||||
-rw-r--r-- | core/options.h | 1 | ||||
-rw-r--r-- | stream/cache2.c | 9 | ||||
-rw-r--r-- | stream/stream.h | 1 |
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 |