aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rwxr-xr-xbuild.sh9
-rw-r--r--include/egl.h10
-rw-r--r--kms/client/kms_client.c11
-rw-r--r--kms/server/kms_server.c11
-rw-r--r--kms/server/project.conf3
-rw-r--r--project.conf1
-rw-r--r--src/capture/kms_vaapi.c2
-rw-r--r--src/capture/nvfbc.c6
-rw-r--r--src/capture/xcomposite_cuda.c1
-rw-r--r--src/capture/xcomposite_vaapi.c1
-rw-r--r--src/egl.c6
-rw-r--r--src/main.cpp10
-rw-r--r--src/sound.cpp1
-rw-r--r--src/utils.c1
15 files changed, 54 insertions, 20 deletions
diff --git a/TODO b/TODO
index 2cf6b70..4db7c81 100644
--- a/TODO
+++ b/TODO
@@ -60,7 +60,6 @@ Intel is a bit weird with monitor capture and multiple monitors. If one of the m
How about if multiple monitors are rotated?
When using multiple monitors kms grab the target monitor instead of the whole screen.
-Enable opus/flac again. It's broken right now when merging audio inputs. The audio gets a lot of static noise!
Support vp8/vp9/av1. This is especially important on amd which on some distros (such as Manjaro) where hardware accelerated h264/hevc is disabled in the mesa package.
diff --git a/build.sh b/build.sh
index d07b7c9..9e0fa7e 100755
--- a/build.sh
+++ b/build.sh
@@ -1,19 +1,20 @@
#!/bin/sh -e
+opts="-O2 -g0 -DNDEBUG -Wall -Wextra -Werror -s"
+[ -n "$DEBUG" ] && opts="-O0 -g3 -Wall -Wextra -Werror";
+
build_gsr_kms_server() {
dependencies="libdrm"
includes="$(pkg-config --cflags $dependencies)"
libs="$(pkg-config --libs $dependencies) -ldl"
- opts="-O2 -g0 -DNDEBUG"
gcc -c kms/server/kms_server.c $opts $includes
- gcc -o gsr-kms-server -O2 kms_server.o -s $libs
+ gcc -o gsr-kms-server -O2 kms_server.o $libs $opts
}
build_gsr() {
dependencies="libavcodec libavformat libavutil x11 xcomposite xrandr xfixes libpulse libswresample libavfilter libva libcap"
includes="$(pkg-config --cflags $dependencies)"
libs="$(pkg-config --libs $dependencies) -ldl -pthread -lm"
- opts="-O2 -g0 -DNDEBUG"
gcc -c src/capture/capture.c $opts $includes
gcc -c src/capture/nvfbc.c $opts $includes
gcc -c src/capture/xcomposite_cuda.c $opts $includes
@@ -32,7 +33,7 @@ build_gsr() {
gcc -c src/library_loader.c $opts $includes
g++ -c src/sound.cpp $opts $includes
g++ -c src/main.cpp $opts $includes
- g++ -o gpu-screen-recorder -O2 capture.o nvfbc.o kms_client.o egl.o cuda.o xnvctrl.o overclock.o window_texture.o shader.o color_conversion.o cursor.o utils.o library_loader.o xcomposite_cuda.o xcomposite_vaapi.o kms_vaapi.o sound.o main.o -s $libs
+ g++ -o gpu-screen-recorder -O2 capture.o nvfbc.o kms_client.o egl.o cuda.o xnvctrl.o overclock.o window_texture.o shader.o color_conversion.o cursor.o utils.o library_loader.o xcomposite_cuda.o xcomposite_vaapi.o kms_vaapi.o sound.o main.o $libs $opts
}
build_gsr_kms_server
diff --git a/include/egl.h b/include/egl.h
index fb8e887..e410958 100644
--- a/include/egl.h
+++ b/include/egl.h
@@ -90,6 +90,10 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void);
#define GL_COMPILE_STATUS 0x8B81
#define GL_LINK_STATUS 0x8B82
+typedef unsigned int (*FUNC_eglExportDMABUFImageQueryMESA)(EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, uint64_t *modifiers);
+typedef unsigned int (*FUNC_eglExportDMABUFImageMESA)(EGLDisplay dpy, EGLImageKHR image, int *fds, int32_t *strides, int32_t *offsets);
+typedef void (*FUNC_glEGLImageTargetTexture2DOES)(unsigned int target, GLeglImageOES image);
+
typedef struct {
void *egl_library;
void *gl_library;
@@ -115,9 +119,9 @@ typedef struct {
unsigned int (*eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
__eglMustCastToProperFunctionPointerType (*eglGetProcAddress)(const char *procname);
- unsigned int (*eglExportDMABUFImageQueryMESA)(EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, uint64_t *modifiers);
- unsigned int (*eglExportDMABUFImageMESA)(EGLDisplay dpy, EGLImageKHR image, int *fds, int32_t *strides, int32_t *offsets);
- void (*glEGLImageTargetTexture2DOES)(unsigned int target, GLeglImageOES image);
+ FUNC_eglExportDMABUFImageQueryMESA eglExportDMABUFImageQueryMESA;
+ FUNC_eglExportDMABUFImageMESA eglExportDMABUFImageMESA;
+ FUNC_glEGLImageTargetTexture2DOES glEGLImageTargetTexture2DOES;
unsigned int (*glGetError)(void);
const unsigned char* (*glGetString)(unsigned int name);
diff --git a/kms/client/kms_client.c b/kms/client/kms_client.c
index bdc556b..587dda3 100644
--- a/kms/client/kms_client.c
+++ b/kms/client/kms_client.c
@@ -96,6 +96,15 @@ static bool create_socket_path(char *output_path, size_t output_path_size) {
return true;
}
+static void strncpy_safe(char *dst, const char *src, int len) {
+ int src_len = strlen(src);
+ int min_len = src_len;
+ if(len - 1 < min_len)
+ min_len = len - 1;
+ memcpy(dst, src, min_len);
+ dst[min_len] = '\0';
+}
+
int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
self->kms_server_pid = -1;
self->socket_fd = -1;
@@ -152,7 +161,7 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
}
local_addr.sun_family = AF_UNIX;
- strncpy(local_addr.sun_path, self->socket_path, sizeof(local_addr.sun_path));
+ strncpy_safe(local_addr.sun_path, self->socket_path, sizeof(local_addr.sun_path));
if(bind(self->socket_fd, (struct sockaddr*)&local_addr, sizeof(local_addr.sun_family) + strlen(local_addr.sun_path)) == -1) {
fprintf(stderr, "gsr error: gsr_kms_client_init: failed to bind socket, error: %s\n", strerror(errno));
goto err;
diff --git a/kms/server/kms_server.c b/kms/server/kms_server.c
index 9f381f6..5aa6590 100644
--- a/kms/server/kms_server.c
+++ b/kms/server/kms_server.c
@@ -294,6 +294,15 @@ static double clock_get_monotonic_seconds(void) {
return (double)ts.tv_sec + (double)ts.tv_nsec * 0.000000001;
}
+static void strncpy_safe(char *dst, const char *src, int len) {
+ int src_len = strlen(src);
+ int min_len = src_len;
+ if(len - 1 < min_len)
+ min_len = len - 1;
+ memcpy(dst, src, min_len);
+ dst[min_len] = '\0';
+}
+
int main(int argc, char **argv) {
if(argc != 3) {
fprintf(stderr, "usage: kms_server <domain_socket_path> <card_path>\n");
@@ -329,7 +338,7 @@ int main(int argc, char **argv) {
while(clock_get_monotonic_seconds() - start_time < connect_timeout_sec) {
struct sockaddr_un remote_addr = {0};
remote_addr.sun_family = AF_UNIX;
- strncpy(remote_addr.sun_path, domain_socket_path, sizeof(remote_addr.sun_path));
+ strncpy_safe(remote_addr.sun_path, domain_socket_path, sizeof(remote_addr.sun_path));
// TODO: Check if parent disconnected
if(connect(socket_fd, (struct sockaddr*)&remote_addr, sizeof(remote_addr.sun_family) + strlen(remote_addr.sun_path)) == -1) {
if(errno == ECONNREFUSED || errno == ENOENT) {
diff --git a/kms/server/project.conf b/kms/server/project.conf
index cf863c1..26a1947 100644
--- a/kms/server/project.conf
+++ b/kms/server/project.conf
@@ -4,5 +4,8 @@ type = "executable"
version = "1.0.0"
platforms = ["posix"]
+[config]
+error_on_warning = "true"
+
[dependencies]
libdrm = ">=2"
diff --git a/project.conf b/project.conf
index ee1d00b..e517709 100644
--- a/project.conf
+++ b/project.conf
@@ -6,6 +6,7 @@ platforms = ["posix"]
[config]
ignore_dirs = ["kms/server"]
+error_on_warning = "true"
[dependencies]
libavcodec = ">=58"
diff --git a/src/capture/kms_vaapi.c b/src/capture/kms_vaapi.c
index 765da68..16c746c 100644
--- a/src/capture/kms_vaapi.c
+++ b/src/capture/kms_vaapi.c
@@ -135,6 +135,7 @@ static bool properties_has_atom(Atom *props, int nprop, Atom atom) {
}
static void monitor_callback(const XRROutputInfo *output_info, const XRRCrtcInfo *crt_info, const XRRModeInfo *mode_info, void *userdata) {
+ (void)mode_info;
MonitorCallbackUserdata *monitor_callback_userdata = userdata;
++monitor_callback_userdata->num_monitors;
@@ -436,6 +437,7 @@ static gsr_kms_response_fd* find_largest_drm(gsr_kms_response *kms_response) {
}
static int gsr_capture_kms_vaapi_capture(gsr_capture *cap, AVFrame *frame) {
+ (void)frame;
gsr_capture_kms_vaapi *cap_kms = cap->priv;
for(int i = 0; i < cap_kms->kms_response.num_fds; ++i) {
diff --git a/src/capture/nvfbc.c b/src/capture/nvfbc.c
index c45712d..32b83fc 100644
--- a/src/capture/nvfbc.c
+++ b/src/capture/nvfbc.c
@@ -95,6 +95,10 @@ static bool version_less_than(int major, int minor, int expected_major, int expe
return major < expected_major || (major == expected_major && minor < expected_minor);
}
+static void set_func_ptr(void **dst, void *src) {
+ *dst = src;
+}
+
static bool gsr_capture_nvfbc_load_library(gsr_capture *cap) {
gsr_capture_nvfbc *cap_nvfbc = cap->priv;
@@ -105,7 +109,7 @@ static bool gsr_capture_nvfbc_load_library(gsr_capture *cap) {
return false;
}
- cap_nvfbc->nv_fbc_create_instance = (PNVFBCCREATEINSTANCE)dlsym(lib, "NvFBCCreateInstance");
+ set_func_ptr((void**)&cap_nvfbc->nv_fbc_create_instance, dlsym(lib, "NvFBCCreateInstance"));
if(!cap_nvfbc->nv_fbc_create_instance) {
fprintf(stderr, "gsr error: unable to resolve symbol 'NvFBCCreateInstance'\n");
dlclose(lib);
diff --git a/src/capture/xcomposite_cuda.c b/src/capture/xcomposite_cuda.c
index f40f9d2..d6fc10b 100644
--- a/src/capture/xcomposite_cuda.c
+++ b/src/capture/xcomposite_cuda.c
@@ -477,7 +477,6 @@ static int gsr_capture_xcomposite_cuda_capture(gsr_capture *cap, AVFrame *frame)
}
static void gsr_capture_xcomposite_cuda_destroy(gsr_capture *cap, AVCodecContext *video_codec_context) {
- gsr_capture_xcomposite_cuda *cap_xcomp = cap->priv;
if(cap->priv) {
gsr_capture_xcomposite_cuda_stop(cap, video_codec_context);
free(cap->priv);
diff --git a/src/capture/xcomposite_vaapi.c b/src/capture/xcomposite_vaapi.c
index 5a39820..bb92f7f 100644
--- a/src/capture/xcomposite_vaapi.c
+++ b/src/capture/xcomposite_vaapi.c
@@ -606,7 +606,6 @@ static void gsr_capture_xcomposite_vaapi_stop(gsr_capture *cap, AVCodecContext *
static void gsr_capture_xcomposite_vaapi_destroy(gsr_capture *cap, AVCodecContext *video_codec_context) {
(void)video_codec_context;
- gsr_capture_xcomposite_vaapi *cap_xcomp = cap->priv;
if(cap->priv) {
gsr_capture_xcomposite_vaapi_stop(cap, video_codec_context);
free(cap->priv);
diff --git a/src/egl.c b/src/egl.c
index c830a70..a0fcc23 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -112,9 +112,9 @@ static bool gsr_egl_load_egl(gsr_egl *self, void *library) {
}
static bool gsr_egl_proc_load_egl(gsr_egl *self) {
- self->eglExportDMABUFImageQueryMESA = self->eglGetProcAddress("eglExportDMABUFImageQueryMESA");
- self->eglExportDMABUFImageMESA = self->eglGetProcAddress("eglExportDMABUFImageMESA");
- self->glEGLImageTargetTexture2DOES = self->eglGetProcAddress("glEGLImageTargetTexture2DOES");
+ self->eglExportDMABUFImageQueryMESA = (FUNC_eglExportDMABUFImageQueryMESA)self->eglGetProcAddress("eglExportDMABUFImageQueryMESA");
+ self->eglExportDMABUFImageMESA = (FUNC_eglExportDMABUFImageMESA)self->eglGetProcAddress("eglExportDMABUFImageMESA");
+ self->glEGLImageTargetTexture2DOES = (FUNC_glEGLImageTargetTexture2DOES)self->eglGetProcAddress("glEGLImageTargetTexture2DOES");
if(!self->glEGLImageTargetTexture2DOES) {
fprintf(stderr, "gsr error: gsr_egl_load failed: could not find glEGLImageTargetTexture2DOES\n");
diff --git a/src/main.cpp b/src/main.cpp
index ed757a4..7d03aeb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -46,6 +46,8 @@ static const int VIDEO_STREAM_INDEX = 0;
static thread_local char av_error_buffer[AV_ERROR_MAX_STRING_SIZE];
static void monitor_output_callback_print(const XRROutputInfo *output_info, const XRRCrtcInfo *crt_info, const XRRModeInfo *mode_info, void *userdata) {
+ (void)mode_info;
+ (void)userdata;
fprintf(stderr, " \"%.*s\" (%dx%d+%d+%d)\n", output_info->nameLen, output_info->name, (int)crt_info->width, (int)crt_info->height, crt_info->x, crt_info->y);
}
@@ -83,11 +85,11 @@ enum class FramerateMode {
VARIABLE
};
-static int x11_error_handler(Display *dpy, XErrorEvent *ev) {
+static int x11_error_handler(Display*, XErrorEvent*) {
return 0;
}
-static int x11_io_error_handler(Display *dpy) {
+static int x11_io_error_handler(Display*) {
return 0;
}
@@ -236,7 +238,7 @@ static AVSampleFormat audio_format_to_sample_format(const AudioFormat audio_form
return AV_SAMPLE_FMT_S16;
}
-static AVCodecContext* create_audio_codec_context(int fps, AudioCodec audio_codec, FramerateMode framerate_mode) {
+static AVCodecContext* create_audio_codec_context(int fps, AudioCodec audio_codec) {
const AVCodec *codec = avcodec_find_encoder(audio_codec_get_id(audio_codec));
if (!codec) {
fprintf(stderr, "Error: Could not find %s audio encoder\n", audio_codec_get_name(audio_codec));
@@ -1615,7 +1617,7 @@ int main(int argc, char **argv) {
int audio_stream_index = VIDEO_STREAM_INDEX + 1;
for(const MergedAudioInputs &merged_audio_inputs : requested_audio_inputs) {
- AVCodecContext *audio_codec_context = create_audio_codec_context(fps, audio_codec, framerate_mode);
+ AVCodecContext *audio_codec_context = create_audio_codec_context(fps, audio_codec);
AVStream *audio_stream = nullptr;
if(replay_buffer_size_secs == -1)
diff --git a/src/sound.cpp b/src/sound.cpp
index f29e474..c3aa4d4 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -309,6 +309,7 @@ static void pa_state_cb(pa_context *c, void *userdata) {
}
static void pa_sourcelist_cb(pa_context *ctx, const pa_source_info *source_info, int eol, void *userdata) {
+ (void)ctx;
if(eol > 0)
return;
diff --git a/src/utils.c b/src/utils.c
index 322d7d9..bee57f3 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -46,6 +46,7 @@ void for_each_active_monitor_output(Display *display, active_monitor_callback ca
}
static void get_monitor_by_name_callback(const XRROutputInfo *output_info, const XRRCrtcInfo *crt_info, const XRRModeInfo *mode_info, void *userdata) {
+ (void)mode_info;
get_monitor_by_name_userdata *data = (get_monitor_by_name_userdata*)userdata;
if(!data->found_monitor && data->name_len == output_info->nameLen && memcmp(data->name, output_info->name, data->name_len) == 0) {
data->monitor->pos = (vec2i){ .x = crt_info->x, .y = crt_info->y };