aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2025-06-06 23:44:48 +0200
committerdec05eba <dec05eba@protonmail.com>2025-06-06 23:46:11 +0200
commit1ab2c066b4de87facf89103602387c370211b190 (patch)
tree088f6bd0d6cf70bbb7ad67c9c72fea5b6a880e4c
parent131209ddc04253fdb37564c576ba2e2350d2c45b (diff)
Remove swap buffer call
-rw-r--r--README.md8
-rw-r--r--TODO11
-rw-r--r--dbus/client/dbus_client.c4
-rw-r--r--kms/client/kms_client.c2
-rw-r--r--src/args_parser.c2
-rw-r--r--src/color_conversion.c1
-rw-r--r--src/egl.c20
-rw-r--r--src/main.cpp1
-rw-r--r--src/utils.c14
9 files changed, 42 insertions, 21 deletions
diff --git a/README.md b/README.md
index af23eb9..c399f82 100644
--- a/README.md
+++ b/README.md
@@ -125,7 +125,9 @@ in this case you could record a window or a monitor with the name `DP-1`.\
To list available audio devices that you can use you can run `gpu-screen-recorder --list-audio-devices` and the name to use is on the left size of the `|`.\
To list available audio application names that you can use you can run `gpu-screen-recorder --list-application-audio`.
## Streaming
-Streaming works the same as recording, but the `-o` argument should be path to the live streaming service you want to use (including your live streaming key). Take a look at `scripts/twitch-stream.sh` to see an example of how to stream to twitch.
+Streaming works the same way as recording, but the `-o` argument should be path to the live streaming service you want to use (including your live streaming key). Take a look at `scripts/twitch-stream.sh` to see an example of how to stream to twitch.\
+GPU Screen Recorder uses Ffmpeg so GPU Screen Recorder supports all protocols that Ffmpeg supports.\
+If you want to reduce latency one thing you can do is to use the `-keyint` option, for example `-keyint 0.5`. Lower value means lower latency at the cost of increased bitrate/decreased quality.
## Replay mode
Run `gpu-screen-recorder` with the `-c mp4` and `-r` option, for example: `gpu-screen-recorder -w screen -f 60 -r 30 -c mp4 -o ~/Videos`. Note that in this case, `-o` should point to a directory.\
If `-df yes` is set, replays are save in folders based on the date.
@@ -195,3 +197,7 @@ I don't know how well recording HDR works in wayland compositors other than KDE
This is a [steam issue](https://github.com/ValveSoftware/steam-for-linux/issues/11446). Prepend the gpu-screen-recorder command with `LD_PREFIX=""`, for example `LD_PREFIX="" gpu-screen-recorder -w screen -o video.mp4`.
## The video isn't smooth when gpu usage is 100%
If you are using the flatpak version of GPU Screen Recorder then try installing GPU Screen Recorder from a non-flatpak source instead (such as from aur or from source). Flatpak has a limitation that prevents GPU Screen Recorder from running faster when playing very heavy games.
+## How do I apply audio effects, such as noise suppression?
+You have to use external software for that, such as Easy Effects or NoiseTorch.
+## My AMD GPU freezes when using GPU Screen Recorder
+This is an AMD driver bug that happens to some people: [https://gitlab.freedesktop.org/mesa/mesa/-/issues/13224](https://gitlab.freedesktop.org/mesa/mesa/-/issues/13224). If you are able to provide system information and output of `sudo dmesg` in that bug report then please do so. It will continue to be an issue until AMD fixes it. As a temporary workaround you can run `sudo setcap -r /usr/bin/gpu-screen-recorder` (but this gets overwritten when you update GPU Screen Recorder).
diff --git a/TODO b/TODO
index 5923989..49b1d71 100644
--- a/TODO
+++ b/TODO
@@ -289,3 +289,14 @@ Support hdr screenshot.
Recreate opengl context on loss. This can happen if there is a gpu driver bug, causing context to need to be recreated. This is a nice improvement to not break recording even with buggy driver.
Support saving video with surround sound. Surround sound audio capture does work, but it gets downmixed to stereo.
+
+Add (render) plugin support. To simplify it (and possibly best performance) create one rgba texture (with the size of the output video) that is used across all plugins.
+ Create a framebuffer and set this texture and the target and set the framebuffer as active before calling the plugins.
+ Then the plugins can render simply by doing simple opengl draw functions.
+ Maybe send some metadata to the plugin, such as video (and framebuffer) size. Although this data can be retrieved from the active framebuffer.
+
+Either support webcam support with raw yuyv, mapping the buffer directly to opengl. Or use mjpeg, mapping the buffer directly to vaapi jpeg decoder and then get then map the decoded buffer to opengl.
+ Some webcams dont support raw yuyv and many webcams support higher framerates for mjpeg.
+
+Allow medium, high, very_high and ultra quality for -bm cbr. If that is used then it will automatically estimate the best bitrate for that quality based on resolution and fps.
+ Maybe do this in the ui instead (or both?), to show estimated file size.
diff --git a/dbus/client/dbus_client.c b/dbus/client/dbus_client.c
index 31f4158..de2df62 100644
--- a/dbus/client/dbus_client.c
+++ b/dbus/client/dbus_client.c
@@ -33,7 +33,7 @@ static bool gsr_dbus_client_wait_for_startup(gsr_dbus_client *self) {
int exit_code = -1;
if(WIFEXITED(status))
exit_code = WEXITSTATUS(status);
- fprintf(stderr, "gsr error: gsr_dbus_client_init: server side or never started, exit code: %d\n", exit_code);
+ fprintf(stderr, "gsr error: gsr_dbus_client_init: server died or never started, exit code: %d\n", exit_code);
self->pid = 0;
return false;
}
@@ -73,7 +73,7 @@ bool gsr_dbus_client_init(gsr_dbus_client *self, const char *screencast_restore_
const char *args[] = { "gsr-dbus-server", socket_pair_server_str, self->screencast_restore_token ? self->screencast_restore_token : "", NULL };
execvp(args[0], (char *const*)args);
- fprintf(stderr, "gsr error: gsr_dbus_client_init: execvp failed, error: %s\n", strerror(errno));
+ fprintf(stderr, "gsr error: gsr_dbus_client_init: failed to launch \"gsr-dbus-server\", error: %s\n", strerror(errno));
_exit(127);
} else { /* parent */
if(!gsr_dbus_client_wait_for_startup(self)) {
diff --git a/kms/client/kms_client.c b/kms/client/kms_client.c
index 8335688..57afd04 100644
--- a/kms/client/kms_client.c
+++ b/kms/client/kms_client.c
@@ -312,7 +312,7 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
const char *args[] = { "pkexec", server_filepath, self->initial_socket_path, card_path, NULL };
execvp(args[0], (char *const*)args);
}
- fprintf(stderr, "gsr error: gsr_kms_client_init: execvp failed, error: %s\n", strerror(errno));
+ fprintf(stderr, "gsr error: gsr_kms_client_init: failed to launch \"gsr-kms-server\", error: %s\n", strerror(errno));
_exit(127);
} else { /* parent */
self->kms_server_pid = pid;
diff --git a/src/args_parser.c b/src/args_parser.c
index 13b3f08..0e05557 100644
--- a/src/args_parser.c
+++ b/src/args_parser.c
@@ -194,7 +194,6 @@ static void usage_header() {
fflush(stdout);
}
-// TODO: Update with portal info
static void usage_full() {
const bool inside_flatpak = getenv("FLATPAK_ID") != NULL;
const char *program_name = inside_flatpak ? "flatpak run --command=gpu-screen-recorder com.dec05eba.gpu_screen_recorder" : "gpu-screen-recorder";
@@ -397,6 +396,7 @@ static void usage_full() {
printf("EXAMPLES:\n");
printf(" %s -w screen -f 60 -a default_output -o video.mp4\n", program_name);
printf(" %s -w screen -f 60 -a default_output -a default_input -o video.mp4\n", program_name);
+ printf(" %s -w $(xdotool selectwindow) -f 60 -a default_output -o video.mp4\n", program_name);
printf(" %s -w screen -f 60 -a \"default_output|default_input\" -o video.mp4\n", program_name);
printf(" %s -w screen -f 60 -a default_output -c mkv -r 60 -o \"$HOME/Videos\"\n", program_name);
printf(" %s -w screen -f 60 -a default_output -c mkv -r 1800 -replay-storage disk -bm cbr -q 40000 -o \"$HOME/Videos\"\n", program_name);
diff --git a/src/color_conversion.c b/src/color_conversion.c
index 88dc398..858990c 100644
--- a/src/color_conversion.c
+++ b/src/color_conversion.c
@@ -961,6 +961,7 @@ void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_
gsr_color_conversion_swizzle_reset(self, source_color);
self->params.egl->glBindTexture(texture_target, 0);
+ self->params.egl->glFlush();
}
void gsr_color_conversion_clear(gsr_color_conversion *self) {
diff --git a/src/egl.c b/src/egl.c
index dd84325..2c7f7be 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -42,7 +42,7 @@ static void reset_cap_nice(void) {
cap_flag_value_t cap_sys_nice_value = CAP_CLEAR;
cap_get_flag(caps, CAP_SYS_NICE, CAP_EFFECTIVE, &cap_sys_nice_value);
if(cap_sys_nice_value == CAP_CLEAR) {
- fprintf(stderr, "gsr warning: cap_sys_nice capability is missing on the gpu-screen-recorder binary, performance might be affected. If you are using the flatpak version of gpu-screen-recorder then the only fix is to use a non-flatpak version of gpu-screen-recorder\n");
+ fprintf(stderr, "gsr warning: cap_sys_nice capability is missing on the gpu-screen-recorder binary, performance might be affected. If you are using the flatpak version of gpu-screen-recorder then the only fix is to use a non-flatpak version of gpu-screen-recorder. Make sure you install gpu-screen-recorder, don't run it from the build directory\n");
}
const cap_value_t cap_to_remove = CAP_SYS_NICE;
@@ -546,13 +546,13 @@ void gsr_egl_unload(gsr_egl *self) {
void gsr_egl_swap_buffers(gsr_egl *self) {
/* This uses less cpu than swap buffer on nvidia */
// TODO: Do these and remove swap
- //self->glFlush();
- //self->glFinish();
- if(self->egl_display) {
- self->eglSwapBuffers(self->egl_display, self->egl_surface);
- } else if(gsr_window_get_display_server(self->window) == GSR_DISPLAY_SERVER_X11) {
- Display *display = gsr_window_get_display(self->window);
- const Window window = (Window)gsr_window_get_window(self->window);
- self->glXSwapBuffers(display, window);
- }
+ self->glFlush();
+// self->glFinish();
+ // if(self->egl_display) {
+ // self->eglSwapBuffers(self->egl_display, self->egl_surface);
+ // } else if(gsr_window_get_display_server(self->window) == GSR_DISPLAY_SERVER_X11) {
+ // Display *display = gsr_window_get_display(self->window);
+ // const Window window = (Window)gsr_window_get_window(self->window);
+ // self->glXSwapBuffers(display, window);
+ // }
}
diff --git a/src/main.cpp b/src/main.cpp
index 698c230..0956d0a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -47,6 +47,7 @@ extern "C" {
extern "C" {
#include <libavutil/pixfmt.h>
#include <libavcodec/avcodec.h>
+#include <libavcodec/defs.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libswresample/swresample.h>
diff --git a/src/utils.c b/src/utils.c
index 27116a0..c625ecf 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -19,6 +19,8 @@
#include <libavcodec/avcodec.h>
#include <libavutil/hwcontext_vaapi.h>
+#define DRM_NUM_BUF_ATTRS 4
+
double clock_get_monotonic_seconds(void) {
struct timespec ts;
ts.tv_sec = 0;
@@ -508,35 +510,35 @@ int create_directory_recursive(char *path) {
}
void setup_dma_buf_attrs(intptr_t *img_attr, uint32_t format, uint32_t width, uint32_t height, const int *fds, const uint32_t *offsets, const uint32_t *pitches, const uint64_t *modifiers, int num_planes, bool use_modifier) {
- const uint32_t plane_fd_attrs[4] = {
+ const uint32_t plane_fd_attrs[DRM_NUM_BUF_ATTRS] = {
EGL_DMA_BUF_PLANE0_FD_EXT,
EGL_DMA_BUF_PLANE1_FD_EXT,
EGL_DMA_BUF_PLANE2_FD_EXT,
EGL_DMA_BUF_PLANE3_FD_EXT
};
- const uint32_t plane_offset_attrs[4] = {
+ const uint32_t plane_offset_attrs[DRM_NUM_BUF_ATTRS] = {
EGL_DMA_BUF_PLANE0_OFFSET_EXT,
EGL_DMA_BUF_PLANE1_OFFSET_EXT,
EGL_DMA_BUF_PLANE2_OFFSET_EXT,
EGL_DMA_BUF_PLANE3_OFFSET_EXT
};
- const uint32_t plane_pitch_attrs[4] = {
+ const uint32_t plane_pitch_attrs[DRM_NUM_BUF_ATTRS] = {
EGL_DMA_BUF_PLANE0_PITCH_EXT,
EGL_DMA_BUF_PLANE1_PITCH_EXT,
EGL_DMA_BUF_PLANE2_PITCH_EXT,
EGL_DMA_BUF_PLANE3_PITCH_EXT
};
- const uint32_t plane_modifier_lo_attrs[4] = {
+ const uint32_t plane_modifier_lo_attrs[DRM_NUM_BUF_ATTRS] = {
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT
};
- const uint32_t plane_modifier_hi_attrs[4] = {
+ const uint32_t plane_modifier_hi_attrs[DRM_NUM_BUF_ATTRS] = {
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT,
EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT,
@@ -554,7 +556,7 @@ void setup_dma_buf_attrs(intptr_t *img_attr, uint32_t format, uint32_t width, ui
img_attr[img_attr_index++] = EGL_HEIGHT;
img_attr[img_attr_index++] = height;
- assert(num_planes <= 4);
+ assert(num_planes <= DRM_NUM_BUF_ATTRS);
for(int i = 0; i < num_planes; ++i) {
img_attr[img_attr_index++] = plane_fd_attrs[i];
img_attr[img_attr_index++] = fds[i];