mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-05-07 23:20:26 +09:00
Fix capture options not available on nvidia x11
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
enum class GsrMode {
|
enum class GsrMode {
|
||||||
@@ -14,6 +15,8 @@ namespace gsr {
|
|||||||
bool exec_program_daemonized(const char **args);
|
bool exec_program_daemonized(const char **args);
|
||||||
// Arguments ending with NULL. |read_fd| can be NULL
|
// Arguments ending with NULL. |read_fd| can be NULL
|
||||||
pid_t exec_program(const char **args, int *read_fd);
|
pid_t exec_program(const char **args, int *read_fd);
|
||||||
|
// Arguments ending with NULL. Returns the exit status of the program or -1 on error
|
||||||
|
int exec_program_get_stdout(const char **args, std::string &result);
|
||||||
// |output_buffer| should be at least PATH_MAX in size
|
// |output_buffer| should be at least PATH_MAX in size
|
||||||
bool read_cmdline_arg0(const char *filepath, char *output_buffer);
|
bool read_cmdline_arg0(const char *filepath, char *output_buffer);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "../include/GsrInfo.hpp"
|
#include "../include/GsrInfo.hpp"
|
||||||
#include "../include/Utils.hpp"
|
#include "../include/Utils.hpp"
|
||||||
|
#include "../include/Process.hpp"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -82,23 +84,19 @@ namespace gsr {
|
|||||||
GsrInfoExitStatus get_gpu_screen_recorder_info(GsrInfo *gsr_info) {
|
GsrInfoExitStatus get_gpu_screen_recorder_info(GsrInfo *gsr_info) {
|
||||||
*gsr_info = GsrInfo{};
|
*gsr_info = GsrInfo{};
|
||||||
|
|
||||||
FILE *f = popen("gpu-screen-recorder --info", "r");
|
std::string stdout_str;
|
||||||
if(!f) {
|
const char *args[] = { "gpu-screen-recorder", "--info", nullptr };
|
||||||
fprintf(stderr, "error: 'gpu-screen-recorder --info' failed\n");
|
const int exit_status = exec_program_get_stdout(args, stdout_str);
|
||||||
return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
|
switch(exit_status) {
|
||||||
|
case 0: break;
|
||||||
|
case 14: return GsrInfoExitStatus::BROKEN_DRIVERS;
|
||||||
|
case 22: return GsrInfoExitStatus::OPENGL_FAILED;
|
||||||
|
case 23: return GsrInfoExitStatus::NO_DRM_CARD;
|
||||||
|
default: return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 --info' output\n");
|
|
||||||
pclose(f);
|
|
||||||
return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
|
|
||||||
}
|
|
||||||
output[bytes_read] = '\0';
|
|
||||||
|
|
||||||
GsrInfoSection section = GsrInfoSection::UNKNOWN;
|
GsrInfoSection section = GsrInfoSection::UNKNOWN;
|
||||||
string_split_char({output, (size_t)bytes_read}, '\n', [&](std::string_view line) {
|
string_split_char(stdout_str, '\n', [&](std::string_view line) {
|
||||||
if(starts_with(line, "section=")) {
|
if(starts_with(line, "section=")) {
|
||||||
const std::string_view section_name = line.substr(8);
|
const std::string_view section_name = line.substr(8);
|
||||||
if(section_name == "system_info")
|
if(section_name == "system_info")
|
||||||
@@ -139,18 +137,7 @@ namespace gsr {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
int status = pclose(f);
|
return GsrInfoExitStatus::OK;
|
||||||
if(WIFEXITED(status)) {
|
|
||||||
switch(WEXITSTATUS(status)) {
|
|
||||||
case 0: return GsrInfoExitStatus::OK;
|
|
||||||
case 14: return GsrInfoExitStatus::BROKEN_DRIVERS;
|
|
||||||
case 22: return GsrInfoExitStatus::OPENGL_FAILED;
|
|
||||||
case 23: return GsrInfoExitStatus::NO_DRM_CARD;
|
|
||||||
default: return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<AudioDevice> parse_audio_device_line(std::string_view line) {
|
static std::optional<AudioDevice> parse_audio_device_line(std::string_view line) {
|
||||||
@@ -166,22 +153,14 @@ namespace gsr {
|
|||||||
std::vector<AudioDevice> get_audio_devices() {
|
std::vector<AudioDevice> get_audio_devices() {
|
||||||
std::vector<AudioDevice> audio_devices;
|
std::vector<AudioDevice> audio_devices;
|
||||||
|
|
||||||
FILE *f = popen("gpu-screen-recorder --list-audio-devices", "r");
|
std::string stdout_str;
|
||||||
if(!f) {
|
const char *args[] = { "gpu-screen-recorder", "--list-audio-devices", nullptr };
|
||||||
|
if(exec_program_get_stdout(args, stdout_str) != 0) {
|
||||||
fprintf(stderr, "error: 'gpu-screen-recorder --list-audio-devices' failed\n");
|
fprintf(stderr, "error: 'gpu-screen-recorder --list-audio-devices' failed\n");
|
||||||
return audio_devices;
|
return audio_devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
char output[16384];
|
string_split_char(stdout_str, '\n', [&](std::string_view line) {
|
||||||
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-audio-devices' output\n");
|
|
||||||
pclose(f);
|
|
||||||
return audio_devices;
|
|
||||||
}
|
|
||||||
output[bytes_read] = '\0';
|
|
||||||
|
|
||||||
string_split_char({output, (size_t)bytes_read}, '\n', [&](std::string_view line) {
|
|
||||||
std::optional<AudioDevice> audio_device = parse_audio_device_line(line);
|
std::optional<AudioDevice> audio_device = parse_audio_device_line(line);
|
||||||
if(audio_device)
|
if(audio_device)
|
||||||
audio_devices.push_back(std::move(audio_device.value()));
|
audio_devices.push_back(std::move(audio_device.value()));
|
||||||
@@ -194,22 +173,14 @@ namespace gsr {
|
|||||||
std::vector<std::string> get_application_audio() {
|
std::vector<std::string> get_application_audio() {
|
||||||
std::vector<std::string> application_audio;
|
std::vector<std::string> application_audio;
|
||||||
|
|
||||||
FILE *f = popen("gpu-screen-recorder --list-application-audio", "r");
|
std::string stdout_str;
|
||||||
if(!f) {
|
const char *args[] = { "gpu-screen-recorder", "--list-application-audio", nullptr };
|
||||||
|
if(exec_program_get_stdout(args, stdout_str) != 0) {
|
||||||
fprintf(stderr, "error: 'gpu-screen-recorder --list-application-audio' failed\n");
|
fprintf(stderr, "error: 'gpu-screen-recorder --list-application-audio' failed\n");
|
||||||
return application_audio;
|
return application_audio;
|
||||||
}
|
}
|
||||||
|
|
||||||
char output[8192];
|
string_split_char(stdout_str, '\n', [&](std::string_view line) {
|
||||||
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");
|
|
||||||
pclose(f);
|
|
||||||
return application_audio;
|
|
||||||
}
|
|
||||||
output[bytes_read] = '\0';
|
|
||||||
|
|
||||||
string_split_char({output, (size_t)bytes_read}, '\n', [&](std::string_view line) {
|
|
||||||
application_audio.emplace_back(line);
|
application_audio.emplace_back(line);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -262,25 +233,14 @@ namespace gsr {
|
|||||||
SupportedCaptureOptions get_supported_capture_options(const GsrInfo &gsr_info) {
|
SupportedCaptureOptions get_supported_capture_options(const GsrInfo &gsr_info) {
|
||||||
SupportedCaptureOptions capture_options;
|
SupportedCaptureOptions capture_options;
|
||||||
|
|
||||||
char command[512];
|
std::string stdout_str;
|
||||||
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));
|
const char *args[] = { "gpu-screen-recorder", "--list-capture-options", gsr_info.gpu_info.card_path.c_str(), gpu_vendor_to_string(gsr_info.gpu_info.vendor), nullptr };
|
||||||
|
if(exec_program_get_stdout(args, stdout_str) != 0) {
|
||||||
FILE *f = popen(command, "r");
|
|
||||||
if(!f) {
|
|
||||||
fprintf(stderr, "error: 'gpu-screen-recorder --list-capture-options' failed\n");
|
fprintf(stderr, "error: 'gpu-screen-recorder --list-capture-options' failed\n");
|
||||||
return capture_options;
|
return capture_options;
|
||||||
}
|
}
|
||||||
|
|
||||||
char output[8192];
|
string_split_char(stdout_str, '\n', [&](std::string_view line) {
|
||||||
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);
|
parse_capture_options_line(capture_options, line);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -92,6 +92,48 @@ namespace gsr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int exec_program_get_stdout(const char **args, std::string &result) {
|
||||||
|
result.clear();
|
||||||
|
int read_fd = -1;
|
||||||
|
pid_t process_id = exec_program(args, &read_fd);
|
||||||
|
if(process_id == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int exit_status = 0;
|
||||||
|
char buffer[8192];
|
||||||
|
for(;;) {
|
||||||
|
ssize_t bytes_read = read(read_fd, buffer, sizeof(buffer));
|
||||||
|
if(bytes_read == 0) {
|
||||||
|
break;
|
||||||
|
} else if(bytes_read == -1) {
|
||||||
|
fprintf(stderr, "Failed to read from pipe to program %s, error: %s\n", args[0], strerror(errno));
|
||||||
|
exit_status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[bytes_read] = '\0';
|
||||||
|
result.append(buffer, bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(exit_status != 0)
|
||||||
|
kill(process_id, SIGKILL);
|
||||||
|
|
||||||
|
int status = 0;
|
||||||
|
if(waitpid(process_id, &status, 0) == -1) {
|
||||||
|
perror("waitpid failed");
|
||||||
|
exit_status = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!WIFEXITED(status))
|
||||||
|
exit_status = -1;
|
||||||
|
|
||||||
|
if(exit_status == 0)
|
||||||
|
exit_status = WEXITSTATUS(status);
|
||||||
|
|
||||||
|
close(read_fd);
|
||||||
|
return exit_status;
|
||||||
|
}
|
||||||
|
|
||||||
bool read_cmdline_arg0(const char *filepath, char *output_buffer) {
|
bool read_cmdline_arg0(const char *filepath, char *output_buffer) {
|
||||||
output_buffer[0] = '\0';
|
output_buffer[0] = '\0';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user