mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-03-31 09:07:13 +09:00
Add card path to --info, add card path and vendor to --list-capture-options if known to speed up the command
This commit is contained in:
@@ -41,9 +41,9 @@ bool generate_random_characters_standard_alphabet(char *buffer, int buffer_size)
|
|||||||
|
|
||||||
typedef void (*active_monitor_callback)(const gsr_monitor *monitor, void *userdata);
|
typedef void (*active_monitor_callback)(const gsr_monitor *monitor, void *userdata);
|
||||||
void for_each_active_monitor_output_x11_not_cached(Display *display, active_monitor_callback callback, void *userdata);
|
void for_each_active_monitor_output_x11_not_cached(Display *display, active_monitor_callback callback, void *userdata);
|
||||||
void for_each_active_monitor_output(const gsr_egl *egl, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata);
|
void for_each_active_monitor_output(const gsr_window *window, const char *card_path, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata);
|
||||||
bool get_monitor_by_name(const gsr_egl *egl, gsr_connection_type connection_type, const char *name, gsr_monitor *monitor);
|
bool get_monitor_by_name(const gsr_egl *egl, gsr_connection_type connection_type, const char *name, gsr_monitor *monitor);
|
||||||
gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl, const gsr_monitor *monitor);
|
gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_window *window, const gsr_monitor *monitor);
|
||||||
|
|
||||||
int get_connector_type_by_name(const char *name);
|
int get_connector_type_by_name(const char *name);
|
||||||
drm_connector_type_count* drm_connector_types_get_index(drm_connector_type_count *type_counts, int *num_type_counts, int connector_type);
|
drm_connector_type_count* drm_connector_types_get_index(drm_connector_type_count *type_counts, int *num_type_counts, int connector_type);
|
||||||
@@ -52,6 +52,7 @@ uint32_t monitor_identifier_from_type_and_count(int monitor_type_index, int moni
|
|||||||
bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info);
|
bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info);
|
||||||
bool gl_driver_version_greater_than(const gsr_egl *egl, int major, int minor, int patch);
|
bool gl_driver_version_greater_than(const gsr_egl *egl, int major, int minor, int patch);
|
||||||
|
|
||||||
|
bool try_card_has_valid_plane(const char *card_path);
|
||||||
/* |output| should be at least 128 bytes in size */
|
/* |output| should be at least 128 bytes in size */
|
||||||
bool gsr_get_valid_card_path(gsr_egl *egl, char *output, bool is_monitor_capture);
|
bool gsr_get_valid_card_path(gsr_egl *egl, char *output, bool is_monitor_capture);
|
||||||
/* |render_path| should be at least 128 bytes in size */
|
/* |render_path| should be at least 128 bytes in size */
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_c
|
|||||||
self->params.display_to_capture, strlen(self->params.display_to_capture),
|
self->params.display_to_capture, strlen(self->params.display_to_capture),
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
for_each_active_monitor_output(self->params.egl, connection_type, monitor_callback, &monitor_callback_userdata);
|
for_each_active_monitor_output(self->params.egl->window, self->params.egl->card_path, connection_type, monitor_callback, &monitor_callback_userdata);
|
||||||
|
|
||||||
if(!get_monitor_by_name(self->params.egl, connection_type, self->params.display_to_capture, &monitor)) {
|
if(!get_monitor_by_name(self->params.egl, connection_type, self->params.display_to_capture, &monitor)) {
|
||||||
fprintf(stderr, "gsr error: gsr_capture_kms_start: failed to find monitor by name \"%s\"\n", self->params.display_to_capture);
|
fprintf(stderr, "gsr error: gsr_capture_kms_start: failed to find monitor by name \"%s\"\n", self->params.display_to_capture);
|
||||||
@@ -205,7 +205,7 @@ static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
monitor.name = self->params.display_to_capture;
|
monitor.name = self->params.display_to_capture;
|
||||||
self->monitor_rotation = drm_monitor_get_display_server_rotation(self->params.egl, &monitor);
|
self->monitor_rotation = drm_monitor_get_display_server_rotation(self->params.egl->window, &monitor);
|
||||||
|
|
||||||
self->capture_pos = monitor.pos;
|
self->capture_pos = monitor.pos;
|
||||||
/* Monitor size is already rotated on x11 when the monitor is rotated, no need to apply it ourselves */
|
/* Monitor size is already rotated on x11 when the monitor is rotated, no need to apply it ourselves */
|
||||||
|
|||||||
123
src/main.cpp
123
src/main.cpp
@@ -1069,7 +1069,7 @@ static void open_video_hardware(AVCodecContext *codec_context, VideoQuality vide
|
|||||||
static void usage_header() {
|
static void usage_header() {
|
||||||
const bool inside_flatpak = getenv("FLATPAK_ID") != NULL;
|
const bool inside_flatpak = getenv("FLATPAK_ID") != NULL;
|
||||||
const char *program_name = inside_flatpak ? "flatpak run --command=gpu-screen-recorder com.dec05eba.gpu_screen_recorder" : "gpu-screen-recorder";
|
const char *program_name = inside_flatpak ? "flatpak run --command=gpu-screen-recorder com.dec05eba.gpu_screen_recorder" : "gpu-screen-recorder";
|
||||||
printf("usage: %s -w <window_id|monitor|focused|portal> [-c <container_format>] [-s WxH] -f <fps> [-a <audio_input>] [-q <quality>] [-r <replay_buffer_size_sec>] [-k h264|hevc|av1|vp8|vp9|hevc_hdr|av1_hdr|hevc_10bit|av1_10bit] [-ac aac|opus|flac] [-ab <bitrate>] [-oc yes|no] [-fm cfr|vfr|content] [-bm auto|qp|vbr|cbr] [-cr limited|full] [-df yes|no] [-sc <script_path>] [-cursor yes|no] [-keyint <value>] [-restore-portal-session yes|no] [-portal-session-token-filepath filepath] [-encoder gpu|cpu] [-o <output_file>] [-v yes|no] [--version] [-h|--help]\n", program_name);
|
printf("usage: %s -w <window_id|monitor|focused|portal> [-c <container_format>] [-s WxH] -f <fps> [-a <audio_input>] [-q <quality>] [-r <replay_buffer_size_sec>] [-k h264|hevc|av1|vp8|vp9|hevc_hdr|av1_hdr|hevc_10bit|av1_10bit] [-ac aac|opus|flac] [-ab <bitrate>] [-oc yes|no] [-fm cfr|vfr|content] [-bm auto|qp|vbr|cbr] [-cr limited|full] [-df yes|no] [-sc <script_path>] [-cursor yes|no] [-keyint <value>] [-restore-portal-session yes|no] [-portal-session-token-filepath filepath] [-encoder gpu|cpu] [-o <output_file>] [--list-capture-options [card_path] [vendor]] [--list-audio-devices] [--list-application-audio] [-v yes|no] [--version] [-h|--help]\n", program_name);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1204,6 +1204,7 @@ static void usage_full() {
|
|||||||
printf(" window\n");
|
printf(" window\n");
|
||||||
printf(" DP-1|1920x1080\n");
|
printf(" DP-1|1920x1080\n");
|
||||||
printf(" The <option> and <monitor_name> is the name that can be passed to GPU Screen Recorder with the -w option.\n");
|
printf(" The <option> and <monitor_name> is the name that can be passed to GPU Screen Recorder with the -w option.\n");
|
||||||
|
printf(" --list-capture-options optionally accepts a card path (\"/dev/dri/cardN\") and vendor (\"amd\", \"intel\" or \"nvidia\") which can improve the performance of running this command.\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" --list-audio-devices\n");
|
printf(" --list-audio-devices\n");
|
||||||
printf(" List audio devices. Lists audio devices in the following format (prints them to stdout and exits):\n");
|
printf(" List audio devices. Lists audio devices in the following format (prints them to stdout and exits):\n");
|
||||||
@@ -1939,6 +1940,7 @@ static void list_gpu_info(gsr_egl *egl) {
|
|||||||
printf("vendor|nvidia\n");
|
printf("vendor|nvidia\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
printf("card_path|%s\n", egl->card_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const AVCodec* get_ffmpeg_video_codec(VideoCodec video_codec, gsr_gpu_vendor vendor) {
|
static const AVCodec* get_ffmpeg_video_codec(VideoCodec video_codec, gsr_gpu_vendor vendor) {
|
||||||
@@ -2037,19 +2039,19 @@ static void list_supported_video_codecs(gsr_egl *egl, bool wayland) {
|
|||||||
// puts("hevc_vulkan"); // TODO: hdr, 10 bit
|
// puts("hevc_vulkan"); // TODO: hdr, 10 bit
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool monitor_capture_use_drm(gsr_egl *egl) {
|
static bool monitor_capture_use_drm(const gsr_window *window, gsr_gpu_vendor vendor) {
|
||||||
return gsr_window_get_display_server(egl->window) == GSR_DISPLAY_SERVER_WAYLAND || egl->gpu_info.vendor != GSR_GPU_VENDOR_NVIDIA;
|
return gsr_window_get_display_server(window) == GSR_DISPLAY_SERVER_WAYLAND || vendor != GSR_GPU_VENDOR_NVIDIA;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gsr_egl *egl;
|
const gsr_window *window;
|
||||||
} capture_options_callback;
|
} capture_options_callback;
|
||||||
|
|
||||||
static void output_monitor_info(const gsr_monitor *monitor, void *userdata) {
|
static void output_monitor_info(const gsr_monitor *monitor, void *userdata) {
|
||||||
const capture_options_callback *options = (capture_options_callback*)userdata;
|
const capture_options_callback *options = (capture_options_callback*)userdata;
|
||||||
if(gsr_window_get_display_server(options->egl->window) == GSR_DISPLAY_SERVER_WAYLAND) {
|
if(gsr_window_get_display_server(options->window) == GSR_DISPLAY_SERVER_WAYLAND) {
|
||||||
vec2i monitor_size = monitor->size;
|
vec2i monitor_size = monitor->size;
|
||||||
const gsr_monitor_rotation rot = drm_monitor_get_display_server_rotation(options->egl, monitor);
|
const gsr_monitor_rotation rot = drm_monitor_get_display_server_rotation(options->window, monitor);
|
||||||
if(rot == GSR_MONITOR_ROT_90 || rot == GSR_MONITOR_ROT_270)
|
if(rot == GSR_MONITOR_ROT_90 || rot == GSR_MONITOR_ROT_270)
|
||||||
std::swap(monitor_size.x, monitor_size.y);
|
std::swap(monitor_size.x, monitor_size.y);
|
||||||
printf("%.*s|%dx%d\n", monitor->name_len, monitor->name, monitor_size.x, monitor_size.y);
|
printf("%.*s|%dx%d\n", monitor->name_len, monitor->name, monitor_size.x, monitor_size.y);
|
||||||
@@ -2058,8 +2060,8 @@ static void output_monitor_info(const gsr_monitor *monitor, void *userdata) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_supported_capture_options(gsr_egl *egl, bool list_monitors) {
|
static void list_supported_capture_options(const gsr_window *window, const char *card_path, gsr_gpu_vendor vendor, bool list_monitors) {
|
||||||
const bool wayland = gsr_window_get_display_server(egl->window) == GSR_DISPLAY_SERVER_WAYLAND;
|
const bool wayland = gsr_window_get_display_server(window) == GSR_DISPLAY_SERVER_WAYLAND;
|
||||||
if(!wayland) {
|
if(!wayland) {
|
||||||
puts("window");
|
puts("window");
|
||||||
puts("focused");
|
puts("focused");
|
||||||
@@ -2067,14 +2069,14 @@ static void list_supported_capture_options(gsr_egl *egl, bool list_monitors) {
|
|||||||
|
|
||||||
if(list_monitors) {
|
if(list_monitors) {
|
||||||
capture_options_callback options;
|
capture_options_callback options;
|
||||||
options.egl = egl;
|
options.window = window;
|
||||||
if(monitor_capture_use_drm(egl)) {
|
if(monitor_capture_use_drm(window, vendor)) {
|
||||||
const bool is_x11 = gsr_window_get_display_server(egl->window) == GSR_DISPLAY_SERVER_X11;
|
const bool is_x11 = gsr_window_get_display_server(window) == GSR_DISPLAY_SERVER_X11;
|
||||||
const gsr_connection_type connection_type = is_x11 ? GSR_CONNECTION_X11 : GSR_CONNECTION_DRM;
|
const gsr_connection_type connection_type = is_x11 ? GSR_CONNECTION_X11 : GSR_CONNECTION_DRM;
|
||||||
for_each_active_monitor_output(egl, connection_type, output_monitor_info, &options);
|
for_each_active_monitor_output(window, card_path, connection_type, output_monitor_info, &options);
|
||||||
} else {
|
} else {
|
||||||
puts("screen"); // All monitors in one, only available on Nvidia X11
|
puts("screen"); // All monitors in one, only available on Nvidia X11
|
||||||
for_each_active_monitor_output(egl, GSR_CONNECTION_X11, output_monitor_info, &options);
|
for_each_active_monitor_output(window, card_path, GSR_CONNECTION_X11, output_monitor_info, &options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2132,7 +2134,7 @@ static void info_command() {
|
|||||||
|
|
||||||
bool list_monitors = true;
|
bool list_monitors = true;
|
||||||
egl.card_path[0] = '\0';
|
egl.card_path[0] = '\0';
|
||||||
if(monitor_capture_use_drm(&egl)) {
|
if(monitor_capture_use_drm(window, egl.gpu_info.vendor)) {
|
||||||
// TODO: Allow specifying another card, and in other places
|
// TODO: Allow specifying another card, and in other places
|
||||||
if(!gsr_get_valid_card_path(&egl, egl.card_path, true)) {
|
if(!gsr_get_valid_card_path(&egl, egl.card_path, true)) {
|
||||||
fprintf(stderr, "Error: no /dev/dri/cardX device found. Make sure that you have at least one monitor connected\n");
|
fprintf(stderr, "Error: no /dev/dri/cardX device found. Make sure that you have at least one monitor connected\n");
|
||||||
@@ -2153,12 +2155,13 @@ static void info_command() {
|
|||||||
puts("section=video_codecs");
|
puts("section=video_codecs");
|
||||||
list_supported_video_codecs(&egl, wayland);
|
list_supported_video_codecs(&egl, wayland);
|
||||||
puts("section=capture_options");
|
puts("section=capture_options");
|
||||||
list_supported_capture_options(&egl, list_monitors);
|
list_supported_capture_options(window, egl.card_path, egl.gpu_info.vendor, list_monitors);
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
// Not needed as this will just slow down shutdown
|
// Not needed as this will just slow down shutdown
|
||||||
//gsr_egl_unload(&egl);
|
//gsr_egl_unload(&egl);
|
||||||
|
//gsr_window_destroy(&window);
|
||||||
//if(dpy)
|
//if(dpy)
|
||||||
// XCloseDisplay(dpy);
|
// XCloseDisplay(dpy);
|
||||||
|
|
||||||
@@ -2202,7 +2205,8 @@ static void list_application_audio_command() {
|
|||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_capture_options_command() {
|
// |card_path| can be NULL. If not NULL then |vendor| has to be valid
|
||||||
|
static void list_capture_options_command(const char *card_path, gsr_gpu_vendor vendor) {
|
||||||
bool wayland = false;
|
bool wayland = false;
|
||||||
Display *dpy = XOpenDisplay(nullptr);
|
Display *dpy = XOpenDisplay(nullptr);
|
||||||
if (!dpy) {
|
if (!dpy) {
|
||||||
@@ -2230,35 +2234,53 @@ static void list_capture_options_command() {
|
|||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
gsr_egl egl;
|
if(card_path) {
|
||||||
if(!gsr_egl_load(&egl, window, false)) {
|
list_supported_capture_options(window, card_path, vendor, true);
|
||||||
fprintf(stderr, "gsr error: failed to load opengl\n");
|
} else {
|
||||||
_exit(1);
|
gsr_egl egl;
|
||||||
}
|
if(!gsr_egl_load(&egl, window, false)) {
|
||||||
|
fprintf(stderr, "gsr error: failed to load opengl\n");
|
||||||
bool list_monitors = true;
|
_exit(1);
|
||||||
egl.card_path[0] = '\0';
|
|
||||||
if(monitor_capture_use_drm(&egl)) {
|
|
||||||
// TODO: Allow specifying another card, and in other places
|
|
||||||
if(!gsr_get_valid_card_path(&egl, egl.card_path, true)) {
|
|
||||||
fprintf(stderr, "Error: no /dev/dri/cardX device found. Make sure that you have at least one monitor connected\n");
|
|
||||||
list_monitors = false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
av_log_set_level(AV_LOG_FATAL);
|
bool list_monitors = true;
|
||||||
list_supported_capture_options(&egl, list_monitors);
|
egl.card_path[0] = '\0';
|
||||||
|
if(monitor_capture_use_drm(window, egl.gpu_info.vendor)) {
|
||||||
|
// TODO: Allow specifying another card, and in other places
|
||||||
|
if(!gsr_get_valid_card_path(&egl, egl.card_path, true)) {
|
||||||
|
fprintf(stderr, "Error: no /dev/dri/cardX device found. Make sure that you have at least one monitor connected\n");
|
||||||
|
list_monitors = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list_supported_capture_options(window, egl.card_path, egl.gpu_info.vendor, list_monitors);
|
||||||
|
}
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
// Not needed as this will just slow down shutdown
|
// Not needed as this will just slow down shutdown
|
||||||
//gsr_egl_unload(&egl);
|
//gsr_egl_unload(&egl);
|
||||||
|
//gsr_window_destroy(&window);
|
||||||
//if(dpy)
|
//if(dpy)
|
||||||
// XCloseDisplay(dpy);
|
// XCloseDisplay(dpy);
|
||||||
|
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool gpu_vendor_from_string(const char *vendor_str, gsr_gpu_vendor *vendor) {
|
||||||
|
if(strcmp(vendor_str, "amd") == 0) {
|
||||||
|
*vendor = GSR_GPU_VENDOR_AMD;
|
||||||
|
return true;
|
||||||
|
} else if(strcmp(vendor_str, "intel") == 0) {
|
||||||
|
*vendor = GSR_GPU_VENDOR_INTEL;
|
||||||
|
return true;
|
||||||
|
} else if(strcmp(vendor_str, "nvidia") == 0) {
|
||||||
|
*vendor = GSR_GPU_VENDOR_NVIDIA;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gsr_capture* create_capture_impl(std::string &window_str, vec2i output_resolution, bool wayland, gsr_egl *egl, int fps, VideoCodec video_codec, gsr_color_range color_range,
|
static gsr_capture* create_capture_impl(std::string &window_str, vec2i output_resolution, bool wayland, gsr_egl *egl, int fps, VideoCodec video_codec, gsr_color_range color_range,
|
||||||
bool record_cursor, bool use_software_video_encoder, bool restore_portal_session, const char *portal_session_token_filepath,
|
bool record_cursor, bool use_software_video_encoder, bool restore_portal_session, const char *portal_session_token_filepath,
|
||||||
gsr_color_depth color_depth)
|
gsr_color_depth color_depth)
|
||||||
@@ -2303,14 +2325,14 @@ static gsr_capture* create_capture_impl(std::string &window_str, vec2i output_re
|
|||||||
_exit(2);
|
_exit(2);
|
||||||
#endif
|
#endif
|
||||||
} else if(contains_non_hex_number(window_str.c_str())) {
|
} else if(contains_non_hex_number(window_str.c_str())) {
|
||||||
if(monitor_capture_use_drm(egl)) {
|
if(monitor_capture_use_drm(egl->window, egl->gpu_info.vendor)) {
|
||||||
const bool is_x11 = gsr_window_get_display_server(egl->window) == GSR_DISPLAY_SERVER_X11;
|
const bool is_x11 = gsr_window_get_display_server(egl->window) == GSR_DISPLAY_SERVER_X11;
|
||||||
const gsr_connection_type connection_type = is_x11 ? GSR_CONNECTION_X11 : GSR_CONNECTION_DRM;
|
const gsr_connection_type connection_type = is_x11 ? GSR_CONNECTION_X11 : GSR_CONNECTION_DRM;
|
||||||
|
|
||||||
if(strcmp(window_str.c_str(), "screen") == 0) {
|
if(strcmp(window_str.c_str(), "screen") == 0) {
|
||||||
FirstOutputCallback first_output;
|
FirstOutputCallback first_output;
|
||||||
first_output.output_name = NULL;
|
first_output.output_name = NULL;
|
||||||
for_each_active_monitor_output(egl, connection_type, get_first_output, &first_output);
|
for_each_active_monitor_output(egl->window, egl->card_path, connection_type, get_first_output, &first_output);
|
||||||
|
|
||||||
if(first_output.output_name) {
|
if(first_output.output_name) {
|
||||||
window_str = first_output.output_name;
|
window_str = first_output.output_name;
|
||||||
@@ -2323,7 +2345,7 @@ static gsr_capture* create_capture_impl(std::string &window_str, vec2i output_re
|
|||||||
if(!get_monitor_by_name(egl, connection_type, window_str.c_str(), &gmon)) {
|
if(!get_monitor_by_name(egl, connection_type, window_str.c_str(), &gmon)) {
|
||||||
fprintf(stderr, "gsr error: display \"%s\" not found, expected one of:\n", window_str.c_str());
|
fprintf(stderr, "gsr error: display \"%s\" not found, expected one of:\n", window_str.c_str());
|
||||||
fprintf(stderr, " \"screen\"\n");
|
fprintf(stderr, " \"screen\"\n");
|
||||||
for_each_active_monitor_output(egl, connection_type, monitor_output_callback_print, NULL);
|
for_each_active_monitor_output(egl->window, egl->card_path, connection_type, monitor_output_callback_print, NULL);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2338,7 +2360,7 @@ static gsr_capture* create_capture_impl(std::string &window_str, vec2i output_re
|
|||||||
fprintf(stderr, " \"screen\" (%dx%d+%d+%d)\n", screens_width, screens_height, 0, 0);
|
fprintf(stderr, " \"screen\" (%dx%d+%d+%d)\n", screens_width, screens_height, 0, 0);
|
||||||
fprintf(stderr, " \"screen-direct\" (%dx%d+%d+%d)\n", screens_width, screens_height, 0, 0);
|
fprintf(stderr, " \"screen-direct\" (%dx%d+%d+%d)\n", screens_width, screens_height, 0, 0);
|
||||||
fprintf(stderr, " \"screen-direct-force\" (%dx%d+%d+%d)\n", screens_width, screens_height, 0, 0);
|
fprintf(stderr, " \"screen-direct-force\" (%dx%d+%d+%d)\n", screens_width, screens_height, 0, 0);
|
||||||
for_each_active_monitor_output(egl, GSR_CONNECTION_X11, monitor_output_callback_print, NULL);
|
for_each_active_monitor_output(egl->window, egl->card_path, GSR_CONNECTION_X11, monitor_output_callback_print, NULL);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3015,9 +3037,30 @@ int main(int argc, char **argv) {
|
|||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(argc == 2 && strcmp(argv[1], "--list-capture-options") == 0) {
|
if(strcmp(argv[1], "--list-capture-options") == 0) {
|
||||||
list_capture_options_command();
|
if(argc == 2) {
|
||||||
_exit(0);
|
list_capture_options_command(nullptr, GSR_GPU_VENDOR_AMD);
|
||||||
|
_exit(0);
|
||||||
|
} else if(argc == 4) {
|
||||||
|
const char *card_path = argv[2];
|
||||||
|
if(!try_card_has_valid_plane(card_path)) {
|
||||||
|
fprintf(stderr, "Error: \"%s\" is not a valid /dev/dri/cardN card. Make sure that you have at least one monitor connected\n", card_path);
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *vendor_str = argv[3];
|
||||||
|
gsr_gpu_vendor vendor;
|
||||||
|
if(!gpu_vendor_from_string(vendor_str, &vendor)) {
|
||||||
|
fprintf(stderr, "Error: \"%s\" is not a valid vendor, expected \"amd\", \"intel\" or \"nvidia\"\n", vendor_str);
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_capture_options_command(card_path, vendor);
|
||||||
|
_exit(0);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Error: expected --list-capture-options to be called with either no extra arguments or 2 extra arguments (card path and vendor)\n");
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(argc == 2 && strcmp(argv[1], "--version") == 0) {
|
if(argc == 2 && strcmp(argv[1], "--version") == 0) {
|
||||||
@@ -3421,7 +3464,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
egl.card_path[0] = '\0';
|
egl.card_path[0] = '\0';
|
||||||
if(monitor_capture_use_drm(&egl)) {
|
if(monitor_capture_use_drm(window, egl.gpu_info.vendor)) {
|
||||||
// TODO: Allow specifying another card, and in other places
|
// TODO: Allow specifying another card, and in other places
|
||||||
if(!gsr_get_valid_card_path(&egl, egl.card_path, is_monitor_capture)) {
|
if(!gsr_get_valid_card_path(&egl, egl.card_path, is_monitor_capture)) {
|
||||||
fprintf(stderr, "Error: no /dev/dri/cardX device found. Make sure that you have at least one monitor connected or record a single window instead on X11 or record with the -w portal option\n");
|
fprintf(stderr, "Error: no /dev/dri/cardX device found. Make sure that you have at least one monitor connected or record a single window instead on X11 or record with the -w portal option\n");
|
||||||
|
|||||||
28
src/utils.c
28
src/utils.c
@@ -188,10 +188,12 @@ static bool connector_get_property_by_name(int drmfd, drmModeConnectorPtr props,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void for_each_active_monitor_output_drm(const gsr_egl *egl, active_monitor_callback callback, void *userdata) {
|
static void for_each_active_monitor_output_drm(const char *card_path, active_monitor_callback callback, void *userdata) {
|
||||||
int fd = open(egl->card_path, O_RDONLY);
|
int fd = open(card_path, O_RDONLY);
|
||||||
if(fd == -1)
|
if(fd == -1) {
|
||||||
|
fprintf(stderr, "gsr error: for_each_active_monitor_output_drm failed, failed to open \"%s\", error: %s\n", card_path, strerror(errno));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||||
|
|
||||||
@@ -250,14 +252,14 @@ static void for_each_active_monitor_output_drm(const gsr_egl *egl, active_monito
|
|||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void for_each_active_monitor_output(const gsr_egl *egl, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata) {
|
void for_each_active_monitor_output(const gsr_window *window, const char *card_path, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata) {
|
||||||
switch(connection_type) {
|
switch(connection_type) {
|
||||||
case GSR_CONNECTION_X11:
|
case GSR_CONNECTION_X11:
|
||||||
case GSR_CONNECTION_WAYLAND:
|
case GSR_CONNECTION_WAYLAND:
|
||||||
gsr_window_for_each_active_monitor_output_cached(egl->window, callback, userdata);
|
gsr_window_for_each_active_monitor_output_cached(window, callback, userdata);
|
||||||
break;
|
break;
|
||||||
case GSR_CONNECTION_DRM:
|
case GSR_CONNECTION_DRM:
|
||||||
for_each_active_monitor_output_drm(egl, callback, userdata);
|
for_each_active_monitor_output_drm(card_path, callback, userdata);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,7 +282,7 @@ bool get_monitor_by_name(const gsr_egl *egl, gsr_connection_type connection_type
|
|||||||
userdata.name_len = strlen(name);
|
userdata.name_len = strlen(name);
|
||||||
userdata.monitor = monitor;
|
userdata.monitor = monitor;
|
||||||
userdata.found_monitor = false;
|
userdata.found_monitor = false;
|
||||||
for_each_active_monitor_output(egl, connection_type, get_monitor_by_name_callback, &userdata);
|
for_each_active_monitor_output(egl->window, egl->card_path, connection_type, get_monitor_by_name_callback, &userdata);
|
||||||
return userdata.found_monitor;
|
return userdata.found_monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,14 +314,14 @@ static void get_monitor_by_connector_id_callback(const gsr_monitor *monitor, voi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl, const gsr_monitor *monitor) {
|
gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_window *window, const gsr_monitor *monitor) {
|
||||||
if(gsr_window_get_display_server(egl->window) == GSR_DISPLAY_SERVER_WAYLAND) {
|
if(gsr_window_get_display_server(window) == GSR_DISPLAY_SERVER_WAYLAND) {
|
||||||
{
|
{
|
||||||
get_monitor_by_connector_id_userdata userdata;
|
get_monitor_by_connector_id_userdata userdata;
|
||||||
userdata.monitor = monitor;
|
userdata.monitor = monitor;
|
||||||
userdata.rotation = GSR_MONITOR_ROT_0;
|
userdata.rotation = GSR_MONITOR_ROT_0;
|
||||||
userdata.match_found = false;
|
userdata.match_found = false;
|
||||||
gsr_window_for_each_active_monitor_output_cached(egl->window, get_monitor_by_name_and_size_callback, &userdata);
|
gsr_window_for_each_active_monitor_output_cached(window, get_monitor_by_name_and_size_callback, &userdata);
|
||||||
if(userdata.match_found)
|
if(userdata.match_found)
|
||||||
return userdata.rotation;
|
return userdata.rotation;
|
||||||
}
|
}
|
||||||
@@ -328,7 +330,7 @@ gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl,
|
|||||||
userdata.monitor = monitor;
|
userdata.monitor = monitor;
|
||||||
userdata.rotation = GSR_MONITOR_ROT_0;
|
userdata.rotation = GSR_MONITOR_ROT_0;
|
||||||
userdata.match_found = false;
|
userdata.match_found = false;
|
||||||
gsr_window_for_each_active_monitor_output_cached(egl->window, get_monitor_by_connector_id_callback, &userdata);
|
gsr_window_for_each_active_monitor_output_cached(window, get_monitor_by_connector_id_callback, &userdata);
|
||||||
return userdata.rotation;
|
return userdata.rotation;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -336,7 +338,7 @@ gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl,
|
|||||||
userdata.monitor = monitor;
|
userdata.monitor = monitor;
|
||||||
userdata.rotation = GSR_MONITOR_ROT_0;
|
userdata.rotation = GSR_MONITOR_ROT_0;
|
||||||
userdata.match_found = false;
|
userdata.match_found = false;
|
||||||
gsr_window_for_each_active_monitor_output_cached(egl->window, get_monitor_by_connector_id_callback, &userdata);
|
gsr_window_for_each_active_monitor_output_cached(window, get_monitor_by_connector_id_callback, &userdata);
|
||||||
return userdata.rotation;
|
return userdata.rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +421,7 @@ bool gl_driver_version_greater_than(const gsr_egl *egl, int major, int minor, in
|
|||||||
return version_greater_than(egl->gpu_info.driver_major, egl->gpu_info.driver_minor, egl->gpu_info.driver_patch, major, minor, patch);
|
return version_greater_than(egl->gpu_info.driver_major, egl->gpu_info.driver_minor, egl->gpu_info.driver_patch, major, minor, patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool try_card_has_valid_plane(const char *card_path) {
|
bool try_card_has_valid_plane(const char *card_path) {
|
||||||
drmVersion *ver = NULL;
|
drmVersion *ver = NULL;
|
||||||
drmModePlaneResPtr planes = NULL;
|
drmModePlaneResPtr planes = NULL;
|
||||||
bool found_screen_card = false;
|
bool found_screen_card = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user