--- a/player/playloop.c 2026-07-10 11:13:19.095396094 +0000 +++ b/player/playloop.c 2026-07-10 11:13:38.244527156 +0000 @@ -34,6 +34,7 @@ #include "common/playlist.h" #include "common/stats.h" #include "demux/demux.h" +#include "demux/packet_pool.h" #include "filters/f_decoder_wrapper.h" #include "filters/filter_internal.h" #include "input/input.h" @@ -1343,6 +1344,24 @@ handle_force_window(mpctx, true); mp_wakeup_core(mpctx); mp_notify(mpctx, MPV_EVENT_IDLE, NULL); + // yauiclient/NextPVR: backport of upstream mpv commit + // 4a815734e3d183dc63fecc08b8f9f8c396c53647 + // ("player/playloop: clear demux packet pool on idle"), + // not yet present in v0.41.0. The packet pool is a global, + // process-wide cache of demux_packet structs kept populated + // across file switches specifically to avoid reallocation + // cost when quickly loading a new file - by design, it is + // NOT cleared on ordinary stop/uninit_demuxer. Confirmed via + // extensive investigation that this pool genuinely holds + // real, substantial memory (thousands of packets at a time + // during playback) that has no other release point once + // idle. This clears it specifically when going idle (no + // file queued, not actively switching), which should not + // affect the fast-reload-same-session optimization this + // pool exists for, since that path never reaches idle_loop + // in the first place. Upstream fixes: + // https://github.com/mpv-player/mpv/issues/17525 + demux_packet_pool_clear(demux_packet_pool_get(mpctx->global)); need_reinit = false; } mp_idle(mpctx);