mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-03-31 09:07:13 +09:00
Match gsr monitor name with wayland monitor name. Thanks info@leocodes
This commit is contained in:
4
TODO
4
TODO
@@ -285,3 +285,7 @@ Maybe disable qp/vbr for replay. In that case we can preallocate all replay data
|
|||||||
That could improve performance/disk write optimization and maybe even reduce ram usage because of less blocks/fragmentation.
|
That could improve performance/disk write optimization and maybe even reduce ram usage because of less blocks/fragmentation.
|
||||||
|
|
||||||
When rpc is added add the option to add/remove audio devices/app audio and also overlays (from new capture sources).
|
When rpc is added add the option to add/remove audio devices/app audio and also overlays (from new capture sources).
|
||||||
|
|
||||||
|
Support hdr screenshot.
|
||||||
|
|
||||||
|
Recreate opengl context on loss. This can happen if there is a gpu driver bug, causing context to need to be recreated. This is a nice improvement to not break recording even with buggy driver.
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define CONNECTOR_TYPE_COUNTS 32
|
|
||||||
|
|
||||||
typedef struct AVCodecContext AVCodecContext;
|
typedef struct AVCodecContext AVCodecContext;
|
||||||
typedef struct AVFrame AVFrame;
|
typedef struct AVFrame AVFrame;
|
||||||
|
|
||||||
@@ -29,12 +27,6 @@ typedef struct {
|
|||||||
bool found_monitor;
|
bool found_monitor;
|
||||||
} get_monitor_by_name_userdata;
|
} get_monitor_by_name_userdata;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int type;
|
|
||||||
int count;
|
|
||||||
int count_active;
|
|
||||||
} drm_connector_type_count;
|
|
||||||
|
|
||||||
double clock_get_monotonic_seconds(void);
|
double clock_get_monotonic_seconds(void);
|
||||||
bool generate_random_characters(char *buffer, int buffer_size, const char *alphabet, size_t alphabet_size);
|
bool generate_random_characters(char *buffer, int buffer_size, const char *alphabet, size_t alphabet_size);
|
||||||
bool generate_random_characters_standard_alphabet(char *buffer, int buffer_size);
|
bool generate_random_characters_standard_alphabet(char *buffer, int buffer_size);
|
||||||
@@ -46,7 +38,7 @@ bool get_monitor_by_name(const gsr_egl *egl, gsr_connection_type connection_type
|
|||||||
bool drm_monitor_get_display_server_data(const gsr_window *window, const gsr_monitor *monitor, gsr_monitor_rotation *monitor_rotation, vec2i *monitor_position);
|
bool drm_monitor_get_display_server_data(const gsr_window *window, const gsr_monitor *monitor, gsr_monitor_rotation *monitor_rotation, vec2i *monitor_position);
|
||||||
|
|
||||||
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);
|
int get_connector_type_id_by_name(const char *name);
|
||||||
uint32_t monitor_identifier_from_type_and_count(int monitor_type_index, int monitor_type_count);
|
uint32_t monitor_identifier_from_type_and_count(int monitor_type_index, int monitor_type_count);
|
||||||
|
|
||||||
bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info);
|
bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info);
|
||||||
@@ -61,7 +53,6 @@ int create_directory_recursive(char *path);
|
|||||||
|
|
||||||
/* |img_attr| needs to be at least 44 in size */
|
/* |img_attr| needs to be at least 44 in size */
|
||||||
void setup_dma_buf_attrs(intptr_t *img_attr, uint32_t format, uint32_t width, uint32_t height, const int *fds, const uint32_t *offsets, const uint32_t *pitches, const uint64_t *modifiers, int num_planes, bool use_modifier);
|
void setup_dma_buf_attrs(intptr_t *img_attr, uint32_t format, uint32_t width, uint32_t height, const int *fds, const uint32_t *offsets, const uint32_t *pitches, const uint64_t *modifiers, int num_planes, bool use_modifier);
|
||||||
bool video_codec_context_is_vaapi(AVCodecContext *video_codec_context);
|
|
||||||
|
|
||||||
vec2i scale_keep_aspect_ratio(vec2i from, vec2i to);
|
vec2i scale_keep_aspect_ratio(vec2i from, vec2i to);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
project('gpu-screen-recorder', ['c', 'cpp'], version : '5.5.3', default_options : ['warning_level=2'])
|
project('gpu-screen-recorder', ['c', 'cpp'], version : '5.5.4', default_options : ['warning_level=2'])
|
||||||
|
|
||||||
add_project_arguments('-Wshadow', language : ['c', 'cpp'])
|
add_project_arguments('-Wshadow', language : ['c', 'cpp'])
|
||||||
if get_option('buildtype') == 'debug'
|
if get_option('buildtype') == 'debug'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "gpu-screen-recorder"
|
name = "gpu-screen-recorder"
|
||||||
type = "executable"
|
type = "executable"
|
||||||
version = "5.5.3"
|
version = "5.5.4"
|
||||||
platforms = ["posix"]
|
platforms = ["posix"]
|
||||||
|
|
||||||
[config]
|
[config]
|
||||||
|
|||||||
77
src/utils.c
77
src/utils.c
@@ -108,7 +108,7 @@ void for_each_active_monitor_output_x11_not_cached(Display *display, active_moni
|
|||||||
// but gpu screen recorder captures the drm framebuffer instead of x11 api. This drm framebuffer which doesn't increase in size when using xrandr scaling.
|
// but gpu screen recorder captures the drm framebuffer instead of x11 api. This drm framebuffer which doesn't increase in size when using xrandr scaling.
|
||||||
// Maybe a better option would be to get the drm crtc size instead.
|
// Maybe a better option would be to get the drm crtc size instead.
|
||||||
const XRRModeInfo *mode_info = get_mode_info(screen_res, crt_info->mode);
|
const XRRModeInfo *mode_info = get_mode_info(screen_res, crt_info->mode);
|
||||||
if(mode_info && out_info->nameLen < (int)sizeof(display_name)) {
|
if(mode_info) {
|
||||||
snprintf(display_name, sizeof(display_name), "%.*s", (int)out_info->nameLen, out_info->name);
|
snprintf(display_name, sizeof(display_name), "%.*s", (int)out_info->nameLen, out_info->name);
|
||||||
const gsr_monitor_rotation rotation = x11_rotation_to_gsr_rotation(crt_info->rotation);
|
const gsr_monitor_rotation rotation = x11_rotation_to_gsr_rotation(crt_info->rotation);
|
||||||
const vec2i monitor_size = get_monitor_size_rotated(mode_info->width, mode_info->height, rotation);
|
const vec2i monitor_size = get_monitor_size_rotated(mode_info->width, mode_info->height, rotation);
|
||||||
@@ -150,21 +150,22 @@ int get_connector_type_by_name(const char *name) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_connector_type_count* drm_connector_types_get_index(drm_connector_type_count *type_counts, int *num_type_counts, int connector_type) {
|
int get_connector_type_id_by_name(const char *name) {
|
||||||
for(int i = 0; i < *num_type_counts; ++i) {
|
int len = strlen(name);
|
||||||
if(type_counts[i].type == connector_type)
|
int num_start = 0;
|
||||||
return &type_counts[i];
|
for(int i = len - 1; i >= 0; --i) {
|
||||||
|
const bool is_num = name[i] >= '0' && name[i] <= '9';
|
||||||
|
if(!is_num) {
|
||||||
|
num_start = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*num_type_counts == CONNECTOR_TYPE_COUNTS)
|
const int num_len = len - num_start;
|
||||||
return NULL;
|
if(num_len <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
const int index = *num_type_counts;
|
return atoi(name + num_start);
|
||||||
type_counts[index].type = connector_type;
|
|
||||||
type_counts[index].count = 0;
|
|
||||||
type_counts[index].count_active = 0;
|
|
||||||
++*num_type_counts;
|
|
||||||
return &type_counts[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t monitor_identifier_from_type_and_count(int monitor_type_index, int monitor_type_count) {
|
uint32_t monitor_identifier_from_type_and_count(int monitor_type_index, int monitor_type_count) {
|
||||||
@@ -195,9 +196,6 @@ static void for_each_active_monitor_output_drm(const char *card_path, active_mon
|
|||||||
|
|
||||||
drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||||
|
|
||||||
drm_connector_type_count type_counts[CONNECTOR_TYPE_COUNTS];
|
|
||||||
int num_type_counts = 0;
|
|
||||||
|
|
||||||
char display_name[256];
|
char display_name[256];
|
||||||
drmModeResPtr resources = drmModeGetResources(fd);
|
drmModeResPtr resources = drmModeGetResources(fd);
|
||||||
if(resources) {
|
if(resources) {
|
||||||
@@ -206,35 +204,29 @@ static void for_each_active_monitor_output_drm(const char *card_path, active_mon
|
|||||||
if(!connector)
|
if(!connector)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
drm_connector_type_count *connector_type = drm_connector_types_get_index(type_counts, &num_type_counts, connector->connector_type);
|
|
||||||
const char *connection_name = drmModeGetConnectorTypeName(connector->connector_type);
|
|
||||||
const int connection_name_len = strlen(connection_name);
|
|
||||||
if(connector_type)
|
|
||||||
++connector_type->count;
|
|
||||||
|
|
||||||
if(connector->connection != DRM_MODE_CONNECTED) {
|
if(connector->connection != DRM_MODE_CONNECTED) {
|
||||||
drmModeFreeConnector(connector);
|
drmModeFreeConnector(connector);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(connector_type)
|
|
||||||
++connector_type->count_active;
|
|
||||||
|
|
||||||
uint64_t crtc_id = 0;
|
uint64_t crtc_id = 0;
|
||||||
connector_get_property_by_name(fd, connector, "CRTC_ID", &crtc_id);
|
connector_get_property_by_name(fd, connector, "CRTC_ID", &crtc_id);
|
||||||
|
|
||||||
drmModeCrtcPtr crtc = drmModeGetCrtc(fd, crtc_id);
|
drmModeCrtcPtr crtc = drmModeGetCrtc(fd, crtc_id);
|
||||||
if(connector_type && crtc_id > 0 && crtc && connection_name_len + 5 < (int)sizeof(display_name)) {
|
const char *connection_name = drmModeGetConnectorTypeName(connector->connector_type);
|
||||||
const int display_name_len = snprintf(display_name, sizeof(display_name), "%s-%d", connection_name, connector_type->count);
|
|
||||||
|
if(connection_name && crtc_id > 0 && crtc) {
|
||||||
const int connector_type_index_name = get_connector_type_by_name(display_name);
|
const int connector_type_index_name = get_connector_type_by_name(display_name);
|
||||||
gsr_monitor monitor = {
|
const int display_name_len = snprintf(display_name, sizeof(display_name), "%s-%u", connection_name, connector->connector_type_id);
|
||||||
|
|
||||||
|
const gsr_monitor monitor = {
|
||||||
.name = display_name,
|
.name = display_name,
|
||||||
.name_len = display_name_len,
|
.name_len = display_name_len,
|
||||||
.pos = { .x = crtc->x, .y = crtc->y },
|
.pos = { .x = crtc->x, .y = crtc->y },
|
||||||
.size = { .x = (int)crtc->width, .y = (int)crtc->height },
|
.size = { .x = (int)crtc->width, .y = (int)crtc->height },
|
||||||
.connector_id = connector->connector_id,
|
.connector_id = connector->connector_id,
|
||||||
.rotation = GSR_MONITOR_ROT_0,
|
.rotation = GSR_MONITOR_ROT_0,
|
||||||
.monitor_identifier = connector_type_index_name != -1 ? monitor_identifier_from_type_and_count(connector_type_index_name, connector_type->count_active) : 0
|
.monitor_identifier = connector_type_index_name != -1 ? monitor_identifier_from_type_and_count(connector_type_index_name, connector->connector_type_id) : 0
|
||||||
};
|
};
|
||||||
callback(&monitor, userdata);
|
callback(&monitor, userdata);
|
||||||
}
|
}
|
||||||
@@ -607,33 +599,6 @@ void setup_dma_buf_attrs(intptr_t *img_attr, uint32_t format, uint32_t width, ui
|
|||||||
assert(img_attr_index <= 44);
|
assert(img_attr_index <= 44);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VADisplay video_codec_context_get_vaapi_display(AVCodecContext *video_codec_context) {
|
|
||||||
AVBufferRef *hw_frames_ctx = video_codec_context->hw_frames_ctx;
|
|
||||||
if(!hw_frames_ctx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
AVHWFramesContext *hw_frame_context = (AVHWFramesContext*)hw_frames_ctx->data;
|
|
||||||
AVHWDeviceContext *device_context = (AVHWDeviceContext*)hw_frame_context->device_ctx;
|
|
||||||
if(device_context->type != AV_HWDEVICE_TYPE_VAAPI)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
AVVAAPIDeviceContext *vactx = device_context->hwctx;
|
|
||||||
return vactx->display;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool video_codec_context_is_vaapi(AVCodecContext *video_codec_context) {
|
|
||||||
if(!video_codec_context)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
AVBufferRef *hw_frames_ctx = video_codec_context->hw_frames_ctx;
|
|
||||||
if(!hw_frames_ctx)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
AVHWFramesContext *hw_frame_context = (AVHWFramesContext*)hw_frames_ctx->data;
|
|
||||||
AVHWDeviceContext *device_context = (AVHWDeviceContext*)hw_frame_context->device_ctx;
|
|
||||||
return device_context->type == AV_HWDEVICE_TYPE_VAAPI;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2i scale_keep_aspect_ratio(vec2i from, vec2i to) {
|
vec2i scale_keep_aspect_ratio(vec2i from, vec2i to) {
|
||||||
if(from.x == 0 || from.y == 0)
|
if(from.x == 0 || from.y == 0)
|
||||||
return (vec2i){0, 0};
|
return (vec2i){0, 0};
|
||||||
|
|||||||
@@ -339,24 +339,13 @@ static gsr_monitor_rotation wayland_transform_to_gsr_rotation(int32_t rot) {
|
|||||||
|
|
||||||
static void gsr_window_wayland_for_each_active_monitor_output_cached(const gsr_window *window, active_monitor_callback callback, void *userdata) {
|
static void gsr_window_wayland_for_each_active_monitor_output_cached(const gsr_window *window, active_monitor_callback callback, void *userdata) {
|
||||||
const gsr_window_wayland *self = window->priv;
|
const gsr_window_wayland *self = window->priv;
|
||||||
drm_connector_type_count type_counts[CONNECTOR_TYPE_COUNTS];
|
|
||||||
int num_type_counts = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < self->num_outputs; ++i) {
|
for(int i = 0; i < self->num_outputs; ++i) {
|
||||||
const gsr_wayland_output *output = &self->outputs[i];
|
const gsr_wayland_output *output = &self->outputs[i];
|
||||||
if(!output->name)
|
if(!output->name)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const int connector_type_index = get_connector_type_by_name(output->name);
|
const int connector_type_index = get_connector_type_by_name(output->name);
|
||||||
drm_connector_type_count *connector_type = NULL;
|
const int connector_type_id = get_connector_type_id_by_name(output->name);
|
||||||
if(connector_type_index != -1)
|
|
||||||
connector_type = drm_connector_types_get_index(type_counts, &num_type_counts, connector_type_index);
|
|
||||||
|
|
||||||
if(connector_type) {
|
|
||||||
++connector_type->count;
|
|
||||||
++connector_type->count_active;
|
|
||||||
}
|
|
||||||
|
|
||||||
const gsr_monitor monitor = {
|
const gsr_monitor monitor = {
|
||||||
.name = output->name,
|
.name = output->name,
|
||||||
.name_len = strlen(output->name),
|
.name_len = strlen(output->name),
|
||||||
@@ -364,7 +353,7 @@ static void gsr_window_wayland_for_each_active_monitor_output_cached(const gsr_w
|
|||||||
.size = { .x = output->size.x, .y = output->size.y },
|
.size = { .x = output->size.x, .y = output->size.y },
|
||||||
.connector_id = 0,
|
.connector_id = 0,
|
||||||
.rotation = wayland_transform_to_gsr_rotation(output->transform),
|
.rotation = wayland_transform_to_gsr_rotation(output->transform),
|
||||||
.monitor_identifier = connector_type ? monitor_identifier_from_type_and_count(connector_type_index, connector_type->count_active) : 0
|
.monitor_identifier = (connector_type_index != -1 && connector_type_id != -1) ? monitor_identifier_from_type_and_count(connector_type_index, connector_type_id) : 0
|
||||||
};
|
};
|
||||||
callback(&monitor, userdata);
|
callback(&monitor, userdata);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user