mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-04-04 02:26:36 +09:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ed9977068 | ||
|
|
8feb94f518 | ||
|
|
6acd65a9c2 | ||
|
|
56e2a82474 |
4
TODO
4
TODO
@@ -253,4 +253,6 @@ When webcam support is added also support v4l2loopback? this is done by using av
|
||||
|
||||
Do proper exit, to call gsr_capture_destroy which will properly stop gsr-kms-server. Otherwise there can be zombie gsr-kms-server on error.
|
||||
|
||||
Replace all scissors with clearing textures if the cursor hits the outside of the frame image
|
||||
Replace all scissors with clearing textures if the cursor hits the outside of the frame image.
|
||||
|
||||
Cursor position might be slightly wrong on rotated monitor.
|
||||
|
||||
@@ -72,7 +72,7 @@ typedef struct {
|
||||
int gsr_color_conversion_init(gsr_color_conversion *self, const gsr_color_conversion_params *params);
|
||||
void gsr_color_conversion_deinit(gsr_color_conversion *self);
|
||||
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i texture_pos, vec2i texture_size, gsr_rotation rotation, bool external_texture, gsr_source_color source_color);
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, bool external_texture, gsr_source_color source_color);
|
||||
void gsr_color_conversion_clear(gsr_color_conversion *self);
|
||||
|
||||
gsr_rotation gsr_monitor_rotation_to_rotation(gsr_monitor_rotation monitor_rotation);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
project('gpu-screen-recorder', ['c', 'cpp'], version : '5.3.4', default_options : ['warning_level=2'])
|
||||
project('gpu-screen-recorder', ['c', 'cpp'], version : '5.3.5', default_options : ['warning_level=2'])
|
||||
|
||||
add_project_arguments('-Wshadow', language : ['c', 'cpp'])
|
||||
if get_option('buildtype') == 'debug'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "gpu-screen-recorder"
|
||||
type = "executable"
|
||||
version = "5.3.4"
|
||||
version = "5.3.5"
|
||||
platforms = ["posix"]
|
||||
|
||||
[config]
|
||||
|
||||
@@ -502,7 +502,7 @@ static void render_drm_cursor(gsr_capture_kms *self, gsr_color_conversion *color
|
||||
|
||||
gsr_color_conversion_draw(color_conversion, self->cursor_texture_id,
|
||||
cursor_pos, (vec2i){cursor_size.x * scale.x, cursor_size.y * scale.y},
|
||||
(vec2i){0, 0}, cursor_size,
|
||||
(vec2i){0, 0}, cursor_size, cursor_size,
|
||||
gsr_monitor_rotation_to_rotation(self->monitor_rotation), cursor_texture_id_is_external, GSR_SOURCE_COLOR_RGB);
|
||||
|
||||
self->params.egl->glDisable(GL_SCISSOR_TEST);
|
||||
@@ -530,7 +530,7 @@ static void render_x11_cursor(gsr_capture_kms *self, gsr_color_conversion *color
|
||||
|
||||
gsr_color_conversion_draw(color_conversion, self->x11_cursor.texture_id,
|
||||
cursor_pos, (vec2i){self->x11_cursor.size.x * scale.x, self->x11_cursor.size.y * scale.y},
|
||||
(vec2i){0, 0}, self->x11_cursor.size,
|
||||
(vec2i){0, 0}, self->x11_cursor.size, self->x11_cursor.size,
|
||||
GSR_ROT_0, false, GSR_SOURCE_COLOR_RGB);
|
||||
|
||||
self->params.egl->glDisable(GL_SCISSOR_TEST);
|
||||
@@ -616,6 +616,7 @@ static int gsr_capture_kms_capture(gsr_capture *cap, gsr_capture_metadata *captu
|
||||
gsr_kms_set_hdr_metadata(self, drm_fd);
|
||||
|
||||
self->capture_size = rotate_capture_size_if_rotated(self, (vec2i){ drm_fd->src_w, drm_fd->src_h });
|
||||
const vec2i original_frame_size = self->capture_size;
|
||||
if(self->params.region_size.x > 0 && self->params.region_size.y > 0)
|
||||
self->capture_size = self->params.region_size;
|
||||
|
||||
@@ -644,7 +645,7 @@ static int gsr_capture_kms_capture(gsr_capture *cap, gsr_capture_metadata *captu
|
||||
|
||||
gsr_color_conversion_draw(color_conversion, self->external_texture_fallback ? self->external_input_texture_id : self->input_texture_id,
|
||||
target_pos, output_size,
|
||||
capture_pos, self->capture_size,
|
||||
capture_pos, self->capture_size, original_frame_size,
|
||||
gsr_monitor_rotation_to_rotation(self->monitor_rotation), self->external_texture_fallback, GSR_SOURCE_COLOR_RGB);
|
||||
|
||||
if(self->params.record_cursor) {
|
||||
|
||||
@@ -363,6 +363,7 @@ static int gsr_capture_nvfbc_capture(gsr_capture *cap, gsr_capture_metadata *cap
|
||||
}
|
||||
|
||||
vec2i frame_size = (vec2i){self->width, self->height};
|
||||
const vec2i original_frame_size = frame_size;
|
||||
if(self->params.region_size.x > 0 && self->params.region_size.y > 0)
|
||||
frame_size = self->params.region_size;
|
||||
|
||||
@@ -395,7 +396,7 @@ static int gsr_capture_nvfbc_capture(gsr_capture *cap, gsr_capture_metadata *cap
|
||||
|
||||
gsr_color_conversion_draw(color_conversion, self->setup_params.dwTextures[grab_params.dwTextureIndex],
|
||||
target_pos, (vec2i){output_size.x, output_size.y},
|
||||
self->params.region_position, frame_size,
|
||||
self->params.region_position, frame_size, original_frame_size,
|
||||
GSR_ROT_0, false, GSR_SOURCE_COLOR_BGR);
|
||||
|
||||
//self->params.egl->glFlush();
|
||||
|
||||
@@ -347,7 +347,7 @@ static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *ca
|
||||
|
||||
gsr_color_conversion_draw(color_conversion, using_external_image ? self->texture_map.external_texture_id : self->texture_map.texture_id,
|
||||
target_pos, output_size,
|
||||
(vec2i){region.x, region.y}, self->capture_size,
|
||||
(vec2i){region.x, region.y}, self->capture_size, self->capture_size,
|
||||
GSR_ROT_0, using_external_image, GSR_SOURCE_COLOR_RGB);
|
||||
|
||||
if(self->params.record_cursor && self->texture_map.cursor_texture_id > 0 && cursor_region.width > 0) {
|
||||
@@ -365,7 +365,7 @@ static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *ca
|
||||
self->params.egl->glScissor(target_pos.x, target_pos.y, output_size.x, output_size.y);
|
||||
gsr_color_conversion_draw(color_conversion, self->texture_map.cursor_texture_id,
|
||||
(vec2i){cursor_pos.x, cursor_pos.y}, (vec2i){cursor_region.width * scale.x, cursor_region.height * scale.y},
|
||||
(vec2i){0, 0}, (vec2i){cursor_region.width, cursor_region.height},
|
||||
(vec2i){0, 0}, (vec2i){cursor_region.width, cursor_region.height}, (vec2i){cursor_region.width, cursor_region.height},
|
||||
GSR_ROT_0, false, GSR_SOURCE_COLOR_RGB);
|
||||
self->params.egl->glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ static int gsr_capture_xcomposite_capture(gsr_capture *cap, gsr_capture_metadata
|
||||
|
||||
gsr_color_conversion_draw(color_conversion, window_texture_get_opengl_texture_id(&self->window_texture),
|
||||
target_pos, output_size,
|
||||
(vec2i){0, 0}, self->texture_size,
|
||||
(vec2i){0, 0}, self->texture_size, self->texture_size,
|
||||
GSR_ROT_0, false, GSR_SOURCE_COLOR_RGB);
|
||||
|
||||
if(self->params.record_cursor && self->cursor.visible) {
|
||||
@@ -279,7 +279,7 @@ static int gsr_capture_xcomposite_capture(gsr_capture *cap, gsr_capture_metadata
|
||||
|
||||
gsr_color_conversion_draw(color_conversion, self->cursor.texture_id,
|
||||
cursor_pos, (vec2i){self->cursor.size.x * scale.x, self->cursor.size.y * scale.y},
|
||||
(vec2i){0, 0}, self->cursor.size,
|
||||
(vec2i){0, 0}, self->cursor.size, self->cursor.size,
|
||||
GSR_ROT_0, false, GSR_SOURCE_COLOR_RGB);
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ static int gsr_capture_ximage_capture(gsr_capture *cap, gsr_capture_metadata *ca
|
||||
|
||||
gsr_color_conversion_draw(color_conversion, self->texture_id,
|
||||
target_pos, output_size,
|
||||
(vec2i){0, 0}, self->capture_size,
|
||||
(vec2i){0, 0}, self->capture_size, self->capture_size,
|
||||
GSR_ROT_0, false, GSR_SOURCE_COLOR_RGB);
|
||||
|
||||
if(self->params.record_cursor && self->cursor.visible) {
|
||||
@@ -180,7 +180,7 @@ static int gsr_capture_ximage_capture(gsr_capture *cap, gsr_capture_metadata *ca
|
||||
|
||||
gsr_color_conversion_draw(color_conversion, self->cursor.texture_id,
|
||||
cursor_pos, (vec2i){self->cursor.size.x * scale.x, self->cursor.size.y * scale.y},
|
||||
(vec2i){0, 0}, self->cursor.size,
|
||||
(vec2i){0, 0}, self->cursor.size, self->cursor.size,
|
||||
GSR_ROT_0, false, GSR_SOURCE_COLOR_RGB);
|
||||
|
||||
self->params.egl->glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
@@ -100,10 +100,11 @@ static int load_compute_shader_y(gsr_shader *shader, gsr_egl *egl, gsr_color_uni
|
||||
" ivec2 size = ivec2(vec2(textureSize(img_input, 0)) * scale + 0.5);\n"
|
||||
" ivec2 output_size = textureSize(img_background, 0);\n"
|
||||
" vec2 rotated_texel_coord = vec2(texel_coord - source_position - size/2) * rotation_matrix + vec2(size/2) + 0.5;\n"
|
||||
" vec2 output_texel_coord = vec2(texel_coord - source_position + target_position) + 0.5;\n"
|
||||
" vec2 tex_coord = vec2(rotated_texel_coord)/vec2(size);\n"
|
||||
" vec4 source_color = texture(img_input, tex_coord);\n"
|
||||
" vec4 source_color_yuv = RGBtoYUV * vec4(source_color.rgb, 1.0);\n"
|
||||
" vec4 output_color_yuv = texture(img_background, (rotated_texel_coord + vec2(target_position))/vec2(output_size));\n"
|
||||
" vec4 output_color_yuv = texture(img_background, output_texel_coord/vec2(output_size));\n"
|
||||
" float y_color = mix(output_color_yuv.r, source_color_yuv.r, source_color.a);\n"
|
||||
" imageStore(img_output, texel_coord + target_position, vec4(y_color, 1.0, 1.0, 1.0));\n"
|
||||
"}\n", max_local_size_dim, max_local_size_dim, external_texture ? "samplerExternalOES" : "sampler2D", color_transform_matrix);
|
||||
@@ -141,10 +142,11 @@ static int load_compute_shader_uv(gsr_shader *shader, gsr_egl *egl, gsr_color_un
|
||||
" ivec2 size = ivec2(vec2(textureSize(img_input, 0)) * scale + 0.5);\n"
|
||||
" ivec2 output_size = textureSize(img_background, 0);\n"
|
||||
" vec2 rotated_texel_coord = vec2(texel_coord - source_position/2 - size/4) * rotation_matrix + vec2(size/4) + 0.5;\n"
|
||||
" vec2 output_texel_coord = vec2(texel_coord - source_position/2 + target_position/2) + 0.5;\n"
|
||||
" vec2 tex_coord = vec2(rotated_texel_coord)/vec2(size);\n"
|
||||
" vec4 source_color = texture(img_input, tex_coord * 2.0);\n"
|
||||
" vec4 source_color_yuv = RGBtoYUV * vec4(source_color.rgb, 1.0);\n"
|
||||
" vec4 output_color_yuv = texture(img_background, (rotated_texel_coord + vec2(target_position/2))/vec2(output_size));\n"
|
||||
" vec4 output_color_yuv = texture(img_background, output_texel_coord/vec2(output_size));\n"
|
||||
" vec2 uv_color = mix(output_color_yuv.rg, source_color_yuv.gb, source_color.a);\n"
|
||||
" imageStore(img_output, texel_coord + target_position/2, vec4(uv_color, 1.0, 1.0));\n"
|
||||
"}\n", max_local_size_dim, max_local_size_dim, external_texture ? "samplerExternalOES" : "sampler2D", color_transform_matrix);
|
||||
@@ -179,9 +181,10 @@ static int load_compute_shader_rgb(gsr_shader *shader, gsr_egl *egl, gsr_color_u
|
||||
" ivec2 size = ivec2(vec2(textureSize(img_input, 0)) * scale + 0.5);\n"
|
||||
" ivec2 output_size = textureSize(img_background, 0);\n"
|
||||
" vec2 rotated_texel_coord = vec2(texel_coord - source_position - size/2) * rotation_matrix + vec2(size/2) + 0.5;\n"
|
||||
" vec2 output_texel_coord = vec2(texel_coord - source_position + target_position) + 0.5;\n"
|
||||
" vec2 tex_coord = vec2(rotated_texel_coord)/vec2(size);\n"
|
||||
" vec4 source_color = texture(img_input, tex_coord);\n"
|
||||
" vec4 output_color = texture(img_background, (rotated_texel_coord + vec2(target_position))/vec2(output_size));\n"
|
||||
" vec4 output_color = texture(img_background, output_texel_coord/vec2(output_size));\n"
|
||||
" vec3 color = mix(output_color.rgb, source_color.rgb, source_color.a);\n"
|
||||
" imageStore(img_output, texel_coord + target_position, vec4(color, 1.0));\n"
|
||||
"}\n", max_local_size_dim, max_local_size_dim, external_texture ? "samplerExternalOES" : "sampler2D");
|
||||
@@ -459,17 +462,17 @@ static void gsr_color_conversion_dispatch_compute_shader(gsr_color_conversion *s
|
||||
self->params.egl->glDispatchCompute(max_int(1, num_groups_x), max_int(1, num_groups_y), 1);
|
||||
}
|
||||
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i texture_pos, vec2i texture_size, gsr_rotation rotation, bool external_texture, gsr_source_color source_color) {
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, bool external_texture, gsr_source_color source_color) {
|
||||
vec2f scale = {0.0f, 0.0f};
|
||||
if(texture_size.x > 0 && texture_size.y > 0)
|
||||
scale = (vec2f){ (double)destination_size.x/(double)texture_size.x, (double)destination_size.y/(double)texture_size.y };
|
||||
if(source_size.x > 0 && source_size.y > 0)
|
||||
scale = (vec2f){ (double)destination_size.x/(double)source_size.x, (double)destination_size.y/(double)source_size.y };
|
||||
|
||||
vec2i source_position = {0, 0};
|
||||
float rotation_matrix[2][2] = {{0, 0}, {0, 0}};
|
||||
gsr_color_conversion_apply_rotation(rotation, rotation_matrix, &source_position, texture_size, scale);
|
||||
|
||||
source_position.x -= (texture_pos.x * scale.x + 0.5);
|
||||
source_position.y -= (texture_pos.y * scale.y + 0.5);
|
||||
source_position.x -= (source_pos.x * scale.x + 0.5);
|
||||
source_position.y -= (source_pos.y * scale.y + 0.5);
|
||||
|
||||
const int texture_target = external_texture ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
|
||||
self->params.egl->glBindTexture(texture_target, texture_id);
|
||||
|
||||
@@ -92,6 +92,10 @@ static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self
|
||||
if(self->prime.fourcc == VA_FOURCC_NV12 || self->prime.fourcc == VA_FOURCC_P010) {
|
||||
const uint32_t *formats = self->prime.fourcc == VA_FOURCC_NV12 ? formats_nv12 : formats_p010;
|
||||
const int div[2] = {1, 2}; // divide UV texture size by 2 because chroma is half size
|
||||
const float border_colors[2][4] = {
|
||||
{0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{0.5f, 0.5f, 0.0f, 1.0f}
|
||||
};
|
||||
|
||||
self->params.egl->glGenTextures(2, self->target_textures);
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
@@ -120,11 +124,10 @@ static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self
|
||||
return false;
|
||||
}
|
||||
|
||||
const float border_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
self->params.egl->glBindTexture(GL_TEXTURE_2D, self->target_textures[i]);
|
||||
self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
self->params.egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
|
||||
self->params.egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_colors[i]);
|
||||
self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ static bool gsr_video_encoder_vulkan_setup_textures(gsr_video_encoder_vulkan *se
|
||||
//AVVkFrame *target_surface_id = (AVVkFrame*)frame->data[0];
|
||||
self->vv = video_codec_context_get_vulkan_data(video_codec_context);
|
||||
|
||||
const unsigned int internal_formats_nv12[2] = { GL_RGBA8, GL_RGBA8 };
|
||||
const unsigned int internal_formats_nv12[2] = { GL_RGBA8, GL_RGBA8 }; // TODO: GL_R8, GL_R16
|
||||
const unsigned int internal_formats_p010[2] = { GL_R16, GL_RG16 };
|
||||
const unsigned int formats[2] = { GL_RED, GL_RG };
|
||||
const int div[2] = {1, 2}; // divide UV texture size by 2 because chroma is half size
|
||||
|
||||
29
src/main.cpp
29
src/main.cpp
@@ -82,11 +82,14 @@ typedef struct {
|
||||
static void monitor_output_callback_print(const gsr_monitor *monitor, void *userdata) {
|
||||
const MonitorOutputCallbackUserdata *options = (MonitorOutputCallbackUserdata*)userdata;
|
||||
vec2i monitor_position = monitor->pos;
|
||||
vec2i monitor_size = monitor->size;
|
||||
if(gsr_window_get_display_server(options->window) == GSR_DISPLAY_SERVER_WAYLAND) {
|
||||
gsr_monitor_rotation monitor_rotation = GSR_MONITOR_ROT_0;
|
||||
drm_monitor_get_display_server_data(options->window, monitor, &monitor_rotation, &monitor_position);
|
||||
if(monitor_rotation == GSR_MONITOR_ROT_90 || monitor_rotation == GSR_MONITOR_ROT_270)
|
||||
std::swap(monitor_size.x, monitor_size.y);
|
||||
}
|
||||
fprintf(stderr, " \"%.*s\" (%dx%d+%d+%d)\n", monitor->name_len, monitor->name, monitor->size.x, monitor->size.y, monitor_position.x, monitor_position.y);
|
||||
fprintf(stderr, " \"%.*s\" (%dx%d+%d+%d)\n", monitor->name_len, monitor->name, monitor_size.x, monitor_size.y, monitor_position.x, monitor_position.y);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@@ -110,9 +113,14 @@ typedef struct {
|
||||
static void get_monitor_by_position_callback(const gsr_monitor *monitor, void *userdata) {
|
||||
MonitorByPositionCallback *data = (MonitorByPositionCallback*)userdata;
|
||||
|
||||
gsr_monitor_rotation monitor_rotation = GSR_MONITOR_ROT_0;
|
||||
vec2i monitor_position = monitor->pos;
|
||||
drm_monitor_get_display_server_data(data->window, monitor, &monitor_rotation, &monitor_position);
|
||||
vec2i monitor_size = monitor->size;
|
||||
if(gsr_window_get_display_server(data->window) == GSR_DISPLAY_SERVER_WAYLAND) {
|
||||
gsr_monitor_rotation monitor_rotation = GSR_MONITOR_ROT_0;
|
||||
drm_monitor_get_display_server_data(data->window, monitor, &monitor_rotation, &monitor_position);
|
||||
if(monitor_rotation == GSR_MONITOR_ROT_90 || monitor_rotation == GSR_MONITOR_ROT_270)
|
||||
std::swap(monitor_size.x, monitor_size.y);
|
||||
}
|
||||
|
||||
if(!data->output_name && data->position.x >= monitor_position.x && data->position.x <= monitor_position.x + monitor->size.x
|
||||
&& data->position.y >= monitor_position.y && data->position.y <= monitor_position.y + monitor->size.y)
|
||||
@@ -1019,7 +1027,7 @@ static void video_hardware_set_qp(AVCodecContext *codec_context, VideoQuality vi
|
||||
}
|
||||
}
|
||||
|
||||
static void open_video_hardware(AVCodecContext *codec_context, VideoQuality video_quality, bool very_old_gpu, gsr_gpu_vendor vendor, PixelFormat pixel_format, bool hdr, gsr_color_depth color_depth, BitrateMode bitrate_mode, VideoCodec video_codec, bool low_power, bool high_performance_encoding) {
|
||||
static void open_video_hardware(AVCodecContext *codec_context, VideoQuality video_quality, bool very_old_gpu, gsr_gpu_vendor vendor, PixelFormat pixel_format, bool hdr, gsr_color_depth color_depth, BitrateMode bitrate_mode, VideoCodec video_codec, bool low_power) {
|
||||
(void)very_old_gpu;
|
||||
AVDictionary *options = nullptr;
|
||||
|
||||
@@ -1074,8 +1082,7 @@ static void open_video_hardware(AVCodecContext *codec_context, VideoQuality vide
|
||||
av_dict_set_int(&options, "low_power", 1, 0);
|
||||
// Improves performance but increases vram.
|
||||
// TODO: Might need a different async_depth for optimal performance on different amd/intel gpus
|
||||
if(high_performance_encoding)
|
||||
av_dict_set_int(&options, "async_depth", 3, 0);
|
||||
av_dict_set_int(&options, "async_depth", 3, 0);
|
||||
|
||||
if(codec_context->codec_id == AV_CODEC_ID_H264) {
|
||||
// Removed because it causes stutter in games for some people
|
||||
@@ -1106,7 +1113,7 @@ static void open_video_hardware(AVCodecContext *codec_context, VideoQuality vide
|
||||
static void usage_header() {
|
||||
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";
|
||||
printf("usage: %s -w <window_id|monitor|focused|portal|region> [-c <container_format>] [-s WxH] [-region WxH+X+Y] [-f <fps>] [-a <audio_input>] [-q <quality>] [-r <replay_buffer_size_sec>] [-restart-replay-on-save yes|no] [-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] [-high-performance-encoding yes|no] [-o <output_file>] [--list-capture-options [card_path] [vendor]] [--list-audio-devices] [--list-application-audio] [-v yes|no] [-gl-debug yes|no] [--version] [-h|--help]\n", program_name);
|
||||
printf("usage: %s -w <window_id|monitor|focused|portal|region> [-c <container_format>] [-s WxH] [-region WxH+X+Y] [-f <fps>] [-a <audio_input>] [-q <quality>] [-r <replay_buffer_size_sec>] [-restart-replay-on-save yes|no] [-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] [-gl-debug yes|no] [--version] [-h|--help]\n", program_name);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
@@ -1240,10 +1247,6 @@ static void usage_full() {
|
||||
printf(" Which device should be used for video encoding. Should either be 'gpu' or 'cpu'. 'cpu' option currently only work with h264 codec option (-k).\n");
|
||||
printf(" Optional, set to 'gpu' by default.\n");
|
||||
printf("\n");
|
||||
printf(" -high-performance-encoding\n");
|
||||
printf(" Enable high performance video encoding mode. Only applicable to AMD and Intel. Optional, set to 'no' by default.\n");
|
||||
printf(" Note: this option is experimental. On some AMD GPUs this may cause the game you are recording to performance worse.\n");
|
||||
printf("\n");
|
||||
printf(" --info\n");
|
||||
printf(" List info about the system. Lists the following information (prints them to stdout and exits):\n");
|
||||
printf(" Supported video codecs (h264, h264_software, hevc, hevc_hdr, hevc_10bit, av1, av1_hdr, av1_10bit, vp8, vp9) and image codecs (jpeg, png) (if supported).\n");
|
||||
@@ -3376,7 +3379,6 @@ int main(int argc, char **argv) {
|
||||
{ "-restore-portal-session", Arg { {}, is_optional, !is_list, ArgType::BOOLEAN, {false} } },
|
||||
{ "-portal-session-token-filepath", Arg { {}, is_optional, !is_list, ArgType::STRING, {false} } },
|
||||
{ "-encoder", Arg { {}, is_optional, !is_list, ArgType::STRING, {false} } },
|
||||
{ "-high-performance-encoding", Arg { {}, is_optional, !is_list, ArgType::BOOLEAN, {false} } },
|
||||
};
|
||||
|
||||
for(int i = 1; i < argc; i += 2) {
|
||||
@@ -3528,7 +3530,6 @@ int main(int argc, char **argv) {
|
||||
const bool date_folders = arg_get_boolean_value(args, "-df", false);
|
||||
const bool restore_portal_session = arg_get_boolean_value(args, "-restore-portal-session", false);
|
||||
const bool restart_replay_on_save = arg_get_boolean_value(args, "-restart-replay-on-save", false);
|
||||
const bool high_performance_encoding = arg_get_boolean_value(args, "-high-performance-encoding", false);
|
||||
|
||||
const char *portal_session_token_filepath = args["-portal-session-token-filepath"].value();
|
||||
if(portal_session_token_filepath) {
|
||||
@@ -4053,7 +4054,7 @@ int main(int argc, char **argv) {
|
||||
if(use_software_video_encoder) {
|
||||
open_video_software(video_codec_context, quality, pixel_format, hdr, color_depth, bitrate_mode);
|
||||
} else {
|
||||
open_video_hardware(video_codec_context, quality, very_old_gpu, egl.gpu_info.vendor, pixel_format, hdr, color_depth, bitrate_mode, video_codec, low_power, high_performance_encoding);
|
||||
open_video_hardware(video_codec_context, quality, very_old_gpu, egl.gpu_info.vendor, pixel_format, hdr, color_depth, bitrate_mode, video_codec, low_power);
|
||||
}
|
||||
if(video_stream)
|
||||
avcodec_parameters_from_context(video_stream->codecpar, video_codec_context);
|
||||
|
||||
@@ -671,12 +671,19 @@ vec2i scale_keep_aspect_ratio(vec2i from, vec2i to) {
|
||||
}
|
||||
|
||||
unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format, int filter) {
|
||||
float border_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
if(format == GL_RG) { // UV
|
||||
border_color[0] = 0.5f;
|
||||
border_color[1] = 0.5f;
|
||||
border_color[2] = 0.0f;
|
||||
border_color[3] = 1.0f;
|
||||
}
|
||||
|
||||
unsigned int texture_id = 0;
|
||||
egl->glGenTextures(1, &texture_id);
|
||||
egl->glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
egl->glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
const float border_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
|
||||
|
||||
Reference in New Issue
Block a user