From 74a5fb9dfbfab90f6e711c1763958cdcf380e77b Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 4 Mar 2023 11:19:31 +0100 Subject: Add screen-direct-force option for VRR monitor --- src/capture/nvfbc.c | 5 +++-- src/main.cpp | 34 +++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/capture/nvfbc.c b/src/capture/nvfbc.c index 9587972..fba3321 100644 --- a/src/capture/nvfbc.c +++ b/src/capture/nvfbc.c @@ -205,6 +205,7 @@ static int gsr_capture_nvfbc_start(gsr_capture *cap, AVCodecContext *video_codec if(direct_capture && get_driver_version(&driver_major_version, &driver_minor_version)) { fprintf(stderr, "Info: detected nvidia version: %d.%d\n", 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)) { direct_capture = false; fprintf(stderr, "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"); @@ -292,8 +293,8 @@ static int gsr_capture_nvfbc_start(gsr_capture *cap, AVCodecContext *video_codec create_capture_params.captureBox = (NVFBC_BOX){ x, y, width, height }; create_capture_params.eTrackingType = tracking_type; create_capture_params.dwSamplingRateMs = 1000u / ((uint32_t)cap_nvfbc->params.fps + 1); - create_capture_params.bAllowDirectCapture = cap_nvfbc->params.direct_capture ? NVFBC_TRUE : NVFBC_FALSE; - create_capture_params.bPushModel = cap_nvfbc->params.direct_capture ? NVFBC_TRUE : NVFBC_FALSE; + create_capture_params.bAllowDirectCapture = direct_capture ? NVFBC_TRUE : NVFBC_FALSE; + create_capture_params.bPushModel = direct_capture ? NVFBC_TRUE : NVFBC_FALSE; if(tracking_type == NVFBC_TRACKING_OUTPUT) create_capture_params.dwOutputId = output_id; diff --git a/src/main.cpp b/src/main.cpp index b55b161..ea70f7d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -494,8 +494,8 @@ static void open_video(AVCodecContext *codec_context, VideoQuality video_quality static void usage() { fprintf(stderr, "usage: gpu-screen-recorder -w [-c ] [-s WxH] -f [-a ...] [-q ] [-r ] [-o ]\n"); fprintf(stderr, "OPTIONS:\n"); - fprintf(stderr, " -w Window to record, a display, \"screen\", \"screen-direct\" or \"focused\". The display is the display (monitor) name in xrandr and if \"screen\" or \"screen-direct\" is selected then all displays are recorded. If this is \"focused\" then the currently focused window is recorded. When recording the focused window then the -s option has to be used as well.\n" - "\"screen-direct\" skips one texture copy for fullscreen applications so it may lead to better performance and it works with VRR monitors when recording fullscreen application but may break some applications, such as mpv in fullscreen mode.\n"); + fprintf(stderr, " -w Window to record, a display, \"screen\", \"screen-direct\", \"screen-direct-force\" or \"focused\". The display is the display (monitor) name in xrandr and if \"screen\" or \"screen-direct\" is selected then all displays are recorded. If this is \"focused\" then the currently focused window is recorded. When recording the focused window then the -s option has to be used as well.\n" + "\"screen-direct\"/\"screen-direct-force\" skips one texture copy for fullscreen applications so it may lead to better performance and it works with VRR monitors when recording fullscreen application but may break some applications, such as mpv in fullscreen mode. Direct mode doesn't capture cursor either.\n"); fprintf(stderr, " -c Container format for output file, for example mp4, or flv. Only required if no output file is specified or if recording in replay buffer mode. If an output file is specified and -c is not used then the container format is determined from the output filename extension.\n"); fprintf(stderr, " -s The size (area) to record at in the format WxH, for example 1920x1080. This option is only supported (and required) when -w is \"focused\".\n"); fprintf(stderr, " -f Framerate to record at.\n"); @@ -509,6 +509,8 @@ static void usage() { fprintf(stderr, "NOTES:\n"); fprintf(stderr, " Send signal SIGINT (Ctrl+C) to gpu-screen-recorder to stop and save the recording (when not using replay mode).\n"); fprintf(stderr, " Send signal SIGUSR1 (killall -SIGUSR1 gpu-screen-recorder) to gpu-screen-recorder to save a replay.\n"); + fprintf(stderr, "EXAMPLES\n"); + fprintf(stderr, " gpu-screen-recorder -w screen -f 60 -a \"$(pactl get-default-sink).monitor\" -o video.mp4\n"); exit(1); } @@ -1115,6 +1117,18 @@ int main(int argc, char **argv) { return 2; } + if(strcmp(window_str, "screen") != 0 && strcmp(window_str, "screen-direct") != 0 && strcmp(window_str, "screen-direct-force") != 0) { + gsr_monitor gmon; + if(!get_monitor_by_name(dpy, window_str, &gmon)) { + fprintf(stderr, "gsr error: display \"%s\" not found, expected one of:\n", window_str); + fprintf(stderr, " \"screen\" (%dx%d+%d+%d)\n", XWidthOfScreen(DefaultScreenOfDisplay(dpy)), XHeightOfScreen(DefaultScreenOfDisplay(dpy)), 0, 0); + fprintf(stderr, " \"screen-direct\" (%dx%d+%d+%d)\n", XWidthOfScreen(DefaultScreenOfDisplay(dpy)), XHeightOfScreen(DefaultScreenOfDisplay(dpy)), 0, 0); + fprintf(stderr, " \"screen-direct-force\" (%dx%d+%d+%d)\n", XWidthOfScreen(DefaultScreenOfDisplay(dpy)), XHeightOfScreen(DefaultScreenOfDisplay(dpy)), 0, 0); + for_each_active_monitor_output(dpy, monitor_output_callback_print, NULL); + return 1; + } + } + const char *capture_target = window_str; bool direct_capture = strcmp(window_str, "screen-direct") == 0; if(direct_capture) { @@ -1124,6 +1138,11 @@ int main(int argc, char **argv) { fprintf(stderr, "Warning: screen-direct has temporary been disabled as it causes stuttering. This is likely a NvFBC bug. Falling back to \"screen\".\n"); } + if(strcmp(window_str, "screen-direct-force") == 0) { + direct_capture = true; + capture_target = "screen"; + } + gsr_capture_nvfbc_params nvfbc_params; nvfbc_params.dpy = dpy; nvfbc_params.display_to_capture = capture_target; @@ -1134,17 +1153,6 @@ int main(int argc, char **argv) { capture = gsr_capture_nvfbc_create(&nvfbc_params); if(!capture) return 1; - - if(strcmp(capture_target, "screen") != 0) { - gsr_monitor gmon; - if(!get_monitor_by_name(dpy, capture_target, &gmon)) { - fprintf(stderr, "gsr error: display \"%s\" not found, expected one of:\n", capture_target); - fprintf(stderr, " \"screen\" (%dx%d+%d+%d)\n", XWidthOfScreen(DefaultScreenOfDisplay(dpy)), XHeightOfScreen(DefaultScreenOfDisplay(dpy)), 0, 0); - fprintf(stderr, " \"screen-direct\" (%dx%d+%d+%d)\n", XWidthOfScreen(DefaultScreenOfDisplay(dpy)), XHeightOfScreen(DefaultScreenOfDisplay(dpy)), 0, 0); - for_each_active_monitor_output(dpy, monitor_output_callback_print, NULL); - return 1; - } - } } else { errno = 0; Window src_window_id = strtol(window_str, nullptr, 0); -- cgit v1.2.3