summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst7
-rw-r--r--demux/demux.c11
2 files changed, 17 insertions, 1 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 4900ccc0e8..ea47fc79b0 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -3204,6 +3204,13 @@ Demuxer
the situation that the forward seek range starts after the current playback
position (as it removes past packets that are seek points).
+ If the end of the file is reached, the remaining unused forward buffer space
+ is "donated" to the backbuffer (unless the backbuffer size is set to 0).
+ This still limits the total cache usage to the sum of the forward and
+ backward cache, and effectively makes better use of the total allowed memory
+ budget. (The opposite does not happen: free backward buffer is never
+ "donated" to the forward buffer.)
+
Keep in mind that other buffers in the player (like decoders) will cause the
demuxer to cache "future" frames in the back buffer, which can skew the
impression about how much data the backbuffer contains.
diff --git a/demux/demux.c b/demux/demux.c
index b7f650bff7..967b5c9310 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -429,6 +429,7 @@ static struct demux_packet *compute_keyframe_times(struct demux_packet *pkt,
static void find_backward_restart_pos(struct demux_stream *ds);
static struct demux_packet *find_seek_target(struct demux_queue *queue,
double pts, int flags);
+static void prune_old_packets(struct demux_internal *in);
static uint64_t get_foward_buffered_bytes(struct demux_stream *ds)
{
@@ -2030,6 +2031,9 @@ static void add_packet_locked(struct sh_stream *stream, demux_packet_t *dp)
adjust_seek_range_on_packet(ds, dp);
+ // May need to reduce backward cache.
+ prune_old_packets(in);
+
// Possibly update duration based on highest TS demuxed (but ignore subs).
if (stream->type != STREAM_SUB) {
if (dp->segmented)
@@ -2192,7 +2196,12 @@ static void prune_old_packets(struct demux_internal *in)
struct demux_stream *ds = in->streams[n]->ds;
fw_bytes += get_foward_buffered_bytes(ds);
}
- if (in->total_bytes - fw_bytes <= max_bytes)
+ uint64_t max_avail = max_bytes;
+ // Backward cache (if enabled at all) can use unused forward cache.
+ // Still leave 1 byte free, so the read_packet logic doesn't get stuck.
+ if (max_avail && in->max_bytes > (fw_bytes + 1))
+ max_avail += in->max_bytes - (fw_bytes + 1);
+ if (in->total_bytes - fw_bytes <= max_avail)
break;
// (Start from least recently used range.)