aboutsummaryrefslogtreecommitdiff
path: root/src/GsrInfo.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-12-08 14:32:11 +0100
committerdec05eba <dec05eba@protonmail.com>2024-12-08 14:32:11 +0100
commitf3565fdd77fb480575feec5de252466b093daf86 (patch)
tree1769a3923eda51aabe8a3f8bfa905a4df7a12df4 /src/GsrInfo.cpp
parent6b66eebb6896b768f1b7cd5f37caa01fbf4b7e28 (diff)
Query capture options when opening settings and validate capture options when starting recording
Diffstat (limited to 'src/GsrInfo.cpp')
-rw-r--r--src/GsrInfo.cpp109
1 files changed, 75 insertions, 34 deletions
diff --git a/src/GsrInfo.cpp b/src/GsrInfo.cpp
index 276870b..a55c354 100644
--- a/src/GsrInfo.cpp
+++ b/src/GsrInfo.cpp
@@ -38,6 +38,8 @@ namespace gsr {
gsr_info->gpu_info.vendor = GpuVendor::INTEL;
else if(key_value->value == "nvidia")
gsr_info->gpu_info.vendor = GpuVendor::NVIDIA;
+ } else if(key_value->key == "card_path") {
+ gsr_info->gpu_info.card_path = key_value->value;
}
}
@@ -64,38 +66,6 @@ namespace gsr {
gsr_info->supported_video_codecs.vp9 = true;
}
- static std::optional<GsrMonitor> capture_option_line_to_monitor(std::string_view line) {
- std::optional<GsrMonitor> monitor;
- const std::optional<KeyValue> key_value = parse_key_value(line);
- if(!key_value)
- return monitor;
-
- char value_buffer[256];
- snprintf(value_buffer, sizeof(value_buffer), "%.*s", (int)key_value->value.size(), key_value->value.data());
-
- monitor = GsrMonitor{std::string(key_value->key), mgl::vec2i{0, 0}};
- if(sscanf(value_buffer, "%dx%d", &monitor->size.x, &monitor->size.y) != 2)
- monitor->size = {0, 0};
-
- return monitor;
- }
-
- static void parse_capture_options_line(GsrInfo *gsr_info, std::string_view line) {
- if(line == "window")
- gsr_info->supported_capture_options.window = true;
- else if(line == "focused")
- gsr_info->supported_capture_options.focused = true;
- else if(line == "screen")
- gsr_info->supported_capture_options.screen = true;
- else if(line == "portal")
- gsr_info->supported_capture_options.portal = true;
- else {
- std::optional<GsrMonitor> monitor = capture_option_line_to_monitor(line);
- if(monitor)
- gsr_info->supported_capture_options.monitors.push_back(std::move(monitor.value()));
- }
- }
-
enum class GsrInfoSection {
UNKNOWN,
SYSTEM_INFO,
@@ -161,7 +131,7 @@ namespace gsr {
break;
}
case GsrInfoSection::CAPTURE_OPTIONS: {
- parse_capture_options_line(gsr_info, line);
+ // Intentionally ignore, get capture options with get_supported_capture_options instead
break;
}
}
@@ -230,7 +200,7 @@ namespace gsr {
return application_audio;
}
- char output[16384];
+ char output[8192];
ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f);
if(bytes_read < 0 || ferror(f)) {
fprintf(stderr, "error: failed to read 'gpu-screen-recorder --list-application-audio' output\n");
@@ -246,4 +216,75 @@ namespace gsr {
return application_audio;
}
+
+ static std::optional<GsrMonitor> capture_option_line_to_monitor(std::string_view line) {
+ std::optional<GsrMonitor> monitor;
+ const std::optional<KeyValue> key_value = parse_key_value(line);
+ if(!key_value)
+ return monitor;
+
+ char value_buffer[256];
+ snprintf(value_buffer, sizeof(value_buffer), "%.*s", (int)key_value->value.size(), key_value->value.data());
+
+ monitor = GsrMonitor{std::string(key_value->key), mgl::vec2i{0, 0}};
+ if(sscanf(value_buffer, "%dx%d", &monitor->size.x, &monitor->size.y) != 2)
+ monitor->size = {0, 0};
+
+ return monitor;
+ }
+
+ static void parse_capture_options_line(SupportedCaptureOptions &capture_options, std::string_view line) {
+ if(line == "window")
+ capture_options.window = true;
+ else if(line == "focused")
+ capture_options.focused = true;
+ else if(line == "screen")
+ capture_options.screen = true;
+ else if(line == "portal")
+ capture_options.portal = true;
+ else {
+ std::optional<GsrMonitor> monitor = capture_option_line_to_monitor(line);
+ if(monitor)
+ capture_options.monitors.push_back(std::move(monitor.value()));
+ }
+ }
+
+ static const char* gpu_vendor_to_string(GpuVendor vendor) {
+ switch(vendor) {
+ case GpuVendor::UNKNOWN: return "unknown";
+ case GpuVendor::AMD: return "amd";
+ case GpuVendor::INTEL: return "intel";
+ case GpuVendor::NVIDIA: return "nvidia";
+ }
+ return "unknown";
+ }
+
+ SupportedCaptureOptions get_supported_capture_options(const GsrInfo &gsr_info) {
+ SupportedCaptureOptions capture_options;
+
+ char command[512];
+ snprintf(command, sizeof(command), "gpu-screen-recorder --list-capture-options %s %s", gsr_info.gpu_info.card_path.c_str(), gpu_vendor_to_string(gsr_info.gpu_info.vendor));
+
+ FILE *f = popen(command, "r");
+ if(!f) {
+ fprintf(stderr, "error: 'gpu-screen-recorder --list-capture-options' failed\n");
+ return capture_options;
+ }
+
+ char output[8192];
+ ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f);
+ if(bytes_read < 0 || ferror(f)) {
+ fprintf(stderr, "error: failed to read 'gpu-screen-recorder --list-capture-options' output\n");
+ pclose(f);
+ return capture_options;
+ }
+ output[bytes_read] = '\0';
+
+ string_split_char({output, (size_t)bytes_read}, '\n', [&](std::string_view line) {
+ parse_capture_options_line(capture_options, line);
+ return true;
+ });
+
+ return capture_options;
+ }
}