diff options
| author | dec05eba <dec05eba@protonmail.com> | 2026-08-01 18:51:59 +0200 |
|---|---|---|
| committer | dec05eba <dec05eba@protonmail.com> | 2026-08-01 18:51:59 +0200 |
| commit | c150d0e6ba0ab1f9ecd6a1c933a58050187e0c81 (patch) | |
| tree | 3cae92f93009e87aeb2487afce569d6a20a8586c | |
| parent | 9c2c0e1d0de9b3968415b08830a45f64091d3b98 (diff) | |
Add gsr_log logging module with log level and overridable log handler
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(¶ms, &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; } @@ -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; } @@ -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; } @@ -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; } |
