Add -low-power option to allow prevent the gpu to go into a high power mode on amd, useful for replay running 24/7

This commit is contained in:
dec05eba
2026-01-15 20:20:01 +01:00
parent 8af761f9bd
commit f4d061eee7
5 changed files with 32 additions and 9 deletions

4
TODO
View File

@@ -395,3 +395,7 @@ Make multiple capture sources work properly in regards to size. The size of the
Support hdr camera capture. Support hdr camera capture.
Return the max resolution of each codec in --info to display an error in the UI before capture starts. Right now its fine since the UI will report bad resolution after capture starts and fails but it doesn't say what the max resolution is. Return the max resolution of each codec in --info to display an error in the UI before capture starts. Right now its fine since the UI will report bad resolution after capture starts and fails but it doesn't say what the max resolution is.
Should -low-power option also use vaapi/vulkan low power, if available?
Should capture option x=bla;y=bla be scaled by -s (output resolution scale)? width and height is.

View File

@@ -358,6 +358,20 @@ OpenGL debug output (default: no).
.TP .TP
.BI \-v " yes|no" .BI \-v " yes|no"
Print FPS and damage info (default: yes). Print FPS and damage info (default: yes).
.TP
.BI \-low-power " yes|no"
Run in low power mode. This currently has only an affect on AMD (as it's only an issue on AMD) and allows the GPU to go into a lower power mode when recording (default: no).
.br
Setting this to
.B yes
might not always be ideal because of AMD driver issues where after playing a video with VAAPI on the system the video encoding performance
also reduces, which affects GPU Screen Recorder.
.br
It's recommended to also use the option
.B -fm content
when this is set to
.B yes
to only encode frames when the screen content updates to lower GPU and video encoding usage when the system is idle.
.SS Output Options .SS Output Options
.TP .TP
.BI \-o " output" .BI \-o " output"

View File

@@ -8,7 +8,7 @@
typedef struct gsr_egl gsr_egl; typedef struct gsr_egl gsr_egl;
#define NUM_ARGS 35 #define NUM_ARGS 36
typedef enum { typedef enum {
GSR_CAPTURE_SOURCE_TYPE_WINDOW, GSR_CAPTURE_SOURCE_TYPE_WINDOW,
@@ -91,6 +91,7 @@ typedef struct {
bool verbose; bool verbose;
bool gl_debug; bool gl_debug;
bool fallback_cpu_encoding; bool fallback_cpu_encoding;
bool low_power;
bool record_cursor; bool record_cursor;
bool date_folders; bool date_folders;
bool restore_portal_session; bool restore_portal_session;

View File

@@ -197,7 +197,7 @@ static void usage_header(void) {
"[-bm auto|qp|vbr|cbr] [-cr limited|full] [-tune performance|quality] [-df yes|no] [-sc <script_path>] [-p <plugin_path>] " "[-bm auto|qp|vbr|cbr] [-cr limited|full] [-tune performance|quality] [-df yes|no] [-sc <script_path>] [-p <plugin_path>] "
"[-cursor yes|no] [-keyint <value>] [-restore-portal-session yes|no] [-portal-session-token-filepath filepath] [-encoder gpu|cpu] " "[-cursor yes|no] [-keyint <value>] [-restore-portal-session yes|no] [-portal-session-token-filepath filepath] [-encoder gpu|cpu] "
"[-fallback-cpu-encoding yes|no] [-o <output_file>] [-ro <output_directory>] [-ffmpeg-opts <options>] [--list-capture-options [card_path]] " "[-fallback-cpu-encoding yes|no] [-o <output_file>] [-ro <output_directory>] [-ffmpeg-opts <options>] [--list-capture-options [card_path]] "
"[--list-audio-devices] [--list-application-audio] [--list-v4l2-devices] [-v yes|no] [-gl-debug yes|no] [--version] [-h|--help]\n", program_name); "[--list-audio-devices] [--list-application-audio] [--list-v4l2-devices] [-low-power yes|no] [-v yes|no] [-gl-debug yes|no] [--version] [-h|--help]\n", program_name);
fflush(stdout); fflush(stdout);
} }
@@ -256,6 +256,7 @@ static bool args_parser_set_values(args_parser *self) {
self->restart_replay_on_save = args_get_boolean_by_key(self->args, NUM_ARGS, "-restart-replay-on-save", false); self->restart_replay_on_save = args_get_boolean_by_key(self->args, NUM_ARGS, "-restart-replay-on-save", false);
self->overclock = args_get_boolean_by_key(self->args, NUM_ARGS, "-oc", false); self->overclock = args_get_boolean_by_key(self->args, NUM_ARGS, "-oc", false);
self->fallback_cpu_encoding = args_get_boolean_by_key(self->args, NUM_ARGS, "-fallback-cpu-encoding", false); self->fallback_cpu_encoding = args_get_boolean_by_key(self->args, NUM_ARGS, "-fallback-cpu-encoding", false);
self->low_power = args_get_boolean_by_key(self->args, NUM_ARGS, "-low-power", false);
self->audio_bitrate = args_get_i64_by_key(self->args, NUM_ARGS, "-ab", 0); self->audio_bitrate = args_get_i64_by_key(self->args, NUM_ARGS, "-ab", 0);
self->audio_bitrate *= 1000LL; self->audio_bitrate *= 1000LL;
@@ -536,6 +537,7 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
self->args[arg_index++] = (Arg){ .key = "-ffmpeg-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING }; self->args[arg_index++] = (Arg){ .key = "-ffmpeg-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING };
self->args[arg_index++] = (Arg){ .key = "-ffmpeg-video-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING }; self->args[arg_index++] = (Arg){ .key = "-ffmpeg-video-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING };
self->args[arg_index++] = (Arg){ .key = "-ffmpeg-audio-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING }; self->args[arg_index++] = (Arg){ .key = "-ffmpeg-audio-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING };
self->args[arg_index++] = (Arg){ .key = "-low-power", .optional = true, .list = false, .type = ARG_TYPE_BOOLEAN };
assert(arg_index == NUM_ARGS); assert(arg_index == NUM_ARGS);
for(int i = 1; i < argc; i += 2) { for(int i = 1; i < argc; i += 2) {

View File

@@ -3652,13 +3652,6 @@ int main(int argc, char **argv) {
// If this is set to 1 then cuGraphicsGLRegisterImage will fail for egl context with error: invalid OpenGL or DirectX context, // If this is set to 1 then cuGraphicsGLRegisterImage will fail for egl context with error: invalid OpenGL or DirectX context,
// so we overwrite it // so we overwrite it
setenv("__GL_THREADED_OPTIMIZATIONS", "0", true); setenv("__GL_THREADED_OPTIMIZATIONS", "0", true);
// Forces low latency encoding mode. Use this environment variable until vaapi supports setting this as a parameter.
// The downside of this is that it always uses maximum power, which is not ideal for replay mode that runs on system startup.
// This option was added in mesa 24.1.4, released in july 17, 2024.
// TODO: Add an option to enable/disable this?
// Seems like the performance issue is not in encoding, but rendering the frame.
// Some frames end up taking 10 times longer. Seems to be an issue with amd gpu power management when letting the application sleep on the cpu side?
setenv("AMD_DEBUG", "lowlatencyenc", true);
// Some people set this to nvidia (for nvdec) or vdpau (for nvidia vdpau), which breaks gpu screen recorder since // Some people set this to nvidia (for nvdec) or vdpau (for nvidia vdpau), which breaks gpu screen recorder since
// nvidia doesn't support vaapi and nvidia-vaapi-driver doesn't support encoding yet. // nvidia doesn't support vaapi and nvidia-vaapi-driver doesn't support encoding yet.
// Let vaapi find the right vaapi driver instead of forcing a specific one. // Let vaapi find the right vaapi driver instead of forcing a specific one.
@@ -3685,6 +3678,15 @@ int main(int argc, char **argv) {
if(!args_parser_parse(&arg_parser, argc, argv, &arg_handlers, NULL)) if(!args_parser_parse(&arg_parser, argc, argv, &arg_handlers, NULL))
_exit(1); _exit(1);
if(!arg_parser.low_power) {
// Forces low latency encoding mode. Use this environment variable until vaapi supports setting this as a parameter.
// The downside of this is that it always uses maximum power, which is not ideal for replay mode that runs on system startup.
// This option was added in mesa 24.1.4, released in july 17, 2024.
// Seems like the performance issue is not in encoding, but rendering the frame.
// Some frames end up taking 10 times longer. Seems to be an issue with amd gpu power management when letting the application sleep on the cpu side?
setenv("AMD_DEBUG", "lowlatencyenc", true);
}
std::vector<CaptureSource> capture_sources = parse_capture_source_arg(arg_parser.capture_source, arg_parser); std::vector<CaptureSource> capture_sources = parse_capture_source_arg(arg_parser.capture_source, arg_parser);
if(capture_sources.empty()) { 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"); fprintf(stderr, "gsr error: option -w can't be empty. You need to capture video from at least one source\n");