perf: prioritize audio preroll after paused network previews
This commit is contained in:
@@ -133,7 +133,9 @@ static bool uncached(PlayerState state, double target) {
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
@autoreleasepool {
|
||||
require(argc == 3, "usage: playback-benchmark <loopback-base-url> <split|hls>");
|
||||
require(argc == 3 || (argc == 4 && std::string(argv[3]) == "--seek-work"),
|
||||
"usage: playback-benchmark <loopback-base-url> <split|hls> [--seek-work]");
|
||||
const bool seekWork = argc == 4;
|
||||
const std::string base = argv[1], mode = argv[2];
|
||||
require(base.rfind("http://127.0.0.1:", 0) == 0 && base.size() > 17 && base.size() <= 22 &&
|
||||
base.find_first_not_of("0123456789", 17) == std::string::npos &&
|
||||
@@ -185,48 +187,57 @@ int main(int argc, char **argv) {
|
||||
@"probe_media_seconds": @(state.position), @"render_width": @1280, @"render_height": @720});
|
||||
|
||||
constexpr double hitTarget = 20.5, missTarget = 100.5;
|
||||
// Waiting for retained packet coverage is preparation, not seek latency.
|
||||
until(player.get(), [](auto s) { return cached(s, hitTarget); }, "cached target coverage");
|
||||
begin(@"cached_seek");
|
||||
auto before = player_get_state(player.get());
|
||||
require(cached(before, hitTarget), "cached seek target and GOP must remain inside retained coverage");
|
||||
const auto hitStart = stamp();
|
||||
state = seek(player.get(), hitTarget, "cached paused decoded seek");
|
||||
[view draw];
|
||||
const auto hitEnd = stamp();
|
||||
finish(@"cached_seek", hitStart, hitEnd, state,
|
||||
@{@"target_seconds": @(hitTarget), @"cache_before_start": @(before.buffered_start),
|
||||
@"cache_before_end": @(before.buffered_end), @"cache_precondition": @"retained_packet_hit"});
|
||||
auto before = state;
|
||||
if (seekWork) {
|
||||
// Preparation is outside the measured phase. Seek directly from the
|
||||
// opening paused position, without the cached seek or paced playback.
|
||||
until(player.get(), [](auto s) {
|
||||
return pausedReady(s) && s.buffered_end >= 59;
|
||||
}, "initial read-ahead coverage");
|
||||
} else {
|
||||
// Waiting for retained packet coverage is preparation, not seek latency.
|
||||
until(player.get(), [](auto s) { return cached(s, hitTarget); }, "cached target coverage");
|
||||
begin(@"cached_seek");
|
||||
before = player_get_state(player.get());
|
||||
require(cached(before, hitTarget), "cached seek target and GOP must remain inside retained coverage");
|
||||
const auto hitStart = stamp();
|
||||
state = seek(player.get(), hitTarget, "cached paused decoded seek");
|
||||
[view draw];
|
||||
const auto hitEnd = stamp();
|
||||
finish(@"cached_seek", hitStart, hitEnd, state,
|
||||
@{@"target_seconds": @(hitTarget), @"cache_before_start": @(before.buffered_start),
|
||||
@"cache_before_end": @(before.buffered_end), @"cache_precondition": @"retained_packet_hit"});
|
||||
|
||||
// Sustained is real paced playback from the cached seek, including
|
||||
// moving-frontier read-ahead, start and final pause acknowledgement.
|
||||
// Position is the actual native audio-master clock. Only watchdogs impose
|
||||
// elapsed-time limits; the completion condition is twelve media seconds.
|
||||
begin(@"sustained");
|
||||
before = player_get_state(player.get());
|
||||
require(pausedReady(before) && std::abs(before.position - hitTarget) < .05 &&
|
||||
before.duration > before.position + 12, "sustained starts at acknowledged cached target");
|
||||
const auto sustainedStart = stamp();
|
||||
auto previousPoll = sustainedStart.wall;
|
||||
bool wasBuffering = true;
|
||||
double bufferingMilliseconds = 0;
|
||||
require(player_play(player.get()), "start paced sustained playback");
|
||||
state = until(player.get(), [&](auto s) {
|
||||
const auto now = Clock::now();
|
||||
if (wasBuffering)
|
||||
bufferingMilliseconds += std::chrono::duration<double, std::milli>(now - previousPoll).count();
|
||||
previousPoll = now;
|
||||
wasBuffering = s.buffering;
|
||||
return s.status == PLAYER_PLAYING && !s.seek_pending && !s.buffering &&
|
||||
s.position >= before.position + 12;
|
||||
}, "twelve media seconds of native playback", view);
|
||||
require(player_pause(player.get()), "pause sustained playback");
|
||||
state = until(player.get(), pausedReady, "sustained pause acknowledgement", view);
|
||||
const auto sustainedEnd = stamp();
|
||||
finish(@"sustained", sustainedStart, sustainedEnd, state,
|
||||
@{@"media_seconds": @(state.position - before.position), @"paced": @YES,
|
||||
@"start_position_seconds": @(before.position), @"buffering_ms": @(bufferingMilliseconds),
|
||||
@"buffering_measurement": @"sampled_at_approximately_1ms"});
|
||||
// Sustained is real paced playback from the cached seek, including
|
||||
// moving-frontier read-ahead, start and final pause acknowledgement.
|
||||
// Position is the actual native audio-master clock. Only watchdogs impose
|
||||
// elapsed-time limits; the completion condition is twelve media seconds.
|
||||
begin(@"sustained");
|
||||
before = player_get_state(player.get());
|
||||
require(pausedReady(before) && std::abs(before.position - hitTarget) < .05 &&
|
||||
before.duration > before.position + 12, "sustained starts at acknowledged cached target");
|
||||
const auto sustainedStart = stamp();
|
||||
auto previousPoll = sustainedStart.wall;
|
||||
bool wasBuffering = true;
|
||||
double bufferingMilliseconds = 0;
|
||||
require(player_play(player.get()), "start paced sustained playback");
|
||||
state = until(player.get(), [&](auto s) {
|
||||
const auto now = Clock::now();
|
||||
if (wasBuffering)
|
||||
bufferingMilliseconds += std::chrono::duration<double, std::milli>(now - previousPoll).count();
|
||||
previousPoll = now;
|
||||
wasBuffering = s.buffering;
|
||||
return s.status == PLAYER_PLAYING && !s.seek_pending && !s.buffering &&
|
||||
s.position >= before.position + 12;
|
||||
}, "twelve media seconds of native playback", view);
|
||||
require(player_pause(player.get()), "pause sustained playback");
|
||||
state = until(player.get(), pausedReady, "sustained pause acknowledgement", view);
|
||||
const auto sustainedEnd = stamp();
|
||||
finish(@"sustained", sustainedStart, sustainedEnd, state,
|
||||
@{@"media_seconds": @(state.position - before.position), @"paced": @YES,
|
||||
@"start_position_seconds": @(before.position), @"buffering_ms": @(bufferingMilliseconds),
|
||||
@"buffering_measurement": @"sampled_at_approximately_1ms"});
|
||||
}
|
||||
|
||||
begin(@"uncached_seek");
|
||||
before = player_get_state(player.get());
|
||||
|
||||
Reference in New Issue
Block a user