Test queued capture gaps without dropping frames or delaying ready video

This commit is contained in:
evgeny committed 2026-10-19 18:23:25 +02:00
1 parent 9bffe49e62
commit 526ee5ec8b
2 files changed
+29 -4

No files matched your search

+28 -3
View File
@@ -14,7 +14,7 @@ static void simulate(unsigned pause_ms, int cpu, int64_t quantum, int accelerate
int64_t arrival = origin + i * 33333ll;
if (!cpu && arrival >= origin + 1000000 && arrival < origin + 1000000 + pause_ms * 1000ll)
arrival = origin + 1000000 + pause_ms * 1000ll;
frames[i] = (struct call_video_playout_frame){origin + i * 33333ll, arrival};
frames[i] = (struct call_video_playout_frame){origin + i * 33333ll, arrival, 33333};
}
unsigned shown = 0, accelerated = 0;
int64_t last_show = 0, recovered_lag = INT64_MAX, audio_pts = origin - (accelerated_audio ? 150000 : 0);
@@ -44,7 +44,7 @@ static void simulate(unsigned pause_ms, int cpu, int64_t quantum, int accelerate
static void order_and_clock(void) {
struct call_video_playout p; call_video_playout_init(&p, 9);
struct call_video_playout_frame f = {origin, origin};
struct call_video_playout_frame f = {origin, origin, 33333};
struct call_clock_snapshot audio = {.pts_us = origin, .rate_ppm = 1000000};
CHECK(call_video_playout_poll(&p, &f, NULL, origin, &audio) == CALL_VIDEO_PLAYOUT_WAIT);
audio.valid = 1;
@@ -57,6 +57,31 @@ static void order_and_clock(void) {
CHECK(call_video_playout_poll(&p, &f, NULL, origin + 200000, &audio) == CALL_VIDEO_PLAYOUT_SHOW);
}
/* Готовые кадры могут разделяться паузой raw capture, пока decoder lookahead не пустел. */
static void queued_capture_gap(void) {
const int64_t gaps[] = {500000, 2264933, 10000000};
const unsigned fps[] = {15, 30, 60};
for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j < 3; ++j) {
struct call_video_playout p; call_video_playout_init(&p, 11);
unsigned interval = 1000000 / fps[j];
struct call_video_playout_frame first = {origin, origin, interval}, next = {origin + gaps[i], origin, interval};
struct call_clock_snapshot audio = {.pts_us = next.pts_us + 1000000, .valid = 1, .rate_ppm = 1000000};
CHECK(call_video_playout_poll(&p, &first, &next, origin, &audio) == CALL_VIDEO_PLAYOUT_SHOW);
CHECK(call_video_playout_poll(&p, &next, NULL, origin, &audio) == CALL_VIDEO_PLAYOUT_WAIT);
CHECK(call_video_playout_poll(&p, &next, NULL, origin + interval, &audio) == CALL_VIDEO_PLAYOUT_SHOW);
CHECK(p.last_pts == next.pts_us && p.source_gaps == 1);
}
struct call_video_playout p; call_video_playout_init(&p, 12);
struct call_video_playout_frame f = {origin, origin, 33333};
struct call_clock_snapshot audio = {.pts_us = origin, .valid = 1, .rate_ppm = 1000000};
CHECK(call_video_playout_poll(&p, &f, NULL, origin, &audio) == CALL_VIDEO_PLAYOUT_SHOW);
f.pts_us += 2000000;
CHECK(call_video_playout_poll(&p, &f, NULL, origin + 33333, &audio) == CALL_VIDEO_PLAYOUT_WAIT);
audio.pts_us = f.pts_us - 40000;
CHECK(call_video_playout_poll(&p, &f, NULL, origin + 50000, &audio) == CALL_VIDEO_PLAYOUT_SHOW);
DEBUG_INFO(DEBUG_CATEGORY_CALL, "PASS queued capture gaps: 0.5/2.265/10s at 15/30/60fps, no repeated wait, no audio lead violation");
}
int main(void) {
debug_config_init(); debug_set_level(DEBUG_LEVEL_INFO);
const unsigned pauses[] = {50, 100, 200, 500};
@@ -65,5 +90,5 @@ int main(void) {
simulate(pauses[i], cpu, 1000, 0);
simulate(pauses[i], cpu, 15625, 1);
}
order_and_clock(); return 0;
order_and_clock(); queued_capture_gap(); return 0;
}
+1 -1
View File
@@ -365,7 +365,7 @@ void CallVideoEngine::receive() {
const int64_t decodedAt = nowUs();
++decoded; decodeMax = std::max(decodeMax, decodedAt - decodeStarted);
rxAgeMax = std::max(rxAgeMax, decodedAt - packet.received_us);
pictures.push_back({{packet.pts_us, packet.received_us}, image});
pictures.push_back({{packet.pts_us, packet.received_us, 1000000u / packet.format.fps}, image});
if (packet.pts_us % 1000000 < 34000)
DEBUG_DEBUG(DEBUG_CATEGORY_CALL,
"video timing stage=decode call=%llu frame=%llu pts=%lld mono_us=%lld decode_us=%lld rx_age_us=%lld queue=%zu",