diff options
author | dec05eba <dec05eba@protonmail.com> | 2024-09-14 01:15:01 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2024-09-14 01:15:01 +0200 |
commit | 8acb34638212ab8dba0d48a57dd40721203a7a44 (patch) | |
tree | 7f1942c56fa2700f2f5fe2d623e9e1c94fb23324 /src/capture | |
parent | 992792fb1f35546b9d66c3f69aa3d0f5adb94ef6 (diff) |
Set update fps to video fps, on x11 sync video to damage tracking
Diffstat (limited to 'src/capture')
-rw-r--r-- | src/capture/capture.c | 5 | ||||
-rw-r--r-- | src/capture/kms.c | 15 | ||||
-rw-r--r-- | src/capture/xcomposite.c | 122 |
3 files changed, 59 insertions, 83 deletions
diff --git a/src/capture/capture.c b/src/capture/capture.c index 7c5737d..5fc96d0 100644 --- a/src/capture/capture.c +++ b/src/capture/capture.c @@ -16,6 +16,11 @@ void gsr_capture_tick(gsr_capture *cap, AVCodecContext *video_codec_context) { cap->tick(cap, video_codec_context); } +void gsr_capture_on_event(gsr_capture *cap, gsr_egl *egl) { + if(cap->on_event) + cap->on_event(cap, egl); +} + bool gsr_capture_should_stop(gsr_capture *cap, bool *err) { assert(cap->started); if(cap->should_stop) diff --git a/src/capture/kms.c b/src/capture/kms.c index bdf3202..9ba4bd2 100644 --- a/src/capture/kms.c +++ b/src/capture/kms.c @@ -4,7 +4,6 @@ #include "../../include/cursor.h" #include "../../kms/client/kms_client.h" -#include <X11/Xlib.h> #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -50,7 +49,6 @@ typedef struct { bool is_x11; gsr_cursor x11_cursor; - XEvent xev; } gsr_capture_kms; static void gsr_capture_kms_cleanup_kms_fds(gsr_capture_kms *self) { @@ -199,17 +197,13 @@ static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_c return 0; } -static void gsr_capture_kms_tick(gsr_capture *cap, AVCodecContext *video_codec_context) { - (void)video_codec_context; +static void gsr_capture_kms_on_event(gsr_capture *cap, gsr_egl *egl) { gsr_capture_kms *self = cap->priv; - if(!self->is_x11) return; - while(XPending(self->params.egl->x11.dpy)) { - XNextEvent(self->params.egl->x11.dpy, &self->xev); - gsr_cursor_update(&self->x11_cursor, &self->xev); - } + XEvent *xev = gsr_egl_get_event_data(egl); + gsr_cursor_update(&self->x11_cursor, xev); } static float monitor_rotation_to_radians(gsr_monitor_rotation rot) { @@ -628,7 +622,8 @@ gsr_capture* gsr_capture_kms_create(const gsr_capture_kms_params *params) { *cap = (gsr_capture) { .start = gsr_capture_kms_start, - .tick = gsr_capture_kms_tick, + .on_event = gsr_capture_kms_on_event, + .tick = NULL, .should_stop = gsr_capture_kms_should_stop, .capture = gsr_capture_kms_capture, .capture_end = gsr_capture_kms_capture_end, diff --git a/src/capture/xcomposite.c b/src/capture/xcomposite.c index 5ec8c12..e99cabf 100644 --- a/src/capture/xcomposite.c +++ b/src/capture/xcomposite.c @@ -2,7 +2,6 @@ #include "../../include/window_texture.h" #include "../../include/utils.h" #include "../../include/cursor.h" -#include "../../include/damage.h" #include "../../include/color_conversion.h" #include <stdlib.h> @@ -17,12 +16,12 @@ typedef struct { gsr_capture_xcomposite_params params; - XEvent xev; bool should_stop; bool stop_is_error; bool window_resized; bool follow_focused_initialized; + bool init_new_window; Window window; vec2i window_size; @@ -34,8 +33,6 @@ typedef struct { Atom net_active_window_atom; gsr_cursor cursor; - gsr_damage damage; - bool cursor_damaged; bool clear_background; } gsr_capture_xcomposite; @@ -43,7 +40,6 @@ typedef struct { static void gsr_capture_xcomposite_stop(gsr_capture_xcomposite *self) { window_texture_deinit(&self->window_texture); gsr_cursor_deinit(&self->cursor); - gsr_damage_deinit(&self->damage); } static int max_int(int a, int b) { @@ -78,13 +74,6 @@ static int gsr_capture_xcomposite_start(gsr_capture *cap, AVCodecContext *video_ self->window = self->params.window; } - if(self->params.track_damage) - gsr_damage_init(&self->damage, self->params.egl->x11.dpy); - else - memset(&self->damage, 0, sizeof(self->damage)); - - gsr_damage_set_target_window(&self->damage, self->window); - /* TODO: Do these in tick, and allow error if follow_focused */ XWindowAttributes attr; @@ -141,59 +130,12 @@ static void gsr_capture_xcomposite_tick(gsr_capture *cap, AVCodecContext *video_ (void)video_codec_context; gsr_capture_xcomposite *self = cap->priv; - bool init_new_window = false; - while(XPending(self->params.egl->x11.dpy)) { - XNextEvent(self->params.egl->x11.dpy, &self->xev); - - switch(self->xev.type) { - case DestroyNotify: { - /* Window died (when not following focused window), so we stop recording */ - if(!self->params.follow_focused && self->xev.xdestroywindow.window == self->window) { - self->should_stop = true; - self->stop_is_error = false; - } - break; - } - case Expose: { - /* Requires window texture recreate */ - if(self->xev.xexpose.count == 0 && self->xev.xexpose.window == self->window) { - self->window_resize_timer = clock_get_monotonic_seconds(); - self->window_resized = true; - } - break; - } - case ConfigureNotify: { - /* Window resized */ - if(self->xev.xconfigure.window == self->window && (self->xev.xconfigure.width != self->window_size.x || self->xev.xconfigure.height != self->window_size.y)) { - self->window_size.x = max_int(self->xev.xconfigure.width, 0); - self->window_size.y = max_int(self->xev.xconfigure.height, 0); - self->window_resize_timer = clock_get_monotonic_seconds(); - self->window_resized = true; - } - break; - } - case PropertyNotify: { - /* Focused window changed */ - if(self->params.follow_focused && self->xev.xproperty.atom == self->net_active_window_atom) { - init_new_window = true; - } - break; - } - } - - gsr_damage_update(&self->damage, &self->xev); - if(gsr_cursor_update(&self->cursor, &self->xev)) { - if(self->params.record_cursor && self->cursor.visible) { - self->cursor_damaged = true; - } - } - } - if(self->params.follow_focused && !self->follow_focused_initialized) { - init_new_window = true; + self->init_new_window = true; } - if(init_new_window) { + if(self->init_new_window) { + self->init_new_window = false; Window focused_window = get_focused_window(self->params.egl->x11.dpy, self->net_active_window_atom); if(focused_window != self->window || !self->follow_focused_initialized) { self->follow_focused_initialized = true; @@ -223,7 +165,6 @@ static void gsr_capture_xcomposite_tick(gsr_capture *cap, AVCodecContext *video_ self->window_resized = false; self->clear_background = true; - gsr_damage_set_target_window(&self->damage, self->window); } } @@ -247,19 +188,49 @@ static void gsr_capture_xcomposite_tick(gsr_capture *cap, AVCodecContext *video_ self->params.egl->glBindTexture(GL_TEXTURE_2D, 0); self->clear_background = true; - gsr_damage_set_target_window(&self->damage, self->window); } } -static bool gsr_capture_xcomposite_is_damaged(gsr_capture *cap) { +static void gsr_capture_xcomposite_on_event(gsr_capture *cap, gsr_egl *egl) { gsr_capture_xcomposite *self = cap->priv; - return gsr_damage_is_damaged(&self->damage) || self->cursor_damaged; -} + XEvent *xev = gsr_egl_get_event_data(egl); + switch(xev->type) { + case DestroyNotify: { + /* Window died (when not following focused window), so we stop recording */ + if(!self->params.follow_focused && xev->xdestroywindow.window == self->window) { + self->should_stop = true; + self->stop_is_error = false; + } + break; + } + case Expose: { + /* Requires window texture recreate */ + if(xev->xexpose.count == 0 && xev->xexpose.window == self->window) { + self->window_resize_timer = clock_get_monotonic_seconds(); + self->window_resized = true; + } + break; + } + case ConfigureNotify: { + /* Window resized */ + if(xev->xconfigure.window == self->window && (xev->xconfigure.width != self->window_size.x || xev->xconfigure.height != self->window_size.y)) { + self->window_size.x = max_int(xev->xconfigure.width, 0); + self->window_size.y = max_int(xev->xconfigure.height, 0); + self->window_resize_timer = clock_get_monotonic_seconds(); + self->window_resized = true; + } + break; + } + case PropertyNotify: { + /* Focused window changed */ + if(self->params.follow_focused && xev->xproperty.atom == self->net_active_window_atom) { + self->init_new_window = true; + } + break; + } + } -static void gsr_capture_xcomposite_clear_damage(gsr_capture *cap) { - gsr_capture_xcomposite *self = cap->priv; - gsr_damage_clear(&self->damage); - self->cursor_damaged = false; + gsr_cursor_update(&self->cursor, xev); } static bool gsr_capture_xcomposite_should_stop(gsr_capture *cap, bool *err) { @@ -325,6 +296,11 @@ static gsr_source_color gsr_capture_xcomposite_get_source_color(gsr_capture *cap return GSR_SOURCE_COLOR_RGB; } +static uint64_t gsr_capture_xcomposite_get_window_id(gsr_capture *cap) { + gsr_capture_xcomposite *self = cap->priv; + return self->window; +} + static void gsr_capture_xcomposite_destroy(gsr_capture *cap, AVCodecContext *video_codec_context) { (void)video_codec_context; if(cap->priv) { @@ -355,14 +331,14 @@ gsr_capture* gsr_capture_xcomposite_create(const gsr_capture_xcomposite_params * *cap = (gsr_capture) { .start = gsr_capture_xcomposite_start, + .on_event = gsr_capture_xcomposite_on_event, .tick = gsr_capture_xcomposite_tick, - .is_damaged = gsr_capture_xcomposite_is_damaged, - .clear_damage = gsr_capture_xcomposite_clear_damage, .should_stop = gsr_capture_xcomposite_should_stop, .capture = gsr_capture_xcomposite_capture, .capture_end = NULL, .get_source_color = gsr_capture_xcomposite_get_source_color, .uses_external_image = NULL, + .get_window_id = gsr_capture_xcomposite_get_window_id, .destroy = gsr_capture_xcomposite_destroy, .priv = cap_xcomp }; |