dmabuf: Limit rate to 30 FPS
parent
f5453ffe1e
commit
4f5933c07f
|
@ -50,6 +50,10 @@ struct dmabuf_capture {
|
||||||
struct zwlr_export_dmabuf_frame_v1* zwlr_frame;
|
struct zwlr_export_dmabuf_frame_v1* zwlr_frame;
|
||||||
struct dmabuf_frame frame;
|
struct dmabuf_frame frame;
|
||||||
uint64_t render_finish_time;
|
uint64_t render_finish_time;
|
||||||
|
uint64_t start_time;
|
||||||
|
|
||||||
|
struct aml_timer* timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
void dmabuf_capture_init(struct dmabuf_capture* self);
|
void dmabuf_capture_init(struct dmabuf_capture* self);
|
||||||
|
void dmabuf_capture_destroy(struct dmabuf_capture* self);
|
||||||
|
|
49
src/dmabuf.c
49
src/dmabuf.c
|
@ -29,8 +29,14 @@
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "usdt.h"
|
#include "usdt.h"
|
||||||
|
|
||||||
|
#define RATE_LIMIT 30.0
|
||||||
|
#define MIN_PERIOD ((uint64_t)(1000.0 / RATE_LIMIT))
|
||||||
|
|
||||||
#define PROCESSING_DURATION_LIMIT 16 /* ms */
|
#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)
|
static void dmabuf_close_fds(struct dmabuf_capture* self)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < self->frame.n_planes; ++i)
|
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;
|
struct dmabuf_capture* self = (void*)fc;
|
||||||
|
|
||||||
|
aml_stop(aml_get_default(), self->timer);
|
||||||
|
|
||||||
fc->status = CAPTURE_STOPPED;
|
fc->status = CAPTURE_STOPPED;
|
||||||
|
|
||||||
if (self->zwlr_frame) {
|
if (self->zwlr_frame) {
|
||||||
|
@ -150,11 +158,41 @@ static void dmabuf_frame_cancel(void* data,
|
||||||
dmabuf_close_fds(self);
|
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,
|
static int dmabuf_capture_start(struct frame_capture* fc,
|
||||||
enum frame_capture_options options)
|
enum frame_capture_options options)
|
||||||
{
|
{
|
||||||
struct dmabuf_capture* self = (void*)fc;
|
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
|
static const struct zwlr_export_dmabuf_frame_v1_listener
|
||||||
dmabuf_frame_listener = {
|
dmabuf_frame_listener = {
|
||||||
.frame = dmabuf_frame_start,
|
.frame = dmabuf_frame_start,
|
||||||
|
@ -172,7 +210,7 @@ static int dmabuf_capture_start(struct frame_capture* fc,
|
||||||
if (!self->zwlr_frame)
|
if (!self->zwlr_frame)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
fc->status = CAPTURE_IN_PROGRESS;
|
self->start_time = gettime_ms();
|
||||||
|
|
||||||
zwlr_export_dmabuf_frame_v1_add_listener(self->zwlr_frame,
|
zwlr_export_dmabuf_frame_v1_add_listener(self->zwlr_frame,
|
||||||
&dmabuf_frame_listener, self);
|
&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)
|
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.start = dmabuf_capture_start;
|
||||||
self->fc.backend.stop = dmabuf_capture_stop;
|
self->fc.backend.stop = dmabuf_capture_stop;
|
||||||
self->fc.backend.render = dmabuf_capture_render;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -885,7 +885,10 @@ int main(int argc, char* argv[])
|
||||||
nvnc_display_unref(self.nvnc_display);
|
nvnc_display_unref(self.nvnc_display);
|
||||||
nvnc_close(self.nvnc);
|
nvnc_close(self.nvnc);
|
||||||
renderer_destroy(&self.renderer);
|
renderer_destroy(&self.renderer);
|
||||||
|
if (self.screencopy_backend.manager)
|
||||||
screencopy_destroy(&self.screencopy_backend);
|
screencopy_destroy(&self.screencopy_backend);
|
||||||
|
if (self.dmabuf_backend.manager)
|
||||||
|
dmabuf_capture_destroy(&self.dmabuf_backend);
|
||||||
wayvnc_destroy(&self);
|
wayvnc_destroy(&self);
|
||||||
aml_unref(aml);
|
aml_unref(aml);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue