dmabuf: Limit rate to 30 FPS

pull/40/head
Andri Yngvason 2020-05-03 19:58:50 +00:00
parent f5453ffe1e
commit 4f5933c07f
3 changed files with 56 additions and 2 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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);