From 1534a6a17eef9cbb20ba2e368f52ded5bdcaf330 Mon Sep 17 00:00:00 2001 From: columbarius Date: Tue, 6 Jul 2021 15:05:12 +0200 Subject: [PATCH] screencast: only end the fps measurement when it was started before Sometimes it can happen that the first frame of the active stream triggers the renegotiation and destroy the frame without copy and with that starting the fps_limit counter. This triggers an assert in fps_limit_measure_end. To avoid it, we only engage the fps_limiter after a frame was copied successfully. --- include/screencast_common.h | 1 + src/screencast/wlr_screencast.c | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/screencast_common.h b/include/screencast_common.h index 2528d2b..f2ed4a0 100644 --- a/include/screencast_common.h +++ b/include/screencast_common.h @@ -108,6 +108,7 @@ struct xdpw_screencast_instance { bool with_cursor; int err; bool quit; + bool copied; // fps limit struct fps_limit_state fps_limit; diff --git a/src/screencast/wlr_screencast.c b/src/screencast/wlr_screencast.c index 1437fc6..567d373 100644 --- a/src/screencast/wlr_screencast.c +++ b/src/screencast/wlr_screencast.c @@ -34,10 +34,15 @@ void xdpw_wlr_frame_free(struct xdpw_screencast_instance *cast) { } if (cast->pwr_stream_state) { - uint64_t delay_ns = fps_limit_measure_end(&cast->fps_limit, cast->framerate); - if (delay_ns > 0) { - xdpw_add_timer(cast->ctx->state, delay_ns, - (xdpw_event_loop_timer_func_t) xdpw_wlr_register_cb, cast); + if (cast->copied) { + uint64_t delay_ns = fps_limit_measure_end(&cast->fps_limit, cast->framerate); + cast->copied = false; + if (delay_ns > 0) { + xdpw_add_timer(cast->ctx->state, delay_ns, + (xdpw_event_loop_timer_func_t) xdpw_wlr_register_cb, cast); + } else { + xdpw_wlr_register_cb(cast); + } } else { xdpw_wlr_register_cb(cast); } @@ -134,6 +139,7 @@ static void wlr_frame_ready(void *data, struct zwlr_screencopy_frame_v1 *frame, cast->current_frame.tv_sec = ((((uint64_t)tv_sec_hi) << 32) | tv_sec_lo); cast->current_frame.tv_nsec = tv_nsec; + cast->copied = true; xdpw_pwr_enqueue_buffer(cast);