diff options
author | Sultan Alsawaf <sultan@kerneltoast.com> | 2022-12-28 22:01:07 -0800 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2022-12-30 10:30:22 +0100 |
commit | eb29aa4839254b9ec7420342da900e0329289547 (patch) | |
tree | 4ed6849b831a50040d877126a5af96c088d2931e /demux | |
parent | b6c98461128e4d9ead56aa42639effb7ac173dca (diff) | |
download | mpv-eb29aa4839254b9ec7420342da900e0329289547.tar.bz2 mpv-eb29aa4839254b9ec7420342da900e0329289547.tar.xz |
demux: add --demuxer-hysteresis-secs option to save power with caching
Buffering ahead nonstop into the cache results in nonstop disk or network
activity to read stream data from wherever it may originate. Currently,
there's no way to configure the demuxer to back off once it's buffered
ahead enough data, since the cache limit will be perpetually not-reached as
a stream continues to play, until the entire stream is eventually buffered.
On a laptop with an i9-12900H with decoding performed by the iGPU,
watching a locally-saved 1080p video which hasn't been buffered into the
page cache consumes approximately 15 W even with caching enabled. When
configuring a hysteresis to make the demuxer back off, power consumption
drops to 9 W when watching the same video, resulting in a whopping 6 W of
power savings.
To make it possible to attain significant power savings via caching, add
a --demuxer-hysteresis-secs option to configure a hysteresis to make the
demuxer back off until there's only the configured number of seconds
remaining in the cache from the current playback position.
This feature is disabled by default.
Diffstat (limited to 'demux')
-rw-r--r-- | demux/demux.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/demux/demux.c b/demux/demux.c index 29b5dccfc7..e1ef65a733 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -91,6 +91,7 @@ struct demux_opts { int64_t max_bytes_bw; int donate_fw; double min_secs; + double hyst_secs; int force_seekable; double min_secs_cache; int access_references; @@ -115,6 +116,7 @@ const struct m_sub_options demux_conf = { {"no", 0}, {"auto", -1}, {"yes", 1})}, {"cache-on-disk", OPT_FLAG(disk_cache)}, {"demuxer-readahead-secs", OPT_DOUBLE(min_secs), M_RANGE(0, DBL_MAX)}, + {"demuxer-hysteresis-secs", OPT_DOUBLE(hyst_secs), M_RANGE(0, DBL_MAX)}, {"demuxer-max-bytes", OPT_BYTE_SIZE(max_bytes), M_RANGE(0, M_MAX_MEM_BYTES)}, {"demuxer-max-back-bytes", OPT_BYTE_SIZE(max_bytes_bw), @@ -210,6 +212,8 @@ struct demux_internal { bool warned_queue_overflow; bool eof; // whether we're in EOF state double min_secs; + double hyst_secs; // stop reading till there's hyst_secs remaining + bool hyst_active; size_t max_bytes; size_t max_bytes_bw; bool seekable_cache; @@ -2205,8 +2209,12 @@ static bool read_packet(struct demux_internal *in) if (ds->eager && ds->queue->last_ts != MP_NOPTS_VALUE && in->min_secs > 0 && ds->base_ts != MP_NOPTS_VALUE && ds->queue->last_ts >= ds->base_ts && - !in->back_demuxing) - prefetch_more |= ds->queue->last_ts - ds->base_ts < in->min_secs; + !in->back_demuxing) { + if (ds->queue->last_ts - ds->base_ts <= in->hyst_secs) + in->hyst_active = false; + if (!in->hyst_active) + prefetch_more |= ds->queue->last_ts - ds->base_ts < in->min_secs; + } total_fw_bytes += get_foward_buffered_bytes(ds); } @@ -2214,8 +2222,10 @@ static bool read_packet(struct demux_internal *in) (size_t)total_fw_bytes, read_more, prefetch_more, refresh_more); if (total_fw_bytes >= in->max_bytes) { // if we hit the limit just by prefetching, simply stop prefetching - if (!read_more) + if (!read_more) { + in->hyst_active = !!in->hyst_secs; return false; + } if (!in->warned_queue_overflow) { in->warned_queue_overflow = true; MP_WARN(in, "Too many packets in the demuxer packet queues:\n"); @@ -2466,6 +2476,7 @@ static void update_opts(struct demux_internal *in) struct demux_opts *opts = in->opts; in->min_secs = opts->min_secs; + in->hyst_secs = opts->hyst_secs; in->max_bytes = opts->max_bytes; in->max_bytes_bw = opts->max_bytes_bw; |