feat: retain streaming media and add opt-in automatic quality

This commit is contained in:
2026-10-11 11:17:41 +02:00
parent 041d2b0644
commit 13554a1574
12 changed files with 921 additions and 164 deletions
+47 -22
View File
@@ -33,8 +33,8 @@ static void validBuffer(PlayerState state) {
require(std::isfinite(state.duration) && state.duration > 0 &&
state.buffered_start >= 0 && buffered(state) && state.buffered_end <= state.duration,
"retained range is nonempty and bounded by finite media duration");
require(std::abs(state.buffered_start - state.position) < .00001,
"retained range follows the authoritative playback position, not a loaded prefix");
require(state.buffered_start <= state.position && state.position <= state.buffered_end,
"the retained interval covers the current playhead");
}
// Only these deadlines use elapsed time: a stuck command/read must fail the check,
@@ -330,20 +330,46 @@ static void prefixBound(PlayerState state, GateState gate, bool splitAudio = fal
"retained coverage cannot bridge withheld audio/video packets or reordered B-frames");
}
static void bufferCoverage(Player *player, const std::string &base) {
require(openNetwork(player, base, "/media/streaming.mp4", "", 30),
"open long network fixture for bounded retained coverage");
auto initial = until(player, [](auto s) { return s.status == PLAYER_PAUSED && buffered(s); },
"paused network source exposes actual retained media");
require(initial.buffered_end < initial.duration,
"bounded queues do not report an entire downloaded movie as retained");
require(player_play(player), "play to advance retained network coverage");
until(player, [=](auto s) {
return s.status == PLAYER_PLAYING && s.position > initial.buffered_end && buffered(s) &&
s.buffered_end > initial.buffered_end;
}, "retained horizon advances with real playback and refills");
require(player_close(player), "close advancing buffered source");
static void cachedWindow(Player *player, const std::string &base) {
const std::string token = "cached-window";
require(openNetwork(player, base, "/stall/" + token + "/cache.mp4?after_seconds=100", "", 120),
"open a two-minute source with a controlled future network stall");
auto initial = until(player, [](auto s) {
return s.status == PLAYER_PAUSED && buffered(s) && s.buffered_end >= 59;
}, "paused playback prefetches a minute without waiting to start");
require(initial.buffered_end < 65, "read-ahead is time-bounded rather than a full download");
seekCompleted(player, 50, PLAYER_PAUSED);
auto retained = until(player, [&](auto s) {
return s.status == PLAYER_PAUSED && buffered(s) && s.buffered_end > 95 &&
gateState(base, token).entered;
}, "cache follows a new playhead until the future network gate");
require(retained.position - retained.buffered_start >= 29,
"a reusable thirty-second rewind window survives forward playback");
require(retained.buffered_start > 15, "old media is evicted instead of caching the whole movie");
const auto before = gateState(base, token);
auto rewind = seekCompleted(player, 20.5, PLAYER_PAUSED);
require(buffered(rewind), "cached rewind preserves the retained interval");
auto after = gateState(base, token);
require(after.requests == before.requests && after.ranges == before.ranges,
"rewinding within history makes no new HTTP request");
stillBlocked(base, token);
seekCompleted(player, 45, PLAYER_PAUSED);
after = gateState(base, token);
require(after.requests == before.requests && after.ranges == before.ranges,
"forward seeking inside retained media makes no new HTTP request");
stillBlocked(base, token);
seekCompleted(player, 5, PLAYER_PAUSED);
until(player, [&](auto s) {
return s.status == PLAYER_PAUSED && buffered(s) && s.buffered_end > 6 &&
gateState(base, token).requests > before.requests;
}, "seeking before retained history refills missing media over HTTP");
require(player_close(player), "close cache while the original future response remains blocked");
closed(player);
stillBlocked(base, token);
std::puts("PASS sliding cache: minute read-ahead/thirty-second history/keyframe replay/cached bidirectional seeks/miss refill/cancel");
}
static void bufferCoverage(Player *player, const std::string &base) {
const std::string token = "buffer-release";
require(openNetwork(player, base, "/stall/" + token + "/streaming.mp4", "", 30),
@@ -373,7 +399,7 @@ static void bufferCoverage(Player *player, const std::string &base) {
}, "released server gate advances retained coverage beyond withheld timestamps");
require(player_close(player), "close released buffered source");
closed(player);
std::puts("PASS retained coverage: bounded queues/advancing clock/stalled timestamp bounds/B-frame dependencies/gate-release refill");
std::puts("PASS retained coverage: supplied timestamp bounds/B-frame dependencies/gate-release refill");
}
static void blockedPlayback(Player *player, const std::string &base, const std::string &token,
@@ -421,19 +447,17 @@ static void cancellation(Player *player, const std::string &base, const std::str
until(player, [](auto s) { return s.status == PLAYER_PAUSED && buffered(s); },
"retain high-timestamp media before invalidating it");
seekCompleted(player, .5, PLAYER_PAUSED);
auto rewound = until(player, [](auto s) {
until(player, [](auto s) {
return s.status == PLAYER_PAUSED && !s.seek_pending && buffered(s);
}, "backward seek rebuilds retained coverage at the new target");
require(rewound.buffered_end < 28,
"backward seek drops the old high-water horizon instead of retaining distant media");
stillBlocked(base, token);
require(player_close(player), "close resumed formerly stalled source");
closed(player);
std::puts(splitAudio
? "PASS stalled secondary audio: required-track bound/seek invalidation/new-target coverage/backward high-water clearing"
? "PASS stalled secondary audio: required-track bound/seek acknowledgement/new-target coverage/backward refill"
: splitVideo
? "PASS stalled primary video: required-track bound/seek invalidation/new-target coverage/backward high-water clearing"
: "PASS stalled combined input: bounded prefix/pause/seek invalidation/new-target coverage/backward high-water clearing");
? "PASS stalled primary video: required-track bound/seek acknowledgement/new-target coverage/backward refill"
: "PASS stalled combined input: bounded prefix/pause/seek acknowledgement/new-target coverage/backward refill");
}
blockedOpening(player, base, "opening-close");
@@ -515,6 +539,7 @@ int main(int argc, char **argv) {
frameSteps(player.get(), view, base);
nativeHLS(player.get(), view, base);
liveAndReplacement(player.get(), base, fixtures);
cachedWindow(player.get(), base);
bufferCoverage(player.get(), base);
cancellation(player.get(), base, fixtures);
failures(player.get(), base);