From 4f5933c07fd38e15045bfb2c383a4049172076d6 Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Sun, 3 May 2020 19:58:50 +0000 Subject: [PATCH] dmabuf: Limit rate to 30 FPS --- include/dmabuf.h | 4 ++++ src/dmabuf.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++- src/main.c | 5 ++++- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/include/dmabuf.h b/include/dmabuf.h index b70c228..e3c320f 100644 --- a/include/dmabuf.h +++ b/include/dmabuf.h @@ -50,6 +50,10 @@ struct dmabuf_capture { struct zwlr_export_dmabuf_frame_v1* zwlr_frame; struct dmabuf_frame frame; uint64_t render_finish_time; + uint64_t start_time; + + struct aml_timer* timer; }; void dmabuf_capture_init(struct dmabuf_capture* self); +void dmabuf_capture_destroy(struct dmabuf_capture* self); diff --git a/src/dmabuf.c b/src/dmabuf.c index f9b932c..9ffd76a 100644 --- a/src/dmabuf.c +++ b/src/dmabuf.c @@ -29,8 +29,14 @@ #include "render.h" #include "usdt.h" +#define RATE_LIMIT 30.0 +#define MIN_PERIOD ((uint64_t)(1000.0 / RATE_LIMIT)) + #define PROCESSING_DURATION_LIMIT 16 /* ms */ +static int dmabuf_capture_start_now(struct frame_capture* fc, + enum frame_capture_options options); + static void dmabuf_close_fds(struct dmabuf_capture* self) { for (size_t i = 0; i < self->frame.n_planes; ++i) @@ -43,6 +49,8 @@ static void dmabuf_capture_stop(struct frame_capture* fc) { struct dmabuf_capture* self = (void*)fc; + aml_stop(aml_get_default(), self->timer); + fc->status = CAPTURE_STOPPED; if (self->zwlr_frame) { @@ -150,11 +158,41 @@ static void dmabuf_frame_cancel(void* data, dmabuf_close_fds(self); } +static void dmabuf__poll(void* obj) +{ + struct dmabuf_capture* self = aml_get_userdata(obj); + struct frame_capture* fc = (struct frame_capture*)self; + + dmabuf_capture_start_now(fc, 0); +} + static int dmabuf_capture_start(struct frame_capture* fc, enum frame_capture_options options) { struct dmabuf_capture* self = (void*)fc; + if (fc->status == CAPTURE_IN_PROGRESS) + return -1; + + uint64_t now = gettime_ms(); + uint64_t dt = now - self->start_time; + + fc->status = CAPTURE_IN_PROGRESS; + + if (dt < MIN_PERIOD) { + uint64_t time_left = MIN_PERIOD - dt; + aml_set_duration(self->timer, time_left); + return aml_start(aml_get_default(), self->timer); + } + + return dmabuf_capture_start_now(fc, options); +} + +static int dmabuf_capture_start_now(struct frame_capture* fc, + enum frame_capture_options options) +{ + struct dmabuf_capture* self = (void*)fc; + static const struct zwlr_export_dmabuf_frame_v1_listener dmabuf_frame_listener = { .frame = dmabuf_frame_start, @@ -172,7 +210,7 @@ static int dmabuf_capture_start(struct frame_capture* fc, if (!self->zwlr_frame) return -1; - fc->status = CAPTURE_IN_PROGRESS; + self->start_time = gettime_ms(); zwlr_export_dmabuf_frame_v1_add_listener(self->zwlr_frame, &dmabuf_frame_listener, self); @@ -190,7 +228,16 @@ static void dmabuf_capture_render(struct frame_capture* fc, void dmabuf_capture_init(struct dmabuf_capture* self) { + self->timer = aml_timer_new(0, dmabuf__poll, self, NULL); + assert(self->timer); + self->fc.backend.start = dmabuf_capture_start; self->fc.backend.stop = dmabuf_capture_stop; self->fc.backend.render = dmabuf_capture_render; } + +void dmabuf_capture_destroy(struct dmabuf_capture* self) +{ + aml_stop(aml_get_default(), self->timer); + aml_unref(self->timer); +} diff --git a/src/main.c b/src/main.c index d2b4809..3f4bd5d 100644 --- a/src/main.c +++ b/src/main.c @@ -885,7 +885,10 @@ int main(int argc, char* argv[]) nvnc_display_unref(self.nvnc_display); nvnc_close(self.nvnc); renderer_destroy(&self.renderer); - screencopy_destroy(&self.screencopy_backend); + if (self.screencopy_backend.manager) + screencopy_destroy(&self.screencopy_backend); + if (self.dmabuf_backend.manager) + dmabuf_capture_destroy(&self.dmabuf_backend); wayvnc_destroy(&self); aml_unref(aml);