aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2026-08-01 18:51:59 +0200
committerdec05eba <dec05eba@protonmail.com>2026-08-01 18:51:59 +0200
commitc150d0e6ba0ab1f9ecd6a1c933a58050187e0c81 (patch)
tree3cae92f93009e87aeb2487afce569d6a20a8586c
parent9c2c0e1d0de9b3968415b08830a45f64091d3b98 (diff)
Add gsr_log logging module with log level and overridable log handler
-rw-r--r--include/log.h28
-rw-r--r--kms/client/kms_client.c61
-rw-r--r--meson.build1
-rw-r--r--src/args_parser.c103
-rw-r--r--src/capture/kms.c26
-rw-r--r--src/capture/nvfbc.c41
-rw-r--r--src/capture/portal.c53
-rw-r--r--src/capture/v4l2.c74
-rw-r--r--src/capture/xcomposite.c13
-rw-r--r--src/capture/ximage.c11
-rw-r--r--src/codec_query/nvenc.c25
-rw-r--r--src/codec_query/vaapi.c9
-rw-r--r--src/codec_query/vulkan.c27
-rw-r--r--src/color_conversion.c47
-rw-r--r--src/cuda.c13
-rw-r--r--src/cursor.c3
-rw-r--r--src/damage.c27
-rw-r--r--src/dbus.c115
-rw-r--r--src/egl.c43
-rw-r--r--src/encoder/encoder.c21
-rw-r--r--src/encoder/video/nvenc.c18
-rw-r--r--src/encoder/video/software.c7
-rw-r--r--src/encoder/video/vaapi.c38
-rw-r--r--src/encoder/video/vulkan.c38
-rw-r--r--src/image_writer.c7
-rw-r--r--src/kde_night_light.c3
-rw-r--r--src/library_loader.c3
-rw-r--r--src/log.c47
-rw-r--r--src/main.cpp267
-rw-r--r--src/pipewire_audio.c13
-rw-r--r--src/pipewire_video.c68
-rw-r--r--src/plugins.c23
-rw-r--r--src/replay_buffer/replay_buffer_disk.c17
-rw-r--r--src/shader.c11
-rw-r--r--src/sound.cpp11
-rw-r--r--src/utils.c15
-rw-r--r--src/wayland_host_bridge.c7
-rw-r--r--src/window/wayland.c17
-rw-r--r--src/window/x11.c5
39 files changed, 723 insertions, 633 deletions
diff --git a/include/log.h b/include/log.h
new file mode 100644
index 0000000..71be585
--- /dev/null
+++ b/include/log.h
@@ -0,0 +1,28 @@
+#ifndef GSR_LOG_H
+#define GSR_LOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ GSR_LOG_LEVEL_DEBUG,
+ GSR_LOG_LEVEL_INFO,
+ GSR_LOG_LEVEL_WARNING,
+ GSR_LOG_LEVEL_ERROR
+} gsr_log_level;
+
+/* The handler may be called from any thread. |message| has no prefix, level name or trailing newline */
+typedef void (*gsr_log_handler)(gsr_log_level level, const char *message, void *userdata);
+
+void gsr_log(gsr_log_level level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+/* Messages below |level| are discarded */
+void gsr_log_set_level(gsr_log_level level);
+/* A NULL |handler| restores the default handler which prints "gsr <level>: <message>" to stderr */
+void gsr_log_set_handler(gsr_log_handler handler, void *userdata);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GSR_LOG_H */
diff --git a/kms/client/kms_client.c b/kms/client/kms_client.c
index e37b4d5..4d70d78 100644
--- a/kms/client/kms_client.c
+++ b/kms/client/kms_client.c
@@ -1,4 +1,5 @@
#include "kms_client.h"
+#include "../../include/log.h"
#include "../../include/utils.h"
#include <stdio.h>
#include <string.h>
@@ -225,14 +226,14 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
struct sockaddr_un remote_addr = {0};
if(!create_socket_path(self->initial_socket_path, sizeof(self->initial_socket_path))) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: failed to create path to kms socket\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: failed to create path to kms socket");
return -1;
}
char server_filepath[PATH_MAX];
#ifdef __linux__
if(!readlink_realpath("/proc/self/exe", server_filepath)) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: failed to resolve /proc/self/exe\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: failed to resolve /proc/self/exe");
return -1;
}
@@ -241,7 +242,7 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
size_t size = PATH_MAX;
if (sysctl(mib, 4, server_filepath, &size, NULL, 0) != 0) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: failed to resolve pathname using sysctl\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: failed to resolve pathname using sysctl");
return -1;
}
@@ -251,19 +252,19 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
file_get_directory(server_filepath);
if(!strcat_safe(server_filepath, sizeof(server_filepath), "/gsr-kms-server")) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: gsr-kms-server path too long\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: gsr-kms-server path too long");
return -1;
}
if(access(server_filepath, F_OK) != 0) {
- fprintf(stderr, "gsr info: gsr_kms_client_init: gsr-kms-server is not installed in the same directory as gpu-screen-recorder (%s not found), looking for gsr-kms-server in PATH instead\n", server_filepath);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_kms_client_init: gsr-kms-server is not installed in the same directory as gpu-screen-recorder (%s not found), looking for gsr-kms-server in PATH instead", server_filepath);
if(!find_program_in_path("gsr-kms-server", server_filepath, sizeof(server_filepath)) || access(server_filepath, F_OK) != 0) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: gsr-kms-server was not found in PATH. Please install gpu-screen-recorder properly\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: gsr-kms-server was not found in PATH. Please install gpu-screen-recorder properly");
return -1;
}
}
- fprintf(stderr, "gsr info: gsr_kms_client_init: setting up connection to %s\n", server_filepath);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_kms_client_init: setting up connection to %s", server_filepath);
const bool inside_flatpak = getenv("FLATPAK_ID") != NULL;
const char *home = getenv("HOME");
@@ -288,23 +289,23 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
cap_free(kms_server_cap);
} else if(!inside_flatpak) {
if(errno == ENODATA)
- fprintf(stderr, "gsr info: gsr_kms_client_init: gsr-kms-server is missing sys_admin cap and will require root authentication. To bypass this automatically, run: sudo setcap cap_sys_admin+ep '%s'\n", server_filepath);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_kms_client_init: gsr-kms-server is missing sys_admin cap and will require root authentication. To bypass this automatically, run: sudo setcap cap_sys_admin+ep '%s'", server_filepath);
else
- fprintf(stderr, "gsr info: gsr_kms_client_init: failed to get cap\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_kms_client_init: failed to get cap");
}
#else
- fprintf(stderr, "gsr info: gsr_kms_client_init: platform doesn't support cap\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_kms_client_init: platform doesn't support cap");
#endif
}
if(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, self->socket_pair) == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: socketpair failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: socketpair failed, error: %s", strerror(errno));
goto err;
}
self->initial_socket_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if(self->initial_socket_fd == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: socket failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: socket failed, error: %s", strerror(errno));
goto err;
}
@@ -316,18 +317,18 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
umask(prev_mask);
if(bind_res == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: failed to bind socket, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: failed to bind socket, error: %s", strerror(errno));
goto err;
}
if(listen(self->initial_socket_fd, 1) == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: failed to listen on socket, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: failed to listen on socket, error: %s", strerror(errno));
goto err;
}
pid_t pid = fork();
if(pid == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: fork failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: fork failed, error: %s", strerror(errno));
goto err;
} else if(pid == 0) { /* child */
if(inside_flatpak) {
@@ -340,7 +341,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: failed to launch \"gsr-kms-server\", error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: failed to launch \"gsr-kms-server\", error: %s", strerror(errno));
_exit(127);
} else { /* parent */
self->kms_server_pid = pid;
@@ -348,7 +349,7 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
// We need this dumb-shit retardation with unix domain socket and then replace it with socketpair because
// pkexec doesn't work with socketpair................
- fprintf(stderr, "gsr info: gsr_kms_client_init: waiting for server to connect\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_kms_client_init: waiting for server to connect");
struct pollfd poll_fd = {
.fd = self->initial_socket_fd,
.events = POLLIN,
@@ -360,7 +361,7 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
socklen_t sock_len = 0;
self->initial_client_fd = accept(self->initial_socket_fd, (struct sockaddr*)&remote_addr, &sock_len);
if(self->initial_client_fd == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_init: accept failed on socket, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: accept failed on socket, error: %s", strerror(errno));
goto err;
}
break;
@@ -371,7 +372,7 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
int exit_code = -1;
if(WIFEXITED(status))
exit_code = WEXITSTATUS(status);
- fprintf(stderr, "gsr error: gsr_kms_client_init: kms server died or never started, exit code: %d\n", exit_code);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_init: kms server died or never started, exit code: %d", exit_code);
self->kms_server_pid = -1;
if(exit_code != 0)
result = exit_code;
@@ -380,14 +381,14 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
}
poll_fd.revents = 0;
}
- fprintf(stderr, "gsr info: gsr_kms_client_init: server connected\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_kms_client_init: server connected");
- fprintf(stderr, "gsr info: replacing file-backed unix domain socket with socketpair\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "replacing file-backed unix domain socket with socketpair");
if(gsr_kms_client_replace_connection(self) != 0)
goto err;
cleanup_socket(self, false);
- fprintf(stderr, "gsr info: using socketpair\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "using socketpair");
return 0;
@@ -445,21 +446,21 @@ int gsr_kms_client_replace_connection(gsr_kms_client *self) {
request.type = KMS_REQUEST_TYPE_REPLACE_CONNECTION;
request.new_connection_fd = self->socket_pair[GSR_SOCKET_PAIR_REMOTE];
if(send_msg_to_server(self->initial_client_fd, &request) == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_replace_connection: failed to send request message to server\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_replace_connection: failed to send request message to server");
return -1;
}
const int recv_res = recv_msg_from_server(self->kms_server_pid, self->socket_pair[GSR_SOCKET_PAIR_LOCAL], &response);
if(recv_res == 0) {
- fprintf(stderr, "gsr warning: gsr_kms_client_replace_connection: kms server shut down\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_kms_client_replace_connection: kms server shut down");
return -1;
} else if(recv_res == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_replace_connection: failed to receive response\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_replace_connection: failed to receive response");
return -1;
}
if(response.version != GSR_KMS_PROTOCOL_VERSION) {
- fprintf(stderr, "gsr error: gsr_kms_client_replace_connection: expected gsr-kms-server protocol version to be %u, but it's %u. please reinstall gpu screen recorder\n", GSR_KMS_PROTOCOL_VERSION, response.version);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_replace_connection: expected gsr-kms-server protocol version to be %u, but it's %u. please reinstall gpu screen recorder", GSR_KMS_PROTOCOL_VERSION, response.version);
/*close_fds(response);*/
return -1;
}
@@ -478,24 +479,24 @@ int gsr_kms_client_get_kms(gsr_kms_client *self, gsr_kms_response *response) {
request.type = KMS_REQUEST_TYPE_GET_KMS;
request.new_connection_fd = 0;
if(send_msg_to_server(self->socket_pair[GSR_SOCKET_PAIR_LOCAL], &request) == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_get_kms: failed to send request message to server\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_get_kms: failed to send request message to server");
strcpy(response->err_msg, "failed to send");
return -1;
}
const int recv_res = recv_msg_from_server(self->kms_server_pid, self->socket_pair[GSR_SOCKET_PAIR_LOCAL], response);
if(recv_res == 0) {
- fprintf(stderr, "gsr warning: gsr_kms_client_get_kms: kms server shut down\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_kms_client_get_kms: kms server shut down");
strcpy(response->err_msg, "failed to receive");
return -1;
} else if(recv_res == -1) {
- fprintf(stderr, "gsr error: gsr_kms_client_get_kms: failed to receive response\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_get_kms: failed to receive response");
strcpy(response->err_msg, "failed to receive");
return -1;
}
if(response->version != GSR_KMS_PROTOCOL_VERSION) {
- fprintf(stderr, "gsr error: gsr_kms_client_get_kms: expected gsr-kms-server protocol version to be %u, but it's %u. please reinstall gpu screen recorder\n", GSR_KMS_PROTOCOL_VERSION, response->version);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_kms_client_get_kms: expected gsr-kms-server protocol version to be %u, but it's %u. please reinstall gpu screen recorder", GSR_KMS_PROTOCOL_VERSION, response->version);
/*close_fds(response);*/
strcpy(response->err_msg, "mismatching protocol version");
return -1;
diff --git a/meson.build b/meson.build
index 4a79378..2bd947e 100644
--- a/meson.build
+++ b/meson.build
@@ -30,6 +30,7 @@ src = [
'src/replay_buffer/replay_buffer.c',
'src/replay_buffer/replay_buffer_ram.c',
'src/replay_buffer/replay_buffer_disk.c',
+ 'src/log.c',
'src/egl.c',
'src/cuda.c',
'src/window_texture.c',
diff --git a/src/args_parser.c b/src/args_parser.c
index c37712a..039dfca 100644
--- a/src/args_parser.c
+++ b/src/args_parser.c
@@ -1,4 +1,5 @@
#include "../include/args_parser.h"
+#include "../include/log.h"
#include "../include/defs.h"
#include "../include/egl.h"
#include "../include/window/window.h"
@@ -116,17 +117,18 @@ static bool arg_get_enum_value_by_name(const Arg *arg, const char *name, int *en
return false;
}
-static void arg_print_expected_enum_names(const Arg *arg) {
+static void arg_get_expected_enum_names(const Arg *arg, char *buf, size_t buf_size) {
assert(arg->type == ARG_TYPE_ENUM);
assert(arg->enum_values);
+ buf[0] = '\0';
+ size_t offset = 0;
for(int i = 0; i < arg->num_enum_values; ++i) {
- if(i > 0) {
- if(i == arg->num_enum_values -1)
- fprintf(stderr, " or ");
- else
- fprintf(stderr, ", ");
- }
- fprintf(stderr, "'%s'", arg->enum_values[i].name);
+ const char *separator = "";
+ if(i > 0)
+ separator = i == arg->num_enum_values - 1 ? " or " : ", ";
+ const int written = snprintf(buf + offset, offset < buf_size ? buf_size - offset : 0, "%s'%s'", separator, arg->enum_values[i].name);
+ if(written > 0)
+ offset += written;
}
}
@@ -280,11 +282,11 @@ static bool args_parser_set_values(args_parser *self) {
self->keyint = args_get_double_by_key(self->args, NUM_ARGS, "-keyint", 2.0);
if(overclock) {
- fprintf(stderr, "gsr info: the overclock option (-oc) is deprecated and no longer has any effect as it's no longer needed (on GPUs that are 12 years old or younger)\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "the overclock option (-oc) is deprecated and no longer has any effect as it's no longer needed (on GPUs that are 12 years old or younger)");
}
if(self->audio_codec == GSR_AUDIO_CODEC_FLAC) {
- fprintf(stderr, "gsr warning: flac audio codec is temporary disabled, using opus audio codec instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "flac audio codec is temporary disabled, using opus audio codec instead");
self->audio_codec = GSR_AUDIO_CODEC_OPUS;
}
@@ -292,7 +294,7 @@ static bool args_parser_set_values(args_parser *self) {
if(self->portal_session_token_filepath) {
int len = strlen(self->portal_session_token_filepath);
if(len > 0 && self->portal_session_token_filepath[len - 1] == '/') {
- fprintf(stderr, "gsr error: -portal-session-token-filepath should be a path to a file but it ends with a /: %s\n", self->portal_session_token_filepath);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "-portal-session-token-filepath should be a path to a file but it ends with a /: %s", self->portal_session_token_filepath);
return false;
}
}
@@ -301,13 +303,13 @@ static bool args_parser_set_values(args_parser *self) {
if(self->recording_saved_script) {
struct stat buf;
if(stat(self->recording_saved_script, &buf) == -1 || !S_ISREG(buf.st_mode)) {
- fprintf(stderr, "gsr error: Script \"%s\" either doesn't exist or it's not a file\n", self->recording_saved_script);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Script \"%s\" either doesn't exist or it's not a file", self->recording_saved_script);
usage();
return false;
}
if(!(buf.st_mode & S_IXUSR)) {
- fprintf(stderr, "gsr error: Script \"%s\" is not executable\n", self->recording_saved_script);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Script \"%s\" is not executable", self->recording_saved_script);
usage();
return false;
}
@@ -319,19 +321,19 @@ static bool args_parser_set_values(args_parser *self) {
if(self->bitrate_mode == GSR_BITRATE_MODE_CBR) {
if(!quality_str) {
- fprintf(stderr, "gsr error: option '-q' is required when using '-bm cbr' option\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "option '-q' is required when using '-bm cbr' option");
usage();
return false;
}
if(sscanf(quality_str, "%" PRIi64, &self->video_bitrate) != 1) {
- fprintf(stderr, "gsr error: -q argument \"%s\" is not an integer value. When using '-bm cbr' option '-q' is expected to be an integer value\n", quality_str);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "-q argument \"%s\" is not an integer value. When using '-bm cbr' option '-q' is expected to be an integer value", quality_str);
usage();
return false;
}
if(self->video_bitrate < 0) {
- fprintf(stderr, "gsr error: -q is expected to be 0 or larger, got %" PRIi64 "\n", self->video_bitrate);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "-q is expected to be 0 or larger, got %" PRIi64, self->video_bitrate);
usage();
return false;
}
@@ -350,7 +352,7 @@ static bool args_parser_set_values(args_parser *self) {
} else if(strcmp(quality_str, "ultra") == 0) {
self->video_quality = GSR_VIDEO_QUALITY_ULTRA;
} else {
- fprintf(stderr, "gsr error: -q should either be 'medium', 'high', 'very_high' or 'ultra', got: '%s'\n", quality_str);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "-q should either be 'medium', 'high', 'very_high' or 'ultra', got: '%s'", quality_str);
usage();
return false;
}
@@ -361,13 +363,13 @@ static bool args_parser_set_values(args_parser *self) {
const char *output_resolution_str = args_get_value_by_key(self->args, NUM_ARGS, "-s");
if(output_resolution_str) {
if(sscanf(output_resolution_str, "%dx%d", &self->output_resolution.x, &self->output_resolution.y) != 2) {
- fprintf(stderr, "gsr error: invalid value for option -s '%s', expected a value in format WxH\n", output_resolution_str);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid value for option -s '%s', expected a value in format WxH", output_resolution_str);
usage();
return false;
}
if(self->output_resolution.x < 0 || self->output_resolution.y < 0) {
- fprintf(stderr, "gsr error: invalid value for option -s '%s', expected width and height to be greater or equal to 0\n", output_resolution_str);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid value for option -s '%s', expected width and height to be greater or equal to 0", output_resolution_str);
usage();
return false;
}
@@ -378,13 +380,13 @@ static bool args_parser_set_values(args_parser *self) {
const char *region_str = args_get_value_by_key(self->args, NUM_ARGS, "-region");
if(region_str) {
if(sscanf(region_str, "%dx%d+%d+%d", &self->region_size.x, &self->region_size.y, &self->region_position.x, &self->region_position.y) != 4) {
- fprintf(stderr, "gsr error: invalid value for option -region '%s', expected a value in format WxH+X+Y\n", region_str);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid value for option -region '%s', expected a value in format WxH+X+Y", region_str);
usage();
return false;
}
if(self->region_size.x < 0 || self->region_size.y < 0) {
- fprintf(stderr, "gsr error: invalid value for option -region '%s', expected width and height to be greater or equal to 0\n", region_str);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid value for option -region '%s', expected width and height to be greater or equal to 0", region_str);
usage();
return false;
}
@@ -406,7 +408,7 @@ static bool args_parser_set_values(args_parser *self) {
self->is_livestream = is_livestream_path(self->filename);
if(self->is_livestream) {
if(self->is_replaying) {
- fprintf(stderr, "gsr error: replay mode is not applicable to live streaming\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "replay mode is not applicable to live streaming");
return false;
}
} else {
@@ -416,20 +418,20 @@ static bool args_parser_set_values(args_parser *self) {
char *directory = dirname(directory_buf);
if(strcmp(directory, ".") != 0 && strcmp(directory, "/") != 0) {
if(create_directory_recursive(directory) != 0) {
- fprintf(stderr, "gsr error: failed to create directory for output file: %s\n", self->filename);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create directory for output file: %s", self->filename);
return false;
}
}
} else {
if(!self->container_format) {
- fprintf(stderr, "gsr error: option -c is required when using option -r\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "option -c is required when using option -r");
usage();
return false;
}
struct stat buf;
if(stat(self->filename, &buf) != -1 && !S_ISDIR(buf.st_mode)) {
- fprintf(stderr, "gsr error: File \"%s\" exists but it's not a directory\n", self->filename);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "File \"%s\" exists but it's not a directory", self->filename);
usage();
return false;
}
@@ -439,13 +441,13 @@ static bool args_parser_set_values(args_parser *self) {
if(!self->is_replaying) {
self->filename = "/dev/stdout";
} else {
- fprintf(stderr, "gsr error: Option -o is required when using option -r\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Option -o is required when using option -r");
usage();
return false;
}
if(!self->container_format) {
- fprintf(stderr, "gsr error: option -c is required when not using option -o\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "option -c is required when not using option -o");
usage();
return false;
}
@@ -454,14 +456,14 @@ static bool args_parser_set_values(args_parser *self) {
self->is_output_piped = file_is_pipe_or_char_device(self->filename);
self->low_latency_recording = self->is_livestream || self->is_output_piped;
if(self->write_first_frame_ts && (self->is_livestream || self->is_output_piped)) {
- fprintf(stderr, "gsr warning: -write-first-frame-ts is ignored for livestreaming or when output is piped\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "-write-first-frame-ts is ignored for livestreaming or when output is piped");
self->write_first_frame_ts = false;
}
self->replay_recording_directory = args_get_value_by_key(self->args, NUM_ARGS, "-ro");
if(self->is_livestream && self->recording_saved_script) {
- fprintf(stderr, "gsr warning: live stream detected, -sc script is ignored\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "live stream detected, -sc script is ignored");
self->recording_saved_script = NULL;
}
@@ -515,7 +517,7 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
arg_handlers->list_capture_options(card_path, userdata);
return true;
} else {
- fprintf(stderr, "gsr error: expected --list-capture-options to be called with either no extra arguments or 1 extra argument (card path)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "expected --list-capture-options to be called with either no extra arguments or 1 extra argument (card path)");
return false;
}
}
@@ -575,19 +577,19 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
const char *arg_name = argv[i];
Arg *arg = args_get_by_key(self->args, NUM_ARGS, arg_name);
if(!arg) {
- fprintf(stderr, "gsr error: invalid argument '%s'\n", arg_name);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid argument '%s'", arg_name);
usage();
return false;
}
if(arg->num_values > 0 && !arg->list) {
- fprintf(stderr, "gsr error: expected argument '%s' to only be specified once\n", arg_name);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "expected argument '%s' to only be specified once", arg_name);
usage();
return false;
}
if(i + 1 >= argc) {
- fprintf(stderr, "gsr error: missing value for argument '%s'\n", arg_name);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "missing value for argument '%s'", arg_name);
usage();
return false;
}
@@ -603,7 +605,7 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
} else if(strcmp(arg_value, "no") == 0) {
arg->typed_value.boolean = false;
} else {
- fprintf(stderr, "gsr error: %s should either be 'yes' or 'no', got: '%s'\n", arg_name, arg_value);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "%s should either be 'yes' or 'no', got: '%s'", arg_name, arg_value);
usage();
return false;
}
@@ -611,9 +613,9 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
}
case ARG_TYPE_ENUM: {
if(!arg_get_enum_value_by_name(arg, arg_value, &arg->typed_value.enum_value)) {
- fprintf(stderr, "gsr error: %s should either be ", arg_name);
- arg_print_expected_enum_names(arg);
- fprintf(stderr, ", got: '%s'\n", arg_value);
+ char expected_enum_names[512];
+ arg_get_expected_enum_names(arg, expected_enum_names, sizeof(expected_enum_names));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "%s should either be %s, got: '%s'", arg_name, expected_enum_names, arg_value);
usage();
return false;
}
@@ -621,19 +623,19 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
}
case ARG_TYPE_I64: {
if(sscanf(arg_value, "%" PRIi64, &arg->typed_value.i64_value) != 1) {
- fprintf(stderr, "gsr error: %s argument \"%s\" is not an integer\n", arg_name, arg_value);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "%s argument \"%s\" is not an integer", arg_name, arg_value);
usage();
return false;
}
if(arg->typed_value.i64_value < arg->integer_value_min) {
- fprintf(stderr, "gsr error: %s argument is expected to be larger than %" PRIi64 ", got %" PRIi64 "\n", arg_name, arg->integer_value_min, arg->typed_value.i64_value);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "%s argument is expected to be larger than %" PRIi64 ", got %" PRIi64, arg_name, arg->integer_value_min, arg->typed_value.i64_value);
usage();
return false;
}
if(arg->typed_value.i64_value > arg->integer_value_max) {
- fprintf(stderr, "gsr error: %s argument is expected to be less than %" PRIi64 ", got %" PRIi64 "\n", arg_name, arg->integer_value_max, arg->typed_value.i64_value);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "%s argument is expected to be less than %" PRIi64 ", got %" PRIi64, arg_name, arg->integer_value_max, arg->typed_value.i64_value);
usage();
return false;
}
@@ -641,19 +643,19 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
}
case ARG_TYPE_DOUBLE: {
if(sscanf(arg_value, "%lf", &arg->typed_value.d_value) != 1) {
- fprintf(stderr, "gsr error: %s argument \"%s\" is not an floating-point number\n", arg_name, arg_value);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "%s argument \"%s\" is not an floating-point number", arg_name, arg_value);
usage();
return false;
}
if(arg->typed_value.d_value < arg->integer_value_min) {
- fprintf(stderr, "gsr error: %s argument is expected to be larger than %" PRIi64 ", got %lf\n", arg_name, arg->integer_value_min, arg->typed_value.d_value);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "%s argument is expected to be larger than %" PRIi64 ", got %lf", arg_name, arg->integer_value_min, arg->typed_value.d_value);
usage();
return false;
}
if(arg->typed_value.d_value > arg->integer_value_max) {
- fprintf(stderr, "gsr error: %s argument is expected to be less than %" PRIi64 ", got %lf\n", arg_name, arg->integer_value_max, arg->typed_value.d_value);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "%s argument is expected to be less than %" PRIi64 ", got %lf", arg_name, arg->integer_value_max, arg->typed_value.d_value);
usage();
return false;
}
@@ -662,7 +664,7 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
}
if(!arg_append_value(arg, arg_value)) {
- fprintf(stderr, "gsr error: failed to append argument, out of memory\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to append argument, out of memory");
return false;
}
}
@@ -670,7 +672,7 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
for(int i = 0; i < NUM_ARGS; ++i) {
const Arg *arg = &self->args[i];
if(!arg->optional && arg->num_values == 0) {
- fprintf(stderr, "gsr error: missing argument '%s'\n", arg->key);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "missing argument '%s'", arg->key);
usage();
return false;
}
@@ -694,28 +696,27 @@ bool args_parser_validate_with_gl_info(args_parser *self, gsr_egl *egl) {
}
if(egl->gpu_info.is_steam_deck && self->bitrate_mode == GSR_BITRATE_MODE_QP) {
- fprintf(stderr, "gsr warning: qp bitrate mode is not supported on Steam Deck because of Steam Deck driver bugs. Using vbr instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "qp bitrate mode is not supported on Steam Deck because of Steam Deck driver bugs. Using vbr instead");
self->bitrate_mode = GSR_BITRATE_MODE_VBR;
}
if(self->video_encoder == GSR_VIDEO_ENCODER_HW_CPU && self->bitrate_mode == GSR_BITRATE_MODE_VBR) {
- fprintf(stderr, "gsr warning: bitrate mode has been forcefully set to qp because software encoding option doesn't support vbr option\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "bitrate mode has been forcefully set to qp because software encoding option doesn't support vbr option");
self->bitrate_mode = GSR_BITRATE_MODE_QP;
}
if(egl->gpu_info.is_steam_deck) {
- fprintf(stderr, "gsr warning: steam deck has multiple driver issues. One of them has been reported here: https://github.com/ValveSoftware/SteamOS/issues/1609\n"
- "If you have issues with GPU Screen Recorder on steam deck that you don't have on a desktop computer then report the issue to Valve and/or AMD.\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "steam deck has multiple driver issues. One of them has been reported here: https://github.com/ValveSoftware/SteamOS/issues/1609\nIf you have issues with GPU Screen Recorder on steam deck that you don't have on a desktop computer then report the issue to Valve and/or AMD.");
}
self->very_old_gpu = false;
if(egl->gpu_info.vendor == GSR_GPU_VENDOR_NVIDIA && egl->gpu_info.gpu_version != 0 && egl->gpu_info.gpu_version < 900) {
- fprintf(stderr, "gsr info: your gpu appears to be very old (older than maxwell architecture). Switching to lower preset\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "your gpu appears to be very old (older than maxwell architecture). Switching to lower preset");
self->very_old_gpu = true;
}
if(video_codec_is_hdr(self->video_codec) && !wayland) {
- fprintf(stderr, "gsr error: hdr video codec option %s is not available on X11\n", video_codec_to_string(self->video_codec));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "hdr video codec option %s is not available on X11", video_codec_to_string(self->video_codec));
usage();
return false;
}
diff --git a/src/capture/kms.c b/src/capture/kms.c
index 0f7c37c..4048a7f 100644
--- a/src/capture/kms.c
+++ b/src/capture/kms.c
@@ -1,4 +1,5 @@
#include "../../include/capture/kms.h"
+#include "../../include/log.h"
#include "../../include/utils.h"
#include "../../include/color_conversion.h"
#include "../../include/cursor.h"
@@ -159,7 +160,7 @@ static void monitor_callback(const gsr_monitor *monitor, void *userdata) {
}
if(monitor_callback_userdata->monitor_id->num_connector_ids == MAX_CONNECTOR_IDS)
- fprintf(stderr, "gsr warning: reached max connector ids\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "reached max connector ids");
}
static vec2i rotate_capture_size_if_rotated(gsr_capture_kms *self, vec2i capture_size, gsr_monitor_rotation rotation) {
@@ -191,7 +192,7 @@ static int gsr_capture_kms_start(gsr_capture *cap, gsr_capture_metadata *capture
for_each_active_monitor_output(self->params.egl->window, self->params.egl->card_path, connection_type, monitor_callback, &monitor_callback_userdata);
if(!get_monitor_by_name(self->params.egl, connection_type, self->params.display_to_capture, &monitor)) {
- fprintf(stderr, "gsr error: gsr_capture_kms_start: failed to find monitor by name \"%s\"\n", self->params.display_to_capture);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_kms_start: failed to find monitor by name \"%s\"", self->params.display_to_capture);
gsr_capture_kms_stop(self);
return -1;
}
@@ -454,7 +455,7 @@ static void gsr_capture_kms_update_hdr_color_transforms(gsr_capture_kms *self, g
const bool night_light = self->params.kde_night_light && gsr_kde_night_light_get_inverse_matrix(self->params.kde_night_light, night_light_compensation, night_light_container_primaries, night_light_matrix);
if(night_light && !self->night_light_message_shown) {
self->night_light_message_shown = true;
- fprintf(stderr, "gsr info: gsr_capture_kms_update_hdr_color_transforms: night light is active, removing the night light tint from the capture\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_kms_update_hdr_color_transforms: night light is active, removing the night light tint from the capture");
}
/* The compositor applies the night light tint at scanout with the crtc gamma lut when it offloads its color transforms to the crtc
@@ -468,24 +469,21 @@ static void gsr_capture_kms_update_hdr_color_transforms(gsr_capture_kms *self, g
luminance_scale = SDR_WHITE_LUMINANCE_REFERENCE / sdr_white_luminance;
if(luminance_scale != 1.0f && !self->hdr_luminance_message_shown) {
self->hdr_luminance_message_shown = true;
- fprintf(stderr, "gsr info: gsr_capture_kms_update_hdr_color_transforms: scaling the luminance of the hdr video from sdr white at %d nits to sdr white at %d nits (hdr peak luminance: %d nits)\n",
- (int)sdr_white_luminance, (int)SDR_WHITE_LUMINANCE_REFERENCE, (int)(hdr_peak_luminance * luminance_scale));
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_kms_update_hdr_color_transforms: scaling the luminance of the hdr video from sdr white at %d nits to sdr white at %d nits (hdr peak luminance: %d nits)", (int)sdr_white_luminance, (int)SDR_WHITE_LUMINANCE_REFERENCE, (int)(hdr_peak_luminance * luminance_scale));
}
}
const bool convert_sdr_to_hdr = self->params.hdr && !plane_is_hdr;
if(convert_sdr_to_hdr && !self->hdr_luminance_message_shown) {
self->hdr_luminance_message_shown = true;
- fprintf(stderr, "gsr info: gsr_capture_kms_update_hdr_color_transforms: the monitor is in sdr mode, converting the captured sdr image to hdr (BT.709 to BT.2020 with sdr white at %d nits)\n",
- (int)SDR_WHITE_LUMINANCE_REFERENCE);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_kms_update_hdr_color_transforms: the monitor is in sdr mode, converting the captured sdr image to hdr (BT.709 to BT.2020 with sdr white at %d nits)", (int)SDR_WHITE_LUMINANCE_REFERENCE);
}
const bool tone_map_hdr_to_sdr = !self->params.hdr && plane_is_hdr;
gsr_color_conversion_set_hdr_to_sdr_tone_mapping(color_conversion, tone_map_hdr_to_sdr, hdr_peak_luminance, sdr_white_luminance);
if(tone_map_hdr_to_sdr && !self->tone_mapping_message_shown) {
self->tone_mapping_message_shown = true;
- fprintf(stderr, "gsr info: gsr_capture_kms_update_hdr_color_transforms: the monitor is in hdr mode, tone mapping the hdr content to sdr (sdr white luminance: %d nits, hdr peak luminance: %d nits). Record with -k hevc_hdr or -k av1_hdr video codec option to record hdr instead\n",
- (int)sdr_white_luminance, (int)hdr_peak_luminance);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_kms_update_hdr_color_transforms: the monitor is in hdr mode, tone mapping the hdr content to sdr (sdr white luminance: %d nits, hdr peak luminance: %d nits). Record with -k hevc_hdr or -k av1_hdr video codec option to record hdr instead", (int)sdr_white_luminance, (int)hdr_peak_luminance);
}
if(convert_sdr_to_hdr) {
@@ -615,7 +613,7 @@ static EGLImage gsr_capture_kms_create_egl_image_with_fallback(gsr_capture_kms *
} else {
image = gsr_capture_kms_create_egl_image(self, drm_fd, fds, offsets, pitches, modifiers, true);
if(!image) {
- fprintf(stderr, "gsr error: gsr_capture_kms_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_kms_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers");
self->no_modifiers_fallback = true;
image = gsr_capture_kms_create_egl_image(self, drm_fd, fds, offsets, pitches, modifiers, false);
}
@@ -638,7 +636,7 @@ static void gsr_capture_kms_bind_image_to_input_texture_with_fallback(gsr_captur
gsr_capture_kms_bind_image_to_texture(self, image, self->external_input_texture_id, true);
} else {
if(!gsr_capture_kms_bind_image_to_texture(self, image, self->input_texture_id, false)) {
- fprintf(stderr, "gsr error: gsr_capture_kms_capture: failed to bind image to texture, trying with external texture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_kms_capture: failed to bind image to texture, trying with external texture");
self->external_texture_fallback = true;
gsr_capture_kms_bind_image_to_texture(self, image, self->external_input_texture_id, true);
}
@@ -824,7 +822,7 @@ static void gsr_capture_kms_update_connector_ids(gsr_capture_kms *self) {
gsr_monitor monitor;
if(!get_monitor_by_name(self->params.egl, connection_type, self->params.display_to_capture, &monitor)) {
- fprintf(stderr, "gsr error: gsr_capture_kms_update_connector_ids: failed to find monitor by name \"%s\"\n", self->params.display_to_capture);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_kms_update_connector_ids: failed to find monitor by name \"%s\"", self->params.display_to_capture);
return;
}
@@ -851,7 +849,7 @@ static void gsr_capture_kms_pre_capture(gsr_capture *cap, gsr_capture_metadata *
static bool error_shown = false;
if(!error_shown) {
error_shown = true;
- fprintf(stderr, "gsr error: gsr_capture_kms_pre_capture: no drm found, capture will fail\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_kms_pre_capture: no drm found, capture will fail");
}
return;
}
@@ -1105,7 +1103,7 @@ static void gsr_capture_kms_destroy(gsr_capture *cap) {
gsr_capture* gsr_capture_kms_create(const gsr_capture_kms_params *params) {
if(!params) {
- fprintf(stderr, "gsr error: gsr_capture_kms_create params is NULL\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_kms_create params is NULL");
return NULL;
}
diff --git a/src/capture/nvfbc.c b/src/capture/nvfbc.c
index 1504323..41e2466 100644
--- a/src/capture/nvfbc.c
+++ b/src/capture/nvfbc.c
@@ -1,4 +1,5 @@
#include "../../include/capture/nvfbc.h"
+#include "../../include/log.h"
#include "../../external/NvFBC.h"
#include "../../include/egl.h"
#include "../../include/utils.h"
@@ -74,13 +75,13 @@ static bool gsr_capture_nvfbc_load_library(gsr_capture *cap) {
dlerror(); /* clear */
void *lib = dlopen("libnvidia-fbc.so.1", RTLD_LAZY);
if(!lib) {
- fprintf(stderr, "gsr error: failed to load libnvidia-fbc.so.1, error: %s\n", dlerror());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to load libnvidia-fbc.so.1, error: %s", dlerror());
return false;
}
set_func_ptr((void**)&self->nv_fbc_create_instance, dlsym(lib, "NvFBCCreateInstance"));
if(!self->nv_fbc_create_instance) {
- fprintf(stderr, "gsr error: unable to resolve symbol 'NvFBCCreateInstance'\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "unable to resolve symbol 'NvFBCCreateInstance'");
dlclose(lib);
return false;
}
@@ -89,7 +90,7 @@ static bool gsr_capture_nvfbc_load_library(gsr_capture *cap) {
self->nv_fbc_function_list.dwVersion = NVFBC_VERSION;
NVFBCSTATUS status = self->nv_fbc_create_instance(&self->nv_fbc_function_list);
if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "gsr error: failed to create NvFBC instance (status: %d)\n", status);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create NvFBC instance (status: %d)", status);
dlclose(lib);
return false;
}
@@ -143,7 +144,7 @@ static int gsr_capture_nvfbc_setup_handle(gsr_capture_nvfbc *self) {
status = self->nv_fbc_function_list.nvFBCCreateHandle(&self->nv_fbc_handle, &create_params);
if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_start failed: %s\n", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_start failed: %s", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle));
goto error_cleanup;
}
}
@@ -155,12 +156,12 @@ static int gsr_capture_nvfbc_setup_handle(gsr_capture_nvfbc *self) {
status = self->nv_fbc_function_list.nvFBCGetStatus(self->nv_fbc_handle, &status_params);
if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_start failed: %s\n", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_start failed: %s", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle));
goto error_cleanup;
}
if(status_params.bCanCreateNow == NVFBC_FALSE) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_start failed: it's not possible to create a capture session on this system\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_start failed: it's not possible to create a capture session on this system");
goto error_cleanup;
}
@@ -172,18 +173,18 @@ static int gsr_capture_nvfbc_setup_handle(gsr_capture_nvfbc *self) {
self->tracking_type = strcmp(self->params.display_to_capture, "screen") == 0 ? NVFBC_TRACKING_SCREEN : NVFBC_TRACKING_OUTPUT;
if(self->tracking_type == NVFBC_TRACKING_OUTPUT) {
if(!status_params.bXRandRAvailable) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_start failed: the xrandr extension is not available\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_start failed: the xrandr extension is not available");
goto error_cleanup;
}
if(status_params.bInModeset) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_start failed: the x server is in modeset, unable to record\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_start failed: the x server is in modeset, unable to record");
goto error_cleanup;
}
self->output_id = get_output_id_from_display_name(status_params.outputs, status_params.dwOutputNum, self->params.display_to_capture, &self->tracking_width, &self->tracking_height);
if(self->output_id == 0) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_start failed: display '%s' not found\n", self->params.display_to_capture);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_start failed: display '%s' not found", self->params.display_to_capture);
goto error_cleanup;
}
}
@@ -215,7 +216,7 @@ static int gsr_capture_nvfbc_setup_session(gsr_capture_nvfbc *self) {
NVFBCSTATUS status = self->nv_fbc_function_list.nvFBCCreateCaptureSession(self->nv_fbc_handle, &create_capture_params);
if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_start failed: %s\n", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_start failed: %s", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle));
return -1;
}
self->capture_session_created = true;
@@ -226,7 +227,7 @@ static int gsr_capture_nvfbc_setup_session(gsr_capture_nvfbc *self) {
status = self->nv_fbc_function_list.nvFBCToGLSetUp(self->nv_fbc_handle, &self->setup_params);
if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_start failed: %s\n", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_start failed: %s", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle));
gsr_capture_nvfbc_destroy_session(self);
return -1;
}
@@ -256,12 +257,12 @@ static int gsr_capture_nvfbc_start(gsr_capture *cap, gsr_capture_metadata *captu
int driver_major_version = 0;
int driver_minor_version = 0;
if(self->params.direct_capture && get_nvidia_driver_version(&driver_major_version, &driver_minor_version)) {
- fprintf(stderr, "gsr info: detected nvidia version: %d.%d\n", driver_major_version, driver_minor_version);
+ gsr_log(GSR_LOG_LEVEL_INFO, "detected nvidia version: %d.%d", driver_major_version, driver_minor_version);
// TODO:
if(version_at_least(driver_major_version, driver_minor_version, 515, 57) && version_less_than(driver_major_version, driver_minor_version, 520, 56)) {
self->params.direct_capture = false;
- fprintf(stderr, "gsr warning: \"screen-direct\" has temporary been disabled as it causes stuttering with driver versions >= 515.57 and < 520.56. Please update your driver if possible. Capturing \"screen\" instead.\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "\"screen-direct\" has temporary been disabled as it causes stuttering with driver versions >= 515.57 and < 520.56. Please update your driver if possible. Capturing \"screen\" instead.");
}
// TODO:
@@ -271,7 +272,7 @@ static int gsr_capture_nvfbc_start(gsr_capture *cap, gsr_capture_metadata *captu
if(version_at_least(driver_major_version, driver_minor_version, 515, 57))
self->supports_direct_cursor = true;
else
- fprintf(stderr, "gsr info: capturing \"screen-direct\" but driver version appears to be less than 515.57. Disabling capture of cursor. Please update your driver if you want to capture your cursor or record \"screen\" instead.\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "capturing \"screen-direct\" but driver version appears to be less than 515.57. Disabling capture of cursor. Please update your driver if you want to capture your cursor or record \"screen\" instead.");
}
*/
}
@@ -349,16 +350,16 @@ static int gsr_capture_nvfbc_capture(gsr_capture *cap, gsr_capture_metadata *cap
gsr_capture_nvfbc_destroy_session_and_handle(self);
if(gsr_capture_nvfbc_setup_handle(self) != 0) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_capture failed to recreate nvfbc handle, trying again in %f second(s)\n", nvfbc_recreate_retry_time_seconds);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_capture failed to recreate nvfbc handle, trying again in %f second(s)", nvfbc_recreate_retry_time_seconds);
return -1;
}
if(gsr_capture_nvfbc_setup_session(self) != 0) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_capture failed to recreate nvfbc session, trying again in %f second(s)\n", nvfbc_recreate_retry_time_seconds);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_capture failed to recreate nvfbc session, trying again in %f second(s)", nvfbc_recreate_retry_time_seconds);
return -1;
}
- fprintf(stderr, "gsr info: gsr_capture_nvfbc_capture: recreated nvfbc session after modeset recovery\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_nvfbc_capture: recreated nvfbc session after modeset recovery");
self->nvfbc_needs_recreate = false;
} else {
return 0;
@@ -385,7 +386,7 @@ static int gsr_capture_nvfbc_capture(gsr_capture *cap, gsr_capture_metadata *cap
NVFBCSTATUS status = self->nv_fbc_function_list.nvFBCToGLGrabFrame(self->nv_fbc_handle, &grab_params);
if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_capture failed: %s (%d), recreating session after %f second(s)\n", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle), status, nvfbc_recreate_retry_time_seconds);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_capture failed: %s (%d), recreating session after %f second(s)", self->nv_fbc_function_list.nvFBCGetLastErrorStr(self->nv_fbc_handle), status, nvfbc_recreate_retry_time_seconds);
self->nvfbc_needs_recreate = true;
self->nvfbc_dead_start = clock_get_monotonic_seconds();
return 0;
@@ -414,12 +415,12 @@ static void gsr_capture_nvfbc_destroy(gsr_capture *cap) {
gsr_capture* gsr_capture_nvfbc_create(const gsr_capture_nvfbc_params *params) {
if(!params) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_create params is NULL\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_create params is NULL");
return NULL;
}
if(!params->display_to_capture) {
- fprintf(stderr, "gsr error: gsr_capture_nvfbc_create params.display_to_capture is NULL\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_nvfbc_create params.display_to_capture is NULL");
return NULL;
}
diff --git a/src/capture/portal.c b/src/capture/portal.c
index fd1caec..622cf4a 100644
--- a/src/capture/portal.c
+++ b/src/capture/portal.c
@@ -1,4 +1,5 @@
#include "../../include/capture/portal.h"
+#include "../../include/log.h"
#include "../../include/color_conversion.h"
#include "../../include/egl.h"
#include "../../include/utils.h"
@@ -111,7 +112,7 @@ static bool create_directory_to_file(const char *filepath) {
snprintf(dir, sizeof(dir), "%.*s", (int)(split - filepath), filepath);
if(create_directory_recursive(dir) != 0) {
- fprintf(stderr, "gsr warning: gsr_capture_portal_save_restore_token: failed to create directory (%s) for restore token\n", dir);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_capture_portal_save_restore_token: failed to create directory (%s) for restore token", dir);
return false;
}
return true;
@@ -130,18 +131,18 @@ static void gsr_capture_portal_save_restore_token(const char *restore_token, con
FILE *f = fopen(restore_token_path, "wb");
if(!f) {
- fprintf(stderr, "gsr warning: gsr_capture_portal_save_restore_token: failed to create restore token file (%s)\n", restore_token_path);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_capture_portal_save_restore_token: failed to create restore token file (%s)", restore_token_path);
return;
}
const int restore_token_len = strlen(restore_token);
if((long)fwrite(restore_token, 1, restore_token_len, f) != restore_token_len) {
- fprintf(stderr, "gsr warning: gsr_capture_portal_save_restore_token: failed to write restore token to file (%s)\n", restore_token_path);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_capture_portal_save_restore_token: failed to write restore token to file (%s)", restore_token_path);
fclose(f);
return;
}
- fprintf(stderr, "gsr info: gsr_capture_portal_save_restore_token: saved restore token to cache (%s)\n", restore_token);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_save_restore_token: saved restore token to cache (%s)", restore_token);
fclose(f);
}
@@ -158,7 +159,7 @@ static void gsr_capture_portal_get_restore_token_from_cache(char *buffer, size_t
FILE *f = fopen(restore_token_path, "rb");
if(!f) {
- fprintf(stderr, "gsr info: gsr_capture_portal_get_restore_token_from_cache: no restore token found in cache or failed to load (%s)\n", restore_token_path);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_get_restore_token_from_cache: no restore token found in cache or failed to load (%s)", restore_token_path);
return;
}
@@ -168,7 +169,7 @@ static void gsr_capture_portal_get_restore_token_from_cache(char *buffer, size_t
if(file_size > 0 && file_size < 1024 && file_size < (long)buffer_size && (long)fread(buffer, 1, file_size, f) != file_size) {
buffer[0] = '\0';
- fprintf(stderr, "gsr warning: gsr_capture_portal_get_restore_token_from_cache: failed to read restore token (%s)\n", restore_token_path);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_capture_portal_get_restore_token_from_cache: failed to read restore token (%s)", restore_token_path);
fclose(f);
return;
}
@@ -176,7 +177,7 @@ static void gsr_capture_portal_get_restore_token_from_cache(char *buffer, size_t
if(file_size > 0 && file_size < (long)buffer_size)
buffer[file_size] = '\0';
- fprintf(stderr, "gsr info: gsr_capture_portal_get_restore_token_from_cache: read cached restore token (%s)\n", buffer);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_get_restore_token_from_cache: read cached restore token (%s)", buffer);
fclose(f);
}
@@ -193,24 +194,24 @@ static int gsr_capture_portal_setup_dbus(gsr_capture_portal *self, int *pipewire
if(!gsr_dbus_init(&self->dbus, restore_token))
return -1;
- fprintf(stderr, "gsr info: gsr_capture_portal_setup_dbus: CreateSession\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_setup_dbus: CreateSession");
response_status = gsr_dbus_screencast_create_session(&self->dbus, &self->session_handle);
if(response_status != 0) {
- fprintf(stderr, "gsr error: gsr_capture_portal_setup_dbus: CreateSession failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_portal_setup_dbus: CreateSession failed");
return response_status;
}
- fprintf(stderr, "gsr info: gsr_capture_portal_setup_dbus: SelectSources\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_setup_dbus: SelectSources");
response_status = gsr_dbus_screencast_select_sources(&self->dbus, self->session_handle, GSR_PORTAL_CAPTURE_TYPE_ALL, self->params.record_cursor ? GSR_PORTAL_CURSOR_MODE_METADATA : GSR_PORTAL_CURSOR_MODE_HIDDEN);
if(response_status != 0) {
- fprintf(stderr, "gsr error: gsr_capture_portal_setup_dbus: SelectSources failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_portal_setup_dbus: SelectSources failed");
return response_status;
}
- fprintf(stderr, "gsr info: gsr_capture_portal_setup_dbus: Start\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_setup_dbus: Start");
response_status = gsr_dbus_screencast_start(&self->dbus, self->session_handle, pipewire_node);
if(response_status != 0) {
- fprintf(stderr, "gsr error: gsr_capture_portal_setup_dbus: Start failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_portal_setup_dbus: Start failed");
return response_status;
}
@@ -218,31 +219,31 @@ static int gsr_capture_portal_setup_dbus(gsr_capture_portal *self, int *pipewire
if(screencast_restore_token)
gsr_capture_portal_save_restore_token(screencast_restore_token, self->params.portal_session_token_filepath);
- fprintf(stderr, "gsr info: gsr_capture_portal_setup_dbus: OpenPipeWireRemote\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_setup_dbus: OpenPipeWireRemote");
if(!gsr_dbus_screencast_open_pipewire_remote(&self->dbus, self->session_handle, pipewire_fd)) {
- fprintf(stderr, "gsr error: gsr_capture_portal_setup_dbus: OpenPipeWireRemote failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_portal_setup_dbus: OpenPipeWireRemote failed");
return -1;
}
- fprintf(stderr, "gsr info: gsr_capture_portal_setup_dbus: desktop portal setup finished\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_setup_dbus: desktop portal setup finished");
return 0;
}
static bool gsr_capture_portal_get_frame_dimensions(gsr_capture_portal *self) {
- fprintf(stderr, "gsr info: gsr_capture_portal_start: waiting for pipewire negotiation\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_start: waiting for pipewire negotiation");
const double start_time = clock_get_monotonic_seconds();
while(clock_get_monotonic_seconds() - start_time < 5.0) {
if(gsr_pipewire_video_map_texture(&self->pipewire, self->texture_map, &self->pipewire_data)) {
self->capture_size.x = self->pipewire_data.region.width;
self->capture_size.y = self->pipewire_data.region.height;
- fprintf(stderr, "gsr info: gsr_capture_portal_start: pipewire negotiation finished\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_start: pipewire negotiation finished");
return true;
}
usleep(30 * 1000); /* 30 milliseconds */
}
- fprintf(stderr, "gsr info: gsr_capture_portal_start: timed out waiting for pipewire negotiation (5 seconds)\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_start: timed out waiting for pipewire negotiation (5 seconds)");
return false;
}
@@ -259,24 +260,24 @@ static int gsr_capture_portal_setup(gsr_capture_portal *self, int fps) {
// 2: The user interaction was ended in some other way
// Response status value 2 happens usually if there was some kind of error in the desktop portal on the system
if(response_status == 2) {
- fprintf(stderr, "gsr error: gsr_capture_portal_setup: desktop portal capture failed. Either you Wayland compositor doesn't support desktop portal capture or it's incorrectly setup on your system\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_portal_setup: desktop portal capture failed. Either you Wayland compositor doesn't support desktop portal capture or it's incorrectly setup on your system");
return 50;
} else if(response_status == 1) {
- fprintf(stderr, "gsr error: gsr_capture_portal_setup: desktop portal capture failed. It seems like desktop portal capture was canceled by the user.\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_portal_setup: desktop portal capture failed. It seems like desktop portal capture was canceled by the user.");
return PORTAL_CAPTURE_CANCELED_BY_USER_EXIT_CODE;
} else {
return -1;
}
}
- fprintf(stderr, "gsr info: gsr_capture_portal_setup: setting up pipewire\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_setup: setting up pipewire");
/* TODO: support hdr when pipewire supports it */
/* gsr_pipewire closes the pipewire fd, even on failure */
if(!gsr_pipewire_video_init(&self->pipewire, pipewire_fd, pipewire_node, fps, self->params.record_cursor, self->params.egl)) {
- fprintf(stderr, "gsr error: gsr_capture_portal_setup: failed to setup pipewire with fd: %d, node: %" PRIu32 "\n", pipewire_fd, pipewire_node);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_portal_setup: failed to setup pipewire with fd: %d, node: %" PRIu32, pipewire_fd, pipewire_node);
return -1;
}
- fprintf(stderr, "gsr info: gsr_capture_portal_setup: pipewire setup finished\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_setup: pipewire setup finished");
if(!gsr_capture_portal_get_frame_dimensions(self))
return -1;
@@ -329,7 +330,7 @@ static void gsr_capture_portal_pre_capture(gsr_capture *cap, gsr_capture_metadat
return;
if(gsr_pipewire_video_should_restart(&self->pipewire)) {
- fprintf(stderr, "gsr info: gsr_capture_portal_pre_capture: pipewire capture was paused, trying to start capture again\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_portal_pre_capture: pipewire capture was paused, trying to start capture again");
gsr_capture_portal_stop(self);
const int result = gsr_capture_portal_setup(self, capture_metadata->fps);
if(result != 0) {
@@ -452,7 +453,7 @@ static void gsr_capture_portal_destroy(gsr_capture *cap) {
gsr_capture* gsr_capture_portal_create(const gsr_capture_portal_params *params) {
if(!params) {
- fprintf(stderr, "gsr error: gsr_capture_portal_create params is NULL\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_portal_create params is NULL");
return NULL;
}
diff --git a/src/capture/v4l2.c b/src/capture/v4l2.c
index a4e81e4..22f0f59 100644
--- a/src/capture/v4l2.c
+++ b/src/capture/v4l2.c
@@ -1,4 +1,5 @@
#include "../../include/capture/v4l2.h"
+#include "../../include/log.h"
#include "../../include/color_conversion.h"
#include "../../include/egl.h"
#include "../../include/utils.h"
@@ -367,12 +368,12 @@ static void gsr_capture_v4l2_update_params(int fd) {
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
};
if(xioctl(fd, VIDIOC_G_PARM, &streamparm) == -1) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_set_framerate: VIDIOC_G_PARM failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_set_framerate: VIDIOC_G_PARM failed, error: %s", strerror(errno));
return;
}
if(xioctl(fd, VIDIOC_S_PARM, &streamparm) == -1) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_set_framerate: VIDIOC_S_PARM failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_set_framerate: VIDIOC_S_PARM failed, error: %s", strerror(errno));
return;
}
}
@@ -382,19 +383,19 @@ static void gsr_capture_v4l2_set_framerate(int fd, gsr_capture_v4l2_framerate fr
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
};
if(xioctl(fd, VIDIOC_G_PARM, &streamparm) == -1) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_set_framerate: VIDIOC_G_PARM failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_set_framerate: VIDIOC_G_PARM failed, error: %s", strerror(errno));
return;
}
streamparm.parm.capture.timeperframe.denominator = framerate.denominator;
streamparm.parm.capture.timeperframe.numerator = framerate.numerator;
if(xioctl(fd, VIDIOC_S_PARM, &streamparm) == -1) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_set_framerate: VIDIOC_S_PARM failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_set_framerate: VIDIOC_S_PARM failed, error: %s", strerror(errno));
return;
}
if(streamparm.parm.capture.timeperframe.denominator == 0 || streamparm.parm.capture.timeperframe.numerator == 0) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_set_framerate: VIDIOC_S_PARM failed, error: invalid framerate: %u/%u\n", framerate.denominator, framerate.numerator);;
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_set_framerate: VIDIOC_S_PARM failed, error: invalid framerate: %u/%u", framerate.denominator, framerate.numerator);;
return;
}
}
@@ -403,21 +404,21 @@ static bool gsr_capture_v4l2_validate_pixfmt(const gsr_capture_v4l2 *self, const
switch(self->params.pixfmt) {
case GSR_CAPTURE_V4L2_PIXFMT_AUTO: {
if(!supported_pixfmts.yuyv && !supported_pixfmts.mjpeg) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: %s doesn't support yuyv nor mjpeg. GPU Screen Recorder supports only yuyv and mjpeg at the moment. Report this as an issue, see: https://git.dec05eba.com/?p=about\n", self->params.device_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: %s doesn't support yuyv nor mjpeg. GPU Screen Recorder supports only yuyv and mjpeg at the moment. Report this as an issue, see: https://git.dec05eba.com/?p=about", self->params.device_path);
return false;
}
break;
}
case GSR_CAPTURE_V4L2_PIXFMT_YUYV: {
if(!supported_pixfmts.yuyv) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: %s doesn't support yuyv. Try recording with pixfmt=mjpeg or pixfmt=auto instead\n", self->params.device_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: %s doesn't support yuyv. Try recording with pixfmt=mjpeg or pixfmt=auto instead", self->params.device_path);
return false;
}
break;
}
case GSR_CAPTURE_V4L2_PIXFMT_MJPEG: {
if(!supported_pixfmts.mjpeg) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: %s doesn't support mjpeg. Try recording with pixfmt=yuyv or pixfmt=auto instead\n", self->params.device_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: %s doesn't support mjpeg. Try recording with pixfmt=yuyv or pixfmt=auto instead", self->params.device_path);
return false;
}
break;
@@ -432,7 +433,7 @@ static bool gsr_capture_v4l2_create_pbos(gsr_capture_v4l2 *self, int width, int
self->params.egl->glGenBuffers(NUM_PBOS, self->pbos);
for(int i = 0; i < NUM_PBOS; ++i) {
if(self->pbos[i] == 0) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create_pbos: failed to create pixel buffer objects\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create_pbos: failed to create pixel buffer objects");
return false;
}
@@ -477,7 +478,7 @@ static bool gsr_capture_v4l2_map_buffer(gsr_capture_v4l2 *self, const struct v4l
});
if(!self->dma_image[i]) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_map_buffer: eglCreateImage failed, error: %d\n", self->params.egl->eglGetError());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_map_buffer: eglCreateImage failed, error: %d", self->params.egl->eglGetError());
return false;
}
}
@@ -488,7 +489,7 @@ static bool gsr_capture_v4l2_map_buffer(gsr_capture_v4l2 *self, const struct v4l
self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
self->params.egl->glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
if(self->texture_id[i] == 0) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_map_buffer: failed to create texture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_map_buffer: failed to create texture");
return false;
}
}
@@ -501,14 +502,14 @@ static bool gsr_capture_v4l2_map_buffer(gsr_capture_v4l2 *self, const struct v4l
self->dmabuf_size[i] = fmt->fmt.pix.sizeimage;
self->dmabuf_map[i] = mmap(NULL, fmt->fmt.pix.sizeimage, PROT_READ, MAP_SHARED, self->dmabuf_fd[i], 0);
if(self->dmabuf_map[i] == MAP_FAILED) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_map_buffer: mmap failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_map_buffer: mmap failed, error: %s", strerror(errno));
return false;
}
// GL_RGBA is intentionally used here instead of GL_RGB, because the performance is much better when using glTexSubImage2D (22% cpu usage compared to 38% cpu usage)
self->texture_id[i] = gl_create_texture(self->params.egl, fmt->fmt.pix.width, fmt->fmt.pix.height, GL_RGBA8, GL_RGBA, GL_LINEAR);
if(self->texture_id[i] == 0) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_map_buffer: failed to create texture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_map_buffer: failed to create texture");
return false;
}
}
@@ -534,28 +535,28 @@ static bool is_libturbojpeg_library_available(void) {
static int gsr_capture_v4l2_setup(gsr_capture_v4l2 *self) {
self->fd = open(self->params.device_path, O_RDWR | O_NONBLOCK);
if(self->fd < 0) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: failed to open %s, error: %s\n", self->params.device_path, strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: failed to open %s, error: %s", self->params.device_path, strerror(errno));
return -1;
}
struct v4l2_capability cap = {0};
if(xioctl(self->fd, VIDIOC_QUERYCAP, &cap) == -1) {
if(EINVAL == errno) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: %s isn't a v4l2 device\n", self->params.device_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: %s isn't a v4l2 device", self->params.device_path);
return -1;
} else {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: VIDIOC_QUERYCAP failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: VIDIOC_QUERYCAP failed, error: %s", strerror(errno));
return -1;
}
}
if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: %s isn't a video capture device\n", self->params.device_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: %s isn't a video capture device", self->params.device_path);
return -1;
}
if(!(cap.capabilities & V4L2_CAP_STREAMING)) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: %s doesn't support streaming i/o\n", self->params.device_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: %s doesn't support streaming i/o", self->params.device_path);
return -1;
}
@@ -563,7 +564,7 @@ static int gsr_capture_v4l2_setup(gsr_capture_v4l2 *self) {
const bool has_libturbojpeg_lib = is_libturbojpeg_library_available();
if(!has_libturbojpeg_lib && self->params.pixfmt == GSR_CAPTURE_V4L2_PIXFMT_AUTO) {
- fprintf(stderr, "gsr warning: gsr_capture_v4l2_create: libturbojpeg.so.0 isn't available on the system, yuyv camera capture will be used\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_capture_v4l2_create: libturbojpeg.so.0 isn't available on the system, yuyv camera capture will be used");
self->params.pixfmt = GSR_CAPTURE_V4L2_PIXFMT_YUYV;
}
@@ -576,12 +577,11 @@ static int gsr_capture_v4l2_setup(gsr_capture_v4l2 *self) {
gsr_capture_v4l2_supported_setup best_supported_setup = {0};
if(!gsr_capture_v4l2_get_best_matching_setup(supported_setups, num_supported_setups, self->params.pixfmt, self->params.camera_fps, self->params.camera_resolution, &best_supported_setup)) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: %s doesn't report any frame resolutions and framerates\n", self->params.device_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: %s doesn't report any frame resolutions and framerates", self->params.device_path);
return -1;
}
- fprintf(stderr, "gsr info: gsr_capture_v4l2_create: capturing %s at %ux%u@%dhz, pixfmt: %s\n",
- self->params.device_path,
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_v4l2_create: capturing %s at %ux%u@%dhz, pixfmt: %s", self->params.device_path,
best_supported_setup.resolution.width,
best_supported_setup.resolution.height,
gsr_capture_v4l2_framerate_to_number(best_supported_setup.framerate),
@@ -594,7 +594,7 @@ static int gsr_capture_v4l2_setup(gsr_capture_v4l2 *self) {
dlerror(); /* clear */
self->libturbojpeg_lib = dlopen("libturbojpeg.so.0", RTLD_LAZY);
if(!self->libturbojpeg_lib) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: failed to load libturbojpeg.so.0 which is required for camera mjpeg capture, error: %s\n", dlerror());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: failed to load libturbojpeg.so.0 which is required for camera mjpeg capture, error: %s", dlerror());
return -1;
}
@@ -605,13 +605,13 @@ static int gsr_capture_v4l2_setup(gsr_capture_v4l2 *self) {
self->tjGetErrorStr2 = (FUNC_tjGetErrorStr2)dlsym(self->libturbojpeg_lib, "tjGetErrorStr2");
if(!self->tjInitDecompress || !self->tjDestroy || !self->tjDecompressHeader2 || !self->tjDecompress2 || !self->tjGetErrorStr2) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: libturbojpeg.so.0 is missing functions. The libturbojpeg version installed on your system might be outdated\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: libturbojpeg.so.0 is missing functions. The libturbojpeg version installed on your system might be outdated");
return -1;
}
self->jpeg_decompressor = self->tjInitDecompress();
if(!self->jpeg_decompressor) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: failed to create jpeg decompressor\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: failed to create jpeg decompressor");
return -1;
}
}
@@ -624,12 +624,12 @@ static int gsr_capture_v4l2_setup(gsr_capture_v4l2 *self) {
.fmt.pix.height = best_supported_setup.resolution.height,
};
if(xioctl(self->fd, VIDIOC_S_FMT, &fmt) == -1) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: VIDIOC_S_FMT failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: VIDIOC_S_FMT failed, error: %s", strerror(errno));
return -1;
}
if(fmt.fmt.pix.pixelformat != v4l2_pixfmt) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: pixel format isn't as requested (got pixel format: %u, requested: %u), error: %s\n", fmt.fmt.pix.pixelformat, v4l2_pixfmt, strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: pixel format isn't as requested (got pixel format: %u, requested: %u), error: %s", fmt.fmt.pix.pixelformat, v4l2_pixfmt, strerror(errno));
return -1;
}
@@ -644,7 +644,7 @@ static int gsr_capture_v4l2_setup(gsr_capture_v4l2 *self) {
.count = NUM_BUFFERS
};
if(xioctl(self->fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: VIDIOC_REQBUFS failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: VIDIOC_REQBUFS failed, error: %s", strerror(errno));
return -1;
}
@@ -655,7 +655,7 @@ static int gsr_capture_v4l2_setup(gsr_capture_v4l2 *self) {
.flags = O_RDONLY
};
if(xioctl(self->fd, VIDIOC_EXPBUF, &expbuf) == -1) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: VIDIOC_EXPBUF failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: VIDIOC_EXPBUF failed, error: %s", strerror(errno));
return -1;
}
self->dmabuf_fd[i] = expbuf.fd;
@@ -674,11 +674,11 @@ static int gsr_capture_v4l2_setup(gsr_capture_v4l2 *self) {
}
if(xioctl(self->fd, VIDIOC_STREAMON, &(enum v4l2_buf_type){V4L2_BUF_TYPE_VIDEO_CAPTURE})) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create: VIDIOC_STREAMON failed, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create: VIDIOC_STREAMON failed, error: %s", strerror(errno));
return -1;
}
- fprintf(stderr, "gsr info: gsr_capture_v4l2_create: waiting for camera %s to be ready\n", self->params.device_path);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_v4l2_create: waiting for camera %s to be ready", self->params.device_path);
return 0;
}
@@ -707,7 +707,7 @@ static void gsr_capture_v4l2_tick(gsr_capture *cap) {
if(!self->got_first_frame && !self->should_stop) {
const double timeout_sec = 5.0;
if(clock_get_monotonic_seconds() - self->capture_start_time >= timeout_sec) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_capture: didn't receive camera data in %f seconds\n", timeout_sec);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_capture: didn't receive camera data in %f seconds", timeout_sec);
self->should_stop = true;
self->stop_is_error = true;
}
@@ -719,12 +719,12 @@ static void gsr_capture_v4l2_decode_jpeg_to_texture(gsr_capture_v4l2 *self, cons
int jpeg_width = 0;
int jpeg_height = 0;
if(self->tjDecompressHeader2(self->jpeg_decompressor, self->dmabuf_map[buf->index], buf->bytesused, &jpeg_width, &jpeg_height, &jpeg_subsamp) != 0) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_capture: failed to decompress camera jpeg header data, error: %s\n", self->tjGetErrorStr2(self->jpeg_decompressor));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_capture: failed to decompress camera jpeg header data, error: %s", self->tjGetErrorStr2(self->jpeg_decompressor));
return;
}
if(jpeg_width != self->capture_size.x || jpeg_height != self->capture_size.y) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_capture: got jpeg data of incorrect dimensions. Expected %dx%d, got %dx%d\n", self->capture_size.x, self->capture_size.y, jpeg_width, jpeg_height);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_capture: got jpeg data of incorrect dimensions. Expected %dx%d, got %dx%d", self->capture_size.x, self->capture_size.y, jpeg_width, jpeg_height);
return;
}
@@ -742,7 +742,7 @@ static void gsr_capture_v4l2_decode_jpeg_to_texture(gsr_capture_v4l2 *self, cons
void *mapped_buffer = self->params.egl->glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, self->capture_size.x * self->capture_size.y * 4, GL_MAP_WRITE_BIT);
if(mapped_buffer) {
if(self->tjDecompress2(self->jpeg_decompressor, self->dmabuf_map[buf->index], buf->bytesused, mapped_buffer, jpeg_width, 0, jpeg_height, TJPF_RGBA, TJFLAG_FASTDCT) != 0)
- fprintf(stderr, "gsr error: gsr_capture_v4l2_capture: failed to decompress camera jpeg data, error: %s\n", self->tjGetErrorStr2(self->jpeg_decompressor));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_capture: failed to decompress camera jpeg data, error: %s", self->tjGetErrorStr2(self->jpeg_decompressor));
self->params.egl->glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
@@ -764,7 +764,7 @@ static int gsr_capture_v4l2_capture(gsr_capture *cap, gsr_capture_metadata *capt
if(buf.bytesused > 0 && !(buf.flags & V4L2_BUF_FLAG_ERROR)) {
if(!self->got_first_frame)
- fprintf(stderr, "gsr info: gsr_capture_v4l2_capture: camera %s is now ready\n", self->params.device_path);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gsr_capture_v4l2_capture: camera %s is now ready", self->params.device_path);
self->got_first_frame = true;
switch(self->buffer_type) {
@@ -852,7 +852,7 @@ static void gsr_capture_v4l2_destroy(gsr_capture *cap) {
gsr_capture* gsr_capture_v4l2_create(const gsr_capture_v4l2_params *params) {
if(!params) {
- fprintf(stderr, "gsr error: gsr_capture_v4l2_create params is NULL\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_v4l2_create params is NULL");
return NULL;
}
diff --git a/src/capture/xcomposite.c b/src/capture/xcomposite.c
index c1bef4f..af48698 100644
--- a/src/capture/xcomposite.c
+++ b/src/capture/xcomposite.c
@@ -1,4 +1,5 @@
#include "../../include/capture/xcomposite.h"
+#include "../../include/log.h"
#include "../../include/window_texture.h"
#include "../../include/utils.h"
#include "../../include/cursor.h"
@@ -63,7 +64,7 @@ static int gsr_capture_xcomposite_start(gsr_capture *cap, gsr_capture_metadata *
if(self->params.follow_focused) {
self->net_active_window_atom = XInternAtom(self->display, "_NET_ACTIVE_WINDOW", False);
if(!self->net_active_window_atom) {
- fprintf(stderr, "gsr error: gsr_capture_xcomposite_start failed: failed to get _NET_ACTIVE_WINDOW atom\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_xcomposite_start failed: failed to get _NET_ACTIVE_WINDOW atom");
return -1;
}
self->window = get_focused_window(self->display, self->net_active_window_atom);
@@ -75,7 +76,7 @@ static int gsr_capture_xcomposite_start(gsr_capture *cap, gsr_capture_metadata *
XWindowAttributes attr;
if(!XGetWindowAttributes(self->display, self->window, &attr) && !self->params.follow_focused) {
- fprintf(stderr, "gsr error: gsr_capture_xcomposite_start failed: invalid window id: %lu\n", self->window);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_xcomposite_start failed: invalid window id: %lu", self->window);
return -1;
}
@@ -89,7 +90,7 @@ static int gsr_capture_xcomposite_start(gsr_capture *cap, gsr_capture_metadata *
XSelectInput(self->display, self->window, StructureNotifyMask | ExposureMask);
if(window_texture_init(&self->window_texture, self->display, self->window, self->params.egl) != 0 && !self->params.follow_focused) {
- fprintf(stderr, "gsr error: gsr_capture_xcomposite_start: failed to get window texture for window %ld\n", (long)self->window);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_xcomposite_start: failed to get window texture for window %ld", (long)self->window);
return -1;
}
@@ -129,7 +130,7 @@ static void gsr_capture_xcomposite_tick(gsr_capture *cap) {
attr.width = 0;
attr.height = 0;
if(!XGetWindowAttributes(self->display, self->window, &attr))
- fprintf(stderr, "gsr error: gsr_capture_xcomposite_tick failed: invalid window id: %lu\n", self->window);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_xcomposite_tick failed: invalid window id: %lu", self->window);
self->window_pos.x = attr.x;
self->window_pos.y = attr.y;
@@ -153,7 +154,7 @@ static void gsr_capture_xcomposite_tick(gsr_capture *cap) {
self->window_resized = false;
if(window_texture_on_resize(&self->window_texture) != 0) {
- fprintf(stderr, "gsr error: gsr_capture_xcomposite_tick: window_texture_on_resize failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_xcomposite_tick: window_texture_on_resize failed");
//self->should_stop = true;
//self->stop_is_error = true;
return;
@@ -291,7 +292,7 @@ static void gsr_capture_xcomposite_destroy(gsr_capture *cap) {
gsr_capture* gsr_capture_xcomposite_create(const gsr_capture_xcomposite_params *params) {
if(!params) {
- fprintf(stderr, "gsr error: gsr_capture_xcomposite_create params is NULL\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_xcomposite_create params is NULL");
return NULL;
}
diff --git a/src/capture/ximage.c b/src/capture/ximage.c
index b0cf364..becca82 100644
--- a/src/capture/ximage.c
+++ b/src/capture/ximage.c
@@ -1,4 +1,5 @@
#include "../../include/capture/ximage.h"
+#include "../../include/log.h"
#include "../../include/utils.h"
#include "../../include/cursor.h"
#include "../../include/color_conversion.h"
@@ -39,7 +40,7 @@ static int gsr_capture_ximage_start(gsr_capture *cap, gsr_capture_metadata *capt
self->root_window = DefaultRootWindow(self->display);
if(!get_monitor_by_name(self->params.egl, GSR_CONNECTION_X11, self->params.display_to_capture, &self->monitor)) {
- fprintf(stderr, "gsr error: gsr_capture_ximage_start: failed to find monitor by name \"%s\"\n", self->params.display_to_capture);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_ximage_start: failed to find monitor by name \"%s\"", self->params.display_to_capture);
gsr_capture_ximage_stop(self);
return -1;
}
@@ -61,7 +62,7 @@ static int gsr_capture_ximage_start(gsr_capture *cap, gsr_capture_metadata *capt
self->texture_id = gl_create_texture(self->params.egl, self->capture_size.x, self->capture_size.y, GL_RGB8, GL_RGB, GL_LINEAR);
if(self->texture_id == 0) {
- fprintf(stderr, "gsr error: gsr_capture_ximage_start: failed to create texture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_ximage_start: failed to create texture");
gsr_capture_ximage_stop(self);
return -1;
}
@@ -95,14 +96,14 @@ static bool gsr_capture_ximage_upload_to_texture(gsr_capture_ximage *self, int x
XImage *image = XGetImage(self->display, self->root_window, x, y, width, height, AllPlanes, ZPixmap);
if(!image) {
- fprintf(stderr, "gsr error: gsr_capture_ximage_upload_to_texture: XGetImage failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_ximage_upload_to_texture: XGetImage failed");
return false;
}
bool success = false;
uint8_t *image_data = malloc(image->width * image->height * 3);
if(!image_data) {
- fprintf(stderr, "gsr error: gsr_capture_ximage_upload_to_texture: failed to allocate image data\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_ximage_upload_to_texture: failed to allocate image data");
goto done;
}
@@ -186,7 +187,7 @@ static void gsr_capture_ximage_destroy(gsr_capture *cap) {
gsr_capture* gsr_capture_ximage_create(const gsr_capture_ximage_params *params) {
if(!params) {
- fprintf(stderr, "gsr error: gsr_capture_ximage_create params is NULL\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_ximage_create params is NULL");
return NULL;
}
diff --git a/src/codec_query/nvenc.c b/src/codec_query/nvenc.c
index 37c25ba..3f8b442 100644
--- a/src/codec_query/nvenc.c
+++ b/src/codec_query/nvenc.c
@@ -1,4 +1,5 @@
#include "../../include/codec_query/nvenc.h"
+#include "../../include/log.h"
#include "../../include/cuda.h"
#include "../../external/nvEncodeAPI.h"
@@ -17,7 +18,7 @@ static void* open_nvenc_library(void) {
if(!lib) {
lib = dlopen("libnvidia-encode.so", RTLD_LAZY);
if(!lib) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc failed: failed to load libnvidia-encode.so/libnvidia-encode.so.1, error: %s\n", dlerror());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc failed: failed to load libnvidia-encode.so/libnvidia-encode.so.1, error: %s", dlerror());
return NULL;
}
}
@@ -107,7 +108,7 @@ static bool encoder_get_supported_profiles(const NV_ENCODE_API_FUNCTION_LIST *fu
uint32_t profile_guid_count = 0;
if(function_list->nvEncGetEncodeProfileGUIDCount(nvenc_encoder, *encoder_guid, &profile_guid_count) != NV_ENC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: nvEncGetEncodeProfileGUIDCount failed, error: %s\n", function_list->nvEncGetLastErrorString(nvenc_encoder));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: nvEncGetEncodeProfileGUIDCount failed, error: %s", function_list->nvEncGetLastErrorString(nvenc_encoder));
goto fail;
}
@@ -116,12 +117,12 @@ static bool encoder_get_supported_profiles(const NV_ENCODE_API_FUNCTION_LIST *fu
profile_guids = calloc(profile_guid_count, sizeof(GUID));
if(!profile_guids) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: failed to allocate %d guids\n", (int)profile_guid_count);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: failed to allocate %d guids", (int)profile_guid_count);
goto fail;
}
if(function_list->nvEncGetEncodeProfileGUIDs(nvenc_encoder, *encoder_guid, profile_guids, profile_guid_count, &profile_guid_count) != NV_ENC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: nvEncGetEncodeProfileGUIDs failed, error: %s\n", function_list->nvEncGetLastErrorString(nvenc_encoder));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: nvEncGetEncodeProfileGUIDs failed, error: %s", function_list->nvEncGetLastErrorString(nvenc_encoder));
goto fail;
}
@@ -157,7 +158,7 @@ static bool get_supported_video_codecs(const NV_ENCODE_API_FUNCTION_LIST *functi
uint32_t encode_guid_count = 0;
if(function_list->nvEncGetEncodeGUIDCount(nvenc_encoder, &encode_guid_count) != NV_ENC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: nvEncGetEncodeGUIDCount failed, error: %s\n", function_list->nvEncGetLastErrorString(nvenc_encoder));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: nvEncGetEncodeGUIDCount failed, error: %s", function_list->nvEncGetLastErrorString(nvenc_encoder));
goto fail;
}
@@ -166,12 +167,12 @@ static bool get_supported_video_codecs(const NV_ENCODE_API_FUNCTION_LIST *functi
encoder_guids = calloc(encode_guid_count, sizeof(GUID));
if(!encoder_guids) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: failed to allocate %d guids\n", (int)encode_guid_count);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: failed to allocate %d guids", (int)encode_guid_count);
goto fail;
}
if(function_list->nvEncGetEncodeGUIDs(nvenc_encoder, encoder_guids, encode_guid_count, &encode_guid_count) != NV_ENC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: nvEncGetEncodeGUIDs failed, error: %s\n", function_list->nvEncGetLastErrorString(nvenc_encoder));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: nvEncGetEncodeGUIDs failed, error: %s", function_list->nvEncGetLastErrorString(nvenc_encoder));
goto fail;
}
@@ -198,7 +199,7 @@ bool gsr_get_supported_video_codecs_nvenc(gsr_supported_video_codecs *video_code
memset(&cuda, 0, sizeof(cuda));
if(!gsr_cuda_load(&cuda)) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: failed to load cuda\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: failed to load cuda");
goto done;
}
@@ -209,7 +210,7 @@ bool gsr_get_supported_video_codecs_nvenc(gsr_supported_video_codecs *video_code
typedef NVENCSTATUS NVENCAPI (*FUNC_NvEncodeAPICreateInstance)(NV_ENCODE_API_FUNCTION_LIST *functionList);
FUNC_NvEncodeAPICreateInstance nvEncodeAPICreateInstance = (FUNC_NvEncodeAPICreateInstance)dlsym(nvenc_lib, "NvEncodeAPICreateInstance");
if(!nvEncodeAPICreateInstance) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: failed to find NvEncodeAPICreateInstance in libnvidia-encode.so\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: failed to find NvEncodeAPICreateInstance in libnvidia-encode.so");
goto done;
}
@@ -217,7 +218,7 @@ bool gsr_get_supported_video_codecs_nvenc(gsr_supported_video_codecs *video_code
memset(&function_list, 0, sizeof(function_list));
function_list.version = NVENCAPI_STRUCT_VERSION(2);
if(nvEncodeAPICreateInstance(&function_list) != NV_ENC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: nvEncodeAPICreateInstance failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: nvEncodeAPICreateInstance failed");
goto done;
}
@@ -232,14 +233,14 @@ bool gsr_get_supported_video_codecs_nvenc(gsr_supported_video_codecs *video_code
// In such cases fallback to old api version if possible and try again.
function_list.version = NVENCAPI_STRUCT_VERSION_CUSTOM(NVENCAPI_VERSION_470, 2);
if(nvEncodeAPICreateInstance(&function_list) != NV_ENC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: nvEncodeAPICreateInstance (retry) failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: nvEncodeAPICreateInstance (retry) failed");
goto done;
}
params.version = NVENCAPI_STRUCT_VERSION_CUSTOM(NVENCAPI_VERSION_470, 1);
params.apiVersion = NVENCAPI_VERSION_470;
if(function_list.nvEncOpenEncodeSessionEx(&params, &nvenc_encoder) != NV_ENC_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_nvenc: nvEncOpenEncodeSessionEx (retry) failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: nvEncOpenEncodeSessionEx (retry) failed");
goto done;
}
}
diff --git a/src/codec_query/vaapi.c b/src/codec_query/vaapi.c
index 0943450..4cc1bab 100644
--- a/src/codec_query/vaapi.c
+++ b/src/codec_query/vaapi.c
@@ -1,4 +1,5 @@
#include "../../include/codec_query/vaapi.h"
+#include "../../include/log.h"
#include "../../include/utils.h"
#include <stdlib.h>
@@ -134,7 +135,7 @@ static bool get_supported_video_codecs(VADisplay va_dpy, gsr_supported_video_cod
int va_major = 0;
int va_minor = 0;
if(vaInitialize(va_dpy, &va_major, &va_minor) != VA_STATUS_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vaapi: vaInitialize failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vaapi: vaInitialize failed");
return false;
}
@@ -207,20 +208,20 @@ bool gsr_get_supported_video_codecs_vaapi(gsr_supported_video_codecs *video_code
char render_path[128];
if(!gsr_card_path_get_render_path(card_path, render_path)) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vaapi: failed to get /dev/dri/renderDXXX file from %s\n", card_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vaapi: failed to get /dev/dri/renderDXXX file from %s", card_path);
goto done;
}
drm_fd = open(render_path, O_RDWR);
if(drm_fd == -1) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vaapi: failed to open device %s\n", render_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vaapi: failed to open device %s", render_path);
goto done;
}
VADisplay va_dpy = vaGetDisplayDRM(drm_fd);
if(va_dpy) {
if(!get_supported_video_codecs(va_dpy, video_codecs, cleanup)) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vaapi: failed to query supported video codecs for device %s\n", render_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vaapi: failed to query supported video codecs for device %s", render_path);
goto done;
}
success = true;
diff --git a/src/codec_query/vulkan.c b/src/codec_query/vulkan.c
index 7dcb44e..d61cee5 100644
--- a/src/codec_query/vulkan.c
+++ b/src/codec_query/vulkan.c
@@ -1,4 +1,5 @@
#include "../../include/codec_query/vulkan.h"
+#include "../../include/log.h"
#include "../../include/utils.h"
#include <stdio.h>
@@ -162,25 +163,25 @@ bool gsr_get_supported_video_codecs_vulkan(gsr_supported_video_codecs *video_cod
char render_path[128];
if(!gsr_card_path_get_render_path(card_path, render_path)) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: failed to get /dev/dri/renderDXXX file from %s\n", card_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: failed to get /dev/dri/renderDXXX file from %s", card_path);
return false;
}
libvulkan = dlopen("libvulkan.so.1", RTLD_NOW);
if (!libvulkan) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: failed to load libvulkan.so.1, error: %s\n", dlerror());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: failed to load libvulkan.so.1, error: %s", dlerror());
return false;
}
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(libvulkan, "vkGetInstanceProcAddr");
if (!vkGetInstanceProcAddr) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: could not find vkGetInstanceProcAddr in libvulkan.so.1\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: could not find vkGetInstanceProcAddr in libvulkan.so.1");
goto done;
}
PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance)vkGetInstanceProcAddr(NULL, "vkCreateInstance");
if(!vkCreateInstance) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: could not find vkCreateInstance in libvulkan.so.1\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: could not find vkCreateInstance in libvulkan.so.1");
goto done;
}
@@ -199,7 +200,7 @@ bool gsr_get_supported_video_codecs_vulkan(gsr_supported_video_codecs *video_cod
};
if(vkCreateInstance(&instance_create_info, NULL, &instance) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: vkCreateInstance failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: vkCreateInstance failed");
goto done;
}
@@ -211,7 +212,7 @@ bool gsr_get_supported_video_codecs_vulkan(gsr_supported_video_codecs *video_cod
PFN_vkDestroyDevice vkDestroyDevice = NULL;
PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR vkGetPhysicalDeviceVideoCapabilitiesKHR = NULL;
- #define LOAD_INST(name) name = (PFN_##name)vkGetInstanceProcAddr(instance, #name); if(!name) { fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: could not find " #name " in libvulkan.so.1\n"); goto done; }
+ #define LOAD_INST(name) name = (PFN_##name)vkGetInstanceProcAddr(instance, #name); if(!name) { gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: could not find " #name " in libvulkan.so.1"); goto done; }
LOAD_INST(vkEnumeratePhysicalDevices)
LOAD_INST(vkDestroyInstance)
@@ -225,12 +226,12 @@ bool gsr_get_supported_video_codecs_vulkan(gsr_supported_video_codecs *video_cod
uint32_t num_devices = 0;
if(vkEnumeratePhysicalDevices(instance, &num_devices, NULL) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: vkEnumeratePhysicalDevices (query num devices) failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: vkEnumeratePhysicalDevices (query num devices) failed");
goto done;
}
if(num_devices == 0) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: no vulkan capable device found\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: no vulkan capable device found");
goto done;
}
@@ -238,7 +239,7 @@ bool gsr_get_supported_video_codecs_vulkan(gsr_supported_video_codecs *video_cod
num_devices = MAX_PHYSICAL_DEVICES;
if(vkEnumeratePhysicalDevices(instance, &num_devices, physical_devices) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: vkEnumeratePhysicalDevices (get data) failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: vkEnumeratePhysicalDevices (get data) failed");
goto done;
}
@@ -267,7 +268,7 @@ bool gsr_get_supported_video_codecs_vulkan(gsr_supported_video_codecs *video_cod
}
if(!physical_device) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: failed to find a vulkan device that matches opengl device %s\n", card_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: failed to find a vulkan device that matches opengl device %s", card_path);
goto done;
}
@@ -284,18 +285,18 @@ bool gsr_get_supported_video_codecs_vulkan(gsr_supported_video_codecs *video_cod
uint32_t num_device_extensions = 0;
if(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &num_device_extensions, NULL) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: vkEnumerateDeviceExtensionProperties (query num device extensions) failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: vkEnumerateDeviceExtensionProperties (query num device extensions) failed");
goto done;
}
device_extensions = calloc(num_device_extensions, sizeof(VkExtensionProperties));
if(!device_extensions) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: failed to allocate %d device extensions\n", num_device_extensions);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: failed to allocate %d device extensions", num_device_extensions);
goto done;
}
if(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &num_device_extensions, device_extensions) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_get_supported_video_codecs_vulkan: vkEnumerateDeviceExtensionProperties (get data) failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_vulkan: vkEnumerateDeviceExtensionProperties (get data) failed");
goto done;
}
diff --git a/src/color_conversion.c b/src/color_conversion.c
index 8076c2b..da922cd 100644
--- a/src/color_conversion.c
+++ b/src/color_conversion.c
@@ -1,4 +1,5 @@
#include "../include/color_conversion.h"
+#include "../include/log.h"
#include "../include/egl.h"
#include <stdio.h>
#include <string.h>
@@ -620,23 +621,23 @@ static bool gsr_color_conversion_load_hdr_graphics_shaders(gsr_color_conversion
case GSR_DESTINATION_COLOR_NV12:
case GSR_DESTINATION_COLOR_P010: {
if(load_graphics_shader_y(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_Y_HDR], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_Y_HDR], self->params.destination_color, self->params.color_range, false, true) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_load_hdr_graphics_shaders: failed to load Y graphics shader (hdr)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_load_hdr_graphics_shaders: failed to load Y graphics shader (hdr)");
return false;
}
if(load_graphics_shader_uv(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_UV_HDR], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_UV_HDR], self->params.destination_color, self->params.color_range, false, true) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_load_hdr_graphics_shaders: failed to load UV graphics shader (hdr)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_load_hdr_graphics_shaders: failed to load UV graphics shader (hdr)");
return false;
}
if(self->params.load_external_image_shader) {
if(load_graphics_shader_y(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_Y_HDR_EXTERNAL], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_Y_HDR_EXTERNAL], self->params.destination_color, self->params.color_range, true, true) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_load_hdr_graphics_shaders: failed to load Y graphics shader (hdr, external)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_load_hdr_graphics_shaders: failed to load Y graphics shader (hdr, external)");
return false;
}
if(load_graphics_shader_uv(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_UV_HDR_EXTERNAL], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_UV_HDR_EXTERNAL], self->params.destination_color, self->params.color_range, true, true) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_load_hdr_graphics_shaders: failed to load UV graphics shader (hdr, external)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_load_hdr_graphics_shaders: failed to load UV graphics shader (hdr, external)");
return false;
}
}
@@ -644,13 +645,13 @@ static bool gsr_color_conversion_load_hdr_graphics_shaders(gsr_color_conversion
}
case GSR_DESTINATION_COLOR_RGB: {
if(load_graphics_shader_rgb(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_RGB_HDR], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_RGB_HDR], false, true) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_load_hdr_graphics_shaders: failed to load RGB graphics shader (hdr)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_load_hdr_graphics_shaders: failed to load RGB graphics shader (hdr)");
return false;
}
if(self->params.load_external_image_shader) {
if(load_graphics_shader_rgb(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_RGB_HDR_EXTERNAL], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_RGB_HDR_EXTERNAL], true, true) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_load_hdr_graphics_shaders: failed to load RGB graphics shader (hdr, external)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_load_hdr_graphics_shaders: failed to load RGB graphics shader (hdr, external)");
return false;
}
}
@@ -686,7 +687,7 @@ static int load_framebuffers(gsr_color_conversion *self) {
self->params.egl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->params.destination_textures[0], 0);
self->params.egl->glDrawBuffers(1, &draw_buffer);
if(self->params.egl->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to create framebuffer for Y\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to create framebuffer for Y");
goto err;
}
@@ -695,7 +696,7 @@ static int load_framebuffers(gsr_color_conversion *self) {
self->params.egl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->params.destination_textures[1], 0);
self->params.egl->glDrawBuffers(1, &draw_buffer);
if(self->params.egl->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to create framebuffer for UV\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to create framebuffer for UV");
goto err;
}
}
@@ -731,34 +732,34 @@ static bool gsr_color_conversion_load_graphics_shaders(gsr_color_conversion *sel
case GSR_DESTINATION_COLOR_NV12:
case GSR_DESTINATION_COLOR_P010: {
if(load_graphics_shader_y(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_Y], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_Y], self->params.destination_color, self->params.color_range, false, false) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load Y graphics shader\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load Y graphics shader");
return false;
}
if(load_graphics_shader_uv(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_UV], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_UV], self->params.destination_color, self->params.color_range, false, false) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load UV graphics shader\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load UV graphics shader");
return false;
}
if(load_graphics_shader_yuyv_to_y(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_YUYV_TO_Y], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_YUYV_TO_Y], false) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load YUYV to Y graphics shader\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load YUYV to Y graphics shader");
return false;
}
if(load_graphics_shader_yuyv_to_uv(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_YUYV_TO_UV], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_YUYV_TO_UV], false) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load YUYV to UV graphics shader\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load YUYV to UV graphics shader");
return false;
}
break;
}
case GSR_DESTINATION_COLOR_RGB: {
if(load_graphics_shader_rgb(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_RGB], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_RGB], false, false) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load RGB graphics shader\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load RGB graphics shader");
return false;
}
if(load_graphics_shader_yuyv_to_rgb(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_YUYV_TO_RGB], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_YUYV_TO_RGB], false) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load YUYV to RGB graphics shader\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load YUYV to RGB graphics shader");
return false;
}
break;
@@ -772,34 +773,34 @@ static bool gsr_color_conversion_load_external_graphics_shaders(gsr_color_conver
case GSR_DESTINATION_COLOR_NV12:
case GSR_DESTINATION_COLOR_P010: {
if(load_graphics_shader_y(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_Y_EXTERNAL], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_Y_EXTERNAL], self->params.destination_color, self->params.color_range, true, false) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load Y graphics shader (external)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load Y graphics shader (external)");
return false;
}
if(load_graphics_shader_uv(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_UV_EXTERNAL], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_UV_EXTERNAL], self->params.destination_color, self->params.color_range, true, false) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load UV graphics shader (external)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load UV graphics shader (external)");
return false;
}
if(load_graphics_shader_yuyv_to_y(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_YUYV_TO_Y_EXTERNAL], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_YUYV_TO_Y_EXTERNAL], true) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load YUYV to Y graphics shader (external)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load YUYV to Y graphics shader (external)");
return false;
}
if(load_graphics_shader_yuyv_to_uv(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_YUYV_TO_UV_EXTERNAL], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_YUYV_TO_UV_EXTERNAL], true) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load YUYV to UV graphics shader (external)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load YUYV to UV graphics shader (external)");
return false;
}
break;
}
case GSR_DESTINATION_COLOR_RGB: {
if(load_graphics_shader_rgb(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_RGB_EXTERNAL], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_RGB_EXTERNAL], true, false) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load RGB graphics shader (external)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load RGB graphics shader (external)");
return false;
}
if(load_graphics_shader_yuyv_to_rgb(&self->graphics_shaders[GRAPHICS_SHADER_INDEX_YUYV_TO_RGB_EXTERNAL], self->params.egl, &self->graphics_uniforms[GRAPHICS_SHADER_INDEX_YUYV_TO_RGB_EXTERNAL], true) != 0) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load YUYV to RGB graphics shader (external)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: failed to load YUYV to RGB graphics shader (external)");
return false;
}
break;
@@ -819,14 +820,14 @@ int gsr_color_conversion_init(gsr_color_conversion *self, const gsr_color_conver
case GSR_DESTINATION_COLOR_NV12:
case GSR_DESTINATION_COLOR_P010: {
if(self->params.num_destination_textures != 2) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: expected 2 destination textures for destination color NV12/P010, got %d destination texture(s)\n", self->params.num_destination_textures);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: expected 2 destination textures for destination color NV12/P010, got %d destination texture(s)", self->params.num_destination_textures);
goto err;
}
break;
}
case GSR_DESTINATION_COLOR_RGB: {
if(self->params.num_destination_textures != 1) {
- fprintf(stderr, "gsr error: gsr_color_conversion_init: expected 1 destination textures for destination color RGB8, got %d destination texture(s)\n", self->params.num_destination_textures);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_init: expected 1 destination textures for destination color RGB8, got %d destination texture(s)", self->params.num_destination_textures);
goto err;
}
break;
@@ -1143,7 +1144,7 @@ static void gsr_color_conversion_draw_graphics(gsr_color_conversion *self, unsig
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, gsr_flip flip, gsr_source_color source_color, bool external_texture) {
assert(!external_texture || self->params.load_external_image_shader);
if(external_texture && !self->params.load_external_image_shader) {
- fprintf(stderr, "gsr error: gsr_color_conversion_draw: external texture not loaded\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_color_conversion_draw: external texture not loaded");
return;
}
diff --git a/src/cuda.c b/src/cuda.c
index bfafbcd..55d1f40 100644
--- a/src/cuda.c
+++ b/src/cuda.c
@@ -1,4 +1,5 @@
#include "../include/cuda.h"
+#include "../include/log.h"
#include "../include/library_loader.h"
#include <string.h>
#include <stdio.h>
@@ -13,7 +14,7 @@ bool gsr_cuda_load(gsr_cuda *self) {
if(!lib) {
lib = dlopen("libcuda.so", RTLD_LAZY);
if(!lib) {
- fprintf(stderr, "gsr error: gsr_cuda_load failed: failed to load libcuda.so/libcuda.so.1, error: %s\n", dlerror());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_cuda_load failed: failed to load libcuda.so/libcuda.so.1, error: %s", dlerror());
return false;
}
}
@@ -45,7 +46,7 @@ bool gsr_cuda_load(gsr_cuda *self) {
CUresult res;
if(!dlsym_load_list(lib, required_dlsym)) {
- fprintf(stderr, "gsr error: gsr_cuda_load failed: missing required symbols in libcuda.so/libcuda.so.1\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_cuda_load failed: missing required symbols in libcuda.so/libcuda.so.1");
goto fail;
}
@@ -53,14 +54,14 @@ bool gsr_cuda_load(gsr_cuda *self) {
if(res != CUDA_SUCCESS) {
const char *err_str = "unknown";
self->cuGetErrorString(res, &err_str);
- fprintf(stderr, "gsr error: gsr_cuda_load failed: cuInit failed, error: %s (result: %d)\n", err_str, res);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_cuda_load failed: cuInit failed, error: %s (result: %d)", err_str, res);
goto fail;
}
int nGpu = 0;
self->cuDeviceGetCount(&nGpu);
if(nGpu <= 0) {
- fprintf(stderr, "gsr error: gsr_cuda_load failed: no cuda supported devices found\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_cuda_load failed: no cuda supported devices found");
goto fail;
}
@@ -70,7 +71,7 @@ bool gsr_cuda_load(gsr_cuda *self) {
if(res != CUDA_SUCCESS) {
const char *err_str = "unknown";
self->cuGetErrorString(res, &err_str);
- fprintf(stderr, "gsr error: gsr_cuda_load failed: unable to get CUDA device, error: %s (result: %d)\n", err_str, res);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_cuda_load failed: unable to get CUDA device, error: %s (result: %d)", err_str, res);
goto fail;
}
@@ -78,7 +79,7 @@ bool gsr_cuda_load(gsr_cuda *self) {
if(res != CUDA_SUCCESS) {
const char *err_str = "unknown";
self->cuGetErrorString(res, &err_str);
- fprintf(stderr, "gsr error: gsr_cuda_load failed: unable to create CUDA context, error: %s (result: %d)\n", err_str, res);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_cuda_load failed: unable to create CUDA context, error: %s (result: %d)", err_str, res);
goto fail;
}
diff --git a/src/cursor.c b/src/cursor.c
index 19047ba..65d9d4c 100644
--- a/src/cursor.c
+++ b/src/cursor.c
@@ -1,4 +1,5 @@
#include "../include/cursor.h"
+#include "../include/log.h"
#include <stdio.h>
#include <stdlib.h>
@@ -81,7 +82,7 @@ int gsr_cursor_init(gsr_cursor *self, gsr_egl *egl, Display *display) {
self->x_fixes_event_base = 0;
if(!XFixesQueryExtension(self->display, &self->x_fixes_event_base, &x_fixes_error_base)) {
- fprintf(stderr, "gsr error: gsr_cursor_init: your X11 server is missing the XFixes extension\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_cursor_init: your X11 server is missing the XFixes extension");
gsr_cursor_deinit(self);
return -1;
}
diff --git a/src/damage.c b/src/damage.c
index bbc025a..351f09a 100644
--- a/src/damage.c
+++ b/src/damage.c
@@ -1,4 +1,5 @@
#include "../include/damage.h"
+#include "../include/log.h"
#include "../include/utils.h"
#include "../include/window/window.h"
@@ -46,13 +47,13 @@ static void add_monitor_callback(const gsr_monitor *monitor, void *userdata) {
}
if(self->num_monitors + 1 > GSR_DAMAGE_MAX_MONITORS) {
- fprintf(stderr, "gsr error: gsr_damage_on_output_change: max monitors reached\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_on_output_change: max monitors reached");
return;
}
char *monitor_name_copy = strdup(monitor->name);
if(!monitor_name_copy) {
- fprintf(stderr, "gsr error: gsr_damage_on_output_change: strdup failed for monitor: %s\n", monitor->name);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_on_output_change: strdup failed for monitor: %s", monitor->name);
return;
}
@@ -71,25 +72,25 @@ bool gsr_damage_init(gsr_damage *self, gsr_egl *egl, gsr_cursor *cursor, bool tr
self->cursor = cursor;
if(gsr_window_get_display_server(egl->window) != GSR_DISPLAY_SERVER_X11) {
- fprintf(stderr, "gsr error: gsr_damage_init: damage tracking is not supported on wayland\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_init: damage tracking is not supported on wayland");
return false;
}
self->display = gsr_window_get_display(egl->window);
if(!XDamageQueryExtension(self->display, &self->damage_event, &self->damage_error)) {
- fprintf(stderr, "gsr error: gsr_damage_init: XDamage is not supported by your X11 server\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_init: XDamage is not supported by your X11 server");
gsr_damage_deinit(self);
return false;
}
if(!XRRQueryExtension(self->display, &self->randr_event, &self->randr_error)) {
- fprintf(stderr, "gsr error: gsr_damage_init: XRandr is not supported by your X11 server\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_init: XRandr is not supported by your X11 server");
gsr_damage_deinit(self);
return false;
}
if(!xrandr_is_supported(self->display)) {
- fprintf(stderr, "gsr error: gsr_damage_init: your X11 randr version is too old\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_init: your X11 randr version is too old");
gsr_damage_deinit(self);
return false;
}
@@ -98,7 +99,7 @@ bool gsr_damage_init(gsr_damage *self, gsr_egl *egl, gsr_cursor *cursor, bool tr
self->monitor_damage = XDamageCreate(self->display, DefaultRootWindow(self->display), XDamageReportNonEmpty);
if(!self->monitor_damage) {
- fprintf(stderr, "gsr error: gsr_damage_init: XDamageCreate failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_init: XDamageCreate failed");
gsr_damage_deinit(self);
return false;
}
@@ -163,7 +164,7 @@ bool gsr_damage_start_tracking_window(gsr_damage *self, int64_t window) {
}
if(self->num_windows_tracked + 1 > GSR_DAMAGE_MAX_TRACKED_TARGETS) {
- fprintf(stderr, "gsr error: gsr_damage_start_tracking_window: max window targets reached\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_start_tracking_window: max window targets reached");
return false;
}
@@ -173,11 +174,11 @@ bool gsr_damage_start_tracking_window(gsr_damage *self, int64_t window) {
win_attr.width = 0;
win_attr.height = 0;
if(!XGetWindowAttributes(self->display, window, &win_attr))
- fprintf(stderr, "gsr warning: gsr_damage_start_tracking_window failed: failed to get window attributes: %ld\n", (long)window);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_damage_start_tracking_window failed: failed to get window attributes: %ld", (long)window);
const Damage damage = XDamageCreate(self->display, window, XDamageReportNonEmpty);
if(!damage) {
- fprintf(stderr, "gsr error: gsr_damage_start_tracking_window: XDamageCreate failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_start_tracking_window: XDamageCreate failed");
return false;
}
XDamageSubtract(self->display, damage, None, None);
@@ -250,19 +251,19 @@ bool gsr_damage_start_tracking_monitor(gsr_damage *self, const char *monitor_nam
}
if(self->num_monitors_tracked + 1 > GSR_DAMAGE_MAX_TRACKED_TARGETS) {
- fprintf(stderr, "gsr error: gsr_damage_start_tracking_monitor: max monitor targets reached\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_start_tracking_monitor: max monitor targets reached");
return false;
}
char *monitor_name_copy = strdup(monitor_name);
if(!monitor_name_copy) {
- fprintf(stderr, "gsr error: gsr_damage_start_tracking_monitor: strdup failed for monitor: %s\n", monitor_name);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_start_tracking_monitor: strdup failed for monitor: %s", monitor_name);
return false;
}
gsr_monitor *monitor = gsr_damage_get_monitor_by_name(self, monitor_name);
if(!monitor) {
- fprintf(stderr, "gsr error: gsr_damage_start_tracking_monitor: failed to find monitor: %s\n", monitor_name);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_damage_start_tracking_monitor: failed to find monitor: %s", monitor_name);
free(monitor_name_copy);
return false;
}
diff --git a/src/dbus.c b/src/dbus.c
index 715a021..bde9950 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -1,4 +1,5 @@
#include "../include/dbus.h"
+#include "../include/log.h"
#include <sys/random.h>
@@ -32,7 +33,7 @@ typedef struct {
static bool generate_random_characters(char *buffer, int buffer_size, const char *alphabet, size_t alphabet_size) {
/* TODO: Use other functions on other platforms than linux */
if(getrandom(buffer, buffer_size, 0) < buffer_size) {
- fprintf(stderr, "Failed to get random bytes, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to get random bytes, error: %s", strerror(errno));
return false;
}
@@ -63,25 +64,25 @@ bool gsr_dbus_init(gsr_dbus *self, const char *screencast_restore_token) {
self->random_str[DBUS_RANDOM_STR_SIZE] = '\0';
if(!generate_random_characters_standard_alphabet(self->random_str, DBUS_RANDOM_STR_SIZE)) {
- fprintf(stderr, "gsr error: gsr_dbus_init: failed to generate random string\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_init: failed to generate random string");
return false;
}
self->con = dbus_bus_get(DBUS_BUS_SESSION, &self->err);
if(dbus_error_is_set(&self->err)) {
- fprintf(stderr, "gsr error: gsr_dbus_init: dbus_bus_get failed with error: %s\n", self->err.message);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_init: dbus_bus_get failed with error: %s", self->err.message);
return false;
}
if(!self->con) {
- fprintf(stderr, "gsr error: gsr_dbus_init: failed to get dbus session\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_init: failed to get dbus session");
return false;
}
if(screencast_restore_token) {
self->screencast_restore_token = strdup(screencast_restore_token);
if(!self->screencast_restore_token) {
- fprintf(stderr, "gsr error: gsr_dbus_init: failed to clone restore token\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_init: failed to clone restore token");
gsr_dbus_deinit(self);
return false;
}
@@ -121,7 +122,7 @@ static bool gsr_dbus_desktop_portal_get_property(gsr_dbus *self, const char *int
"org.freedesktop.DBus.Properties", // interface to call on
"Get"); // method name
if(!msg) {
- fprintf(stderr, "gsr error: gsr_dbus_desktop_portal_get_property: dbus_message_new_method_call failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_desktop_portal_get_property: dbus_message_new_method_call failed");
return false;
}
@@ -129,20 +130,20 @@ static bool gsr_dbus_desktop_portal_get_property(gsr_dbus *self, const char *int
dbus_message_iter_init_append(msg, &it);
if(!dbus_message_iter_append_basic(&it, DBUS_TYPE_STRING, &interface)) {
- fprintf(stderr, "gsr error: gsr_dbus_desktop_portal_get_property: failed to add interface\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_desktop_portal_get_property: failed to add interface");
dbus_message_unref(msg);
return false;
}
if(!dbus_message_iter_append_basic(&it, DBUS_TYPE_STRING, &property_name)) {
- fprintf(stderr, "gsr error: gsr_dbus_desktop_portal_get_property: failed to add property_name\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_desktop_portal_get_property: failed to add property_name");
dbus_message_unref(msg);
return false;
}
DBusPendingCall *pending = NULL;
if(!dbus_connection_send_with_reply(self->con, msg, &pending, -1) || !pending) { // -1 is default timeout
- fprintf(stderr, "gsr error: gsr_dbus_desktop_portal_get_property: dbus_connection_send_with_reply failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_desktop_portal_get_property: dbus_connection_send_with_reply failed");
dbus_message_unref(msg);
return false;
}
@@ -157,7 +158,7 @@ static bool gsr_dbus_desktop_portal_get_property(gsr_dbus *self, const char *int
msg = dbus_pending_call_steal_reply(pending);
if(!msg) {
- fprintf(stderr, "gsr error: gsr_dbus_desktop_portal_get_property: dbus_pending_call_steal_reply failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_desktop_portal_get_property: dbus_pending_call_steal_reply failed");
dbus_pending_call_unref(pending);
dbus_message_unref(msg);
return false;
@@ -168,7 +169,7 @@ static bool gsr_dbus_desktop_portal_get_property(gsr_dbus *self, const char *int
DBusMessageIter resp_args;
if(!dbus_message_iter_init(msg, &resp_args)) {
- fprintf(stderr, "gsr error: gsr_dbus_desktop_portal_get_property: response message is missing arguments\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_desktop_portal_get_property: response message is missing arguments");
dbus_message_unref(msg);
return false;
} else if(DBUS_TYPE_UINT32 == dbus_message_iter_get_arg_type(&resp_args)) {
@@ -180,12 +181,12 @@ static bool gsr_dbus_desktop_portal_get_property(gsr_dbus *self, const char *int
if(dbus_message_iter_get_arg_type(&variant_iter) == DBUS_TYPE_UINT32) {
dbus_message_iter_get_basic(&variant_iter, result);
} else {
- fprintf(stderr, "gsr error: gsr_dbus_desktop_portal_get_property: response message is not a variant with an uint32, %c\n", dbus_message_iter_get_arg_type(&variant_iter));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_desktop_portal_get_property: response message is not a variant with an uint32, %c", dbus_message_iter_get_arg_type(&variant_iter));
dbus_message_unref(msg);
return false;
}
} else {
- fprintf(stderr, "gsr error: gsr_dbus_desktop_portal_get_property: response message is not an uint32, %c\n", dbus_message_iter_get_arg_type(&resp_args));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_desktop_portal_get_property: response message is not an uint32, %c", dbus_message_iter_get_arg_type(&resp_args));
dbus_message_unref(msg);
return false;
// TODO: Check dbus_error_is_set?
@@ -208,7 +209,7 @@ static bool gsr_dbus_ensure_desktop_portal_rule_added(gsr_dbus *self) {
dbus_bus_add_match(self->con, DESKTOP_PORTAL_SIGNAL_RULE, &self->err);
dbus_connection_flush(self->con);
if(dbus_error_is_set(&self->err)) {
- fprintf(stderr, "gsr error: gsr_dbus_ensure_desktop_portal_rule_added: failed to add dbus rule %s, error: %s\n", DESKTOP_PORTAL_SIGNAL_RULE, self->err.message);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_ensure_desktop_portal_rule_added: failed to add dbus rule %s, error: %s", DESKTOP_PORTAL_SIGNAL_RULE, self->err.message);
return false;
}
self->desktop_portal_rule_added = true;
@@ -293,7 +294,7 @@ static bool gsr_dbus_call_screencast_method(gsr_dbus *self, const char *method_n
"org.freedesktop.portal.ScreenCast", // interface to call on
method_name); // method name
if(!msg) {
- fprintf(stderr, "gsr error: gsr_dbus_call_screencast_method: dbus_message_new_method_call failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_call_screencast_method: dbus_message_new_method_call failed");
return false;
}
@@ -302,7 +303,7 @@ static bool gsr_dbus_call_screencast_method(gsr_dbus *self, const char *method_n
if(session_handle) {
if(!dbus_message_iter_append_basic(&it, DBUS_TYPE_OBJECT_PATH, &session_handle)) {
- fprintf(stderr, "gsr error: gsr_dbus_call_screencast_method: failed to add session_handle\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_call_screencast_method: failed to add session_handle");
dbus_message_unref(msg);
return false;
}
@@ -310,21 +311,21 @@ static bool gsr_dbus_call_screencast_method(gsr_dbus *self, const char *method_n
if(parent_window) {
if(!dbus_message_iter_append_basic(&it, DBUS_TYPE_STRING, &parent_window)) {
- fprintf(stderr, "gsr error: gsr_dbus_call_screencast_method: failed to add parent_window\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_call_screencast_method: failed to add parent_window");
dbus_message_unref(msg);
return false;
}
}
if(!dbus_add_dict(&it, entries, num_entries)) {
- fprintf(stderr, "gsr error: gsr_dbus_call_screencast_method: failed to add dict\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_call_screencast_method: failed to add dict");
dbus_message_unref(msg);
return false;
}
DBusPendingCall *pending = NULL;
if(!dbus_connection_send_with_reply(self->con, msg, &pending, -1) || !pending) { // -1 is default timeout
- fprintf(stderr, "gsr error: gsr_dbus_call_screencast_method: dbus_connection_send_with_reply failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_call_screencast_method: dbus_connection_send_with_reply failed");
dbus_message_unref(msg);
return false;
}
@@ -339,7 +340,7 @@ static bool gsr_dbus_call_screencast_method(gsr_dbus *self, const char *method_n
msg = dbus_pending_call_steal_reply(pending);
if(!msg) {
- fprintf(stderr, "gsr error: gsr_dbus_call_screencast_method: dbus_pending_call_steal_reply failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_call_screencast_method: dbus_pending_call_steal_reply failed");
dbus_pending_call_unref(pending);
dbus_message_unref(msg);
return false;
@@ -350,7 +351,7 @@ static bool gsr_dbus_call_screencast_method(gsr_dbus *self, const char *method_n
DBusMessageIter resp_args;
if(!dbus_message_iter_init(msg, &resp_args)) {
- fprintf(stderr, "gsr error: gsr_dbus_call_screencast_method: response message is missing arguments\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_call_screencast_method: response message is missing arguments");
dbus_message_unref(msg);
return false;
} else if (DBUS_TYPE_OBJECT_PATH == dbus_message_iter_get_arg_type(&resp_args)) {
@@ -365,13 +366,13 @@ static bool gsr_dbus_call_screencast_method(gsr_dbus *self, const char *method_n
} else if(DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&resp_args)) {
char *err = NULL;
dbus_message_iter_get_basic(&resp_args, &err);
- fprintf(stderr, "gsr error: gsr_dbus_call_screencast_method: failed with error: %s\n", err);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_call_screencast_method: failed with error: %s", err);
dbus_message_unref(msg);
return false;
// TODO: Check dbus_error_is_set?
} else {
- fprintf(stderr, "gsr error: gsr_dbus_call_screencast_method: response message is not an object path or unix fd\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_call_screencast_method: response message is not an object path or unix fd");
dbus_message_unref(msg);
return false;
// TODO: Check dbus_error_is_set?
@@ -404,7 +405,7 @@ static bool gsr_dbus_call_screencast_method(gsr_dbus *self, const char *method_n
static int gsr_dbus_get_response_status(DBusMessageIter *resp_args) {
if(dbus_message_iter_get_arg_type(resp_args) != DBUS_TYPE_UINT32) {
- fprintf(stderr, "gsr error: gsr_dbus_get_response_status: missing uint32 in response\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_response_status: missing uint32 in response");
return -1;
}
@@ -425,7 +426,7 @@ static dict_entry* find_dict_entry_by_key(dict_entry *entries, int num_entries,
static bool gsr_dbus_get_variant_value(DBusMessageIter *iter, dict_entry *entry) {
if(dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT) {
- fprintf(stderr, "gsr error: gsr_dbus_get_variant_value: value is not a variant\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_variant_value: value is not a variant");
return false;
}
@@ -435,7 +436,7 @@ static bool gsr_dbus_get_variant_value(DBusMessageIter *iter, dict_entry *entry)
switch(dbus_message_iter_get_arg_type(&variant_iter)) {
case DBUS_TYPE_STRING: {
if(entry->value_type != DICT_TYPE_STRING) {
- fprintf(stderr, "gsr error: gsr_dbus_get_variant_value: expected entry value to be a(n) %s was a string\n", dict_value_type_to_string(entry->value_type));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_variant_value: expected entry value to be a(n) %s was a string", dict_value_type_to_string(entry->value_type));
return false;
}
@@ -443,7 +444,7 @@ static bool gsr_dbus_get_variant_value(DBusMessageIter *iter, dict_entry *entry)
dbus_message_iter_get_basic(&variant_iter, &value);
if(!value) {
- fprintf(stderr, "gsr error: gsr_dbus_get_variant_value: failed to get entry value as value\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_variant_value: failed to get entry value as value");
return false;
}
@@ -454,14 +455,14 @@ static bool gsr_dbus_get_variant_value(DBusMessageIter *iter, dict_entry *entry)
entry->str = strdup(value);
if(!entry->str) {
- fprintf(stderr, "gsr error: gsr_dbus_get_variant_value: failed to copy value\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_variant_value: failed to copy value");
return false;
}
return true;
}
case DBUS_TYPE_UINT32: {
if(entry->value_type != DICT_TYPE_UINT32) {
- fprintf(stderr, "gsr error: gsr_dbus_get_variant_value: expected entry value to be a(n) %s was an uint32\n", dict_value_type_to_string(entry->value_type));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_variant_value: expected entry value to be a(n) %s was an uint32", dict_value_type_to_string(entry->value_type));
return false;
}
@@ -470,7 +471,7 @@ static bool gsr_dbus_get_variant_value(DBusMessageIter *iter, dict_entry *entry)
}
case DBUS_TYPE_BOOLEAN: {
if(entry->value_type != DICT_TYPE_BOOL) {
- fprintf(stderr, "gsr error: gsr_dbus_get_variant_value: expected entry value to be a(n) %s was a boolean\n", dict_value_type_to_string(entry->value_type));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_variant_value: expected entry value to be a(n) %s was a boolean", dict_value_type_to_string(entry->value_type));
return false;
}
@@ -479,7 +480,7 @@ static bool gsr_dbus_get_variant_value(DBusMessageIter *iter, dict_entry *entry)
}
}
- fprintf(stderr, "gsr error: gsr_dbus_get_variant_value: got unexpected type, expected string, uint32 or boolean\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_variant_value: got unexpected type, expected string, uint32 or boolean");
return false;
}
@@ -492,7 +493,7 @@ static bool gsr_dbus_get_variant_value(DBusMessageIter *iter, dict_entry *entry)
*/
static bool gsr_dbus_get_map(DBusMessageIter *resp_args, dict_entry *entries, int num_entries) {
if(dbus_message_iter_get_arg_type(resp_args) != DBUS_TYPE_ARRAY) {
- fprintf(stderr, "gsr error: gsr_dbus_get_map: missing array in response\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_map: missing array in response");
return false;
}
@@ -508,20 +509,20 @@ static bool gsr_dbus_get_map(DBusMessageIter *resp_args, dict_entry *entries, in
// dbus_message_iter_get_arg_type(&subiter),
// dbus_message_iter_get_signature(&subiter));
if(dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_DICT_ENTRY) {
- fprintf(stderr, "gsr error: gsr_dbus_get_map: array value is not an entry\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_map: array value is not an entry");
return false;
}
dbus_message_iter_recurse(&subiter, &dictiter);
if(dbus_message_iter_get_arg_type(&dictiter) != DBUS_TYPE_STRING) {
- fprintf(stderr, "gsr error: gsr_dbus_get_map: entry key is not a string\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_map: entry key is not a string");
goto error;
}
dbus_message_iter_get_basic(&dictiter, &key);
if(!key) {
- fprintf(stderr, "gsr error: gsr_dbus_get_map: failed to get entry key as value\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_map: failed to get entry key as value");
goto error;
}
@@ -532,7 +533,7 @@ static bool gsr_dbus_get_map(DBusMessageIter *resp_args, dict_entry *entries, in
}
if(!dbus_message_iter_next(&dictiter)) {
- fprintf(stderr, "gsr error: gsr_dbus_get_map: missing entry value\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_get_map: missing entry value");
goto error;
}
@@ -575,7 +576,7 @@ int gsr_dbus_screencast_create_session(gsr_dbus *self, char **session_handle) {
DBusMessage *response_msg = NULL;
if(!gsr_dbus_call_screencast_method(self, "CreateSession", NULL, NULL, args, 2, NULL, &response_msg)) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_create_session: failed to setup ScreenCast session. Make sure you have a desktop portal running with support for the ScreenCast interface and that the desktop portal matches the Wayland compositor you are running.\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_create_session: failed to setup ScreenCast session. Make sure you have a desktop portal running with support for the ScreenCast interface and that the desktop portal matches the Wayland compositor you are running.");
return -1;
}
@@ -584,7 +585,7 @@ int gsr_dbus_screencast_create_session(gsr_dbus *self, char **session_handle) {
//fprintf(stderr, "signature: %s, sender: %s\n", dbus_message_get_signature(msg), dbus_message_get_sender(msg));
DBusMessageIter resp_args;
if(!dbus_message_iter_init(response_msg, &resp_args)) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_create_session: missing response\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_create_session: missing response");
dbus_message_unref(response_msg);
return -1;
}
@@ -605,7 +606,7 @@ int gsr_dbus_screencast_create_session(gsr_dbus *self, char **session_handle) {
}
if(!entries[0].str) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_create_session: missing \"session_handle\" in response\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_create_session: missing \"session_handle\" in response");
dbus_message_unref(response_msg);
return -1;
}
@@ -644,16 +645,16 @@ int gsr_dbus_screencast_select_sources(gsr_dbus *self, const char *session_handl
uint32_t available_source_types = 0;
gsr_dbus_desktop_portal_get_property(self, "org.freedesktop.portal.ScreenCast", "AvailableSourceTypes", &available_source_types);
if(available_source_types == 0)
- fprintf(stderr, "gsr error: gsr_dbus_screencast_select_sources: no source types are available\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_select_sources: no source types are available");
capture_type = unset_unsupported_capture_types(capture_type, available_source_types);
uint32_t available_cursor_modes = 0;
gsr_dbus_desktop_portal_get_property(self, "org.freedesktop.portal.ScreenCast", "AvailableCursorModes", &available_cursor_modes);
if(available_cursor_modes == 0)
- fprintf(stderr, "gsr warning: gsr_dbus_screencast_select_sources: no cursors modes are available\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_dbus_screencast_select_sources: no cursors modes are available");
if(cursor_mode == GSR_PORTAL_CURSOR_MODE_METADATA && !(available_cursor_modes & GSR_PORTAL_CURSOR_MODE_METADATA)) {
- fprintf(stderr, "gsr warning: gsr_dbus_screencast_select_sources: cursor mode metadata is not available, using cursor mode embedded instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_dbus_screencast_select_sources: cursor mode metadata is not available, using cursor mode embedded instead");
cursor_mode = GSR_PORTAL_CURSOR_MODE_EMBEDDED;
}
cursor_mode = unset_unsupported_cursor_modes(cursor_mode, available_cursor_modes);
@@ -696,14 +697,14 @@ int gsr_dbus_screencast_select_sources(gsr_dbus *self, const char *session_handl
args[5].str = self->screencast_restore_token;
}
} else if(self->screencast_restore_token && self->screencast_restore_token[0]) {
- fprintf(stderr, "gsr warning: gsr_dbus_screencast_select_sources: tried to use restore token but this option is only available in screencast version >= 4, your wayland compositors screencast version is %d\n", screencast_server_version);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_dbus_screencast_select_sources: tried to use restore token but this option is only available in screencast version >= 4, your wayland compositors screencast version is %d", screencast_server_version);
}
DBusMessage *response_msg = NULL;
if(!gsr_dbus_call_screencast_method(self, "SelectSources", session_handle, NULL, args, num_arg_dict, NULL, &response_msg)) {
if(num_arg_dict == 6) {
/* We dont know what the error exactly is but assume it may be because of invalid restore token. In that case try without restore token */
- fprintf(stderr, "gsr warning: gsr_dbus_screencast_select_sources: SelectSources failed, retrying without restore_token\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_dbus_screencast_select_sources: SelectSources failed, retrying without restore_token");
num_arg_dict = 5;
if(!gsr_dbus_call_screencast_method(self, "SelectSources", session_handle, NULL, args, num_arg_dict, NULL, &response_msg))
return -1;
@@ -716,7 +717,7 @@ int gsr_dbus_screencast_select_sources(gsr_dbus *self, const char *session_handl
//fprintf(stderr, "signature: %s, sender: %s\n", dbus_message_get_signature(msg), dbus_message_get_sender(msg));
DBusMessageIter resp_args;
if(!dbus_message_iter_init(response_msg, &resp_args)) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_create_session: missing response\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_create_session: missing response");
dbus_message_unref(response_msg);
return -1;
}
@@ -770,7 +771,7 @@ int gsr_dbus_screencast_start(gsr_dbus *self, const char *session_handle, uint32
//fprintf(stderr, "signature: %s, sender: %s\n", dbus_message_get_signature(msg), dbus_message_get_sender(msg));
DBusMessageIter resp_args;
if(!dbus_message_iter_init(response_msg, &resp_args)) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: missing response\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: missing response");
dbus_message_unref(response_msg);
return -1;
}
@@ -782,7 +783,7 @@ int gsr_dbus_screencast_start(gsr_dbus *self, const char *session_handle, uint32
}
if(dbus_message_iter_get_arg_type(&resp_args) != DBUS_TYPE_ARRAY) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: missing array in response\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: missing array in response");
dbus_message_unref(response_msg);
return -1;
}
@@ -798,31 +799,31 @@ int gsr_dbus_screencast_start(gsr_dbus *self, const char *session_handle, uint32
// dbus_message_iter_get_arg_type(&subiter),
// dbus_message_iter_get_signature(&subiter));
if(dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_DICT_ENTRY) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: array value is not an entry\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: array value is not an entry");
goto error;
}
dbus_message_iter_recurse(&subiter, &dictiter);
if(dbus_message_iter_get_arg_type(&dictiter) != DBUS_TYPE_STRING) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: entry key is not a string\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: entry key is not a string");
goto error;
}
dbus_message_iter_get_basic(&dictiter, &key);
if(!key) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: failed to get entry key as value\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: failed to get entry key as value");
goto error;
}
if(strcmp(key, "restore_token") == 0) {
if(!dbus_message_iter_next(&dictiter)) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: missing restore_token value\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: missing restore_token value");
goto error;
}
if(dbus_message_iter_get_arg_type(&dictiter) != DBUS_TYPE_VARIANT) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: restore_token is not a variant\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: restore_token is not a variant");
goto error;
}
@@ -830,7 +831,7 @@ int gsr_dbus_screencast_start(gsr_dbus *self, const char *session_handle, uint32
dbus_message_iter_recurse(&dictiter, &variant_iter);
if(dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRING) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: restore_token is not a string\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: restore_token is not a string");
goto error;
}
@@ -847,12 +848,12 @@ int gsr_dbus_screencast_start(gsr_dbus *self, const char *session_handle, uint32
}
} else if(strcmp(key, "streams") == 0) {
if(!dbus_message_iter_next(&dictiter)) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: missing streams value\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: missing streams value");
goto error;
}
if(dbus_message_iter_get_arg_type(&dictiter) != DBUS_TYPE_VARIANT) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: streams value is not a variant\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: streams value is not a variant");
goto error;
}
@@ -860,7 +861,7 @@ int gsr_dbus_screencast_start(gsr_dbus *self, const char *session_handle, uint32
dbus_message_iter_recurse(&dictiter, &variant_iter);
if(dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: streams value is not an array\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: streams value is not an array");
goto error;
}
@@ -881,7 +882,7 @@ int gsr_dbus_screencast_start(gsr_dbus *self, const char *session_handle, uint32
}
if(*pipewire_node == 0) {
- fprintf(stderr, "gsr error: gsr_dbus_screencast_start: no pipewire node returned\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_dbus_screencast_start: no pipewire node returned");
goto error;
}
diff --git a/src/egl.c b/src/egl.c
index 3dcd5df..7e29bbc 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -1,4 +1,5 @@
#include "../include/egl.h"
+#include "../include/log.h"
#include "../include/window/window.h"
#include "../include/library_loader.h"
#include "../include/utils.h"
@@ -53,34 +54,34 @@ static bool gsr_egl_create_window(gsr_egl *self, bool enable_debug) {
self->egl_display = self->eglGetDisplay((EGLNativeDisplayType)gsr_window_get_display(self->window));
if(!self->egl_display) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: eglGetDisplay failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_create_window failed: eglGetDisplay failed");
goto fail;
}
if(!self->eglInitialize(self->egl_display, NULL, NULL)) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: eglInitialize failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_create_window failed: eglInitialize failed");
goto fail;
}
if(!self->eglChooseConfig(self->egl_display, attr, &ecfg, 1, &num_config) || num_config != 1) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: failed to find a matching config\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_create_window failed: failed to find a matching config");
goto fail;
}
self->egl_context = self->eglCreateContext(self->egl_display, ecfg, NULL, ctxattr);
if(!self->egl_context) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: failed to create egl context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_create_window failed: failed to create egl context");
goto fail;
}
self->egl_surface = self->eglCreateWindowSurface(self->egl_display, ecfg, (EGLNativeWindowType)gsr_window_get_window(self->window), NULL);
if(!self->egl_surface) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: failed to create window surface\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_create_window failed: failed to create window surface");
goto fail;
}
if(!self->eglMakeCurrent(self->egl_display, self->egl_surface, self->egl_surface, self->egl_context)) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: failed to make egl context current\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_create_window failed: failed to make egl context current");
goto fail;
}
@@ -141,7 +142,7 @@ static bool gsr_egl_switch_to_glx_context(gsr_egl *self) {
self->glx_fb_config = glx_fb_config_choose(self, display);
if(!self->glx_fb_config) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: failed to find a suitable fb config\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_create_window failed: failed to find a suitable fb config");
goto fail;
}
@@ -149,12 +150,12 @@ static bool gsr_egl_switch_to_glx_context(gsr_egl *self) {
//self->glx_context = self->glXCreateContextAttribsARB(display, self->glx_fb_config, NULL, True, context_attrib_list);
self->glx_context = self->glXCreateNewContext(display, self->glx_fb_config, GLX_RGBA_TYPE, NULL, True);
if(!self->glx_context) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: failed to create glx context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_create_window failed: failed to create glx context");
goto fail;
}
if(!self->glXMakeContextCurrent(display, window, window, self->glx_context)) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: failed to make glx context current\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_create_window failed: failed to make glx context current");
goto fail;
}
@@ -193,7 +194,7 @@ static bool gsr_egl_load_egl(gsr_egl *self, void *library) {
};
if(!dlsym_load_list(library, required_dlsym)) {
- fprintf(stderr, "gsr error: gsr_egl_load failed: missing required symbols in libEGL.so.1\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_load failed: missing required symbols in libEGL.so.1");
return false;
}
@@ -221,17 +222,17 @@ static bool gsr_egl_proc_load_egl(gsr_egl *self) {
self->glSignalSemaphoreEXT = (FUNC_glSignalSemaphoreEXT)self->eglGetProcAddress("glSignalSemaphoreEXT");
if(!self->eglExportDMABUFImageQueryMESA) {
- fprintf(stderr, "gsr error: gsr_egl_load failed: could not find eglExportDMABUFImageQueryMESA\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_load failed: could not find eglExportDMABUFImageQueryMESA");
return false;
}
if(!self->eglExportDMABUFImageMESA) {
- fprintf(stderr, "gsr error: gsr_egl_load failed: could not find eglExportDMABUFImageMESA\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_load failed: could not find eglExportDMABUFImageMESA");
return false;
}
if(!self->glEGLImageTargetTexture2DOES) {
- fprintf(stderr, "gsr error: gsr_egl_load failed: could not find glEGLImageTargetTexture2DOES\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_load failed: could not find glEGLImageTargetTexture2DOES");
return false;
}
@@ -251,13 +252,13 @@ static bool gsr_egl_load_glx(gsr_egl *self, void *library) {
};
if(!dlsym_load_list(library, required_dlsym)) {
- fprintf(stderr, "gsr error: gsr_egl_load failed: missing required symbols in libGLX.so.0\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_load failed: missing required symbols in libGLX.so.0");
return false;
}
self->glXCreateContextAttribsARB = (FUNC_glXCreateContextAttribsARB)self->glXGetProcAddress((const unsigned char*)"glXCreateContextAttribsARB");
if(!self->glXCreateContextAttribsARB) {
- fprintf(stderr, "gsr error: gsr_egl_load_glx failed: could not find glXCreateContextAttribsARB\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_load_glx failed: could not find glXCreateContextAttribsARB");
return false;
}
@@ -343,7 +344,7 @@ static bool gsr_egl_load_gl(gsr_egl *self, void *library) {
};
if(!dlsym_load_list(library, required_dlsym)) {
- fprintf(stderr, "gsr error: gsr_egl_load failed: missing required symbols in libGL.so.1\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_load failed: missing required symbols in libGL.so.1");
return false;
}
@@ -358,7 +359,7 @@ static void debug_callback(unsigned int source, unsigned int type, unsigned int
(void)length;
(void)userParam;
if(severity != GL_DEBUG_SEVERITY_NOTIFICATION)
- fprintf(stderr, "gsr info: gl callback: %s type = 0x%x, severity = 0x%x, message = %s\n", type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "", type, severity, message);
+ gsr_log(GSR_LOG_LEVEL_INFO, "gl callback: %s type = 0x%x, severity = 0x%x, message = %s", type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "", type, severity, message);
}
/* TODO: check for glx swap control extension string (GLX_EXT_swap_control, etc) */
@@ -378,12 +379,12 @@ static void set_vertical_sync_enabled(gsr_egl *egl, int enabled) {
static int warned = 0;
if (!warned) {
warned = 1;
- fprintf(stderr, "gsr warning: setting vertical sync not supported\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "setting vertical sync not supported");
}
}
if(result != 0)
- fprintf(stderr, "gsr warning: setting vertical sync failed\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "setting vertical sync failed");
}
static void gsr_egl_disable_vsync(gsr_egl *self) {
@@ -407,7 +408,7 @@ bool gsr_egl_load(gsr_egl *self, gsr_window *window, bool is_monitor_capture, bo
dlerror(); /* clear */
self->egl_library = dlopen("libEGL.so.1", RTLD_LAZY);
if(!self->egl_library) {
- fprintf(stderr, "gsr error: gsr_egl_load: failed to load libEGL.so.1, error: %s\n", dlerror());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_load: failed to load libEGL.so.1, error: %s", dlerror());
goto fail;
}
@@ -415,7 +416,7 @@ bool gsr_egl_load(gsr_egl *self, gsr_window *window, bool is_monitor_capture, bo
self->gl_library = dlopen("libGL.so.1", RTLD_LAZY);
if(!self->gl_library) {
- fprintf(stderr, "gsr error: gsr_egl_load: failed to load libGL.so.1, error: %s\n", dlerror());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_egl_load: failed to load libGL.so.1, error: %s", dlerror());
goto fail;
}
diff --git a/src/encoder/encoder.c b/src/encoder/encoder.c
index 9ce7d19..2df4666 100644
--- a/src/encoder/encoder.c
+++ b/src/encoder/encoder.c
@@ -1,4 +1,5 @@
#include "../../include/encoder/encoder.h"
+#include "../../include/log.h"
#include "../../include/utils.h"
#include <string.h>
@@ -25,7 +26,7 @@ static void gsr_write_first_frame_timestamp_file(const char *filepath) {
FILE *file = fopen(filepath, "w");
if(!file) {
- fprintf(stderr, "gsr warning: failed to open timestamp file '%s': %s\n", filepath, strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_WARNING, "failed to open timestamp file '%s': %s", filepath, strerror(errno));
return;
}
@@ -41,14 +42,14 @@ bool gsr_encoder_init(gsr_encoder *self, gsr_replay_storage replay_storage, size
self->first_pts = -1;
if(pthread_mutex_init(&self->file_write_mutex, NULL) != 0) {
- fprintf(stderr, "gsr error: gsr_encoder_init: failed to create mutex\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_encoder_init: failed to create mutex");
gsr_encoder_deinit(self);
return false;
}
self->file_write_mutex_created = true;
if(pthread_mutex_init(&self->replay_mutex, NULL) != 0) {
- fprintf(stderr, "gsr error: gsr_encoder_init: failed to create mutex\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_encoder_init: failed to create mutex");
gsr_encoder_deinit(self);
return false;
}
@@ -57,7 +58,7 @@ bool gsr_encoder_init(gsr_encoder *self, gsr_replay_storage replay_storage, size
if(replay_buffer_num_packets > 0) {
self->replay_buffer = gsr_replay_buffer_create(replay_storage, replay_directory, replay_buffer_time, replay_buffer_num_packets);
if(!self->replay_buffer) {
- fprintf(stderr, "gsr error: gsr_encoder_init: failed to create replay buffer\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_encoder_init: failed to create replay buffer");
gsr_encoder_deinit(self);
return false;
}
@@ -120,7 +121,7 @@ void gsr_encoder_receive_packets(gsr_encoder *self, AVCodecContext *codec_contex
pthread_mutex_lock(&self->replay_mutex);
const double time_now = clock_get_monotonic_seconds();
if(!gsr_replay_buffer_append(self->replay_buffer, av_packet, time_now))
- fprintf(stderr, "gsr error: gsr_encoder_receive_packets: failed to add replay buffer data\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_encoder_receive_packets: failed to add replay buffer data");
pthread_mutex_unlock(&self->replay_mutex);
}
@@ -155,7 +156,7 @@ void gsr_encoder_receive_packets(gsr_encoder *self, AVCodecContext *codec_contex
char error_buffer[AV_ERROR_MAX_STRING_SIZE];
if(av_strerror(ret, error_buffer, sizeof(error_buffer)) < 0)
snprintf(error_buffer, sizeof(error_buffer), "Unknown error");
- fprintf(stderr, "gsr error: gsr_encoder_receive_packets: failed to write frame index %d to muxer, reason: %s (%d)\n", av_packet->stream_index, error_buffer, ret);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_encoder_receive_packets: failed to write frame index %d to muxer, reason: %s (%d)", av_packet->stream_index, error_buffer, ret);
}
}
pthread_mutex_unlock(&self->file_write_mutex);
@@ -167,11 +168,11 @@ void gsr_encoder_receive_packets(gsr_encoder *self, AVCodecContext *codec_contex
break;
} else if (res == AVERROR_EOF) { // this is the end of the stream
av_packet_free(&av_packet);
- fprintf(stderr, "End of stream!\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_encoder_receive_packets: end of stream");
break;
} else {
av_packet_free(&av_packet);
- fprintf(stderr, "Unexpected error: %d\n", res);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_encoder_receive_packets: unexpected error: %d", res);
break;
}
}
@@ -179,13 +180,13 @@ void gsr_encoder_receive_packets(gsr_encoder *self, AVCodecContext *codec_contex
size_t gsr_encoder_add_recording_destination(gsr_encoder *self, AVCodecContext *codec_context, AVFormatContext *format_context, AVStream *stream, int64_t start_pts) {
if(self->num_recording_destinations >= GSR_MAX_RECORDING_DESTINATIONS) {
- fprintf(stderr, "gsr error: gsr_encoder_add_recording_destination: failed to add destination, reached the max amount of recording destinations (%d)\n", GSR_MAX_RECORDING_DESTINATIONS);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_encoder_add_recording_destination: failed to add destination, reached the max amount of recording destinations (%d)", GSR_MAX_RECORDING_DESTINATIONS);
return (size_t)-1;
}
for(size_t i = 0; i < self->num_recording_destinations; ++i) {
if(self->recording_destinations[i].stream == stream) {
- fprintf(stderr, "gsr error: gsr_encoder_add_recording_destination: failed to add destination, the stream %p already exists as an output\n", (void*)stream);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_encoder_add_recording_destination: failed to add destination, the stream %p already exists as an output", (void*)stream);
return (size_t)-1;
}
}
diff --git a/src/encoder/video/nvenc.c b/src/encoder/video/nvenc.c
index dd877c5..f7fca41 100644
--- a/src/encoder/video/nvenc.c
+++ b/src/encoder/video/nvenc.c
@@ -1,4 +1,5 @@
#include "../../../include/encoder/video/nvenc.h"
+#include "../../../include/log.h"
#include "../../../include/egl.h"
#include "../../../include/cuda.h"
#include "../../../include/utils.h"
@@ -25,7 +26,7 @@ typedef struct {
static bool gsr_video_encoder_nvenc_setup_context(gsr_video_encoder_nvenc *self, AVCodecContext *video_codec_context) {
self->device_ctx = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_CUDA);
if(!self->device_ctx) {
- fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_setup_context failed: failed to create hardware device context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_nvenc_setup_context failed: failed to create hardware device context");
return false;
}
@@ -33,14 +34,14 @@ static bool gsr_video_encoder_nvenc_setup_context(gsr_video_encoder_nvenc *self,
AVCUDADeviceContext *cuda_device_context = (AVCUDADeviceContext*)hw_device_context->hwctx;
cuda_device_context->cuda_ctx = self->cuda.cu_ctx;
if(av_hwdevice_ctx_init(self->device_ctx) < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_setup_context failed: failed to create hardware device context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_nvenc_setup_context failed: failed to create hardware device context");
av_buffer_unref(&self->device_ctx);
return false;
}
AVBufferRef *frame_context = av_hwframe_ctx_alloc(self->device_ctx);
if(!frame_context) {
- fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_setup_context failed: failed to create hwframe context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_nvenc_setup_context failed: failed to create hwframe context");
av_buffer_unref(&self->device_ctx);
return false;
}
@@ -53,8 +54,7 @@ static bool gsr_video_encoder_nvenc_setup_context(gsr_video_encoder_nvenc *self,
hw_frame_context->device_ctx = (AVHWDeviceContext*)self->device_ctx->data;
if (av_hwframe_ctx_init(frame_context) < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_setup_context failed: failed to initialize hardware frame context "
- "(note: ffmpeg version needs to be > 4.0)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_nvenc_setup_context failed: failed to initialize hardware frame context (note: ffmpeg version needs to be > 4.0)");
av_buffer_unref(&self->device_ctx);
//av_buffer_unref(&frame_context);
return false;
@@ -72,7 +72,7 @@ static bool cuda_register_opengl_texture(gsr_cuda *cuda, CUgraphicsResource *cud
if (res != CUDA_SUCCESS) {
const char *err_str = "unknown";
cuda->cuGetErrorString(res, &err_str);
- fprintf(stderr, "gsr error: cuda_register_opengl_texture: cuGraphicsGLRegisterImage failed, error: %s, texture " "id: %u\n", err_str, texture_id);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "cuda_register_opengl_texture: cuGraphicsGLRegisterImage failed, error: %s, texture id: %u", err_str, texture_id);
return false;
}
@@ -86,7 +86,7 @@ static bool cuda_register_opengl_texture(gsr_cuda *cuda, CUgraphicsResource *cud
static bool gsr_video_encoder_nvenc_setup_textures(gsr_video_encoder_nvenc *self, AVCodecContext *video_codec_context, AVFrame *frame) {
const int res = av_hwframe_get_buffer(video_codec_context->hw_frames_ctx, frame, 0);
if(res < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_setup_textures: av_hwframe_get_buffer failed: %d\n", res);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_nvenc_setup_textures: av_hwframe_get_buffer failed: %d", res);
return false;
}
@@ -99,7 +99,7 @@ static bool gsr_video_encoder_nvenc_setup_textures(gsr_video_encoder_nvenc *self
self->target_texture_size[i] = (vec2i){ video_codec_context->width / div[i], video_codec_context->height / div[i] };
self->target_textures[i] = gl_create_texture(self->params.egl, self->target_texture_size[i].x, self->target_texture_size[i].y, self->params.color_depth == GSR_COLOR_DEPTH_8_BITS ? internal_formats_nv12[i] : internal_formats_p010[i], formats[i], GL_NEAREST);
if(self->target_textures[i] == 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_setup_textures: failed to create opengl texture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_nvenc_setup_textures: failed to create opengl texture");
return false;
}
@@ -117,7 +117,7 @@ static bool gsr_video_encoder_nvenc_start(gsr_video_encoder *encoder, AVCodecCon
gsr_video_encoder_nvenc *self = encoder->priv;
if(!gsr_cuda_load(&self->cuda)) {
- fprintf(stderr, "gsr error: gsr_video_encoder_nvenc_start: failed to load cuda\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_nvenc_start: failed to load cuda");
gsr_video_encoder_nvenc_stop(self, video_codec_context);
return false;
}
diff --git a/src/encoder/video/software.c b/src/encoder/video/software.c
index b473bb9..5ee3ab9 100644
--- a/src/encoder/video/software.c
+++ b/src/encoder/video/software.c
@@ -1,4 +1,5 @@
#include "../../../include/encoder/video/software.h"
+#include "../../../include/log.h"
#include "../../../include/egl.h"
#include "../../../include/utils.h"
@@ -19,13 +20,13 @@ typedef struct {
static bool gsr_video_encoder_software_setup_textures(gsr_video_encoder_software *self, AVCodecContext *video_codec_context, AVFrame *frame) {
int res = av_frame_get_buffer(frame, LINESIZE_ALIGNMENT);
if(res < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_software_setup_textures: av_frame_get_buffer failed: %d\n", res);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_software_setup_textures: av_frame_get_buffer failed: %d", res);
return false;
}
res = av_frame_make_writable(frame);
if(res < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_software_setup_textures: av_frame_make_writable failed: %d\n", res);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_software_setup_textures: av_frame_make_writable failed: %d", res);
return false;
}
@@ -38,7 +39,7 @@ static bool gsr_video_encoder_software_setup_textures(gsr_video_encoder_software
self->texture_sizes[i] = (vec2i){ video_codec_context->width / div[i], video_codec_context->height / div[i] };
self->target_textures[i] = gl_create_texture(self->params.egl, self->texture_sizes[i].x, self->texture_sizes[i].y, self->params.color_depth == GSR_COLOR_DEPTH_8_BITS ? internal_formats_nv12[i] : internal_formats_p010[i], formats[i], GL_NEAREST);
if(self->target_textures[i] == 0) {
- fprintf(stderr, "gsr error: gsr_capture_kms_setup_cuda_textures: failed to create opengl texture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_kms_setup_cuda_textures: failed to create opengl texture");
return false;
}
}
diff --git a/src/encoder/video/vaapi.c b/src/encoder/video/vaapi.c
index 449fb1d..d310125 100644
--- a/src/encoder/video/vaapi.c
+++ b/src/encoder/video/vaapi.c
@@ -1,4 +1,5 @@
#include "../../../include/encoder/video/vaapi.h"
+#include "../../../include/log.h"
#include "../../../include/utils.h"
#include "../../../include/egl.h"
@@ -28,18 +29,18 @@ typedef struct {
static bool gsr_video_encoder_vaapi_setup_context(gsr_video_encoder_vaapi *self, AVCodecContext *video_codec_context) {
char render_path[128];
if(!gsr_card_path_get_render_path(self->params.egl->card_path, render_path)) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_setup_context: failed to get /dev/dri/renderDXXX file from %s\n", self->params.egl->card_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vaapi_setup_context: failed to get /dev/dri/renderDXXX file from %s", self->params.egl->card_path);
return false;
}
if(av_hwdevice_ctx_create(&self->device_ctx, AV_HWDEVICE_TYPE_VAAPI, render_path, NULL, 0) < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_setup_context: failed to create hardware device context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vaapi_setup_context: failed to create hardware device context");
return false;
}
AVBufferRef *frame_context = av_hwframe_ctx_alloc(self->device_ctx);
if(!frame_context) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_setup_context: failed to create hwframe context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vaapi_setup_context: failed to create hwframe context");
av_buffer_unref(&self->device_ctx);
return false;
}
@@ -57,8 +58,7 @@ static bool gsr_video_encoder_vaapi_setup_context(gsr_video_encoder_vaapi *self,
self->va_dpy = vactx->display;
if (av_hwframe_ctx_init(frame_context) < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_setup_context: failed to initialize hardware frame context "
- "(note: ffmpeg version needs to be > 4.0)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vaapi_setup_context: failed to initialize hardware frame context (note: ffmpeg version needs to be > 4.0)");
av_buffer_unref(&self->device_ctx);
//av_buffer_unref(&frame_context);
return false;
@@ -76,7 +76,7 @@ static uint32_t fourcc(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self, AVCodecContext *video_codec_context, AVFrame *frame) {
const int res = av_hwframe_get_buffer(video_codec_context->hw_frames_ctx, frame, 0);
if(res < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_setup_textures: av_hwframe_get_buffer failed: %d\n", res);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vaapi_setup_textures: av_hwframe_get_buffer failed: %d", res);
return false;
}
@@ -84,7 +84,7 @@ static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self
VAStatus va_status = vaExportSurfaceHandle(self->va_dpy, target_surface_id, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, VA_EXPORT_SURFACE_WRITE_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS, &self->prime);
if(va_status != VA_STATUS_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_setup_textures: vaExportSurfaceHandle failed, error: %d\n", va_status);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vaapi_setup_textures: vaExportSurfaceHandle failed, error: %d", va_status);
return false;
}
vaSyncSurface(self->va_dpy, target_surface_id);
@@ -120,7 +120,7 @@ static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self
while(self->params.egl->eglGetError() != EGL_SUCCESS){}
EGLImage image = self->params.egl->eglCreateImage(self->params.egl->egl_display, 0, EGL_LINUX_DMA_BUF_EXT, NULL, img_attr);
if(!image) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_setup_textures: failed to create egl image from drm fd for output drm fd, error: %d\n", self->params.egl->eglGetError());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vaapi_setup_textures: failed to create egl image from drm fd for output drm fd, error: %d", self->params.egl->eglGetError());
return false;
}
@@ -133,7 +133,7 @@ static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self
self->params.egl->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
if(self->params.egl->glGetError() != 0 || self->params.egl->eglGetError() != EGL_SUCCESS) {
// TODO: Get the error properly
- fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_setup_textures: failed to bind egl image to gl texture, error: %d\n", self->params.egl->eglGetError());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vaapi_setup_textures: failed to bind egl image to gl texture, error: %d", self->params.egl->eglGetError());
self->params.egl->eglDestroyImage(self->params.egl->egl_display, image);
self->params.egl->glBindTexture(GL_TEXTURE_2D, 0);
return false;
@@ -145,7 +145,7 @@ static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self
return true;
} else {
- fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_setup_textures: unexpected fourcc %u for output drm fd, expected nv12 or p010\n", self->prime.fourcc);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vaapi_setup_textures: unexpected fourcc %u for output drm fd, expected nv12 or p010", self->prime.fourcc);
return false;
}
}
@@ -165,26 +165,26 @@ static bool supports_hevc_without_padding(const char *card_path) {
char render_path[128];
if(!gsr_card_path_get_render_path(card_path, render_path)) {
- fprintf(stderr, "gsr error: supports_hevc_without_padding: failed to get /dev/dri/renderDXXX file from %s\n", card_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "supports_hevc_without_padding: failed to get /dev/dri/renderDXXX file from %s", card_path);
return false;
}
const int drm_fd = open(render_path, O_RDWR);
if(drm_fd == -1) {
- fprintf(stderr, "gsr error: supports_hevc_without_padding: failed to open device %s\n", render_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "supports_hevc_without_padding: failed to open device %s", render_path);
return false;
}
const VADisplay va_dpy = vaGetDisplayDRM(drm_fd);
if(!va_dpy) {
- fprintf(stderr, "gsr error: supports_hevc_without_padding: failed to get vaapi display for device %s\n", render_path);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "supports_hevc_without_padding: failed to get vaapi display for device %s", render_path);
goto done;
}
vaSetInfoCallback(va_dpy, NULL, NULL);
if(vaInitialize(va_dpy, &va_major, &va_minor) != VA_STATUS_SUCCESS) {
- fprintf(stderr, "gsr error: supports_hevc_without_padding: vaInitialize failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "supports_hevc_without_padding: vaInitialize failed");
goto done;
}
initialized = true;
@@ -193,26 +193,26 @@ static bool supports_hevc_without_padding(const char *card_path) {
if(va_status != VA_STATUS_SUCCESS) {
va_status = vaCreateConfig(va_dpy, VAProfileHEVCMain, VAEntrypointEncSliceLP, NULL, 0, &va_config);
if(va_status != VA_STATUS_SUCCESS) {
- fprintf(stderr, "gsr error: supports_hevc_without_padding: failed to create hevc vaapi config, error: %s (%d)\n", vaErrorStr(va_status), va_status);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "supports_hevc_without_padding: failed to create hevc vaapi config, error: %s (%d)", vaErrorStr(va_status), va_status);
return false;
}
}
va_status = vaQuerySurfaceAttributes(va_dpy, va_config, 0, &num_surface_attr);
if(va_status != VA_STATUS_SUCCESS) {
- fprintf(stderr, "gsr error: supports_hevc_without_padding: failed to query vaapi surface attributes size, error: %s (%d)\n", vaErrorStr(va_status), va_status);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "supports_hevc_without_padding: failed to query vaapi surface attributes size, error: %s (%d)", vaErrorStr(va_status), va_status);
goto done;
}
surface_attr_list = malloc(num_surface_attr * sizeof(VASurfaceAttrib));
if(!surface_attr_list) {
- fprintf(stderr, "gsr error: supports_hevc_without_padding: failed to allocate memory for %u vaapi surface attributes, error: %s (%d)\n", num_surface_attr, vaErrorStr(va_status), va_status);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "supports_hevc_without_padding: failed to allocate memory for %u vaapi surface attributes, error: %s (%d)", num_surface_attr, vaErrorStr(va_status), va_status);
goto done;
}
va_status = vaQuerySurfaceAttributes(va_dpy, va_config, surface_attr_list, &num_surface_attr);
if(va_status != VA_STATUS_SUCCESS) {
- fprintf(stderr, "gsr error: supports_hevc_without_padding: failed to query vaapi surface attributes data, error: %s (%d)\n", vaErrorStr(va_status), va_status);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "supports_hevc_without_padding: failed to query vaapi surface attributes data, error: %s (%d)", vaErrorStr(va_status), va_status);
goto done;
}
@@ -264,7 +264,7 @@ static bool gsr_video_encoder_vaapi_start(gsr_video_encoder *encoder, AVCodecCon
}
if(FFALIGN(video_codec_context->width, 2) != FFALIGN(frame->width, 2) || FFALIGN(video_codec_context->height, 2) != FFALIGN(frame->height, 2)) {
- fprintf(stderr, "gsr warning: gsr_video_encoder_vaapi_start: black bars have been added to the video because of a bug in AMD drivers/hardware. Record with h264/hevc codec instead (-k h264) to get around this issue\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_video_encoder_vaapi_start: black bars have been added to the video because of a bug in AMD drivers/hardware. Record with h264/hevc codec instead (-k h264) to get around this issue");
}
if(video_codec_context->width < 128)
diff --git a/src/encoder/video/vulkan.c b/src/encoder/video/vulkan.c
index 3b7c567..f2872d0 100644
--- a/src/encoder/video/vulkan.c
+++ b/src/encoder/video/vulkan.c
@@ -1,4 +1,5 @@
#include "../../../include/encoder/video/vulkan.h"
+#include "../../../include/log.h"
#include "../../../include/utils.h"
#include "../../../include/egl.h"
@@ -73,12 +74,12 @@ typedef struct {
static bool gsr_vk_funcs_load(gsr_vk_funcs *vk, PFN_vkGetInstanceProcAddr get_inst_proc, VkInstance inst, VkDevice dev) {
PFN_vkGetDeviceProcAddr get_dev_proc = (PFN_vkGetDeviceProcAddr)get_inst_proc(inst, "vkGetDeviceProcAddr");
if(!get_dev_proc) {
- fprintf(stderr, "gsr error: gsr_vk_funcs_load: failed to load vkGetDeviceProcAddr\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_vk_funcs_load: failed to load vkGetDeviceProcAddr");
return false;
}
-#define LOAD_INST(name) vk->name = (PFN_##name)get_inst_proc(inst, #name); if(!vk->name) { fprintf(stderr, "gsr error: gsr_vk_funcs_load: failed to load " #name "\n"); return false; }
-#define LOAD_DEV(name) vk->name = (PFN_##name)get_dev_proc(dev, #name); if(!vk->name) { fprintf(stderr, "gsr error: gsr_vk_funcs_load: failed to load " #name "\n"); return false; }
+#define LOAD_INST(name) vk->name = (PFN_##name)get_inst_proc(inst, #name); if(!vk->name) { gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_vk_funcs_load: failed to load " #name); return false; }
+#define LOAD_DEV(name) vk->name = (PFN_##name)get_dev_proc(dev, #name); if(!vk->name) { gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_vk_funcs_load: failed to load " #name); return false; }
LOAD_INST(vkGetPhysicalDeviceMemoryProperties)
LOAD_DEV(vkCreateImage)
@@ -118,13 +119,13 @@ static bool gsr_video_encoder_vulkan_setup_context(gsr_video_encoder_vulkan *sel
snprintf(device_index_str, sizeof(device_index_str), "%d", self->params.egl->vulkan_device_index);
if(av_hwdevice_ctx_create(&self->device_ctx, AV_HWDEVICE_TYPE_VULKAN, device_index_str, options, 0) < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_context: failed to create hardware device context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_context: failed to create hardware device context");
return false;
}
AVBufferRef *frame_context = av_hwframe_ctx_alloc(self->device_ctx);
if(!frame_context) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_context: failed to create hwframe context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_context: failed to create hwframe context");
av_buffer_unref(&self->device_ctx);
return false;
}
@@ -137,8 +138,7 @@ static bool gsr_video_encoder_vulkan_setup_context(gsr_video_encoder_vulkan *sel
hw_frame_context->device_ctx = (AVHWDeviceContext*)self->device_ctx->data;
if (av_hwframe_ctx_init(frame_context) < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_context: failed to initialize hardware frame context "
- "(note: ffmpeg version needs to be > 4.0)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_context: failed to initialize hardware frame context (note: ffmpeg version needs to be > 4.0)");
av_buffer_unref(&self->device_ctx);
return false;
}
@@ -230,7 +230,7 @@ static bool create_exportable_image(
};
if(vk->vkCreateImage(dev, &img_info, NULL, out_image) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: create_exportable_image: vkCreateImage failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "create_exportable_image: vkCreateImage failed");
return false;
}
@@ -240,7 +240,7 @@ static bool create_exportable_image(
uint32_t mem_type_idx = get_memory_type_idx(phys_dev, &mem_reqs,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vk->vkGetPhysicalDeviceMemoryProperties);
if(mem_type_idx == UINT32_MAX) {
- fprintf(stderr, "gsr error: create_exportable_image: no suitable memory type\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "create_exportable_image: no suitable memory type");
vk->vkDestroyImage(dev, *out_image, NULL);
*out_image = VK_NULL_HANDLE;
return false;
@@ -263,14 +263,14 @@ static bool create_exportable_image(
};
if(vk->vkAllocateMemory(dev, &mem_alloc_info, NULL, out_memory) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: create_exportable_image: vkAllocateMemory failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "create_exportable_image: vkAllocateMemory failed");
vk->vkDestroyImage(dev, *out_image, NULL);
*out_image = VK_NULL_HANDLE;
return false;
}
if(vk->vkBindImageMemory(dev, *out_image, *out_memory, 0) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: create_exportable_image: vkBindImageMemory failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "create_exportable_image: vkBindImageMemory failed");
vk->vkFreeMemory(dev, *out_memory, NULL);
vk->vkDestroyImage(dev, *out_image, NULL);
*out_memory = VK_NULL_HANDLE;
@@ -285,7 +285,7 @@ static bool create_exportable_image(
static bool gsr_video_encoder_vulkan_setup_textures(gsr_video_encoder_vulkan *self, AVCodecContext *video_codec_context, AVFrame *frame) {
const int res = av_hwframe_get_buffer(video_codec_context->hw_frames_ctx, frame, 0);
if(res < 0) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_textures: av_hwframe_get_buffer failed: %d\n", res);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_textures: av_hwframe_get_buffer failed: %d", res);
return false;
}
@@ -293,7 +293,7 @@ static bool gsr_video_encoder_vulkan_setup_textures(gsr_video_encoder_vulkan *se
AVVulkanDeviceContext *vv = video_codec_context_get_vulkan_data(video_codec_context);
if(!vv) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_textures: failed to get vulkan device context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_textures: failed to get vulkan device context");
return false;
}
@@ -327,7 +327,7 @@ static bool gsr_video_encoder_vulkan_setup_textures(gsr_video_encoder_vulkan *se
};
int fd = -1;
if(self->vk.vkGetMemoryFdKHR(vv->act_dev, &fd_info, &fd) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_textures: vkGetMemoryFdKHR failed for plane %d\n", i);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_textures: vkGetMemoryFdKHR failed for plane %d", i);
return false;
}
@@ -338,7 +338,7 @@ static bool gsr_video_encoder_vulkan_setup_textures(gsr_video_encoder_vulkan *se
self->params.egl->glImportMemoryFdEXT(self->gl_memory_objects[i], self->export_memory_size[i],
GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd);
if(!self->params.egl->glIsMemoryObjectEXT(self->gl_memory_objects[i])) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_textures: failed to import memory FD for plane %d\n", i);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_textures: failed to import memory FD for plane %d", i);
return false;
}
}
@@ -370,7 +370,7 @@ static bool gsr_video_encoder_vulkan_setup_textures(gsr_video_encoder_vulkan *se
.queueFamilyIndex = (uint32_t)get_graphics_queue_family(vv),
};
if(self->vk.vkCreateCommandPool(vv->act_dev, &pool_info, NULL, &self->command_pool) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_textures: vkCreateCommandPool failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_textures: vkCreateCommandPool failed");
return false;
}
@@ -381,7 +381,7 @@ static bool gsr_video_encoder_vulkan_setup_textures(gsr_video_encoder_vulkan *se
.commandBufferCount = 1,
};
if(self->vk.vkAllocateCommandBuffers(vv->act_dev, &cb_alloc_info, &self->command_buffer) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_textures: vkAllocateCommandBuffers failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_textures: vkAllocateCommandBuffers failed");
return false;
}
@@ -389,7 +389,7 @@ static bool gsr_video_encoder_vulkan_setup_textures(gsr_video_encoder_vulkan *se
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
};
if(self->vk.vkCreateFence(vv->act_dev, &fence_info, NULL, &self->fence) != VK_SUCCESS) {
- fprintf(stderr, "gsr error: gsr_video_encoder_vulkan_setup_textures: vkCreateFence failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_video_encoder_vulkan_setup_textures: vkCreateFence failed");
return false;
}
@@ -484,7 +484,7 @@ static bool gsr_video_encoder_vulkan_start(gsr_video_encoder *encoder, AVCodecCo
}
if(FFALIGN(video_codec_context->width, 2) != FFALIGN(frame->width, 2) || FFALIGN(video_codec_context->height, 2) != FFALIGN(frame->height, 2)) {
- fprintf(stderr, "gsr warning: gsr_video_encoder_vulkan_start: black bars have been added to the video because of a bug in AMD drivers/hardware. Record with h264/hevc vulkan codec instead (-k h264_vulkan) to get around this issue\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_video_encoder_vulkan_start: black bars have been added to the video because of a bug in AMD drivers/hardware. Record with h264/hevc vulkan codec instead (-k h264_vulkan) to get around this issue");
}
if(video_codec_context->width < 128)
diff --git a/src/image_writer.c b/src/image_writer.c
index adc88a7..5f3fe9e 100644
--- a/src/image_writer.c
+++ b/src/image_writer.c
@@ -1,4 +1,5 @@
#include "../include/image_writer.h"
+#include "../include/log.h"
#include "../include/egl.h"
#include "../include/utils.h"
@@ -83,7 +84,7 @@ bool gsr_image_writer_init_opengl(gsr_image_writer *self, gsr_egl *egl, int widt
self->height = height;
self->texture = gl_create_texture(self->egl, self->width, self->height, GL_RGBA8, GL_RGBA, GL_NEAREST); /* TODO: use GL_RGB16 instead of GL_RGB8 for hdr/10-bit */
if(self->texture == 0) {
- fprintf(stderr, "gsr error: gsr_image_writer_init: failed to create texture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_image_writer_init: failed to create texture");
return false;
}
@@ -128,7 +129,7 @@ static bool gsr_image_writer_write_memory_to_file(gsr_image_writer *self, const
}
if(!success)
- fprintf(stderr, "gsr error: gsr_image_writer_write_to_file: failed to write image data to output file %s\n", filepath);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_image_writer_write_to_file: failed to write image data to output file %s", filepath);
return success;
}
@@ -136,7 +137,7 @@ static bool gsr_image_writer_write_memory_to_file(gsr_image_writer *self, const
static bool gsr_image_writer_write_opengl_texture_to_file(gsr_image_writer *self, const char *filepath, gsr_image_format image_format, int quality) {
uint8_t *frame_data = malloc(self->width * self->height * 4);
if(!frame_data) {
- fprintf(stderr, "gsr error: gsr_image_writer_write_to_file: failed to allocate memory for image frame\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_image_writer_write_to_file: failed to allocate memory for image frame");
return false;
}
diff --git a/src/kde_night_light.c b/src/kde_night_light.c
index d5c9578..587e0c8 100644
--- a/src/kde_night_light.c
+++ b/src/kde_night_light.c
@@ -1,4 +1,5 @@
#include "../include/kde_night_light.h"
+#include "../include/log.h"
#ifdef GSR_DBUS
@@ -346,7 +347,7 @@ bool gsr_kde_night_light_get_inverse_matrix(gsr_kde_night_light *self, gsr_night
#include <stddef.h>
gsr_kde_night_light* gsr_kde_night_light_create(void) {
- fprintf(stderr, "gsr warning: kde night light handling disabled because gsr was compiled without pipewire (which also disables dbus)\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "kde night light handling disabled because gsr was compiled without pipewire (which also disables dbus)");
return NULL;
}
diff --git a/src/library_loader.c b/src/library_loader.c
index 0aeee9b..37a1767 100644
--- a/src/library_loader.c
+++ b/src/library_loader.c
@@ -1,4 +1,5 @@
#include "../include/library_loader.h"
+#include "../include/log.h"
#include <dlfcn.h>
#include <stdbool.h>
@@ -10,7 +11,7 @@ void* dlsym_print_fail(void *handle, const char *name, bool required) {
char *err_str = dlerror();
if(!sym)
- fprintf(stderr, "%s: dlsym(handle, \"%s\") failed, error: %s\n", required ? "error" : "warning", name, err_str ? err_str : "(null)");
+ gsr_log(required ? GSR_LOG_LEVEL_ERROR : GSR_LOG_LEVEL_WARNING, "dlsym(handle, \"%s\") failed, error: %s", name, err_str ? err_str : "(null)");
return sym;
}
diff --git a/src/log.c b/src/log.c
new file mode 100644
index 0000000..b3ebc49
--- /dev/null
+++ b/src/log.c
@@ -0,0 +1,47 @@
+#include "../include/log.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#define GSR_LOG_MESSAGE_MAX_SIZE 4096
+
+static const char* log_level_to_string(gsr_log_level level) {
+ switch(level) {
+ case GSR_LOG_LEVEL_DEBUG: return "debug";
+ case GSR_LOG_LEVEL_INFO: return "info";
+ case GSR_LOG_LEVEL_WARNING: return "warning";
+ case GSR_LOG_LEVEL_ERROR: return "error";
+ }
+ return "unknown";
+}
+
+static void gsr_log_default_handler(gsr_log_level level, const char *message, void *userdata) {
+ (void)userdata;
+ fprintf(stderr, "gsr %s: %s\n", log_level_to_string(level), message);
+}
+
+static gsr_log_level log_level = GSR_LOG_LEVEL_INFO;
+static gsr_log_handler log_handler = gsr_log_default_handler;
+static void *log_handler_userdata = NULL;
+
+void gsr_log(gsr_log_level level, const char *fmt, ...) {
+ if(level < log_level)
+ return;
+
+ char message[GSR_LOG_MESSAGE_MAX_SIZE];
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(message, sizeof(message), fmt, args);
+ va_end(args);
+
+ log_handler(level, message, log_handler_userdata);
+}
+
+void gsr_log_set_level(gsr_log_level level) {
+ log_level = level;
+}
+
+void gsr_log_set_handler(gsr_log_handler handler, void *userdata) {
+ log_handler = handler ? handler : gsr_log_default_handler;
+ log_handler_userdata = userdata;
+}
diff --git a/src/main.cpp b/src/main.cpp
index 06996c3..df609bb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -31,6 +31,7 @@ extern "C" {
#include "../kms/client/kms_client.h"
}
+#include "../include/log.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -196,7 +197,7 @@ static AVSampleFormat audio_codec_get_sample_format(AVCodecContext *audio_codec_
supports_s16 = false;
if(!supports_s16 && !supports_flt) {
- fprintf(stderr, "gsr warning: opus audio codec is chosen but your ffmpeg version does not support s16/flt sample format and performance might be slightly worse.\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "opus audio codec is chosen but your ffmpeg version does not support s16/flt sample format and performance might be slightly worse.");
fprintf(stderr, " You can either rebuild ffmpeg with libopus instead of the built-in opus, use the flatpak version of gpu screen recorder or record with aac audio codec instead (-ac aac).\n");
fprintf(stderr, " Falling back to fltp audio sample format instead.\n");
}
@@ -250,7 +251,7 @@ static AVCodecContext* create_audio_codec_context(int fps, gsr_audio_codec audio
(void)fps;
const AVCodec *codec = avcodec_find_encoder(audio_codec_get_id(audio_codec));
if (!codec) {
- fprintf(stderr, "gsr error: Could not find %s audio encoder\n", audio_codec_get_name(audio_codec));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Could not find %s audio encoder", audio_codec_get_name(audio_codec));
_exit(1);
}
@@ -578,7 +579,7 @@ static void open_video_software(AVCodecContext *codec_context, const args_parser
int ret = avcodec_open2(codec_context, codec_context->codec, &options);
if (ret < 0) {
- fprintf(stderr, "gsr error: Could not open video codec: %s\n", av_error_to_string(ret));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Could not open video codec: %s", av_error_to_string(ret));
_exit(1);
}
}
@@ -728,7 +729,7 @@ static void open_video_hardware(AVCodecContext *codec_context, bool low_power, c
int ret = avcodec_open2(codec_context, codec_context->codec, &options);
if (ret < 0) {
- fprintf(stderr, "gsr error: Could not open video codec: %s\n", av_error_to_string(ret));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Could not open video codec: %s", av_error_to_string(ret));
_exit(1);
}
}
@@ -807,7 +808,7 @@ static std::string get_time_only_str() {
static AVStream* create_stream(AVFormatContext *av_format_context, AVCodecContext *codec_context) {
AVStream *stream = avformat_new_stream(av_format_context, nullptr);
if (!stream) {
- fprintf(stderr, "gsr error: Could not allocate stream\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Could not allocate stream");
_exit(1);
}
stream->id = av_format_context->nb_streams - 1;
@@ -821,7 +822,7 @@ static void run_recording_saved_script_async(const char *script_file, const char
char script_file_full[PATH_MAX];
script_file_full[0] = '\0';
if(!realpath(script_file, script_file_full)) {
- fprintf(stderr, "gsr error: script file not found: %s\n", script_file);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "script file not found: %s", script_file);
return;
}
@@ -966,7 +967,7 @@ static void set_format_context_options(AVFormatContext *av_format_context) {
if(strcmp(file_extension, "mp4") != 0 && strcmp(file_extension, "mov") != 0)
return;
- fprintf(stderr, "gsr warning: your FFmpeg version is known to be buggy (it doesn't have working hybrid_fragmented movflags). If you experience stutter in the mp4 file then update your FFmpeg to at least version 8 or record to a mkv file\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "your FFmpeg version is known to be buggy (it doesn't have working hybrid_fragmented movflags). If you experience stutter in the mp4 file then update your FFmpeg to at least version 8 or record to a mkv file");
}
}
@@ -1036,7 +1037,7 @@ static RecordingStartResult start_recording_create_streams(const char *filename,
const int open_ret = avio_open(&av_format_context->pb, filename, AVIO_FLAG_WRITE);
if(open_ret < 0) {
- fprintf(stderr, "gsr error: start_recording_create_streams: could not open '%s': %s\n", filename, av_error_to_string(open_ret));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "start_recording_create_streams: could not open '%s': %s", filename, av_error_to_string(open_ret));
return result;
}
@@ -1049,7 +1050,7 @@ static RecordingStartResult start_recording_create_streams(const char *filename,
const int header_write_ret = avformat_write_header(av_format_context, &options);
av_dict_free(&options);
if(header_write_ret < 0) {
- fprintf(stderr, "gsr error: start_recording_create_streams: error occurred when writing header to output file: %s\n", av_error_to_string(header_write_ret));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "start_recording_create_streams: error occurred when writing header to output file: %s", av_error_to_string(header_write_ret));
avio_close(av_format_context->pb);
avformat_free_context(av_format_context);
return result;
@@ -1085,11 +1086,11 @@ static std::string create_new_recording_filepath_from_timestamp(std::string dire
if(date_folders) {
std::string output_folder = directory + '/' + get_date_only_str();
if(create_directory_recursive(&output_folder[0]) != 0)
- fprintf(stderr, "gsr error: failed to create directory: %s\n", output_folder.c_str());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create directory: %s", output_folder.c_str());
output_filepath = output_folder + "/" + filename_prefix + "_" + get_time_only_str() + "." + file_extension;
} else {
if(create_directory_recursive(&directory[0]) != 0)
- fprintf(stderr, "gsr error: failed to create directory: %s\n", directory.c_str());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create directory: %s", directory.c_str());
output_filepath = directory + "/" + filename_prefix + "_" + get_date_str() + "." + file_extension;
}
return output_filepath;
@@ -1117,14 +1118,14 @@ static bool save_replay_async(AVCodecContext *video_codec_context, int video_str
pthread_mutex_unlock(&encoder->replay_mutex);
if(!cloned_replay_buffer) {
// TODO: Return this error to mark the replay as failed
- fprintf(stderr, "gsr error: failed to save replay: failed to clone replay buffer\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to save replay: failed to clone replay buffer");
return false;
}
const gsr_replay_buffer_iterator search_start_iterator = current_save_replay_seconds == save_replay_seconds_full ? gsr_replay_buffer_iterator{0, 0} : gsr_replay_buffer_find_packet_index_by_time_passed(cloned_replay_buffer, current_save_replay_seconds);
const gsr_replay_buffer_iterator video_start_iterator = gsr_replay_buffer_find_keyframe(cloned_replay_buffer, search_start_iterator, video_stream_index, false);
if(video_start_iterator.packet_index == (size_t)-1) {
- fprintf(stderr, "gsr error: failed to save replay: failed to find a video keyframe. perhaps replay was saved too fast, before anything has been recorded\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to save replay: failed to find a video keyframe. perhaps replay was saved too fast, before anything has been recorded");
pthread_mutex_lock(&encoder->replay_mutex);
gsr_replay_buffer_destroy(cloned_replay_buffer);
pthread_mutex_unlock(&encoder->replay_mutex);
@@ -1166,13 +1167,13 @@ static bool save_replay_async(AVCodecContext *video_codec_context, int video_str
}
if(!replay_packet) {
- fprintf(stderr, "gsr error: save_replay_async: no replay packet\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "save_replay_async: no replay packet");
success = false;
break;
}
if(!replay_packet->data && !replay_packet_data) {
- fprintf(stderr, "gsr error: save_replay_async: no replay packet data\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "save_replay_async: no replay packet data");
success = false;
break;
}
@@ -1198,7 +1199,7 @@ static bool save_replay_async(AVCodecContext *video_codec_context, int video_str
} else {
RecordingStartAudio *recording_start_audio = get_recording_start_item_by_stream_index(recording_start_result, av_packet.stream_index);
if(!recording_start_audio) {
- fprintf(stderr, "gsr error: save_replay_async: failed to find audio stream by index: %d\n", av_packet.stream_index);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "save_replay_async: failed to find audio stream by index: %d", av_packet.stream_index);
free(replay_packet_data);
continue;
}
@@ -1218,7 +1219,7 @@ static bool save_replay_async(AVCodecContext *video_codec_context, int video_str
const int ret = av_write_frame(recording_start_result.av_format_context, &av_packet);
if(ret < 0)
- fprintf(stderr, "gsr error: Failed to write frame index %d to muxer, reason: %s (%d)\n", av_packet.stream_index, av_error_to_string(ret), ret);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Failed to write frame index %d to muxer, reason: %s (%d)", av_packet.stream_index, av_error_to_string(ret), ret);
free(replay_packet_data);
@@ -1388,7 +1389,7 @@ static int init_filter_graph(AVCodecContext* audio_codec_context, AVFilterGraph*
snprintf(args, sizeof(args), "inputs=%d:normalize=%s", (int)num_sources, normalize ? "true" : "false");
#else
snprintf(args, sizeof(args), "inputs=%d", (int)num_sources);
- fprintf(stderr, "gsr warning: your ffmpeg version doesn't support disabling normalizing of mixed audio. Volume might be lower than expected\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "your ffmpeg version doesn't support disabling normalizing of mixed audio. Volume might be lower than expected");
#endif
err = avfilter_graph_create_filter(&mix_ctx, mix_filter, "amix", args, NULL, filter_graph);
@@ -1807,7 +1808,7 @@ static WindowingSetup setup_windowing(bool setup_egl) {
setup.dpy = XOpenDisplay(nullptr);
if (!setup.dpy) {
wayland = true;
- fprintf(stderr, "gsr warning: failed to connect to the X server. Assuming wayland is running without Xwayland\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "failed to connect to the X server. Assuming wayland is running without Xwayland");
}
XSetErrorHandler(x11_error_handler);
@@ -1820,13 +1821,13 @@ static WindowingSetup setup_windowing(bool setup_egl) {
// Disable prime-run and similar options as it doesn't work, the monitor to capture has to be run on the same device.
// This is fine on wayland since nvidia uses drm interface there and the monitor query checks the monitors connected
// to the drm device.
- fprintf(stderr, "gsr warning: use of prime-run on X11 is not supported. Disabling prime-run\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "use of prime-run on X11 is not supported. Disabling prime-run");
disable_prime_run();
}
setup.window = gsr_window_create(setup.dpy, wayland);
if(!setup.window) {
- fprintf(stderr, "gsr error: failed to create window\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create window");
_exit(1);
}
@@ -1834,7 +1835,7 @@ static WindowingSetup setup_windowing(bool setup_egl) {
if(setup_egl) {
if(!gsr_egl_load(&setup.egl, setup.window, false, false)) {
- fprintf(stderr, "gsr error: failed to load opengl\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to load opengl");
_exit(22);
}
@@ -1842,7 +1843,7 @@ static WindowingSetup setup_windowing(bool setup_egl) {
if(monitor_capture_use_drm(setup.window, setup.egl.gpu_info.vendor)) {
// TODO: Allow specifying another card, and in other places
if(!gsr_get_valid_card_path(&setup.egl, setup.egl.card_path, true)) {
- fprintf(stderr, "gsr error: no /dev/dri/cardX device found. Make sure that you have at least one monitor connected\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "no /dev/dri/cardX device found. Make sure that you have at least one monitor connected");
setup.list_monitors = false;
}
} else {
@@ -1989,13 +1990,13 @@ static std::string validate_monitor_get_valid(const gsr_egl *egl, const char* wi
capture_source_result = data.output_name;
free(data.output_name);
} else {
- fprintf(stderr, "gsr error: no usable output found\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "no usable output found");
_exit(51);
}
} else if(capture_use_drm || (strcmp(capture_source_result.c_str(), "screen-direct") != 0 && strcmp(capture_source_result.c_str(), "screen-direct-force") != 0)) {
gsr_monitor gmon;
if(!get_monitor_by_name(egl, connection_type, capture_source_result.c_str(), &gmon)) {
- fprintf(stderr, "gsr error: display \"%s\" not found, expected one of:\n", capture_source_result.c_str());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "display \"%s\" not found, expected one of:", capture_source_result.c_str());
fprintf(stderr, " \"screen\"\n");
if(!capture_use_drm)
fprintf(stderr, " \"screen-direct\"\n");
@@ -2088,7 +2089,7 @@ static gsr_capture* create_monitor_capture(const args_parser &arg_parser, gsr_eg
const bool direct_capture = strcmp(capture_source.name.c_str(), "screen-direct") == 0 || strcmp(capture_source.name.c_str(), "screen-direct-force") == 0;
if(direct_capture) {
capture_source_real = "screen";
- fprintf(stderr, "gsr warning: %s capture option is not recommended unless you use G-SYNC as Nvidia has driver issues that can cause your system or games to freeze/crash.\n", capture_source.name.c_str());
+ gsr_log(GSR_LOG_LEVEL_WARNING, "%s capture option is not recommended unless you use G-SYNC as Nvidia has driver issues that can cause your system or games to freeze/crash.", capture_source.name.c_str());
}
gsr_capture_nvfbc_params nvfbc_params;
@@ -2119,7 +2120,7 @@ static std::string region_get_data(gsr_egl *egl, vec2i *region_size, vec2i *regi
if(window.empty()) {
const bool is_x11 = gsr_window_get_display_server(egl->window) == GSR_DISPLAY_SERVER_X11;
const gsr_connection_type connection_type = is_x11 ? GSR_CONNECTION_X11 : GSR_CONNECTION_WAYLAND;
- fprintf(stderr, "gsr error: the region %dx%d+%d+%d doesn't match any monitor. Available monitors and their regions:\n", region_size->x, region_size->y, region_position->x, region_position->y);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "the region %dx%d+%d+%d doesn't match any monitor. Available monitors and their regions:", region_size->x, region_size->y, region_position->x, region_position->y);
MonitorOutputCallbackUserdata userdata;
userdata.window = egl->window;
@@ -2151,12 +2152,12 @@ static gsr_capture* create_capture_impl(const args_parser &arg_parser, gsr_egl *
gsr_capture *capture = nullptr;
if(capture_source.type == GSR_CAPTURE_SOURCE_TYPE_FOCUSED_WINDOW) {
if(wayland) {
- fprintf(stderr, "gsr error: GPU Screen Recorder window capture only works in a pure X11 session. Xwayland is not supported. You can record a monitor instead on wayland\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "GPU Screen Recorder window capture only works in a pure X11 session. Xwayland is not supported. You can record a monitor instead on wayland");
_exit(2);
}
if(arg_parser.output_resolution.x <= 0 || arg_parser.output_resolution.y <= 0) {
- fprintf(stderr, "gsr error: invalid value for option -s '%dx%d' when using -w focused option. expected width and height to be greater than 0\n", arg_parser.output_resolution.x, arg_parser.output_resolution.y);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid value for option -s '%dx%d' when using -w focused option. expected width and height to be greater than 0", arg_parser.output_resolution.x, arg_parser.output_resolution.y);
args_parser_print_usage();
_exit(1);
}
@@ -2166,7 +2167,7 @@ static gsr_capture* create_capture_impl(const args_parser &arg_parser, gsr_egl *
#ifdef GSR_PORTAL
// Desktop portal capture on x11 doesn't seem to be hardware accelerated
if(!wayland) {
- fprintf(stderr, "gsr error: desktop portal capture is not supported on X11\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "desktop portal capture is not supported on X11");
_exit(1);
}
@@ -2181,7 +2182,7 @@ static gsr_capture* create_capture_impl(const args_parser &arg_parser, gsr_egl *
if(!capture)
_exit(1);
#else
- fprintf(stderr, "gsr error: option '-w portal' used but GPU Screen Recorder was compiled without desktop portal support. Please recompile GPU Screen recorder with the -Dportal=true option\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "option '-w portal' used but GPU Screen Recorder was compiled without desktop portal support. Please recompile GPU Screen recorder with the -Dportal=true option");
_exit(2);
#endif
} else if(capture_source.type == GSR_CAPTURE_SOURCE_TYPE_REGION) {
@@ -2209,7 +2210,7 @@ static gsr_capture* create_capture_impl(const args_parser &arg_parser, gsr_egl *
_exit(1);
} else {
if(wayland) {
- fprintf(stderr, "gsr error: GPU Screen Recorder window capture only works in a pure X11 session. Xwayland is not supported. You can record a monitor instead on wayland or use -w portal option which supports window capture if your wayland compositor supports window capture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "GPU Screen Recorder window capture only works in a pure X11 session. Xwayland is not supported. You can record a monitor instead on wayland or use -w portal option which supports window capture if your wayland compositor supports window capture");
_exit(2);
}
}
@@ -2280,7 +2281,7 @@ static std::vector<VideoSource> create_video_sources(const args_parser &arg_pars
for(VideoSource &video_source : video_sources) {
int capture_result = gsr_capture_start(video_source.capture, &video_source.metadata);
if(capture_result != 0) {
- fprintf(stderr, "gsr error: gsr_capture_start failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_capture_start failed");
_exit(capture_result);
}
}
@@ -2411,7 +2412,7 @@ static void capture_image_to_file(args_parser &arg_parser, gsr_egl *egl, gsr_win
gsr_image_writer image_writer;
if(!gsr_image_writer_init_opengl(&image_writer, egl, video_size.x, video_size.y)) {
- fprintf(stderr, "gsr error: capture_image_to_file: gsr_image_write_gl_init failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "capture_image_to_file: gsr_image_write_gl_init failed");
_exit(1);
}
@@ -2428,7 +2429,7 @@ static void capture_image_to_file(args_parser &arg_parser, gsr_egl *egl, gsr_win
gsr_color_conversion color_conversion;
if(gsr_color_conversion_init(&color_conversion, &color_conversion_params) != 0) {
- fprintf(stderr, "gsr error: capture_image_to_file: failed to create color conversion\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "capture_image_to_file: failed to create color conversion");
_exit(1);
}
@@ -2456,7 +2457,7 @@ static void capture_image_to_file(args_parser &arg_parser, gsr_egl *egl, gsr_win
if(kms_client_initialized) {
if(gsr_kms_client_get_kms(&kms_client, &kms_response) != 0)
- fprintf(stderr, "gsr error: failed to get kms, error: %d (%s)\n", kms_response.result, kms_response.err_msg);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to get kms, error: %d (%s)", kms_response.result, kms_response.err_msg);
}
should_stop_error = false;
@@ -2507,7 +2508,7 @@ static void capture_image_to_file(args_parser &arg_parser, gsr_egl *egl, gsr_win
if(!should_stop_error) {
if(!gsr_image_writer_write_to_file(&image_writer, arg_parser.filename, image_format, image_quality)) {
- fprintf(stderr, "gsr error: capture_image_to_file: failed to write opengl texture to image output file %s\n", arg_parser.filename);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "capture_image_to_file: failed to write opengl texture to image output file %s", arg_parser.filename);
_exit(1);
}
@@ -2548,7 +2549,7 @@ static void match_app_audio_input_to_available_apps(const std::vector<AudioInput
}
if(!match) {
- fprintf(stderr, "gsr warning: no audio application with the name \"%s\" was found, expected one of the following:\n", request_audio_input.name.c_str());
+ gsr_log(GSR_LOG_LEVEL_WARNING, "no audio application with the name \"%s\" was found, expected one of the following:", request_audio_input.name.c_str());
for(const std::string &app_name : app_audio_names) {
fprintf(stderr, " * %s\n", app_name.c_str());
}
@@ -2625,14 +2626,14 @@ static std::vector<MergedAudioInputs> parse_audio_inputs(const AudioDevices &aud
if(request_audio_input.name == "default_output") {
if(audio_devices.default_output.empty()) {
- fprintf(stderr, "gsr error: -a default_output was specified but no default audio output is specified in the audio server\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "-a default_output was specified but no default audio output is specified in the audio server");
_exit(2);
}
match = true;
audio_track_description.devices.push_back("Default output");
} else if(request_audio_input.name == "default_input") {
if(audio_devices.default_input.empty()) {
- fprintf(stderr, "gsr error: -a default_input was specified but no default audio input is specified in the audio server\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "-a default_input was specified but no default audio input is specified in the audio server");
_exit(2);
}
match = true;
@@ -2646,7 +2647,7 @@ static std::vector<MergedAudioInputs> parse_audio_inputs(const AudioDevices &aud
}
if(!match) {
- fprintf(stderr, "gsr error: Audio device '%s' is not a valid audio device, expected one of:\n", request_audio_input.name.c_str());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Audio device '%s' is not a valid audio device, expected one of:", request_audio_input.name.c_str());
if(!audio_devices.default_output.empty())
fprintf(stderr, " default_output (Default output)\n");
if(!audio_devices.default_input.empty())
@@ -2783,7 +2784,7 @@ static void parse_capture_source_options(const std::string &capture_source_str,
sub += 2;
size -= 2;
if(!string_to_int(sub, size, &capture_source.pos.x)) {
- fprintf(stderr, "gsr error: invalid capture target value for option x: \"%.*s\", expected a number\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target value for option x: \"%.*s\", expected a number", (int)size, sub);
_exit(1);
}
} else if(string_starts_with(sub, size, "y=")) {
@@ -2791,7 +2792,7 @@ static void parse_capture_source_options(const std::string &capture_source_str,
sub += 2;
size -= 2;
if(!string_to_int(sub, size, &capture_source.pos.y)) {
- fprintf(stderr, "gsr error: invalid capture target value for option y: \"%.*s\", expected a number\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target value for option y: \"%.*s\", expected a number", (int)size, sub);
_exit(1);
}
@@ -2800,7 +2801,7 @@ static void parse_capture_source_options(const std::string &capture_source_str,
sub += 6;
size -= 6;
if(!string_to_int(sub, size, &capture_source.size.x)) {
- fprintf(stderr, "gsr error: invalid capture target value for option width: \"%.*s\", expected a number\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target value for option width: \"%.*s\", expected a number", (int)size, sub);
_exit(1);
}
} else if(string_starts_with(sub, size, "height=")) {
@@ -2808,28 +2809,28 @@ static void parse_capture_source_options(const std::string &capture_source_str,
sub += 7;
size -= 7;
if(!string_to_int(sub, size, &capture_source.size.y)) {
- fprintf(stderr, "gsr error: invalid capture target value for option height: \"%.*s\", expected a number\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target value for option height: \"%.*s\", expected a number", (int)size, sub);
_exit(1);
}
} else if(string_starts_with(sub, size, "halign=")) {
sub += 7;
size -= 7;
if(!string_to_capture_alignment(sub, size, &capture_source.halign)) {
- fprintf(stderr, "gsr error: invalid capture target value for option halign: \"%.*s\", expected a \"start\", \"center\" or \"end\"\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target value for option halign: \"%.*s\", expected a \"start\", \"center\" or \"end\"", (int)size, sub);
_exit(1);
}
} else if(string_starts_with(sub, size, "valign=")) {
sub += 7;
size -= 7;
if(!string_to_capture_alignment(sub, size, &capture_source.valign)) {
- fprintf(stderr, "gsr error: invalid capture target value for option valign: \"%.*s\", expected a \"start\", \"center\" or \"end\"\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target value for option valign: \"%.*s\", expected a \"start\", \"center\" or \"end\"", (int)size, sub);
_exit(1);
}
} else if(string_starts_with(sub, size, "pixfmt=")) {
sub += 7;
size -= 7;
if(!string_to_v4l2_pixfmt(sub, size, &capture_source.v4l2_pixfmt)) {
- fprintf(stderr, "gsr error: invalid v4l2 pixfmt value for option pixfmt: \"%.*s\", expected a \"auto\", \"yuyv\" or \"mjpeg\"\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid v4l2 pixfmt value for option pixfmt: \"%.*s\", expected a \"auto\", \"yuyv\" or \"mjpeg\"", (int)size, sub);
_exit(1);
}
} else if(string_starts_with(sub, size, "hflip=")) {
@@ -2837,7 +2838,7 @@ static void parse_capture_source_options(const std::string &capture_source_str,
size -= 6;
bool hflip = false;
if(!string_to_bool(sub, size, &hflip)) {
- fprintf(stderr, "gsr error: invalid bool value for option hflip: \"%.*s\", expected a \"true\" or \"false\"\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid bool value for option hflip: \"%.*s\", expected a \"true\" or \"false\"", (int)size, sub);
_exit(1);
}
@@ -2848,7 +2849,7 @@ static void parse_capture_source_options(const std::string &capture_source_str,
size -= 6;
bool vflip = false;
if(!string_to_bool(sub, size, &vflip)) {
- fprintf(stderr, "gsr error: invalid bool value for option vflip: \"%.*s\", expected a \"true\" or \"false\"\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid bool value for option vflip: \"%.*s\", expected a \"true\" or \"false\"", (int)size, sub);
_exit(1);
}
@@ -2858,25 +2859,25 @@ static void parse_capture_source_options(const std::string &capture_source_str,
sub += 11;
size -= 11;
if(!string_to_int(sub, size, &capture_source.camera_fps)) {
- fprintf(stderr, "gsr error: invalid capture target value for option camera_fps: \"%.*s\", expected a number\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target value for option camera_fps: \"%.*s\", expected a number", (int)size, sub);
_exit(1);
}
} else if(string_starts_with(sub, size, "camera_width=")) {
sub += 13;
size -= 13;
if(!string_to_int(sub, size, &capture_source.camera_resolution.x)) {
- fprintf(stderr, "gsr error: invalid capture target value for option camera_width: \"%.*s\", expected a number\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target value for option camera_width: \"%.*s\", expected a number", (int)size, sub);
_exit(1);
}
} else if(string_starts_with(sub, size, "camera_height=")) {
sub += 14;
size -= 14;
if(!string_to_int(sub, size, &capture_source.camera_resolution.y)) {
- fprintf(stderr, "gsr error: invalid capture target value for option camera_height: \"%.*s\", expected a number\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target value for option camera_height: \"%.*s\", expected a number", (int)size, sub);
_exit(1);
}
} else {
- fprintf(stderr, "gsr error: invalid capture target option \"%.*s\", expected x, y, width, height, halign, valign, pixfmt, hflip, vflip, camera_fps, camera_width or camera_height\n", (int)size, sub);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid capture target option \"%.*s\", expected x, y, width, height, halign, valign, pixfmt, hflip, vflip, camera_fps, camera_width or camera_height", (int)size, sub);
_exit(1);
}
@@ -2922,7 +2923,7 @@ static std::vector<CaptureSource> parse_capture_source_arg(const char *capture_s
if(capture_source.type == GSR_CAPTURE_SOURCE_TYPE_WINDOW) {
if(!string_to_int(capture_source.name.c_str(), capture_source.name.size(), &capture_source.window_id)) {
- fprintf(stderr, "gsr error: invalid window number %s\n", capture_source.name.c_str());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "invalid window number %s", capture_source.name.c_str());
args_parser_print_usage();
_exit(1);
}
@@ -2998,7 +2999,7 @@ static void validate_merged_audio_inputs_app_audio(const std::vector<MergedAudio
match_app_audio_input_to_available_apps(merged_audio_input.audio_inputs, app_audio_names);
if(num_app_audio > 0 && num_app_inverted_audio > 0) {
- fprintf(stderr, "gsr error: argument -a was provided with both app: and app-inverse:, only one of them can be used for one audio track\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "argument -a was provided with both app: and app-inverse:, only one of them can be used for one audio track");
_exit(2);
}
}
@@ -3010,7 +3011,7 @@ static gsr_audio_codec select_audio_codec_with_fallback(gsr_audio_codec audio_co
if(file_extension == "webm") {
//audio_codec_to_use = "opus";
audio_codec = GSR_AUDIO_CODEC_OPUS;
- fprintf(stderr, "gsr warning: .webm files only support opus audio codec, changing audio codec from aac to opus\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, ".webm files only support opus audio codec, changing audio codec from aac to opus");
}
break;
}
@@ -3018,7 +3019,7 @@ static gsr_audio_codec select_audio_codec_with_fallback(gsr_audio_codec audio_co
if(file_extension != "mp4" && file_extension != "mkv" && file_extension != "webm" && file_extension != "ts" && file_extension != "whip") {
//audio_codec_to_use = "aac";
audio_codec = GSR_AUDIO_CODEC_AAC;
- fprintf(stderr, "gsr warning: opus audio codec is only supported by .mp4, .mkv, .webm and .ts files, falling back to aac instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "opus audio codec is only supported by .mp4, .mkv, .webm and .ts files, falling back to aac instead");
}
break;
}
@@ -3027,16 +3028,16 @@ static gsr_audio_codec select_audio_codec_with_fallback(gsr_audio_codec audio_co
if(file_extension == "webm") {
//audio_codec_to_use = "opus";
audio_codec = GSR_AUDIO_CODEC_OPUS;
- fprintf(stderr, "gsr warning: .webm files only support opus audio codec, changing audio codec from flac to opus\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, ".webm files only support opus audio codec, changing audio codec from flac to opus");
} else if(file_extension != "mp4" && file_extension != "mkv") {
//audio_codec_to_use = "aac";
audio_codec = GSR_AUDIO_CODEC_AAC;
- fprintf(stderr, "gsr warning: flac audio codec is only supported by .mp4 and .mkv files, falling back to aac instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "flac audio codec is only supported by .mp4 and .mkv files, falling back to aac instead");
} else if(uses_amix) {
// TODO: remove this? is it true anymore?
//audio_codec_to_use = "opus";
audio_codec = GSR_AUDIO_CODEC_OPUS;
- fprintf(stderr, "gsr warning: flac audio codec is not supported when mixing audio sources, falling back to opus instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "flac audio codec is not supported when mixing audio sources, falling back to opus instead");
}
break;
}
@@ -3197,21 +3198,14 @@ static void print_codec_error(gsr_video_codec video_codec) {
video_codec = GSR_VIDEO_CODEC_H264;
const char *video_codec_name = video_codec_to_string(video_codec);
- fprintf(stderr, "gsr error: your gpu does not support '%s' video codec. If you are sure that your gpu does support '%s' video encoding and you are using an AMD/Intel GPU,\n"
- " then make sure you have installed the GPU specific vaapi packages (intel-media-driver, libva-intel-driver, libva-mesa-driver and linux-firmware).\n"
- " It's also possible that your distro has disabled hardware accelerated video encoding for '%s' video codec.\n"
- " This may be the case on corporate distros such as Manjaro, Fedora or OpenSUSE.\n"
- " You can test this by running 'vainfo | grep VAEntrypointEncSlice' to see if it matches any H264/HEVC/AV1/VP8/VP9 profile.\n"
- " On such distros, you need to manually install mesa from source to enable H264/HEVC hardware acceleration, or use a more user friendly distro. Alternatively record with AV1 if supported by your GPU.\n"
- " You can alternatively use the flatpak version of GPU Screen Recorder (https://flathub.org/apps/com.dec05eba.gpu_screen_recorder) which bypasses system issues with patented H264/HEVC codecs.\n"
- " If your GPU doesn't support hardware accelerated video encoding then you can use '-fallback-cpu-encoding yes' option to encode with your cpu instead.\n", video_codec_name, video_codec_name, video_codec_name);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "your gpu does not support '%s' video codec. If you are sure that your gpu does support '%s' video encoding and you are using an AMD/Intel GPU,\n then make sure you have installed the GPU specific vaapi packages (intel-media-driver, libva-intel-driver, libva-mesa-driver and linux-firmware).\n It's also possible that your distro has disabled hardware accelerated video encoding for '%s' video codec.\n This may be the case on corporate distros such as Manjaro, Fedora or OpenSUSE.\n You can test this by running 'vainfo | grep VAEntrypointEncSlice' to see if it matches any H264/HEVC/AV1/VP8/VP9 profile.\n On such distros, you need to manually install mesa from source to enable H264/HEVC hardware acceleration, or use a more user friendly distro. Alternatively record with AV1 if supported by your GPU.\n You can alternatively use the flatpak version of GPU Screen Recorder (https://flathub.org/apps/com.dec05eba.gpu_screen_recorder) which bypasses system issues with patented H264/HEVC codecs.\n If your GPU doesn't support hardware accelerated video encoding then you can use '-fallback-cpu-encoding yes' option to encode with your cpu instead.", video_codec_name, video_codec_name, video_codec_name);
}
static void force_cpu_encoding(args_parser *args_parser) {
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
args_parser->video_encoder = GSR_VIDEO_ENCODER_HW_CPU;
if(args_parser->bitrate_mode == GSR_BITRATE_MODE_VBR) {
- fprintf(stderr, "gsr warning: bitrate mode has been forcefully set to qp because software encoding option doesn't support vbr option\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "bitrate mode has been forcefully set to qp because software encoding option doesn't support vbr option");
args_parser->bitrate_mode = GSR_BITRATE_MODE_QP;
}
}
@@ -3224,9 +3218,9 @@ static const AVCodec* pick_video_codec(gsr_egl *egl, args_parser *args_parser, b
if(!video_codec_f && use_fallback_codec && args_parser->video_encoder != GSR_VIDEO_ENCODER_HW_CPU) {
switch(args_parser->video_codec) {
case GSR_VIDEO_CODEC_H264: {
- fprintf(stderr, "gsr error: selected video codec h264 is not supported by your hardware\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "selected video codec h264 is not supported by your hardware");
if(args_parser->fallback_cpu_encoding) {
- fprintf(stderr, "gsr warning: gpu encoding is not available on your system, trying cpu encoding instead because -fallback-cpu-encoding is enabled. Install the proper vaapi drivers on your system (if supported) if you experience performance issues\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gpu encoding is not available on your system, trying cpu encoding instead because -fallback-cpu-encoding is enabled. Install the proper vaapi drivers on your system (if supported) if you experience performance issues");
force_cpu_encoding(args_parser);
}
break;
@@ -3234,14 +3228,14 @@ static const AVCodec* pick_video_codec(gsr_egl *egl, args_parser *args_parser, b
case GSR_VIDEO_CODEC_HEVC:
case GSR_VIDEO_CODEC_HEVC_HDR:
case GSR_VIDEO_CODEC_HEVC_10BIT: {
- fprintf(stderr, "gsr warning: selected video codec hevc is not supported by your hardware, trying h264 instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "selected video codec hevc is not supported by your hardware, trying h264 instead");
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
return pick_video_codec(egl, args_parser, true, low_power, supported_video_codecs);
}
case GSR_VIDEO_CODEC_AV1:
case GSR_VIDEO_CODEC_AV1_HDR:
case GSR_VIDEO_CODEC_AV1_10BIT: {
- fprintf(stderr, "gsr warning: selected video codec av1 is not supported by your hardware, trying h264 instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "selected video codec av1 is not supported by your hardware, trying h264 instead");
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
return pick_video_codec(egl, args_parser, true, low_power, supported_video_codecs);
}
@@ -3250,11 +3244,11 @@ static const AVCodec* pick_video_codec(gsr_egl *egl, args_parser *args_parser, b
// TODO: Cant fallback to other codec because webm only supports vp8/vp9
break;
case GSR_VIDEO_CODEC_H264_VULKAN: {
- fprintf(stderr, "gsr warning: selected video codec h264_vulkan is not supported by your hardware, trying h264 instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "selected video codec h264_vulkan is not supported by your hardware, trying h264 instead");
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
// Need to do a query again because this time it's without vulkan
if(!get_supported_video_codecs(egl, args_parser->video_codec, false, true, supported_video_codecs)) {
- fprintf(stderr, "gsr error: failed to query for supported video codecs\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to query for supported video codecs");
print_codec_error(args_parser->video_codec);
_exit(11);
}
@@ -3263,11 +3257,11 @@ static const AVCodec* pick_video_codec(gsr_egl *egl, args_parser *args_parser, b
case GSR_VIDEO_CODEC_HEVC_VULKAN:
case GSR_VIDEO_CODEC_HEVC_HDR_VULKAN:
case GSR_VIDEO_CODEC_HEVC_10BIT_VULKAN: {
- fprintf(stderr, "gsr warning: selected video codec hevc_vulkan is not supported by your hardware, trying hevc instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "selected video codec hevc_vulkan is not supported by your hardware, trying hevc instead");
args_parser->video_codec = GSR_VIDEO_CODEC_HEVC;
// Need to do a query again because this time it's without vulkan
if(!get_supported_video_codecs(egl, args_parser->video_codec, false, true, supported_video_codecs)) {
- fprintf(stderr, "gsr error: failed to query for supported video codecs\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to query for supported video codecs");
print_codec_error(args_parser->video_codec);
_exit(11);
}
@@ -3276,11 +3270,11 @@ static const AVCodec* pick_video_codec(gsr_egl *egl, args_parser *args_parser, b
case GSR_VIDEO_CODEC_AV1_VULKAN:
case GSR_VIDEO_CODEC_AV1_HDR_VULKAN:
case GSR_VIDEO_CODEC_AV1_10BIT_VULKAN: {
- fprintf(stderr, "gsr warning: selected video codec av1_vulkan is not supported by your hardware, trying av1 instead\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "selected video codec av1_vulkan is not supported by your hardware, trying av1 instead");
args_parser->video_codec = GSR_VIDEO_CODEC_AV1;
// Need to do a query again because this time it's without vulkan
if(!get_supported_video_codecs(egl, args_parser->video_codec, false, true, supported_video_codecs)) {
- fprintf(stderr, "gsr error: failed to query for supported video codecs\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to query for supported video codecs");
print_codec_error(args_parser->video_codec);
_exit(11);
}
@@ -3304,16 +3298,14 @@ static const AVCodec* pick_video_codec(gsr_egl *egl, args_parser *args_parser, b
/* Returns -1 if none is available */
static gsr_video_codec select_appropriate_video_codec_automatically(vec2i video_size, const gsr_supported_video_codecs *supported_video_codecs) {
if(supported_video_codecs->h264.supported && codec_supports_resolution(supported_video_codecs->h264.max_resolution, video_size)) {
- fprintf(stderr, "gsr info: using h264 encoder because a codec was not specified\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "using h264 encoder because a codec was not specified");
return GSR_VIDEO_CODEC_H264;
} else if(supported_video_codecs->hevc.supported && codec_supports_resolution(supported_video_codecs->hevc.max_resolution, video_size)) {
- fprintf(stderr, "gsr info: using hevc encoder because a codec was not specified and h264 supported max resolution (%dx%d) is less than the capture resolution (%dx%d)\n",
- supported_video_codecs->h264.max_resolution.x, supported_video_codecs->h264.max_resolution.y,
+ gsr_log(GSR_LOG_LEVEL_INFO, "using hevc encoder because a codec was not specified and h264 supported max resolution (%dx%d) is less than the capture resolution (%dx%d)", supported_video_codecs->h264.max_resolution.x, supported_video_codecs->h264.max_resolution.y,
video_size.x, video_size.y);
return GSR_VIDEO_CODEC_HEVC;
} else if(supported_video_codecs->av1.supported && codec_supports_resolution(supported_video_codecs->av1.max_resolution, video_size)) {
- fprintf(stderr, "gsr info: using av1 encoder because a codec was not specified and hevc supported max resolution (%dx%d) is less than the capture resolution (%dx%d)\n",
- supported_video_codecs->hevc.max_resolution.x, supported_video_codecs->hevc.max_resolution.y,
+ gsr_log(GSR_LOG_LEVEL_INFO, "using av1 encoder because a codec was not specified and hevc supported max resolution (%dx%d) is less than the capture resolution (%dx%d)", supported_video_codecs->hevc.max_resolution.x, supported_video_codecs->hevc.max_resolution.y,
video_size.x, video_size.y);
return GSR_VIDEO_CODEC_AV1;
} else {
@@ -3335,19 +3327,19 @@ static const AVCodec* select_video_codec_with_fallback(vec2i video_size, args_pa
const bool video_codec_auto = args_parser->video_codec == (gsr_video_codec)GSR_VIDEO_CODEC_AUTO;
if(video_codec_auto) {
if(strcmp(file_extension, "webm") == 0) {
- fprintf(stderr, "gsr info: using vp8 encoder because a codec was not specified and the file extension is .webm\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "using vp8 encoder because a codec was not specified and the file extension is .webm");
args_parser->video_codec = GSR_VIDEO_CODEC_VP8;
} else if(args_parser->video_encoder == GSR_VIDEO_ENCODER_HW_CPU) {
- fprintf(stderr, "gsr info: using h264 encoder because a codec was not specified\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "using h264 encoder because a codec was not specified");
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
} else if(args_parser->video_encoder != GSR_VIDEO_ENCODER_HW_CPU) {
args_parser->video_codec = select_appropriate_video_codec_automatically(video_size, &supported_video_codecs_non_vulkan);
if(args_parser->video_codec == (gsr_video_codec)-1) {
if(args_parser->fallback_cpu_encoding) {
- fprintf(stderr, "gsr warning: gpu encoding is not available on your system or your gpu doesn't support recording at the resolution you are trying to record, trying cpu encoding instead because -fallback-cpu-encoding is enabled. Install the proper vaapi drivers on your system (if supported) if you experience performance issues\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gpu encoding is not available on your system or your gpu doesn't support recording at the resolution you are trying to record, trying cpu encoding instead because -fallback-cpu-encoding is enabled. Install the proper vaapi drivers on your system (if supported) if you experience performance issues");
force_cpu_encoding(args_parser);
} else {
- fprintf(stderr, "gsr error: no video encoder was specified and neither h264, hevc nor av1 are supported on your system or you are trying to capture at a resolution higher than your system supports for each codec.\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "no video encoder was specified and neither h264, hevc nor av1 are supported on your system or you are trying to capture at a resolution higher than your system supports for each codec.");
fprintf(stderr, " Ensure that you have installed the proper vaapi driver. If your gpu doesn't support video encoding then you can run gpu-screen-recorder with \"-fallback-cpu-encoding yes\" option to use cpu encoding.\n");
_exit(52);
}
@@ -3358,12 +3350,12 @@ static const AVCodec* select_video_codec_with_fallback(vec2i video_size, args_pa
if(LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(60, 10, 100) && strcmp(file_extension, "flv") == 0) {
if(args_parser->video_codec != GSR_VIDEO_CODEC_H264) {
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
- fprintf(stderr, "gsr warning: hevc/av1 is not compatible with flv in your outdated version of ffmpeg, falling back to h264 instead.\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "hevc/av1 is not compatible with flv in your outdated version of ffmpeg, falling back to h264 instead.");
}
} else if(strcmp(file_extension, "m3u8") == 0) {
if(video_codec_is_av1(args_parser->video_codec)) {
args_parser->video_codec = GSR_VIDEO_CODEC_HEVC;
- fprintf(stderr, "gsr warning: av1 is not compatible with hls (m3u8), falling back to hevc instead.\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "av1 is not compatible with hls (m3u8), falling back to hevc instead.");
}
}
@@ -3372,8 +3364,7 @@ static const AVCodec* select_video_codec_with_fallback(vec2i video_size, args_pa
const vec2i codec_max_resolution = codec_get_max_resolution(args_parser->video_codec, args_parser->video_encoder == GSR_VIDEO_ENCODER_HW_CPU, supported_video_codecs);
if(!codec_supports_resolution(codec_max_resolution, video_size)) {
const char *video_codec_name = video_codec_to_string(args_parser->video_codec);
- fprintf(stderr, "gsr error: The max resolution for video codec %s is %dx%d while you are trying to capture at resolution %dx%d. Change capture resolution or video codec and try again\n",
- video_codec_name, codec_max_resolution.x, codec_max_resolution.y, video_size.x, video_size.y);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "The max resolution for video codec %s is %dx%d while you are trying to capture at resolution %dx%d. Change capture resolution or video codec and try again", video_codec_name, codec_max_resolution.x, codec_max_resolution.y, video_size.x, video_size.y);
_exit(53);
}
@@ -3398,7 +3389,7 @@ static std::vector<AudioDeviceData> create_device_audio_inputs(const std::vector
} else {
const std::string description = "gsr-" + audio_input.name;
if(sound_device_get_by_name(&audio_device.sound_device, description.c_str(), audio_input.name.c_str(), description.c_str(), num_channels, audio_codec_context->frame_size, audio_codec_context_get_audio_format(audio_codec_context)) != 0) {
- fprintf(stderr, "gsr error: failed to get \"%s\" audio device\n", audio_input.name.c_str());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to get \"%s\" audio device", audio_input.name.c_str());
_exit(1);
}
}
@@ -3419,7 +3410,7 @@ static AudioDeviceData create_application_audio_audio_input(const MergedAudioInp
char random_str[8];
if(!generate_random_characters_standard_alphabet(random_str, sizeof(random_str))) {
- fprintf(stderr, "gsr error: failed to generate random string\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to generate random string");
_exit(1);
}
@@ -3428,7 +3419,7 @@ static AudioDeviceData create_application_audio_audio_input(const MergedAudioInp
combined_sink_name += ".monitor";
if(sound_device_get_by_name(&audio_device.sound_device, combined_sink_name.c_str(), "", "gpu-screen-recorder", num_channels, audio_codec_context->frame_size, audio_codec_context_get_audio_format(audio_codec_context)) != 0) {
- fprintf(stderr, "gsr error: failed to setup audio recording to combined sink\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to setup audio recording to combined sink");
_exit(1);
}
@@ -3449,19 +3440,19 @@ static AudioDeviceData create_application_audio_audio_input(const MergedAudioInp
if(!audio_devices_sources.empty()) {
if(!gsr_pipewire_audio_add_link_from_sources_to_stream(pipewire_audio, audio_devices_sources.data(), audio_devices_sources.size(), combined_sink_name.c_str())) {
- fprintf(stderr, "gsr error: failed to add application audio link\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to add application audio link");
_exit(1);
}
}
if(app_audio_inverted) {
if(!gsr_pipewire_audio_add_link_from_apps_to_stream_inverted(pipewire_audio, app_names.data(), app_names.size(), combined_sink_name.c_str())) {
- fprintf(stderr, "gsr error: failed to add application audio link\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to add application audio link");
_exit(1);
}
} else {
if(!gsr_pipewire_audio_add_link_from_apps_to_stream(pipewire_audio, app_names.data(), app_names.size(), combined_sink_name.c_str())) {
- fprintf(stderr, "gsr error: failed to add application audio link\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to add application audio link");
_exit(1);
}
}
@@ -3574,7 +3565,7 @@ static void validate_args_with_capture_sources(args_parser &arg_parser, const st
assert(region_arg);
if(is_capturing_type(capture_sources, GSR_CAPTURE_SOURCE_TYPE_FOCUSED_WINDOW) && output_resolution_arg->num_values == 0) {
- fprintf(stderr, "gsr error: option -s is required when using '-w focused' option\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "option -s is required when using '-w focused' option");
args_parser_print_usage();
_exit(1);
}
@@ -3582,22 +3573,22 @@ static void validate_args_with_capture_sources(args_parser &arg_parser, const st
const bool is_capturing_region = is_capturing_type(capture_sources, GSR_CAPTURE_SOURCE_TYPE_REGION);
if(region_arg->num_values == 0) {
if(is_capturing_region && !has_capture_source_with_region_set(capture_sources)) {
- fprintf(stderr, "gsr error: option -region is required when '-w region' is used\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "option -region is required when '-w region' is used");
args_parser_print_usage();
_exit(1);
}
} else {
if(is_capturing_region) {
- fprintf(stderr, "gsr warning: option -region is deprecated, use -w with region directly instead, for example: -w %s\n", region_arg->values[0]);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "option -region is deprecated, use -w with region directly instead, for example: -w %s", region_arg->values[0]);
} else {
- fprintf(stderr, "gsr error: option -region can only be used when option '-w region' is used\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "option -region can only be used when option '-w region' is used");
args_parser_print_usage();
_exit(1);
}
}
if(!arg_parser.restore_portal_session && is_capturing_type(capture_sources, GSR_CAPTURE_SOURCE_TYPE_PORTAL))
- fprintf(stderr, "gsr info: option '-w portal' was used without '-restore-portal-session yes'. The previous screencast session will be ignored\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "option '-w portal' was used without '-restore-portal-session yes'. The previous screencast session will be ignored");
}
static void install_cuda_no_stable_perf_limit() {
@@ -3606,7 +3597,7 @@ static void install_cuda_no_stable_perf_limit() {
const char *home = getenv("HOME");
if(!home) {
- fprintf(stderr, "gsr warning: install_cuda_no_stable_perf_limit: $HOME not set\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "install_cuda_no_stable_perf_limit: $HOME not set");
return;
}
@@ -3614,7 +3605,7 @@ static void install_cuda_no_stable_perf_limit() {
snprintf(nv_profiles_path, sizeof(nv_profiles_path), "%s/.nv/nvidia-application-profiles-rc.d", home);
if(create_directory_recursive(nv_profiles_path) != 0) {
- fprintf(stderr, "gsr warning: install_cuda_no_stable_perf_limit: failed to create directory: %s\n", nv_profiles_path);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "install_cuda_no_stable_perf_limit: failed to create directory: %s", nv_profiles_path);
return;
}
@@ -3622,7 +3613,7 @@ static void install_cuda_no_stable_perf_limit() {
FILE *f = fopen(nv_profiles_path, "wb");
if(!f) {
- fprintf(stderr, "gsr warning: install_cuda_no_stable_perf_limit: failed to create file: %s\n", nv_profiles_path);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "install_cuda_no_stable_perf_limit: failed to create file: %s", nv_profiles_path);
return;
}
@@ -3683,7 +3674,7 @@ int main(int argc, char **argv) {
unsetenv("vblank_mode");
if(geteuid() == 0) {
- fprintf(stderr, "gsr error: don't run gpu-screen-recorder as the root user\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "don't run gpu-screen-recorder as the root user");
_exit(1);
}
@@ -3711,7 +3702,7 @@ int main(int argc, char **argv) {
std::vector<CaptureSource> capture_sources = parse_capture_source_arg(arg_parser.capture_source, arg_parser);
if(capture_sources.empty()) {
- fprintf(stderr, "gsr error: option -w can't be empty. You need to capture video from at least one source\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "option -w can't be empty. You need to capture video from at least one source");
args_parser_print_usage();
_exit(1);
}
@@ -3735,12 +3726,12 @@ int main(int argc, char **argv) {
memset(&pipewire_audio, 0, sizeof(pipewire_audio));
if(uses_app_audio) {
if(!pulseaudio_server_is_pipewire()) {
- fprintf(stderr, "gsr error: your sound server is not PipeWire. Application audio is only available when running PipeWire audio server\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "your sound server is not PipeWire. Application audio is only available when running PipeWire audio server");
_exit(2);
}
if(!gsr_pipewire_audio_init(&pipewire_audio)) {
- fprintf(stderr, "gsr error: failed to setup PipeWire audio for application audio capture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to setup PipeWire audio for application audio capture");
_exit(2);
}
@@ -3752,7 +3743,7 @@ int main(int argc, char **argv) {
}
#else
if(uses_app_audio) {
- fprintf(stderr, "gsr error: application audio can't be recorded because GPU Screen Recorder is built without application audio support (-Dapp_audio option)\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "application audio can't be recorded because GPU Screen Recorder is built without application audio support (-Dapp_audio option)");
_exit(2);
}
#endif
@@ -3765,7 +3756,7 @@ int main(int argc, char **argv) {
XSelectInput(dpy, DefaultRootWindow(dpy), PropertyChangeMask);
} else {
wayland = true;
- fprintf(stderr, "gsr warning: failed to connect to the X server. Assuming wayland is running without Xwayland\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "failed to connect to the X server. Assuming wayland is running without Xwayland");
}
XSetErrorHandler(x11_error_handler);
@@ -3778,31 +3769,31 @@ int main(int argc, char **argv) {
// Disable prime-run and similar options as it doesn't work, the monitor to capture has to be run on the same device.
// This is fine on wayland since nvidia uses drm interface there and the monitor query checks the monitors connected
// to the drm device.
- fprintf(stderr, "gsr warning: use of prime-run on X11 is not supported. Disabling prime-run\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "use of prime-run on X11 is not supported. Disabling prime-run");
disable_prime_run();
}
gsr_window *window = gsr_window_create(dpy, wayland);
if(!window) {
- fprintf(stderr, "gsr error: failed to create window\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create window");
_exit(1);
}
if(is_capturing_type(capture_sources, GSR_CAPTURE_SOURCE_TYPE_PORTAL)) {
if(is_using_prime_run()) {
- fprintf(stderr, "gsr warning: use of prime-run with -w portal option is currently not supported. Disabling prime-run\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "use of prime-run with -w portal option is currently not supported. Disabling prime-run");
disable_prime_run();
}
if(video_codec_is_hdr(arg_parser.video_codec)) {
- fprintf(stderr, "gsr warning: portal capture option doesn't support hdr yet (PipeWire doesn't support hdr), the video will be tonemapped from hdr to sdr\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "portal capture option doesn't support hdr yet (PipeWire doesn't support hdr), the video will be tonemapped from hdr to sdr");
arg_parser.video_codec = hdr_video_codec_to_sdr_video_codec(arg_parser.video_codec);
}
}
gsr_egl egl;
if(!gsr_egl_load(&egl, window, is_capturing_monitor_or_region(capture_sources), arg_parser.gl_debug)) {
- fprintf(stderr, "gsr error: failed to load opengl\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to load opengl");
_exit(1);
}
@@ -3818,7 +3809,7 @@ int main(int argc, char **argv) {
if(monitor_capture_use_drm(window, egl.gpu_info.vendor)) {
// TODO: Allow specifying another card, and in other places
if(!gsr_get_valid_card_path(&egl, egl.card_path, is_capturing_monitor_or_region(capture_sources))) {
- fprintf(stderr, "gsr error: no /dev/dri/cardX device found. Make sure that you have at least one monitor connected or record a single window instead on X11 or record with the -w portal option\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "no /dev/dri/cardX device found. Make sure that you have at least one monitor connected or record a single window instead on X11 or record with the -w portal option");
_exit(2);
}
} else {
@@ -3840,7 +3831,7 @@ int main(int argc, char **argv) {
gsr_image_format image_format;
if(get_image_format_from_filename(arg_parser.filename, &image_format)) {
if(audio_input_arg->num_values > 0) {
- fprintf(stderr, "gsr error: can't record audio (-a) when taking a screenshot\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "can't record audio (-a) when taking a screenshot");
_exit(1);
}
@@ -3853,9 +3844,9 @@ int main(int argc, char **argv) {
avformat_alloc_output_context2(&av_format_context, nullptr, arg_parser.container_format, arg_parser.filename);
if (!av_format_context) {
if(arg_parser.container_format) {
- fprintf(stderr, "gsr error: Container format '%s' (argument -c) is not valid\n", arg_parser.container_format);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Container format '%s' (argument -c) is not valid", arg_parser.container_format);
} else {
- fprintf(stderr, "gsr error: Failed to deduce container format from file extension. Use the '-c' option to specify container format\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Failed to deduce container format from file extension. Use the '-c' option to specify container format");
args_parser_print_usage();
_exit(1);
}
@@ -3888,7 +3879,7 @@ int main(int argc, char **argv) {
// (Some?) livestreaming services require at least one audio track to work.
// If not audio is provided then create one silent audio track.
if(arg_parser.is_livestream && requested_audio_inputs.empty()) {
- fprintf(stderr, "gsr info: live streaming but no audio track was added. Adding a silent audio track\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "live streaming but no audio track was added. Adding a silent audio track");
MergedAudioInputs mai;
mai.audio_inputs.push_back({""});
requested_audio_inputs.push_back(std::move(mai));
@@ -3898,7 +3889,7 @@ int main(int argc, char **argv) {
std::vector<AudioTrack> audio_tracks;
if(arg_parser.video_encoder == GSR_VIDEO_ENCODER_HW_CPU && arg_parser.video_codec != (gsr_video_codec)GSR_VIDEO_CODEC_AUTO && arg_parser.video_codec != GSR_VIDEO_CODEC_H264) {
- fprintf(stderr, "gsr error: -encoder cpu was specified but a codec other than h264 was specified. -encoder cpu supports only h264 at the moment\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "-encoder cpu was specified but a codec other than h264 was specified. -encoder cpu supports only h264 at the moment");
_exit(1);
}
@@ -3912,7 +3903,7 @@ int main(int argc, char **argv) {
AVFrame *video_frame = av_frame_alloc();
if(!video_frame) {
- fprintf(stderr, "gsr error: Failed to allocate video frame\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Failed to allocate video frame");
_exit(1);
}
video_frame->format = video_codec_context->pix_fmt;
@@ -3927,18 +3918,18 @@ int main(int argc, char **argv) {
const size_t estimated_replay_buffer_packets = calculate_estimated_replay_buffer_packets(arg_parser.replay_buffer_size_secs, arg_parser.fps, arg_parser.audio_codec, requested_audio_inputs);
gsr_encoder encoder;
if(!gsr_encoder_init(&encoder, arg_parser.replay_storage, estimated_replay_buffer_packets, arg_parser.replay_buffer_size_secs, arg_parser.filename)) {
- fprintf(stderr, "gsr error: failed to create encoder\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create encoder");
_exit(1);
}
gsr_video_encoder *video_encoder = create_video_encoder(&egl, arg_parser);
if(!video_encoder) {
- fprintf(stderr, "gsr error: failed to create video encoder\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create video encoder");
_exit(1);
}
if(!gsr_video_encoder_start(video_encoder, video_codec_context, video_frame)) {
- fprintf(stderr, "gsr error: failed to start video encoder\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to start video encoder");
_exit(1);
}
@@ -3964,7 +3955,7 @@ int main(int argc, char **argv) {
gsr_color_conversion color_conversion;
if(gsr_color_conversion_init(&color_conversion, &color_conversion_params) != 0) {
- fprintf(stderr, "gsr error: main: failed to create color conversion\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "main: failed to create color conversion");
_exit(1);
}
@@ -3997,7 +3988,7 @@ int main(int argc, char **argv) {
if(!arg_parser.is_replaying) {
audio_stream = create_stream(av_format_context, audio_codec_context);
if(gsr_encoder_add_recording_destination(&encoder, audio_codec_context, av_format_context, audio_stream, 0) == (size_t)-1)
- fprintf(stderr, "gsr error: added too many audio sources\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "added too many audio sources");
}
if(audio_stream && !merged_audio_inputs.track_name.empty() && !arg_parser.exclude_metadata)
@@ -4021,7 +4012,7 @@ int main(int argc, char **argv) {
if(use_amix) {
int err = init_filter_graph(audio_codec_context, &graph, &sink, src_filter_ctx, merged_audio_inputs.audio_inputs.size());
if(err < 0) {
- fprintf(stderr, "gsr error: failed to create audio filter\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create audio filter");
_exit(1);
}
}
@@ -4063,7 +4054,7 @@ int main(int argc, char **argv) {
if(!arg_parser.is_replaying && !(output_format->flags & AVFMT_NOFILE)) {
const int ret = avio_open(&av_format_context->pb, arg_parser.filename, AVIO_FLAG_WRITE);
if(ret < 0) {
- fprintf(stderr, "gsr error: Could not open '%s': %s\n", arg_parser.filename, av_error_to_string(ret));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "Could not open '%s': %s", arg_parser.filename, av_error_to_string(ret));
_exit(1);
}
}
@@ -4092,7 +4083,7 @@ int main(int argc, char **argv) {
const size_t audio_buffer_size = audio_max_frame_size * 4 * 2; // max 4 bytes/sample, 2 channels
uint8_t *empty_audio = (uint8_t*)malloc(audio_buffer_size);
if(!empty_audio) {
- fprintf(stderr, "gsr error: failed to create empty audio\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to create empty audio");
_exit(1);
}
memset(empty_audio, 0, audio_buffer_size);
@@ -4198,7 +4189,7 @@ int main(int argc, char **argv) {
if(audio_track.graph) {
// TODO: av_buffersrc_add_frame
if(av_buffersrc_write_frame(audio_device.src_filter_ctx, audio_device.frame) < 0) {
- fprintf(stderr, "gsr error: failed to add audio frame to filter\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to add audio frame to filter");
}
} else {
ret = avcodec_send_frame(audio_track.codec_context, audio_device.frame);
@@ -4239,7 +4230,7 @@ int main(int argc, char **argv) {
if(audio_track.graph) {
// TODO: av_buffersrc_add_frame
if(av_buffersrc_write_frame(audio_device.src_filter_ctx, audio_device.frame) < 0) {
- fprintf(stderr, "gsr error: failed to add audio frame to filter\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to add audio frame to filter");
}
} else {
ret = avcodec_send_frame(audio_track.codec_context, audio_device.frame);
@@ -4335,7 +4326,7 @@ int main(int argc, char **argv) {
}
}
} else if(is_capturing_monitor_or_region(capture_sources)) {
- fprintf(stderr, "gsr warning: \"-fm content\" has no effect on Wayland when recording a monitor. Either record a monitor on X11 or capture with desktop portal instead (-w portal)\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "\"-fm content\" has no effect on Wayland when recording a monitor. Either record a monitor on X11 or capture with desktop portal instead (-w portal)");
}
}
@@ -4424,7 +4415,7 @@ int main(int argc, char **argv) {
if(kms_client_initialized) {
if(gsr_kms_client_get_kms(&kms_client, &kms_response) != 0)
- fprintf(stderr, "gsr error: failed to get kms, error: %d (%s)\n", kms_response.result, kms_response.err_msg);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to get kms, error: %d (%s)", kms_response.result, kms_response.err_msg);
}
bool capture_has_synchronous_task = false;
@@ -4500,7 +4491,7 @@ int main(int argc, char **argv) {
// TODO: Move to separate thread because this could write to network (for example when livestreaming)
gsr_encoder_receive_packets(&encoder, video_codec_context, video_frame->pts, VIDEO_STREAM_INDEX);
} else {
- fprintf(stderr, "gsr error: avcodec_send_frame failed, error: %s\n", av_error_to_string(ret));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "avcodec_send_frame failed, error: %s", av_error_to_string(ret));
}
if(force_iframe_frame) {
diff --git a/src/pipewire_audio.c b/src/pipewire_audio.c
index ec4fde1..be1ba21 100644
--- a/src/pipewire_audio.c
+++ b/src/pipewire_audio.c
@@ -1,4 +1,5 @@
#include "../include/pipewire_audio.h"
+#include "../include/log.h"
#include <pipewire/pipewire.h>
#include <pipewire/extensions/metadata.h>
@@ -388,7 +389,7 @@ static bool gsr_pipewire_audio_listen_on_metadata(gsr_pipewire_audio *self, uint
self->metadata_proxy = pw_registry_bind(self->registry, id, PW_TYPE_INTERFACE_Metadata, PW_VERSION_METADATA, 0);
if(!self->metadata_proxy) {
- fprintf(stderr, "gsr error: gsr_pipewire_audio_listen_on_metadata: failed to bind to registry\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_audio_listen_on_metadata: failed to bind to registry");
return false;
}
@@ -407,7 +408,7 @@ static bool array_ensure_capacity(void **array, size_t size, size_t *capacity_it
void *new_data = realloc(*array, new_capacity_items * element_size);
if(!new_data) {
- fprintf(stderr, "gsr error: pipewire_audio: failed to reallocate memory\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "pipewire_audio: failed to reallocate memory");
return false;
}
@@ -533,7 +534,7 @@ static void gsr_pipewire_audio_bind_node(gsr_pipewire_audio *self, uint32_t id)
struct pw_proxy *proxy = pw_registry_bind(self->registry, id, PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, 0);
if(!proxy) {
- fprintf(stderr, "gsr error: gsr_pipewire_audio_bind_node: failed to bind to node %u\n", id);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_audio_bind_node: failed to bind to node %u", id);
free(node_binding);
return;
}
@@ -701,14 +702,14 @@ bool gsr_pipewire_audio_init(gsr_pipewire_audio *self) {
self->thread_loop = pw_thread_loop_new("gsr screen capture", NULL);
if(!self->thread_loop) {
- fprintf(stderr, "gsr error: gsr_pipewire_audio_init: failed to create pipewire thread\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_audio_init: failed to create pipewire thread");
gsr_pipewire_audio_deinit(self);
return false;
}
self->context = pw_context_new(pw_thread_loop_get_loop(self->thread_loop), NULL, 0);
if(!self->context) {
- fprintf(stderr, "gsr error: gsr_pipewire_audio_init: failed to create pipewire context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_audio_init: failed to create pipewire context");
gsr_pipewire_audio_deinit(self);
return false;
}
@@ -716,7 +717,7 @@ bool gsr_pipewire_audio_init(gsr_pipewire_audio *self) {
pw_context_load_module(self->context, "libpipewire-module-link-factory", NULL, NULL);
if(pw_thread_loop_start(self->thread_loop) < 0) {
- fprintf(stderr, "gsr error: gsr_pipewire_audio_init: failed to start thread\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_audio_init: failed to start thread");
gsr_pipewire_audio_deinit(self);
return false;
}
diff --git a/src/pipewire_video.c b/src/pipewire_video.c
index 18f6c9a..80cef7e 100644
--- a/src/pipewire_video.c
+++ b/src/pipewire_video.c
@@ -1,4 +1,5 @@
#include "../include/pipewire_video.h"
+#include "../include/log.h"
#include "../include/egl.h"
#include "../include/utils.h"
@@ -62,11 +63,11 @@ static bool check_pw_version(const gsr_pipewire_video_data_version *pw_version,
}
static void update_pw_versions(gsr_pipewire_video *self, const char *version) {
- fprintf(stderr, "gsr info: pipewire: server version: %s\n", version);
- fprintf(stderr, "gsr info: pipewire: library version: %s\n", pw_get_library_version());
- fprintf(stderr, "gsr info: pipewire: header version: %s\n", pw_get_headers_version());
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: server version: %s", version);
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: library version: %s", pw_get_library_version());
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: header version: %s", pw_get_headers_version());
if(!parse_pw_version(&self->server_version, version))
- fprintf(stderr, "gsr error: pipewire: failed to parse server version\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "pipewire: failed to parse server version");
}
static void on_core_info_cb(void *user_data, const struct pw_core_info *info) {
@@ -76,7 +77,7 @@ static void on_core_info_cb(void *user_data, const struct pw_core_info *info) {
static void on_core_error_cb(void *user_data, uint32_t id, int seq, int res, const char *message) {
gsr_pipewire_video *self = user_data;
- fprintf(stderr, "gsr error: pipewire: error id:%u seq:%d res:%d: %s\n", id, seq, res, message);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "pipewire: error id:%u seq:%d res:%d: %s", id, seq, res, message);
pw_thread_loop_signal(self->thread_loop, false);
}
@@ -138,8 +139,7 @@ static void gsr_pipewire_video_read_cursor_metadata(gsr_pipewire_video *self, st
if(bitmap && bitmap->size.width > 0 && bitmap->size.height > 0 && is_cursor_format_supported(bitmap->format)) {
/* Animated cursors update the bitmap for every animation frame, only log when the size changes */
if((int)bitmap->size.width != self->cursor.width || (int)bitmap->size.height != self->cursor.height) {
- fprintf(stderr, "gsr info: pipewire: cursor bitmap update, size: %dx%d, format: %s\n",
- (int)bitmap->size.width, (int)bitmap->size.height, spa_debug_type_find_name(spa_type_video_format, bitmap->format));
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: cursor bitmap update, size: %dx%d, format: %s", (int)bitmap->size.width, (int)bitmap->size.height, spa_debug_type_find_name(spa_type_video_format, bitmap->format));
}
const uint8_t *bitmap_data = SPA_MEMBER(bitmap, bitmap->offset, uint8_t);
@@ -205,7 +205,7 @@ static void on_process_cb(void *user_data) {
}
if(!got_buffer) {
- fprintf(stderr, "gsr info: pipewire: out of buffers!\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: out of buffers!");
return;
}
@@ -315,19 +315,18 @@ static void on_param_changed_cb(void *user_data, uint32_t id, const struct spa_p
if(has_modifier || check_pw_version(&self->server_version, 0, 3, 24))
buffer_types |= 1 << SPA_DATA_DmaBuf;
- fprintf(stderr, "gsr info: pipewire: negotiated format:\n");
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: negotiated format:");
- fprintf(stderr, "gsr info: pipewire: Format: %d (%s)\n",
- self->format.info.raw.format,
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: Format: %d (%s)", self->format.info.raw.format,
spa_debug_type_find_name(spa_type_video_format, self->format.info.raw.format));
self->has_modifier = has_modifier;
if(self->has_modifier) {
- fprintf(stderr, "gsr info: pipewire: Modifier: 0x%" PRIx64 "\n", self->format.info.raw.modifier);
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: Modifier: 0x%" PRIx64, self->format.info.raw.modifier);
}
- fprintf(stderr, "gsr info: pipewire: Size: %dx%d\n", self->format.info.raw.size.width, self->format.info.raw.size.height);
- fprintf(stderr, "gsr info: pipewire: Framerate: %d/%d\n", self->format.info.raw.framerate.num, self->format.info.raw.framerate.denom);
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: Size: %dx%d", self->format.info.raw.size.width, self->format.info.raw.size.height);
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: Framerate: %d/%d", self->format.info.raw.framerate.num, self->format.info.raw.framerate.denom);
uint8_t params_buffer[2048];
struct spa_pod_builder pod_builder = SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
@@ -378,14 +377,11 @@ static void on_param_changed_cb(void *user_data, uint32_t id, const struct spa_p
static void on_state_changed_cb(void *user_data, enum pw_stream_state prev_state, enum pw_stream_state new_state, const char *error) {
gsr_pipewire_video *self = user_data;
- fprintf(stderr, "gsr info: pipewire: stream %p previous state: \"%s\", new state: \"%s\" (error: %s)\n",
- (void*)self->stream, pw_stream_state_as_string(prev_state), pw_stream_state_as_string(new_state),
+ gsr_log(GSR_LOG_LEVEL_INFO, "pipewire: stream %p previous state: \"%s\", new state: \"%s\" (error: %s)", (void*)self->stream, pw_stream_state_as_string(prev_state), pw_stream_state_as_string(new_state),
error ? error : "none");
if(new_state == PW_STREAM_STATE_ERROR && error && strstr(error, "alloc buffers")) {
- fprintf(stderr, "gsr error: pipewire: the desktop portal failed to provide dmabuf (GPU) video frames. This happens when the "
- "compositor only provides the frames as shared memory (CPU), which gpu-screen-recorder intentionally doesn't support for portal capture. "
- "Capture the monitor directly (for example '-w screen' or '-w <monitor-name>', see 'gpu-screen-recorder --list-capture-options') instead of '-w portal'.\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "pipewire: the desktop portal failed to provide dmabuf (GPU) video frames. This happens when the compositor only provides the frames as shared memory (CPU), which gpu-screen-recorder intentionally doesn't support for portal capture. Capture the monitor directly (for example '-w screen' or '-w <monitor-name>', see 'gpu-screen-recorder --list-capture-options') instead of '-w portal'.");
}
pthread_mutex_lock(&self->mutex);
@@ -528,7 +524,7 @@ static void renegotiate_format(void *data, uint64_t expirations) {
uint8_t params_buffer[8192];
struct spa_pod_builder pod_builder = SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
if (!gsr_pipewire_video_build_format_params(self, &pod_builder, params, &num_video_formats)) {
- fprintf(stderr, "gsr error: renegotiate_format: failed to build formats\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "renegotiate_format: failed to build formats");
pw_thread_loop_unlock(self->thread_loop);
return;
}
@@ -541,7 +537,7 @@ static bool spa_video_format_get_modifiers(gsr_pipewire_video *self, const enum
*num_modifiers = 0;
if(max_modifiers == 0) {
- fprintf(stderr, "gsr error: spa_video_format_get_modifiers: no space for modifiers left\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "spa_video_format_get_modifiers: no space for modifiers left");
//modifiers[0] = DRM_FORMAT_MOD_LINEAR;
//modifiers[1] = DRM_FORMAT_MOD_INVALID;
//*num_modifiers = 2;
@@ -549,7 +545,7 @@ static bool spa_video_format_get_modifiers(gsr_pipewire_video *self, const enum
}
if(!self->egl->eglQueryDmaBufModifiersEXT) {
- fprintf(stderr, "gsr error: spa_video_format_get_modifiers: failed to initialize modifiers because eglQueryDmaBufModifiersEXT is not available\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "spa_video_format_get_modifiers: failed to initialize modifiers because eglQueryDmaBufModifiersEXT is not available");
//modifiers[0] = DRM_FORMAT_MOD_LINEAR;
//modifiers[1] = DRM_FORMAT_MOD_INVALID;
//*num_modifiers = 2;
@@ -560,12 +556,12 @@ static bool spa_video_format_get_modifiers(gsr_pipewire_video *self, const enum
const int64_t drm_format = spa_video_format_to_drm_format(format);
if(drm_format == DRM_FORMAT_INVALID) {
- fprintf(stderr, "gsr error: spa_video_format_get_modifiers: unsupported format: %d\n", (int)format);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "spa_video_format_get_modifiers: unsupported format: %d", (int)format);
return false;
}
if(!self->egl->eglQueryDmaBufModifiersEXT(self->egl->egl_display, drm_format, max_modifiers, modifiers, NULL, num_modifiers)) {
- fprintf(stderr, "gsr error: spa_video_format_get_modifiers: eglQueryDmaBufModifiersEXT failed with drm format %d, %" PRIi64 "\n", (int)format, drm_format);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "spa_video_format_get_modifiers: eglQueryDmaBufModifiersEXT failed with drm format %d, %" PRIi64, (int)format, drm_format);
modifiers[0] = DRM_FORMAT_MOD_INVALID;
*num_modifiers = 1;
return false;
@@ -618,18 +614,18 @@ static bool gsr_pipewire_video_setup_stream(gsr_pipewire_video *self) {
self->thread_loop = pw_thread_loop_new("gsr screen capture", NULL);
if(!self->thread_loop) {
- fprintf(stderr, "gsr error: gsr_pipewire_video_setup_stream: failed to create pipewire thread\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_setup_stream: failed to create pipewire thread");
goto error;
}
self->context = pw_context_new(pw_thread_loop_get_loop(self->thread_loop), NULL, 0);
if(!self->context) {
- fprintf(stderr, "gsr error: gsr_pipewire_video_setup_stream: failed to create pipewire context\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_setup_stream: failed to create pipewire context");
goto error;
}
if(pw_thread_loop_start(self->thread_loop) < 0) {
- fprintf(stderr, "gsr error: gsr_pipewire_video_setup_stream: failed to start thread\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_setup_stream: failed to start thread");
goto error;
}
@@ -639,7 +635,7 @@ static bool gsr_pipewire_video_setup_stream(gsr_pipewire_video *self) {
self->core = pw_context_connect_fd(self->context, fcntl(self->fd, F_DUPFD_CLOEXEC, 5), NULL, 0);
if(!self->core) {
pw_thread_loop_unlock(self->thread_loop);
- fprintf(stderr, "gsr error: gsr_pipewire_video_setup_stream: failed to connect to fd %d\n", self->fd);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_setup_stream: failed to connect to fd %d", self->fd);
goto error;
}
@@ -655,7 +651,7 @@ static bool gsr_pipewire_video_setup_stream(gsr_pipewire_video *self) {
self->reneg = pw_loop_add_event(pw_thread_loop_get_loop(self->thread_loop), renegotiate_format, self);
if(!self->reneg) {
pw_thread_loop_unlock(self->thread_loop);
- fprintf(stderr, "gsr error: gsr_pipewire_video_setup_stream: pw_loop_add_event failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_setup_stream: pw_loop_add_event failed");
goto error;
}
@@ -665,14 +661,14 @@ static bool gsr_pipewire_video_setup_stream(gsr_pipewire_video *self) {
PW_KEY_MEDIA_ROLE, "Screen", NULL));
if(!self->stream) {
pw_thread_loop_unlock(self->thread_loop);
- fprintf(stderr, "gsr error: gsr_pipewire_video_setup_stream: failed to create stream\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_setup_stream: failed to create stream");
goto error;
}
pw_stream_add_listener(self->stream, &self->stream_listener, &stream_events, self);
if(!gsr_pipewire_video_build_format_params(self, &pod_builder, params, &num_video_formats)) {
pw_thread_loop_unlock(self->thread_loop);
- fprintf(stderr, "gsr error: gsr_pipewire_video_setup_stream: failed to build format params\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_setup_stream: failed to build format params");
goto error;
}
@@ -682,7 +678,7 @@ static bool gsr_pipewire_video_setup_stream(gsr_pipewire_video *self) {
num_video_formats) < 0)
{
pw_thread_loop_unlock(self->thread_loop);
- fprintf(stderr, "gsr error: gsr_pipewire_video_setup_stream: failed to connect stream\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_setup_stream: failed to connect stream");
goto error;
}
@@ -729,7 +725,7 @@ bool gsr_pipewire_video_init(gsr_pipewire_video *self, int pipewire_fd, uint32_t
self->fd = pipewire_fd;
self->node = pipewire_node;
if(pthread_mutex_init(&self->mutex, NULL) != 0) {
- fprintf(stderr, "gsr error: gsr_pipewire_video_init: failed to initialize mutex\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_init: failed to initialize mutex");
gsr_pipewire_video_deinit(self);
return false;
}
@@ -839,11 +835,11 @@ static EGLImage gsr_pipewire_video_create_egl_image_with_fallback(gsr_pipewire_v
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, true);
if(!image) {
if(self->format.info.raw.modifier == DRM_FORMAT_MOD_INVALID) {
- fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers");
self->no_modifiers_fallback = true;
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false);
} else {
- fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifier 0x%" PRIx64 ", renegotiating with a different modifier\n", self->format.info.raw.modifier);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifier 0x%" PRIx64 ", renegotiating with a different modifier", self->format.info.raw.modifier);
self->negotiated = false;
pw_thread_loop_lock(self->thread_loop);
gsr_pipewire_video_remove_modifier(self, self->format.info.raw.modifier);
@@ -870,7 +866,7 @@ static void gsr_pipewire_video_bind_image_to_texture_with_fallback(gsr_pipewire_
gsr_pipewire_video_bind_image_to_texture(self, image, texture_map.external_texture_id, true);
} else {
if(!gsr_pipewire_video_bind_image_to_texture(self, image, texture_map.texture_id, false)) {
- fprintf(stderr, "gsr error: gsr_pipewire_video_map_texture: failed to bind image to texture, trying with external texture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_pipewire_video_map_texture: failed to bind image to texture, trying with external texture");
self->external_texture_fallback = true;
gsr_pipewire_video_bind_image_to_texture(self, image, texture_map.external_texture_id, true);
}
diff --git a/src/plugins.c b/src/plugins.c
index 053b2a3..7686683 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -1,4 +1,5 @@
#include "../include/plugins.h"
+#include "../include/log.h"
#include "../include/utils.h"
#include <stdio.h>
#include <string.h>
@@ -23,7 +24,7 @@ bool gsr_plugins_init(gsr_plugins *self, gsr_plugin_init_params init_params, gsr
const unsigned int texture = gl_create_texture(egl, init_params.width, init_params.height, color_depth_to_gl_internal_format(init_params.color_depth), GL_RGBA, GL_LINEAR);
if(texture == 0) {
- fprintf(stderr, "gsr error: gsr_plugins_init failed to create texture\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_plugins_init failed to create texture");
return false;
}
self->texture = texture;
@@ -41,7 +42,7 @@ bool gsr_plugins_init(gsr_plugins *self, gsr_plugin_init_params init_params, gsr
color_conversion_params.destination_textures[0] = self->texture;
if(gsr_color_conversion_init(&self->color_conversion, &color_conversion_params) != 0) {
- fprintf(stderr, "gsr error: gsr_plugins_init failed to create color conversion\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_plugins_init failed to create color conversion");
gsr_plugins_deinit(self);
return false;
}
@@ -54,7 +55,7 @@ void gsr_plugins_deinit(gsr_plugins *self) {
for(int i = self->num_plugins - 1; i >= 0; --i) {
gsr_plugin *plugin = &self->plugins[i];
plugin->gsr_plugin_deinit(plugin->data.userdata);
- fprintf(stderr, "gsr info: unloaded plugin: %s\n", plugin->data.name);
+ gsr_log(GSR_LOG_LEVEL_INFO, "unloaded plugin: %s", plugin->data.name);
}
self->num_plugins = 0;
@@ -68,7 +69,7 @@ void gsr_plugins_deinit(gsr_plugins *self) {
bool gsr_plugins_load_plugin(gsr_plugins *self, const char *plugin_filepath) {
if(self->num_plugins >= GSR_MAX_PLUGINS) {
- fprintf(stderr, "gsr error: gsr_plugins_load_plugin failed, more plugins can't load more than %d plugins. Report this as an issue\n", GSR_MAX_PLUGINS);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_plugins_load_plugin failed, more plugins can't load more than %d plugins. Report this as an issue", GSR_MAX_PLUGINS);
return false;
}
@@ -77,38 +78,38 @@ bool gsr_plugins_load_plugin(gsr_plugins *self, const char *plugin_filepath) {
plugin.lib = dlopen(plugin_filepath, RTLD_LAZY);
if(!plugin.lib) {
- fprintf(stderr, "gsr error: gsr_plugins_load_plugin failed to load \"%s\", error: %s\n", plugin_filepath, dlerror());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_plugins_load_plugin failed to load \"%s\", error: %s", plugin_filepath, dlerror());
return false;
}
plugin.gsr_plugin_init = dlsym(plugin.lib, "gsr_plugin_init");
if(!plugin.gsr_plugin_init) {
- fprintf(stderr, "gsr error: gsr_plugins_load_plugin failed to find \"gsr_plugin_init\" in plugin \"%s\"\n", plugin_filepath);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_plugins_load_plugin failed to find \"gsr_plugin_init\" in plugin \"%s\"", plugin_filepath);
goto fail;
}
plugin.gsr_plugin_deinit = dlsym(plugin.lib, "gsr_plugin_deinit");
if(!plugin.gsr_plugin_deinit) {
- fprintf(stderr, "gsr error: gsr_plugins_load_plugin failed to find \"gsr_plugin_deinit\" in plugin \"%s\"\n", plugin_filepath);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_plugins_load_plugin failed to find \"gsr_plugin_deinit\" in plugin \"%s\"", plugin_filepath);
goto fail;
}
if(!plugin.gsr_plugin_init(&self->init_params, &plugin.data)) {
- fprintf(stderr, "gsr error: gsr_plugins_load_plugin failed to load plugin \"%s\", gsr_plugin_init in the plugin failed\n", plugin_filepath);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_plugins_load_plugin failed to load plugin \"%s\", gsr_plugin_init in the plugin failed", plugin_filepath);
goto fail;
}
if(!plugin.data.name) {
- fprintf(stderr, "gsr error: gsr_plugins_load_plugin failed to load plugin \"%s\", the plugin didn't set the name (gsr_plugin_init_return.name)\n", plugin_filepath);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_plugins_load_plugin failed to load plugin \"%s\", the plugin didn't set the name (gsr_plugin_init_return.name)", plugin_filepath);
goto fail;
}
if(plugin.data.version == 0) {
- fprintf(stderr, "gsr error: gsr_plugins_load_plugin failed to load plugin \"%s\", the plugin didn't set the version (gsr_plugin_init_return.version)\n", plugin_filepath);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_plugins_load_plugin failed to load plugin \"%s\", the plugin didn't set the version (gsr_plugin_init_return.version)", plugin_filepath);
goto fail;
}
- fprintf(stderr, "gsr info: loaded plugin: %s, name: %s, version: %u\n", plugin_filepath, plugin.data.name, plugin.data.version);
+ gsr_log(GSR_LOG_LEVEL_INFO, "loaded plugin: %s, name: %s, version: %u", plugin_filepath, plugin.data.name, plugin.data.version);
self->plugins[self->num_plugins] = plugin;
++self->num_plugins;
return true;
diff --git a/src/replay_buffer/replay_buffer_disk.c b/src/replay_buffer/replay_buffer_disk.c
index ce42d93..9a0d247 100644
--- a/src/replay_buffer/replay_buffer_disk.c
+++ b/src/replay_buffer/replay_buffer_disk.c
@@ -1,4 +1,5 @@
#include "../../include/replay_buffer/replay_buffer_disk.h"
+#include "../../include/log.h"
#include "../../include/utils.h"
#include <stdlib.h>
@@ -25,12 +26,12 @@ static void gsr_av_packet_disk_init(gsr_av_packet_disk *self, const AVPacket *av
static gsr_replay_buffer_file* gsr_replay_buffer_file_create(char *replay_directory, size_t replay_storage_counter, double timestamp, int *replay_storage_fd) {
gsr_replay_buffer_file *self = calloc(1, sizeof(gsr_replay_buffer_file));
if(!self) {
- fprintf(stderr, "gsr error: gsr_av_packet_file_init: failed to create buffer file\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_av_packet_file_init: failed to create buffer file");
return NULL;
}
if(create_directory_recursive(replay_directory) != 0) {
- fprintf(stderr, "gsr error: gsr_av_packet_file_init: failed to create replay directory: %s\n", replay_directory);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_av_packet_file_init: failed to create replay directory: %s", replay_directory);
free(self);
return NULL;
}
@@ -39,7 +40,7 @@ static gsr_replay_buffer_file* gsr_replay_buffer_file_create(char *replay_direct
snprintf(filename, sizeof(filename), "%s/%s_%d.gsr", replay_directory, FILE_PREFIX, (int)replay_storage_counter);
*replay_storage_fd = creat(filename, 0700);
if(*replay_storage_fd <= 0) {
- fprintf(stderr, "gsr error: gsr_av_packet_file_init: failed to create replay file: %s\n", filename);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_av_packet_file_init: failed to create replay file: %s", filename);
free(self);
return NULL;
}
@@ -135,7 +136,7 @@ static bool file_write_all(int fd, const uint8_t *data, size_t size, size_t *byt
static bool gsr_replay_buffer_disk_create_next_file(gsr_replay_buffer_disk *self, double timestamp) {
if(self->num_files + 1 >= GSR_REPLAY_BUFFER_CAPACITY_NUM_FILES) {
- fprintf(stderr, "gsr error: gsr_replay_buffer_disk_create_next_file: too many replay buffer files created! (> %d), either reduce the replay buffer time or report this as a bug\n", (int)GSR_REPLAY_BUFFER_CAPACITY_NUM_FILES);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_replay_buffer_disk_create_next_file: too many replay buffer files created! (> %d), either reduce the replay buffer time or report this as a bug", (int)GSR_REPLAY_BUFFER_CAPACITY_NUM_FILES);
return false;
}
@@ -160,7 +161,7 @@ static bool gsr_replay_buffer_disk_append_to_current_file(gsr_replay_buffer_disk
void *new_packets = realloc(replay_buffer_file->packets, new_capacity_num_packets * sizeof(gsr_av_packet_disk));
if(!new_packets) {
- fprintf(stderr, "gsr error: gsr_replay_buffer_disk_append_to_current_file: failed to reallocate replay buffer file packets\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_replay_buffer_disk_append_to_current_file: failed to reallocate replay buffer file packets");
return false;
}
@@ -233,20 +234,20 @@ static uint8_t* gsr_replay_buffer_disk_iterator_get_packet_data(gsr_replay_buffe
snprintf(filename, sizeof(filename), "%s/%s_%d.gsr", self->replay_directory, FILE_PREFIX, (int)file->id);
file->fd = open(filename, O_RDONLY);
if(file->fd <= 0) {
- fprintf(stderr, "gsr error: gsr_replay_buffer_disk_iterator_get_packet_data: failed to open file\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_replay_buffer_disk_iterator_get_packet_data: failed to open file");
return NULL;
}
}
const gsr_av_packet_disk *packet = &self->files[iterator.file_index]->packets[iterator.packet_index];
if(lseek(file->fd, packet->data_index, SEEK_SET) == -1) {
- fprintf(stderr, "gsr error: gsr_replay_buffer_disk_iterator_get_packet_data: failed to seek\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_replay_buffer_disk_iterator_get_packet_data: failed to seek");
return NULL;
}
uint8_t *packet_data = malloc(packet->packet.size);
if(read(file->fd, packet_data, packet->packet.size) != packet->packet.size) {
- fprintf(stderr, "gsr error: gsr_replay_buffer_disk_iterator_get_packet_data: failed to read data from file\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_replay_buffer_disk_iterator_get_packet_data: failed to read data from file");
free(packet_data);
return NULL;
}
diff --git a/src/shader.c b/src/shader.c
index f20ebb2..17315dc 100644
--- a/src/shader.c
+++ b/src/shader.c
@@ -1,4 +1,5 @@
#include "../include/shader.h"
+#include "../include/log.h"
#include "../include/egl.h"
#include <stdio.h>
#include <assert.h>
@@ -12,7 +13,7 @@ static int min_int(int a, int b) {
static unsigned int load_shader(gsr_egl *egl, unsigned int type, const char *source) {
unsigned int shader_id = egl->glCreateShader(type);
if(shader_id == 0) {
- fprintf(stderr, "gsr error: load_shader: failed to create shader, error: %d\n", egl->glGetError());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "load_shader: failed to create shader, error: %d", egl->glGetError());
return 0;
}
@@ -28,7 +29,7 @@ static unsigned int load_shader(gsr_egl *egl, unsigned int type, const char *sou
if(info_length > 1 && print_compile_errors) {
char info_log[4096];
egl->glGetShaderInfoLog(shader_id, min_int(4096, info_length), NULL, info_log);
- fprintf(stderr, "gsr error: load_shader: failed to compile shader, error:\n%s\nshader source:\n%s\n", info_log, source);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "load_shader: failed to compile shader, error:\n%s\nshader source:\n%s", info_log, source);
}
egl->glDeleteShader(shader_id);
@@ -59,7 +60,7 @@ static unsigned int load_program(gsr_egl *egl, const char *vertex_shader, const
program_id = egl->glCreateProgram();
if(program_id == 0) {
- fprintf(stderr, "gsr error: load_program: failed to create shader program, error: %d\n", egl->glGetError());
+ gsr_log(GSR_LOG_LEVEL_ERROR, "load_program: failed to create shader program, error: %d", egl->glGetError());
goto done;
}
@@ -79,7 +80,7 @@ static unsigned int load_program(gsr_egl *egl, const char *vertex_shader, const
if(info_length > 1) {
char info_log[4096];
egl->glGetProgramInfoLog(program_id, min_int(4096, info_length), NULL, info_log);
- fprintf(stderr, "gsr error: load program: linking shader program failed, error:\n%s\n", info_log);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "load program: linking shader program failed, error:\n%s", info_log);
}
goto done;
@@ -106,7 +107,7 @@ int gsr_shader_init(gsr_shader *self, gsr_egl *egl, const char *vertex_shader, c
self->program_id = 0;
if(!vertex_shader && !fragment_shader) {
- fprintf(stderr, "gsr error: gsr_shader_init: vertex and fragment shader can't be NULL at the same time\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_shader_init: vertex and fragment shader can't be NULL at the same time");
return -1;
}
diff --git a/src/sound.cpp b/src/sound.cpp
index 4e04d8f..9a72e78 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -1,4 +1,5 @@
#include "../include/sound.hpp"
+#include "../include/log.h"
extern "C" {
#include "../include/utils.h"
}
@@ -163,7 +164,7 @@ static bool startup_get_default_devices(pa_handle *p, const char *device_name) {
}
if(p->default_output_device_name[0] == '\0') {
- fprintf(stderr, "gsr error: failed to find default audio output device\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to find default audio output device");
return false;
}
@@ -207,7 +208,7 @@ static pa_handle* pa_sound_device_new(const char *server,
const int buffer_size = attr->fragsize;
void *buffer = malloc(buffer_size);
if(!buffer) {
- fprintf(stderr, "gsr error: failed to allocate buffer for audio\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to allocate buffer for audio");
*rerror = -1;
return NULL;
}
@@ -286,12 +287,12 @@ static bool pa_sound_device_handle_context_recreate(pa_handle *p) {
}
if (!(p->context = pa_context_new_with_proplist(pa_mainloop_get_api(p->mainloop), p->node_name, p->proplist))) {
- fprintf(stderr, "gsr error: pa_context_new_with_proplist failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "pa_context_new_with_proplist failed");
goto fail;
}
if(pa_context_connect(p->context, nullptr, PA_CONTEXT_NOFLAGS, NULL) < 0) {
- fprintf(stderr, "gsr error: pa_context_connect failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "pa_context_connect failed");
goto fail;
}
@@ -505,7 +506,7 @@ int sound_device_get_by_name(SoundDevice *device, const char *node_name, const c
int error = 0;
pa_handle *handle = pa_sound_device_new(nullptr, node_name, device_name, description, &ss, &buffer_attr, &error);
if(!handle) {
- fprintf(stderr, "gsr error: pa_sound_device_new() failed: %s. Audio input device %s might not be valid\n", pa_strerror(error), device_name);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "pa_sound_device_new() failed: %s. Audio input device %s might not be valid", pa_strerror(error), device_name);
return -1;
}
diff --git a/src/utils.c b/src/utils.c
index 31853e2..75a6427 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -1,4 +1,5 @@
#include "../include/utils.h"
+#include "../include/log.h"
#include "../include/window/window.h"
#include "../include/capture/capture.h"
@@ -33,7 +34,7 @@ double clock_get_monotonic_seconds(void) {
bool generate_random_characters(char *buffer, int buffer_size, const char *alphabet, size_t alphabet_size) {
/* TODO: Use other functions on other platforms than linux */
if(getrandom(buffer, buffer_size, 0) < buffer_size) {
- fprintf(stderr, "Failed to get random bytes, error: %s\n", strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to get random bytes, error: %s", strerror(errno));
return false;
}
@@ -197,7 +198,7 @@ static bool connector_get_property_by_name(int drmfd, drmModeConnectorPtr props,
static void for_each_active_monitor_output_drm(const char *card_path, active_monitor_callback callback, void *userdata) {
int fd = open(card_path, O_RDONLY);
if(fd == -1) {
- fprintf(stderr, "gsr error: for_each_active_monitor_output_drm failed, failed to open \"%s\", error: %s\n", card_path, strerror(errno));
+ gsr_log(GSR_LOG_LEVEL_ERROR, "for_each_active_monitor_output_drm failed, failed to open \"%s\", error: %s", card_path, strerror(errno));
return;
}
@@ -365,14 +366,14 @@ bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info) {
info->is_steam_deck = false;
if(!gl_vendor) {
- fprintf(stderr, "gsr error: failed to get gpu vendor\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "failed to get gpu vendor");
return false;
}
if(gl_renderer) {
for(int i = 0; software_renderers[i]; ++i) {
if(strstr(gl_renderer, software_renderers[i])) {
- fprintf(stderr, "gsr error: your opengl environment is not properly setup. It's using %s (software rendering) for opengl instead of your graphics card. Please make sure your graphics driver is properly installed\n", software_renderers[i]);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "your opengl environment is not properly setup. It's using %s (software rendering) for opengl instead of your graphics card. Please make sure your graphics driver is properly installed", software_renderers[i]);
return false;
}
}
@@ -389,7 +390,7 @@ bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info) {
else if(strstr(gl_vendor, "Broadcom"))
info->vendor = GSR_GPU_VENDOR_BROADCOM;
else {
- fprintf(stderr, "gsr error: unknown gpu vendor: %s\n", gl_vendor);
+ gsr_log(GSR_LOG_LEVEL_ERROR, "unknown gpu vendor: %s", gl_vendor);
return false;
}
@@ -656,7 +657,7 @@ bool get_nvidia_driver_version(int *major, int *minor) {
FILE *f = fopen("/proc/driver/nvidia/version", "rb");
if(!f) {
- fprintf(stderr, "gsr warning: failed to get nvidia driver version (failed to read /proc/driver/nvidia/version)\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "failed to get nvidia driver version (failed to read /proc/driver/nvidia/version)");
return false;
}
@@ -677,7 +678,7 @@ bool get_nvidia_driver_version(int *major, int *minor) {
}
if(!success)
- fprintf(stderr, "gsr warning: failed to get nvidia driver version\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "failed to get nvidia driver version");
fclose(f);
return success;
diff --git a/src/wayland_host_bridge.c b/src/wayland_host_bridge.c
index 4e8319b..f9299a4 100644
--- a/src/wayland_host_bridge.c
+++ b/src/wayland_host_bridge.c
@@ -1,4 +1,5 @@
#include "../include/wayland_host_bridge.h"
+#include "../include/log.h"
#include <stdio.h>
#include <stdlib.h>
@@ -84,14 +85,14 @@ static struct wl_display* connect_via_bridge() {
waitpid(pid, &status, 0);
if(wayland_fd < 0) {
- fprintf(stderr, "WaylandHostBridge: gsr-wayland-bridge did not return a wayland fd\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "WaylandHostBridge: gsr-wayland-bridge did not return a wayland fd");
return NULL;
}
struct wl_display *dpy = wl_display_connect_to_fd(wayland_fd);
if(!dpy) {
close(wayland_fd);
- fprintf(stderr, "WaylandHostBridge: wl_display_connect_to_fd failed\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "WaylandHostBridge: wl_display_connect_to_fd failed");
return NULL;
}
return dpy;
@@ -103,7 +104,7 @@ struct wl_display* wayland_connect_to_host() {
struct wl_display *dpy = connect_via_bridge();
if(dpy)
return dpy;
- fprintf(stderr, "WaylandHostBridge: falling back to sandboxed wl_display_connect\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "WaylandHostBridge: falling back to sandboxed wl_display_connect");
}
return wl_display_connect(NULL);
}
diff --git a/src/window/wayland.c b/src/window/wayland.c
index 6c263c5..75e36f0 100644
--- a/src/window/wayland.c
+++ b/src/window/wayland.c
@@ -1,4 +1,5 @@
#include "../../include/window/wayland.h"
+#include "../../include/log.h"
#include "../../include/wayland_host_bridge.h"
#include "../../include/vec2.h"
@@ -234,12 +235,12 @@ static void registry_add_object(void *data, struct wl_registry *registry, uint32
window_wayland->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);
} else if(strcmp(interface, wl_output_interface.name) == 0) {
if(version < 4) {
- fprintf(stderr, "gsr warning: wl output interface version is < 4, expected >= 4 to capture a monitor\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "wl output interface version is < 4, expected >= 4 to capture a monitor");
return;
}
if(window_wayland->num_outputs == GSR_MAX_OUTPUTS) {
- fprintf(stderr, "gsr warning: reached maximum outputs (%d), ignoring output %u\n", GSR_MAX_OUTPUTS, name);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "reached maximum outputs (%d), ignoring output %u", GSR_MAX_OUTPUTS, name);
return;
}
@@ -257,7 +258,7 @@ static void registry_add_object(void *data, struct wl_registry *registry, uint32
wl_output_add_listener(gsr_output->output, &output_listener, gsr_output);
} else if(strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) {
if(version < 1) {
- fprintf(stderr, "gsr warning: xdg output interface version is < 1, expected >= 1 to capture a monitor\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "xdg output interface version is < 1, expected >= 1 to capture a monitor");
return;
}
@@ -326,7 +327,7 @@ static const struct zxdg_output_v1_listener xdg_output_listener = {
static void gsr_window_wayland_set_monitor_outputs_from_xdg_output(gsr_window_wayland *self) {
if(!self->xdg_output_manager) {
- fprintf(stderr, "gsr warning: zxdg_output_manager not found. registered monitor positions might be incorrect\n");
+ gsr_log(GSR_LOG_LEVEL_WARNING, "zxdg_output_manager not found. registered monitor positions might be incorrect");
return;
}
@@ -464,7 +465,7 @@ static void gsr_window_wayland_deinit(gsr_window_wayland *self) {
static bool gsr_window_wayland_init(gsr_window_wayland *self) {
self->display = wayland_connect_to_host();
if(!self->display) {
- fprintf(stderr, "gsr error: gsr_window_wayland_init failed: failed to connect to the Wayland server\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_window_wayland_init failed: failed to connect to the Wayland server");
goto fail;
}
@@ -482,19 +483,19 @@ static bool gsr_window_wayland_init(gsr_window_wayland *self) {
gsr_window_wayland_set_monitor_real_positions(self);
if(!self->compositor) {
- fprintf(stderr, "gsr error: gsr_window_wayland_init failed: failed to find compositor\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_window_wayland_init failed: failed to find compositor");
goto fail;
}
self->surface = wl_compositor_create_surface(self->compositor);
if(!self->surface) {
- fprintf(stderr, "gsr error: gsr_window_wayland_init failed: failed to create surface\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_window_wayland_init failed: failed to create surface");
goto fail;
}
self->window = wl_egl_window_create(self->surface, 16, 16);
if(!self->window) {
- fprintf(stderr, "gsr error: gsr_window_wayland_init failed: failed to create window\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_window_wayland_init failed: failed to create window");
goto fail;
}
diff --git a/src/window/x11.c b/src/window/x11.c
index 3b3c955..b9b6cbf 100644
--- a/src/window/x11.c
+++ b/src/window/x11.c
@@ -1,4 +1,5 @@
#include "../../include/window/x11.h"
+#include "../../include/log.h"
#include "../../include/vec2.h"
#include "../../include/defs.h"
@@ -32,7 +33,7 @@ typedef struct {
static void store_x11_monitor(const gsr_monitor *monitor, void *userdata) {
gsr_window_x11 *window_x11 = userdata;
if(window_x11->num_outputs == GSR_MAX_OUTPUTS) {
- fprintf(stderr, "gsr warning: reached maximum outputs (%d), ignoring output %s\n", GSR_MAX_OUTPUTS, monitor->name);
+ gsr_log(GSR_LOG_LEVEL_WARNING, "reached maximum outputs (%d), ignoring output %s", GSR_MAX_OUTPUTS, monitor->name);
return;
}
@@ -68,7 +69,7 @@ static void gsr_window_x11_deinit(gsr_window_x11 *self) {
static bool gsr_window_x11_init(gsr_window_x11 *self) {
self->window = XCreateWindow(self->display, DefaultRootWindow(self->display), 0, 0, 16, 16, 0, CopyFromParent, InputOutput, CopyFromParent, 0, NULL);
if(!self->window) {
- fprintf(stderr, "gsr error: gsr_window_x11_init failed: failed to create gl window\n");
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_window_x11_init failed: failed to create gl window");
return false;
}