summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/input.rst4
-rw-r--r--player/command.c11
-rw-r--r--player/core.h1
-rw-r--r--player/playloop.c20
4 files changed, 35 insertions, 1 deletions
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 89be9dcaec..301d779850 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -869,6 +869,10 @@ Property list
``paused-for-cache``
Returns ``yes`` when playback is paused because of waiting for the cache.
+``cache-buffering-state``
+ Return the percentage (0-100) of the cache fill status until the player
+ will unpause (related to ``paused-for-cache``).
+
``eof-reached``
Returns ``yes`` if end of playback was reached, ``no`` otherwise. Note
that this is usually interesting only if ``--keep-open`` is enabled,
diff --git a/player/command.c b/player/command.c
index 4b1f37288c..758a62a8d9 100644
--- a/player/command.c
+++ b/player/command.c
@@ -1198,6 +1198,16 @@ static int mp_property_paused_for_cache(void *ctx, struct m_property *prop,
return m_property_flag_ro(action, arg, mpctx->paused_for_cache);
}
+static int mp_property_cache_buffering(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ MPContext *mpctx = ctx;
+ double state = get_cache_buffering_percentage(mpctx);
+ if (state < 0)
+ return M_PROPERTY_UNAVAILABLE;
+ return m_property_int_ro(action, arg, state * 100);
+}
+
static int mp_property_clock(void *ctx, struct m_property *prop,
int action, void *arg)
{
@@ -2757,6 +2767,7 @@ static const struct m_property mp_properties[] = {
{"cache-idle", mp_property_cache_idle},
{"demuxer-cache-duration", mp_property_demuxer_cache_duration},
{"demuxer-cache-idle", mp_property_demuxer_cache_idle},
+ {"cache-buffering-state", mp_property_cache_buffering},
{"paused-for-cache", mp_property_paused_for_cache},
{"pts-association-mode", mp_property_generic_option},
{"hr-seek", mp_property_generic_option},
diff --git a/player/core.h b/player/core.h
index 390f8da7b8..d25322ecd1 100644
--- a/player/core.h
+++ b/player/core.h
@@ -455,6 +455,7 @@ char *chapter_display_name(struct MPContext *mpctx, int chapter);
char *chapter_name(struct MPContext *mpctx, int chapter);
double chapter_start_time(struct MPContext *mpctx, int chapter);
int get_chapter_count(struct MPContext *mpctx);
+double get_cache_buffering_percentage(struct MPContext *mpctx);
void execute_queued_seek(struct MPContext *mpctx);
void run_playloop(struct MPContext *mpctx);
void mp_idle(struct MPContext *mpctx);
diff --git a/player/playloop.c b/player/playloop.c
index 5d9abf923d..c54554d049 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -155,6 +155,7 @@ void reset_playback_state(struct MPContext *mpctx)
mpctx->last_seek_pts = MP_NOPTS_VALUE;
mpctx->cache_wait_time = 0;
mpctx->restart_complete = false;
+ mpctx->paused_for_cache = false;
#if HAVE_ENCODING
encode_lavc_discontinuity(mpctx->encode_lavc_ctx);
@@ -557,7 +558,6 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
if (mpctx->restart_complete && idle != -1) {
if (mpctx->paused && mpctx->paused_for_cache) {
- mpctx->cache_wait_time = MPCLAMP(mpctx->cache_wait_time, 1, 10);
if (!opts->cache_pausing || s.ts_duration >= mpctx->cache_wait_time
|| s.idle)
{
@@ -570,6 +570,7 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
mpctx->paused_for_cache = false;
if (!opts->pause)
unpause_player(mpctx);
+ mp_notify(mpctx, MP_EVENT_CACHE_UPDATE, NULL);
}
mpctx->sleeptime = MPMIN(mpctx->sleeptime, 0.2);
} else {
@@ -579,8 +580,10 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
mpctx->paused_for_cache = true;
opts->pause = prev_paused_user;
mpctx->cache_stop_time = mp_time_sec();
+ mp_notify(mpctx, MP_EVENT_CACHE_UPDATE, NULL);
}
}
+ mpctx->cache_wait_time = MPCLAMP(mpctx->cache_wait_time, 1, 10);
}
// Also update cache properties.
@@ -602,6 +605,21 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
}
}
+double get_cache_buffering_percentage(struct MPContext *mpctx)
+{
+ struct demux_ctrl_reader_state s = {.idle = true, .ts_duration = -1};
+ if (mpctx->demuxer && mpctx->paused_for_cache && mpctx->cache_wait_time > 0) {
+ demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s);
+ if (s.ts_duration < 0)
+ s.ts_duration = 0;
+
+ return MPCLAMP(s.ts_duration / mpctx->cache_wait_time, 0.0, 1.0);
+ }
+ if (mpctx->demuxer && !mpctx->paused_for_cache)
+ return 1.0;
+ return -1;
+}
+
static void handle_heartbeat_cmd(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;