diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | src/main.cpp | 31 | ||||
-rw-r--r-- | src/utils.c | 10 |
3 files changed, 36 insertions, 7 deletions
@@ -56,7 +56,7 @@ Intel is a bit weird with monitor capture and multiple monitors. If one of the m Support vp8/vp9. This is especially important on amd which on some distros (such as Manjaro) where hardware accelerated h264/hevc is disabled in the mesa package. -Support screen (all monitors) capture on amd/intel when no combined plane is found. +Support screen (all monitors) capture on amd/intel and nvidia wayland when no combined plane is found. Right now screen just takes the first output. Use separate plane (which has offset and pitch) from combined plane instead of the combined plane. Both twitch and youtube support variable bitrate but twitch recommends constant bitrate to reduce stream buffering/dropped frames when going from low motion to high motion: https://help.twitch.tv/s/article/broadcasting-guidelines?language=en_US. Info for youtube: https://support.google.com/youtube/answer/2853702?hl=en#zippy=%2Cvariable-bitrate-with-custom-stream-keys-in-live-control-room%2Ck-p-fps%2Cp-fps. diff --git a/src/main.cpp b/src/main.cpp index c9f793e..797c290 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,6 +52,16 @@ static void monitor_output_callback_print(const gsr_monitor *monitor, void *user fprintf(stderr, " \"%.*s\" (%dx%d+%d+%d)\n", monitor->name_len, monitor->name, monitor->size.x, monitor->size.y, monitor->pos.x, monitor->pos.y); } +typedef struct { + const char *output_name; +} FirstOutputCallback; + +static void get_first_output(const gsr_monitor *monitor, void *userdata) { + FirstOutputCallback *first_output = (FirstOutputCallback*)userdata; + if(!first_output->output_name) + first_output->output_name = strndup(monitor->name, monitor->name_len + 1); +} + static char* av_error_to_string(int err) { if(av_strerror(err, av_error_buffer, sizeof(av_error_buffer)) < 0) strcpy(av_error_buffer, "Unknown error"); @@ -1557,7 +1567,7 @@ int main(int argc, char **argv) { } const char *screen_region = args["-s"].value(); - const char *window_str = args["-w"].value(); + const char *window_str = strdup(args["-w"].value()); if(screen_region && strcmp(window_str, "focused") != 0) { fprintf(stderr, "Error: option -s is only available when using -w focused\n"); @@ -1593,10 +1603,27 @@ int main(int argc, char **argv) { follow_focused = true; } else if(contains_non_hex_number(window_str)) { if(wayland || gpu_inf.vendor != GSR_GPU_VENDOR_NVIDIA) { + if(strcmp(window_str, "screen") == 0) { + FirstOutputCallback first_output; + first_output.output_name = NULL; + if(gsr_egl_supports_wayland_capture(&egl)) { + for_each_active_monitor_output(&egl, GSR_CONNECTION_WAYLAND, get_first_output, &first_output); + } else { + for_each_active_monitor_output(card_path, GSR_CONNECTION_DRM, get_first_output, &first_output); + } + + if(first_output.output_name) { + window_str = first_output.output_name; + } else { + fprintf(stderr, "Error: no available output found\n"); + } + } + if(gsr_egl_supports_wayland_capture(&egl)) { gsr_monitor gmon; if(!get_monitor_by_name(&egl, GSR_CONNECTION_WAYLAND, window_str, &gmon)) { fprintf(stderr, "gsr error: display \"%s\" not found, expected one of:\n", window_str); + fprintf(stderr, " \"screen\"\n"); for_each_active_monitor_output(&egl, GSR_CONNECTION_WAYLAND, monitor_output_callback_print, NULL); _exit(1); } @@ -1604,6 +1631,7 @@ int main(int argc, char **argv) { gsr_monitor gmon; if(!get_monitor_by_name(card_path, GSR_CONNECTION_DRM, window_str, &gmon)) { fprintf(stderr, "gsr error: display \"%s\" not found, expected one of:\n", window_str); + fprintf(stderr, " \"screen\"\n"); for_each_active_monitor_output(card_path, GSR_CONNECTION_DRM, monitor_output_callback_print, NULL); _exit(1); } @@ -2357,6 +2385,7 @@ int main(int argc, char **argv) { //XCloseDisplay(dpy); } + free((void*)window_str); free(empty_audio); // We do an _exit here because cuda uses at_exit to do _something_ that causes the program to freeze, // but only on some nvidia driver versions on some gpus (RTX?), and _exit exits the program without calling diff --git a/src/utils.c b/src/utils.c index db0bd6f..94b0037 100644 --- a/src/utils.c +++ b/src/utils.c @@ -137,17 +137,17 @@ static void for_each_active_monitor_output_drm(const char *drm_card_path, active if(!connector) continue; - if(connector->connection != DRM_MODE_CONNECTED) { - drmModeFreeConnector(connector); - continue; - } - drm_connector_type_count *connector_type = drm_connector_types_get_index(type_counts, &num_type_counts, connector->connector_type); const char *connection_name = drmModeGetConnectorTypeName(connector->connector_type); const int connection_name_len = strlen(connection_name); if(connector_type) ++connector_type->count; + if(connector->connection != DRM_MODE_CONNECTED) { + drmModeFreeConnector(connector); + continue; + } + uint64_t crtc_id = 0; connector_get_property_by_name(fd, connector, "CRTC_ID", &crtc_id); |