diff --git a/src/call/call_video_playout.c b/src/call/call_video_playout.c index 0803b810..88cf2104 100644 --- a/src/call/call_video_playout.c +++ b/src/call/call_video_playout.c @@ -50,6 +50,11 @@ void call_video_playout_log_event(const struct call_video_playout_event *event) (unsigned long long)p->call_id, (long long)f->pts_us, (long long)p->pending.pts_us, p->awaiting, (long long)now, (long long)p->selected_us); return; } + if (event->kind == CALL_VIDEO_LOG_RECOVERY) { + DEBUG_INFO(DEBUG_CATEGORY_CALL, "video display catchup call=%llu lag_us=%lld recovered_us=%lld window_us=%lld queued=%u reserve=%u; decoded presentation only", + (unsigned long long)p->call_id, (long long)-p->pending_av, (long long)(p->recovery_lag + p->pending_av), + (long long)(now - p->recovery_us), p->queued, p->reserve); return; + } DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "video playout call=%llu interval_us=%lld shown=%u speed_ppm=%u drop_order=%u drop_display=%u " "cadence_us=%lld..%lld gap_pts_us=%lld gap_rx_us=%lld gap_dispatch_us=%lld " @@ -112,10 +117,12 @@ enum call_video_playout_action call_video_playout_poll(struct call_video_playout // (например, вход 60 fps и экран 60 Hz). Небольшие паузы сохраняют все кадры. if (-av <= working_lag || queued <= target_frames + 1) { p->recovery_us = 0; p->skipping = 0; - } else if (-av > working_lag + 100000) { + } else { if (!p->recovery_us) { p->recovery_us = now; p->recovery_lag = -av; } else if (now - p->recovery_us >= 500000) { - if (p->recovery_lag + av < f->interval_us / 4) p->skipping = 1; + if (p->recovery_lag + av < f->interval_us / 4 && !p->skipping) { + p->skipping = 1; p->pending_av = av; log_event(p, CALL_VIDEO_LOG_RECOVERY, f, now); + } p->recovery_us = now; p->recovery_lag = -av; } } diff --git a/src/call/call_video_playout.h b/src/call/call_video_playout.h index 18892138..e2e4b01e 100644 --- a/src/call/call_video_playout.h +++ b/src/call/call_video_playout.h @@ -43,7 +43,7 @@ struct call_video_playout { void *log_arg; }; enum call_video_playout_event_kind { - CALL_VIDEO_LOG_REPORT, CALL_VIDEO_LOG_CLOCK, CALL_VIDEO_LOG_ORDER, CALL_VIDEO_LOG_GAP, CALL_VIDEO_LOG_ACK + CALL_VIDEO_LOG_REPORT, CALL_VIDEO_LOG_CLOCK, CALL_VIDEO_LOG_ORDER, CALL_VIDEO_LOG_GAP, CALL_VIDEO_LOG_ACK, CALL_VIDEO_LOG_RECOVERY }; struct call_video_playout_event { enum call_video_playout_event_kind kind; diff --git a/tests/test_call_video_playout.c b/tests/test_call_video_playout.c index dc38de7d..5f8d41b9 100644 --- a/tests/test_call_video_playout.c +++ b/tests/test_call_video_playout.c @@ -44,7 +44,7 @@ static void simulate(unsigned pause_ms, int cpu, int64_t quantum, int accelerate DEBUG_INFO(DEBUG_CATEGORY_CALL, "presentation recovery pause_ms=%u cpu=%d quantum_us=%lld audio_fast=%d shown=%u skipped=%u total=%u lag_us=%lld", pause_ms, cpu, (long long)quantum, accelerated_audio, shown, skipped, COUNT, (long long)recovered_lag); CHECK(shown + skipped == COUNT && accelerated); - if (quantum < 2000 || pause_ms <= 100) CHECK(skipped == 0); + if (quantum < 2000) CHECK(skipped == 0); // При достаточной частоте показа ускорение сохраняет все кадры. CHECK(recovered_lag < (quantum < 2000 ? 100000 : 220000)); } @@ -163,8 +163,8 @@ static void limited_display(unsigned pause_ms) { DEBUG_INFO(DEBUG_CATEGORY_CALL, "60Hz recovery pause_ms=%u decoded=%u shown=%u skipped=%u lag_us=%lld", pause_ms, consumed, shown, skipped, (long long)recovered); CHECK(consumed == COUNT && shown + skipped == COUNT); - if (pause_ms <= 100) CHECK(skipped == 0); - else CHECK(skipped > 0 && recovered < 180000); + if (!pause_ms) CHECK(skipped == 0); + else CHECK(skipped > 0 && recovered < 130000); } int main(void) { @@ -176,5 +176,5 @@ int main(void) { simulate(pauses[i], cpu, 15625, 1); } presentation_deadline(); queued_capture_gap(); slowing_with_queue(); render_latency_change(); - limited_display(50); limited_display(100); limited_display(500); return 0; + limited_display(0); limited_display(50); limited_display(100); limited_display(500); return 0; }