aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-03-11 19:01:46 +0100
committerdec05eba <dec05eba@protonmail.com>2024-03-11 19:01:46 +0100
commitba096a3ba7815eff41159eedfb646c97451fbef7 (patch)
tree01bea3fea22cec135000e4aa1eaeea16406b56d5
parent1292892d4dd9c94fccdead7afd58e38c85234bb9 (diff)
Add -cursor option to not record cursor
-rw-r--r--include/capture/kms.h2
-rw-r--r--include/capture/kms_cuda.h3
-rw-r--r--include/capture/kms_vaapi.h3
-rw-r--r--include/capture/nvfbc.h1
-rw-r--r--include/capture/xcomposite.h1
-rw-r--r--src/capture/kms.c4
-rw-r--r--src/capture/kms_cuda.c2
-rw-r--r--src/capture/kms_vaapi.c2
-rw-r--r--src/capture/nvfbc.c2
-rw-r--r--src/capture/xcomposite.c4
-rw-r--r--src/main.cpp32
11 files changed, 41 insertions, 15 deletions
diff --git a/include/capture/kms.h b/include/capture/kms.h
index aa58e93..674813a 100644
--- a/include/capture/kms.h
+++ b/include/capture/kms.h
@@ -44,7 +44,7 @@ struct gsr_capture_kms {
/* Returns 0 on success */
int gsr_capture_kms_start(gsr_capture_kms *self, const char *display_to_capture, gsr_egl *egl, AVCodecContext *video_codec_context, AVFrame *frame);
void gsr_capture_kms_stop(gsr_capture_kms *self);
-bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bool screen_plane_use_modifiers, bool cursor_texture_is_external);
+bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bool screen_plane_use_modifiers, bool cursor_texture_is_external, bool record_cursor);
void gsr_capture_kms_cleanup_kms_fds(gsr_capture_kms *self);
#endif /* GSR_CAPTURE_KMS_H */
diff --git a/include/capture/kms_cuda.h b/include/capture/kms_cuda.h
index ce3e8ce..fd0d396 100644
--- a/include/capture/kms_cuda.h
+++ b/include/capture/kms_cuda.h
@@ -6,14 +6,13 @@
#include "../color_conversion.h"
#include "capture.h"
-typedef struct _XDisplay Display;
-
typedef struct {
gsr_egl *egl;
const char *display_to_capture; /* if this is "screen", then the first monitor is captured. A copy is made of this */
gsr_gpu_info gpu_inf;
bool hdr;
gsr_color_range color_range;
+ bool record_cursor;
} gsr_capture_kms_cuda_params;
gsr_capture* gsr_capture_kms_cuda_create(const gsr_capture_kms_cuda_params *params);
diff --git a/include/capture/kms_vaapi.h b/include/capture/kms_vaapi.h
index 54d0bad..196b597 100644
--- a/include/capture/kms_vaapi.h
+++ b/include/capture/kms_vaapi.h
@@ -6,14 +6,13 @@
#include "../color_conversion.h"
#include "capture.h"
-typedef struct _XDisplay Display;
-
typedef struct {
gsr_egl *egl;
const char *display_to_capture; /* if this is "screen", then the first monitor is captured. A copy is made of this */
gsr_gpu_info gpu_inf;
bool hdr;
gsr_color_range color_range;
+ bool record_cursor;
} gsr_capture_kms_vaapi_params;
gsr_capture* gsr_capture_kms_vaapi_create(const gsr_capture_kms_vaapi_params *params);
diff --git a/include/capture/nvfbc.h b/include/capture/nvfbc.h
index da486f2..36bc2b6 100644
--- a/include/capture/nvfbc.h
+++ b/include/capture/nvfbc.h
@@ -14,6 +14,7 @@ typedef struct {
bool overclock;
bool hdr;
gsr_color_range color_range;
+ bool record_cursor;
} gsr_capture_nvfbc_params;
gsr_capture* gsr_capture_nvfbc_create(const gsr_capture_nvfbc_params *params);
diff --git a/include/capture/xcomposite.h b/include/capture/xcomposite.h
index e311a93..ce0dbad 100644
--- a/include/capture/xcomposite.h
+++ b/include/capture/xcomposite.h
@@ -14,6 +14,7 @@ typedef struct {
bool follow_focused; /* If this is set then |window| is ignored */
vec2i region_size; /* This is currently only used with |follow_focused| */
gsr_color_range color_range;
+ bool record_cursor;
} gsr_capture_xcomposite_params;
typedef struct {
diff --git a/src/capture/kms.c b/src/capture/kms.c
index 0b75b1f..16b20b7 100644
--- a/src/capture/kms.c
+++ b/src/capture/kms.c
@@ -193,7 +193,7 @@ static vec2i swap_vec2i(vec2i value) {
return value;
}
-bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bool screen_plane_use_modifiers, bool cursor_texture_is_external) {
+bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bool screen_plane_use_modifiers, bool cursor_texture_is_external, bool record_cursor) {
//egl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
self->base.egl->glClear(0);
@@ -300,7 +300,7 @@ bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bo
capture_pos, self->capture_size,
texture_rotation, false);
- if(cursor_drm_fd) {
+ if(record_cursor && cursor_drm_fd) {
const vec2i cursor_size = {cursor_drm_fd->width, cursor_drm_fd->height};
vec2i cursor_pos = {cursor_drm_fd->x, cursor_drm_fd->y};
switch(self->monitor_rotation) {
diff --git a/src/capture/kms_cuda.c b/src/capture/kms_cuda.c
index c206fde..0349228 100644
--- a/src/capture/kms_cuda.c
+++ b/src/capture/kms_cuda.c
@@ -90,7 +90,7 @@ static void gsr_capture_kms_unload_cuda_graphics(gsr_capture_kms_cuda *cap_kms)
static int gsr_capture_kms_cuda_capture(gsr_capture *cap, AVFrame *frame) {
gsr_capture_kms_cuda *cap_kms = cap->priv;
- gsr_capture_kms_capture(&cap_kms->kms, frame, cap_kms->params.hdr, true, true);
+ gsr_capture_kms_capture(&cap_kms->kms, frame, cap_kms->params.hdr, true, true, cap_kms->params.record_cursor);
const int div[2] = {1, 2}; // divide UV texture size by 2 because chroma is half size
for(int i = 0; i < 2; ++i) {
diff --git a/src/capture/kms_vaapi.c b/src/capture/kms_vaapi.c
index bd0e99d..a7e8182 100644
--- a/src/capture/kms_vaapi.c
+++ b/src/capture/kms_vaapi.c
@@ -57,7 +57,7 @@ static bool gsr_capture_kms_vaapi_should_stop(gsr_capture *cap, bool *err) {
static int gsr_capture_kms_vaapi_capture(gsr_capture *cap, AVFrame *frame) {
gsr_capture_kms_vaapi *cap_kms = cap->priv;
- gsr_capture_kms_capture(&cap_kms->kms, frame, cap_kms->params.hdr, false, false);
+ gsr_capture_kms_capture(&cap_kms->kms, frame, cap_kms->params.hdr, false, false, cap_kms->params.record_cursor);
return 0;
}
diff --git a/src/capture/nvfbc.c b/src/capture/nvfbc.c
index 7ba0438..5acf083 100644
--- a/src/capture/nvfbc.c
+++ b/src/capture/nvfbc.c
@@ -272,6 +272,8 @@ static int gsr_capture_nvfbc_start(gsr_capture *cap, AVCodecContext *video_codec
create_capture_params.dwVersion = NVFBC_CREATE_CAPTURE_SESSION_PARAMS_VER;
create_capture_params.eCaptureType = NVFBC_CAPTURE_TO_GL;
create_capture_params.bWithCursor = (!direct_capture || supports_direct_cursor) ? NVFBC_TRUE : NVFBC_FALSE;
+ if(!cap_nvfbc->params.record_cursor)
+ create_capture_params.bWithCursor = false;
if(capture_region)
create_capture_params.captureBox = (NVFBC_BOX){ x, y, width, height };
create_capture_params.eTrackingType = tracking_type;
diff --git a/src/capture/xcomposite.c b/src/capture/xcomposite.c
index f1d620c..ae7481b 100644
--- a/src/capture/xcomposite.c
+++ b/src/capture/xcomposite.c
@@ -275,7 +275,7 @@ int gsr_capture_xcomposite_capture(gsr_capture_xcomposite *self, AVFrame *frame)
will not get overdrawn the next frame causing a cursor trail to be visible since we dont clear the background.
To fix this we detect if the cursor is partially inside the window and clear the background only in that case.
*/
- if(!cursor_completely_inside_window && cursor_inside_window)
+ if(!cursor_completely_inside_window && cursor_inside_window && self->params.record_cursor)
self->clear_next_frame = true;
gsr_color_conversion_draw(&self->base.color_conversion, window_texture_get_opengl_texture_id(&self->window_texture),
@@ -283,7 +283,7 @@ int gsr_capture_xcomposite_capture(gsr_capture_xcomposite *self, AVFrame *frame)
(vec2i){0, 0}, self->texture_size,
0.0f, false);
- if(cursor_inside_window) {
+ if(cursor_inside_window && self->params.record_cursor) {
gsr_color_conversion_draw(&self->base.color_conversion, self->cursor.texture_id,
cursor_pos, self->cursor.size,
(vec2i){0, 0}, self->cursor.size,
diff --git a/src/main.cpp b/src/main.cpp
index 2da5e19..59adf8c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -801,7 +801,7 @@ static void open_video(AVCodecContext *codec_context, VideoQuality video_quality
}
static void usage_header() {
- fprintf(stderr, "usage: gpu-screen-recorder -w <window_id|monitor|focused> [-c <container_format>] [-s WxH] -f <fps> [-a <audio_input>] [-q <quality>] [-r <replay_buffer_size_sec>] [-k h264|hevc|hevc_hdr|av1|av1_hdr] [-ac aac|opus|flac] [-oc yes|no] [-fm cfr|vfr] [-cr limited|full] [-v yes|no] [-h|--help] [-o <output_file>] [-mf yes|no] [-sc <script_path>]\n");
+ fprintf(stderr, "usage: gpu-screen-recorder -w <window_id|monitor|focused> [-c <container_format>] [-s WxH] -f <fps> [-a <audio_input>] [-q <quality>] [-r <replay_buffer_size_sec>] [-k h264|hevc|hevc_hdr|av1|av1_hdr] [-ac aac|opus|flac] [-oc yes|no] [-fm cfr|vfr] [-cr limited|full] [-v yes|no] [-h|--help] [-o <output_file>] [-mf yes|no] [-sc <script_path>] [-cursor yes|no]\n");
}
static void usage_full() {
@@ -860,7 +860,11 @@ static void usage_full() {
fprintf(stderr, "\n");
fprintf(stderr, " -mf Organise replays in folders based on the current date.\n");
fprintf(stderr, "\n");
- fprintf(stderr, " -sc Run a script on the saved video file (non-blocking). The first argument to the script is the filepath to the saved video file and the second argument is the recording type (either \"regular\" or \"replay\"). Not applicable for live streams.\n");
+ fprintf(stderr, " -sc Run a script on the saved video file (non-blocking). The first argument to the script is the filepath to the saved video file and the second argument is the recording type (either \"regular\" or \"replay\").\n");
+ fprintf(stderr, " Not applicable for live streams.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -cursor\n");
+ fprintf(stderr, " Record cursor. Defaults to 'yes'.\n");
fprintf(stderr, "\n");
fprintf(stderr, " --list-supported-video-codecs\n");
fprintf(stderr, " List supported video codecs and exits. Prints h264, hevc, hevc_hdr, av1 and av1_hdr (if supported).\n");
@@ -1403,7 +1407,7 @@ static void list_supported_video_codecs() {
XCloseDisplay(dpy);
}
-static gsr_capture* create_capture_impl(const char *window_str, const char *screen_region, bool wayland, gsr_gpu_info gpu_inf, gsr_egl &egl, int fps, bool overclock, VideoCodec video_codec, gsr_color_range color_range) {
+static gsr_capture* create_capture_impl(const char *window_str, const char *screen_region, bool wayland, gsr_gpu_info gpu_inf, gsr_egl &egl, int fps, bool overclock, VideoCodec video_codec, gsr_color_range color_range, bool record_cursor) {
vec2i region_size = { 0, 0 };
Window src_window_id = None;
bool follow_focused = false;
@@ -1476,6 +1480,7 @@ static gsr_capture* create_capture_impl(const char *window_str, const char *scre
kms_params.gpu_inf = gpu_inf;
kms_params.hdr = video_codec_is_hdr(video_codec);
kms_params.color_range = color_range;
+ kms_params.record_cursor = record_cursor;
capture = gsr_capture_kms_cuda_create(&kms_params);
if(!capture)
_exit(1);
@@ -1504,6 +1509,7 @@ static gsr_capture* create_capture_impl(const char *window_str, const char *scre
nvfbc_params.overclock = overclock;
nvfbc_params.hdr = video_codec_is_hdr(video_codec);
nvfbc_params.color_range = color_range;
+ nvfbc_params.record_cursor = record_cursor;
capture = gsr_capture_nvfbc_create(&nvfbc_params);
if(!capture)
_exit(1);
@@ -1515,6 +1521,7 @@ static gsr_capture* create_capture_impl(const char *window_str, const char *scre
kms_params.gpu_inf = gpu_inf;
kms_params.hdr = video_codec_is_hdr(video_codec);
kms_params.color_range = color_range;
+ kms_params.record_cursor = record_cursor;
capture = gsr_capture_kms_vaapi_create(&kms_params);
if(!capture)
_exit(1);
@@ -1543,6 +1550,7 @@ static gsr_capture* create_capture_impl(const char *window_str, const char *scre
xcomposite_params.base.follow_focused = follow_focused;
xcomposite_params.base.region_size = region_size;
xcomposite_params.base.color_range = color_range;
+ xcomposite_params.base.record_cursor = record_cursor;
capture = gsr_capture_xcomposite_vaapi_create(&xcomposite_params);
if(!capture)
_exit(1);
@@ -1555,6 +1563,7 @@ static gsr_capture* create_capture_impl(const char *window_str, const char *scre
xcomposite_params.base.follow_focused = follow_focused;
xcomposite_params.base.region_size = region_size;
xcomposite_params.overclock = overclock;
+ xcomposite_params.base.record_cursor = record_cursor;
capture = gsr_capture_xcomposite_cuda_create(&xcomposite_params);
if(!capture)
_exit(1);
@@ -1621,6 +1630,7 @@ int main(int argc, char **argv) {
{ "-mf", Arg { {}, true, false } },
{ "-sc", Arg { {}, true, false } },
{ "-cr", Arg { {}, true, false } },
+ { "-cursor", Arg { {}, true, false } },
};
for(int i = 1; i < argc; i += 2) {
@@ -1714,6 +1724,20 @@ int main(int argc, char **argv) {
usage();
}
+ bool record_cursor = true;
+ const char *record_cursor_str = args["-cursor"].value();
+ if(!record_cursor_str)
+ record_cursor_str = "yes";
+
+ if(strcmp(record_cursor_str, "yes") == 0) {
+ record_cursor = true;
+ } else if(strcmp(record_cursor_str, "no") == 0) {
+ record_cursor = false;
+ } else {
+ fprintf(stderr, "Error: -cursor should either be either 'yes' or 'no', got: '%s'\n", record_cursor_str);
+ usage();
+ }
+
bool make_folders = false;
const char *make_folders_str = args["-mf"].value();
if(!make_folders_str)
@@ -2141,7 +2165,7 @@ int main(int argc, char **argv) {
_exit(2);
}
- gsr_capture *capture = create_capture_impl(window_str, screen_region, wayland, egl.gpu_info, egl, fps, overclock, video_codec, color_range);
+ gsr_capture *capture = create_capture_impl(window_str, screen_region, wayland, egl.gpu_info, egl, fps, overclock, video_codec, color_range, record_cursor);
// (Some?) livestreaming services require at least one audio track to work.
// If not audio is provided then create one silent audio track.