diff options
author | dec05eba <dec05eba@protonmail.com> | 2025-02-22 01:05:29 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2025-02-22 01:05:29 +0100 |
commit | 000da7d64044c4ea2a1679c2864252fee9895d48 (patch) | |
tree | dadeb51a2c1aeab844cbe5eb074a926905eff6d4 /src/capture | |
parent | fe4cd2bb0e244c568b24ed1c39a19497c41cb2f9 (diff) |
Make image output lossy (use stb image writer), also significantly improves performance for jpeg
Diffstat (limited to 'src/capture')
-rw-r--r-- | src/capture/capture.c | 12 | ||||
-rw-r--r-- | src/capture/kms.c | 31 | ||||
-rw-r--r-- | src/capture/nvfbc.c | 56 | ||||
-rw-r--r-- | src/capture/portal.c | 32 | ||||
-rw-r--r-- | src/capture/xcomposite.c | 29 |
5 files changed, 50 insertions, 110 deletions
diff --git a/src/capture/capture.c b/src/capture/capture.c index 2a4a689..bc95300 100644 --- a/src/capture/capture.c +++ b/src/capture/capture.c @@ -1,9 +1,9 @@ #include "../../include/capture/capture.h" #include <assert.h> -int gsr_capture_start(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame) { +int gsr_capture_start(gsr_capture *cap, gsr_capture_metadata *capture_metadata) { assert(!cap->started); - int res = cap->start(cap, video_codec_context, frame); + int res = cap->start(cap, capture_metadata); if(res == 0) cap->started = true; @@ -29,9 +29,9 @@ bool gsr_capture_should_stop(gsr_capture *cap, bool *err) { return false; } -int gsr_capture_capture(gsr_capture *cap, AVFrame *frame, gsr_color_conversion *color_conversion) { +int gsr_capture_capture(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion) { assert(cap->started); - return cap->capture(cap, frame, color_conversion); + return cap->capture(cap, capture_metadata, color_conversion); } bool gsr_capture_uses_external_image(gsr_capture *cap) { @@ -48,6 +48,6 @@ bool gsr_capture_set_hdr_metadata(gsr_capture *cap, AVMasteringDisplayMetadata * return false; } -void gsr_capture_destroy(gsr_capture *cap, AVCodecContext *video_codec_context) { - cap->destroy(cap, video_codec_context); +void gsr_capture_destroy(gsr_capture *cap) { + cap->destroy(cap); } diff --git a/src/capture/kms.c b/src/capture/kms.c index ae0c36f..266d4e6 100644 --- a/src/capture/kms.c +++ b/src/capture/kms.c @@ -55,7 +55,6 @@ typedef struct { bool is_x11; gsr_cursor x11_cursor; - AVCodecContext *video_codec_context; bool performance_error_shown; bool fast_path_failed; bool mesa_supports_compute_only_vaapi_copy; @@ -177,7 +176,7 @@ static vec2i rotate_capture_size_if_rotated(gsr_capture_kms *self, vec2i capture return capture_size; } -static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame) { +static int gsr_capture_kms_start(gsr_capture *cap, gsr_capture_metadata *capture_metadata) { gsr_capture_kms *self = cap->priv; gsr_capture_kms_create_input_texture_ids(self); @@ -219,17 +218,14 @@ static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_c else self->capture_size = rotate_capture_size_if_rotated(self, monitor.size); - /* Disable vsync */ - self->params.egl->eglSwapInterval(self->params.egl->egl_display, 0); - if(self->params.output_resolution.x == 0 && self->params.output_resolution.y == 0) { self->params.output_resolution = self->capture_size; - video_codec_context->width = FFALIGN(self->capture_size.x, 2); - video_codec_context->height = FFALIGN(self->capture_size.y, 2); + capture_metadata->width = FFALIGN(self->capture_size.x, 2); + capture_metadata->height = FFALIGN(self->capture_size.y, 2); } else { self->params.output_resolution = scale_keep_aspect_ratio(self->capture_size, self->params.output_resolution); - video_codec_context->width = FFALIGN(self->params.output_resolution.x, 2); - video_codec_context->height = FFALIGN(self->params.output_resolution.y, 2); + capture_metadata->width = FFALIGN(self->params.output_resolution.x, 2); + capture_metadata->height = FFALIGN(self->params.output_resolution.y, 2); } self->fast_path_failed = self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && !gl_driver_version_greater_than(&self->params.egl->gpu_info, 24, 0, 9); @@ -243,10 +239,6 @@ static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_c self->mesa_supports_compute_only_vaapi_copy = self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && gl_driver_version_greater_than(&self->params.egl->gpu_info, 24, 3, 6); - frame->width = video_codec_context->width; - frame->height = video_codec_context->height; - - self->video_codec_context = video_codec_context; self->last_time_monitor_check = clock_get_monotonic_seconds(); return 0; } @@ -617,7 +609,7 @@ static void gsr_capture_kms_fail_fast_path_if_not_fast(gsr_capture_kms *self, ui } } -static int gsr_capture_kms_capture(gsr_capture *cap, AVFrame *frame, gsr_color_conversion *color_conversion) { +static int gsr_capture_kms_capture(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion) { gsr_capture_kms *self = cap->priv; gsr_capture_kms_cleanup_kms_fds(self); @@ -648,7 +640,7 @@ static int gsr_capture_kms_capture(gsr_capture *cap, AVFrame *frame, gsr_color_c if(drm_fd->has_hdr_metadata && self->params.hdr && hdr_metadata_is_supported_format(&drm_fd->hdr_metadata)) gsr_kms_set_hdr_metadata(self, drm_fd); - if(!self->performance_error_shown && self->monitor_rotation != GSR_MONITOR_ROT_0 && video_codec_context_is_vaapi(self->video_codec_context) && self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD) { + if(!self->performance_error_shown && self->monitor_rotation != GSR_MONITOR_ROT_0 && video_codec_context_is_vaapi(capture_metadata->video_codec_context) && self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD) { self->performance_error_shown = true; self->fast_path_failed = true; fprintf(stderr, "gsr warning: gsr_capture_kms_capture: the monitor you are recording is rotated, composition will have to be used." @@ -664,7 +656,7 @@ static int gsr_capture_kms_capture(gsr_capture *cap, AVFrame *frame, gsr_color_c output_size = scale_keep_aspect_ratio(self->capture_size, output_size); const float texture_rotation = monitor_rotation_to_radians(self->monitor_rotation); - const vec2i target_pos = { max_int(0, frame->width / 2 - output_size.x / 2), max_int(0, frame->height / 2 - output_size.y / 2) }; + const vec2i target_pos = { max_int(0, capture_metadata->width / 2 - output_size.x / 2), max_int(0, capture_metadata->height / 2 - output_size.y / 2) }; gsr_capture_kms_update_capture_size_change(self, color_conversion, target_pos, drm_fd); vec2i capture_pos = self->capture_pos; @@ -675,7 +667,7 @@ static int gsr_capture_kms_capture(gsr_capture *cap, AVFrame *frame, gsr_color_c self->params.egl->glFinish(); /* Fast opengl free path */ - if(!self->fast_path_failed && self->monitor_rotation == GSR_MONITOR_ROT_0 && video_codec_context_is_vaapi(self->video_codec_context) && self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD) { + if(!self->fast_path_failed && self->monitor_rotation == GSR_MONITOR_ROT_0 && video_codec_context_is_vaapi(capture_metadata->video_codec_context) && self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD) { int fds[4]; uint32_t offsets[4]; uint32_t pitches[4]; @@ -686,7 +678,7 @@ static int gsr_capture_kms_capture(gsr_capture *cap, AVFrame *frame, gsr_color_c pitches[i] = drm_fd->dma_buf[i].pitch; modifiers[i] = drm_fd->modifier; } - if(!vaapi_copy_drm_planes_to_video_surface(self->video_codec_context, frame, (vec2i){capture_pos.x, capture_pos.y}, self->capture_size, target_pos, output_size, drm_fd->pixel_format, (vec2i){drm_fd->width, drm_fd->height}, fds, offsets, pitches, modifiers, drm_fd->num_dma_bufs)) { + if(!vaapi_copy_drm_planes_to_video_surface(capture_metadata->video_codec_context, capture_metadata->frame, (vec2i){capture_pos.x, capture_pos.y}, self->capture_size, target_pos, output_size, drm_fd->pixel_format, (vec2i){drm_fd->width, drm_fd->height}, fds, offsets, pitches, modifiers, drm_fd->num_dma_bufs)) { fprintf(stderr, "gsr error: gsr_capture_kms_capture: vaapi_copy_drm_planes_to_video_surface failed, falling back to opengl copy. Please report this as an issue at https://github.com/dec05eba/gpu-screen-recorder-issues\n"); self->fast_path_failed = true; } @@ -777,8 +769,7 @@ static bool gsr_capture_kms_set_hdr_metadata(gsr_capture *cap, AVMasteringDispla // self->damaged = false; // } -static void gsr_capture_kms_destroy(gsr_capture *cap, AVCodecContext *video_codec_context) { - (void)video_codec_context; +static void gsr_capture_kms_destroy(gsr_capture *cap) { gsr_capture_kms *self = cap->priv; if(cap->priv) { gsr_capture_kms_stop(self); diff --git a/src/capture/nvfbc.c b/src/capture/nvfbc.c index 676d269..af79e0d 100644 --- a/src/capture/nvfbc.c +++ b/src/capture/nvfbc.c @@ -133,31 +133,6 @@ static bool gsr_capture_nvfbc_load_library(gsr_capture *cap) { return true; } -/* TODO: check for glx swap control extension string (GLX_EXT_swap_control, etc) */ -static void set_vertical_sync_enabled(gsr_egl *egl, int enabled) { - int result = 0; - - if(egl->glXSwapIntervalEXT) { - assert(gsr_window_get_display_server(egl->window) == GSR_DISPLAY_SERVER_X11); - Display *display = gsr_window_get_display(egl->window); - const Window window = (Window)gsr_window_get_window(egl->window); - egl->glXSwapIntervalEXT(display, window, enabled ? 1 : 0); - } else if(egl->glXSwapIntervalMESA) { - result = egl->glXSwapIntervalMESA(enabled ? 1 : 0); - } else if(egl->glXSwapIntervalSGI) { - result = egl->glXSwapIntervalSGI(enabled ? 1 : 0); - } else { - static int warned = 0; - if (!warned) { - warned = 1; - fprintf(stderr, "gsr warning: setting vertical sync not supported\n"); - } - } - - if(result != 0) - fprintf(stderr, "gsr warning: setting vertical sync failed\n"); -} - static void gsr_capture_nvfbc_destroy_session(gsr_capture_nvfbc *self) { if(self->fbc_handle_created && self->capture_session_created) { NVFBC_DESTROY_CAPTURE_SESSION_PARAMS destroy_capture_params; @@ -311,7 +286,7 @@ static void gsr_capture_nvfbc_stop(gsr_capture_nvfbc *self) { } } -static int gsr_capture_nvfbc_start(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame) { +static int gsr_capture_nvfbc_start(gsr_capture *cap, gsr_capture_metadata *capture_metadata) { gsr_capture_nvfbc *self = cap->priv; if(!gsr_capture_nvfbc_load_library(cap)) @@ -357,27 +332,21 @@ static int gsr_capture_nvfbc_start(gsr_capture *cap, AVCodecContext *video_codec } if(self->capture_region) { - video_codec_context->width = FFALIGN(self->width, 2); - video_codec_context->height = FFALIGN(self->height, 2); + capture_metadata->width = FFALIGN(self->width, 2); + capture_metadata->height = FFALIGN(self->height, 2); } else { - video_codec_context->width = FFALIGN(self->tracking_width, 2); - video_codec_context->height = FFALIGN(self->tracking_height, 2); + capture_metadata->width = FFALIGN(self->tracking_width, 2); + capture_metadata->height = FFALIGN(self->tracking_height, 2); } if(self->params.output_resolution.x == 0 && self->params.output_resolution.y == 0) { - self->params.output_resolution = (vec2i){video_codec_context->width, video_codec_context->height}; + self->params.output_resolution = (vec2i){capture_metadata->width, capture_metadata->height}; } else { - self->params.output_resolution = scale_keep_aspect_ratio((vec2i){video_codec_context->width, video_codec_context->height}, self->params.output_resolution); - video_codec_context->width = FFALIGN(self->params.output_resolution.x, 2); - video_codec_context->height = FFALIGN(self->params.output_resolution.y, 2); + self->params.output_resolution = scale_keep_aspect_ratio((vec2i){capture_metadata->width, capture_metadata->height}, self->params.output_resolution); + capture_metadata->width = FFALIGN(self->params.output_resolution.x, 2); + capture_metadata->height = FFALIGN(self->params.output_resolution.y, 2); } - frame->width = video_codec_context->width; - frame->height = video_codec_context->height; - - /* Disable vsync */ - set_vertical_sync_enabled(self->params.egl, 0); - return 0; error_cleanup: @@ -385,7 +354,7 @@ static int gsr_capture_nvfbc_start(gsr_capture *cap, AVCodecContext *video_codec return -1; } -static int gsr_capture_nvfbc_capture(gsr_capture *cap, AVFrame *frame, gsr_color_conversion *color_conversion) { +static int gsr_capture_nvfbc_capture(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion) { gsr_capture_nvfbc *self = cap->priv; const double nvfbc_recreate_retry_time_seconds = 1.0; @@ -416,7 +385,7 @@ static int gsr_capture_nvfbc_capture(gsr_capture *cap, AVFrame *frame, gsr_color vec2i output_size = is_scaled ? self->params.output_resolution : frame_size; output_size = scale_keep_aspect_ratio(frame_size, output_size); - const vec2i target_pos = { max_int(0, frame->width / 2 - output_size.x / 2), max_int(0, frame->height / 2 - output_size.y / 2) }; + const vec2i target_pos = { max_int(0, capture_metadata->width / 2 - output_size.x / 2), max_int(0, capture_metadata->height / 2 - output_size.y / 2) }; NVFBC_FRAME_GRAB_INFO frame_info; memset(&frame_info, 0, sizeof(frame_info)); @@ -450,8 +419,7 @@ static int gsr_capture_nvfbc_capture(gsr_capture *cap, AVFrame *frame, gsr_color return 0; } -static void gsr_capture_nvfbc_destroy(gsr_capture *cap, AVCodecContext *video_codec_context) { - (void)video_codec_context; +static void gsr_capture_nvfbc_destroy(gsr_capture *cap) { gsr_capture_nvfbc *self = cap->priv; gsr_capture_nvfbc_stop(self); free(cap->priv); diff --git a/src/capture/portal.c b/src/capture/portal.c index 27486fd..cfbfbcd 100644 --- a/src/capture/portal.c +++ b/src/capture/portal.c @@ -25,7 +25,6 @@ typedef struct { gsr_pipewire_video_dmabuf_data dmabuf_data[GSR_PIPEWIRE_VIDEO_DMABUF_MAX_PLANES]; int num_dmabuf_data; - AVCodecContext *video_codec_context; bool fast_path_failed; bool mesa_supports_compute_only_vaapi_copy; } gsr_capture_portal; @@ -257,7 +256,7 @@ static bool gsr_capture_portal_get_frame_dimensions(gsr_capture_portal *self) { return false; } -static int gsr_capture_portal_start(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame) { +static int gsr_capture_portal_start(gsr_capture *cap, gsr_capture_metadata *capture_metadata) { gsr_capture_portal *self = cap->priv; gsr_capture_portal_create_input_textures(self); @@ -286,7 +285,7 @@ static int gsr_capture_portal_start(gsr_capture *cap, AVCodecContext *video_code fprintf(stderr, "gsr info: gsr_capture_portal_start: setting up pipewire\n"); /* TODO: support hdr when pipewire supports it */ /* gsr_pipewire closes the pipewire fd, even on failure */ - if(!gsr_pipewire_video_init(&self->pipewire, pipewire_fd, pipewire_node, video_codec_context->framerate.num, self->params.record_cursor, self->params.egl)) { + if(!gsr_pipewire_video_init(&self->pipewire, pipewire_fd, pipewire_node, capture_metadata->fps, self->params.record_cursor, self->params.egl)) { fprintf(stderr, "gsr error: gsr_capture_portal_start: failed to setup pipewire with fd: %d, node: %" PRIu32 "\n", pipewire_fd, pipewire_node); gsr_capture_portal_stop(self); return -1; @@ -298,17 +297,14 @@ static int gsr_capture_portal_start(gsr_capture *cap, AVCodecContext *video_code return -1; } - /* Disable vsync */ - self->params.egl->eglSwapInterval(self->params.egl->egl_display, 0); - if(self->params.output_resolution.x == 0 && self->params.output_resolution.y == 0) { self->params.output_resolution = self->capture_size; - video_codec_context->width = FFALIGN(self->capture_size.x, 2); - video_codec_context->height = FFALIGN(self->capture_size.y, 2); + capture_metadata->width = FFALIGN(self->capture_size.x, 2); + capture_metadata->height = FFALIGN(self->capture_size.y, 2); } else { self->params.output_resolution = scale_keep_aspect_ratio(self->capture_size, self->params.output_resolution); - video_codec_context->width = FFALIGN(self->params.output_resolution.x, 2); - video_codec_context->height = FFALIGN(self->params.output_resolution.y, 2); + capture_metadata->width = FFALIGN(self->params.output_resolution.x, 2); + capture_metadata->height = FFALIGN(self->params.output_resolution.y, 2); } self->fast_path_failed = self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && !gl_driver_version_greater_than(&self->params.egl->gpu_info, 24, 0, 9); @@ -317,10 +313,6 @@ static int gsr_capture_portal_start(gsr_capture *cap, AVCodecContext *video_code self->mesa_supports_compute_only_vaapi_copy = self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && gl_driver_version_greater_than(&self->params.egl->gpu_info, 24, 3, 6); - frame->width = video_codec_context->width; - frame->height = video_codec_context->height; - - self->video_codec_context = video_codec_context; return 0; } @@ -338,8 +330,7 @@ static void gsr_capture_portal_fail_fast_path_if_not_fast(gsr_capture_portal *se } } -static int gsr_capture_portal_capture(gsr_capture *cap, AVFrame *frame, gsr_color_conversion *color_conversion) { - (void)frame; +static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion) { (void)color_conversion; gsr_capture_portal *self = cap->priv; @@ -365,7 +356,7 @@ static int gsr_capture_portal_capture(gsr_capture *cap, AVFrame *frame, gsr_colo vec2i output_size = is_scaled ? self->params.output_resolution : self->capture_size; output_size = scale_keep_aspect_ratio(self->capture_size, output_size); - const vec2i target_pos = { max_int(0, frame->width / 2 - output_size.x / 2), max_int(0, frame->height / 2 - output_size.y / 2) }; + const vec2i target_pos = { max_int(0, capture_metadata->width / 2 - output_size.x / 2), max_int(0, capture_metadata->height / 2 - output_size.y / 2) }; self->params.egl->glFlush(); self->params.egl->glFinish(); @@ -373,7 +364,7 @@ static int gsr_capture_portal_capture(gsr_capture *cap, AVFrame *frame, gsr_colo // TODO: Handle region crop /* Fast opengl free path */ - if(!self->fast_path_failed && video_codec_context_is_vaapi(self->video_codec_context) && self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD) { + if(!self->fast_path_failed && video_codec_context_is_vaapi(capture_metadata->video_codec_context) && self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD) { int fds[4]; uint32_t offsets[4]; uint32_t pitches[4]; @@ -384,7 +375,7 @@ static int gsr_capture_portal_capture(gsr_capture *cap, AVFrame *frame, gsr_colo pitches[i] = self->dmabuf_data[i].stride; modifiers[i] = pipewire_modifiers; } - if(!vaapi_copy_drm_planes_to_video_surface(self->video_codec_context, frame, (vec2i){region.x, region.y}, self->capture_size, target_pos, output_size, pipewire_fourcc, self->capture_size, fds, offsets, pitches, modifiers, self->num_dmabuf_data)) { + if(!vaapi_copy_drm_planes_to_video_surface(capture_metadata->video_codec_context, capture_metadata->frame, (vec2i){region.x, region.y}, self->capture_size, target_pos, output_size, pipewire_fourcc, self->capture_size, fds, offsets, pitches, modifiers, self->num_dmabuf_data)) { fprintf(stderr, "gsr error: gsr_capture_portal_capture: vaapi_copy_drm_planes_to_video_surface failed, falling back to opengl copy. Please report this as an issue at https://github.com/dec05eba/gpu-screen-recorder-issues\n"); self->fast_path_failed = true; } @@ -442,8 +433,7 @@ static void gsr_capture_portal_clear_damage(gsr_capture *cap) { gsr_pipewire_video_clear_damage(&self->pipewire); } -static void gsr_capture_portal_destroy(gsr_capture *cap, AVCodecContext *video_codec_context) { - (void)video_codec_context; +static void gsr_capture_portal_destroy(gsr_capture *cap) { gsr_capture_portal *self = cap->priv; if(cap->priv) { gsr_capture_portal_stop(self); diff --git a/src/capture/xcomposite.c b/src/capture/xcomposite.c index 5cef71d..94e691b 100644 --- a/src/capture/xcomposite.c +++ b/src/capture/xcomposite.c @@ -31,7 +31,6 @@ typedef struct { double window_resize_timer; WindowTexture window_texture; - AVCodecContext *video_codec_context; Atom net_active_window_atom; @@ -64,7 +63,7 @@ static Window get_focused_window(Display *display, Atom net_active_window_atom) return None; } -static int gsr_capture_xcomposite_start(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame) { +static int gsr_capture_xcomposite_start(gsr_capture *cap, gsr_capture_metadata *capture_metadata) { gsr_capture_xcomposite *self = cap->priv; if(self->params.follow_focused) { @@ -95,8 +94,6 @@ static int gsr_capture_xcomposite_start(gsr_capture *cap, AVCodecContext *video_ // TODO: Get select and add these on top of it and then restore at the end. Also do the same in other xcomposite XSelectInput(self->display, self->window, StructureNotifyMask | ExposureMask); - /* Disable vsync */ - self->params.egl->eglSwapInterval(self->params.egl->egl_display, 0); if(window_texture_init(&self->window_texture, self->display, self->window, self->params.egl) != 0 && !self->params.follow_focused) { fprintf(stderr, "gsr error: gsr_capture_xcomposite_start: failed to get window texture for window %ld\n", (long)self->window); return -1; @@ -117,21 +114,17 @@ static int gsr_capture_xcomposite_start(gsr_capture *cap, AVCodecContext *video_ if(self->params.output_resolution.x == 0 && self->params.output_resolution.y == 0) { self->params.output_resolution = self->texture_size; - video_codec_context->width = FFALIGN(self->texture_size.x, 2); - video_codec_context->height = FFALIGN(self->texture_size.y, 2); + capture_metadata->width = FFALIGN(self->texture_size.x, 2); + capture_metadata->height = FFALIGN(self->texture_size.y, 2); } else { - video_codec_context->width = FFALIGN(self->params.output_resolution.x, 2); - video_codec_context->height = FFALIGN(self->params.output_resolution.y, 2); + capture_metadata->width = FFALIGN(self->params.output_resolution.x, 2); + capture_metadata->height = FFALIGN(self->params.output_resolution.y, 2); } self->fast_path_failed = self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && !gl_driver_version_greater_than(&self->params.egl->gpu_info, 24, 0, 9); if(self->fast_path_failed) fprintf(stderr, "gsr warning: gsr_capture_kms_start: your amd driver (mesa) version is known to be buggy (<= version 24.0.9), falling back to opengl copy\n"); - frame->width = video_codec_context->width; - frame->height = video_codec_context->height; - - self->video_codec_context = video_codec_context; self->window_resize_timer = clock_get_monotonic_seconds(); return 0; } @@ -255,9 +248,8 @@ static bool gsr_capture_xcomposite_should_stop(gsr_capture *cap, bool *err) { return false; } -static int gsr_capture_xcomposite_capture(gsr_capture *cap, AVFrame *frame, gsr_color_conversion *color_conversion) { +static int gsr_capture_xcomposite_capture(gsr_capture *cap, gsr_capture_metadata *capture_metdata, gsr_color_conversion *color_conversion) { gsr_capture_xcomposite *self = cap->priv; - (void)frame; if(self->clear_background) { self->clear_background = false; @@ -268,14 +260,14 @@ static int gsr_capture_xcomposite_capture(gsr_capture *cap, AVFrame *frame, gsr_ vec2i output_size = is_scaled ? self->params.output_resolution : self->texture_size; output_size = scale_keep_aspect_ratio(self->texture_size, output_size); - const vec2i target_pos = { max_int(0, frame->width / 2 - output_size.x / 2), max_int(0, frame->height / 2 - output_size.y / 2) }; + const vec2i target_pos = { max_int(0, capture_metdata->width / 2 - output_size.x / 2), max_int(0, capture_metdata->height / 2 - output_size.y / 2) }; self->params.egl->glFlush(); self->params.egl->glFinish(); /* Fast opengl free path */ - if(!self->fast_path_failed && video_codec_context_is_vaapi(self->video_codec_context) && self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD) { - if(!vaapi_copy_egl_image_to_video_surface(self->params.egl, self->window_texture.image, (vec2i){0, 0}, self->texture_size, target_pos, output_size, self->video_codec_context, frame)) { + if(!self->fast_path_failed && video_codec_context_is_vaapi(capture_metdata->video_codec_context) && self->params.egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD) { + if(!vaapi_copy_egl_image_to_video_surface(self->params.egl, self->window_texture.image, (vec2i){0, 0}, self->texture_size, target_pos, output_size, capture_metdata->video_codec_context, capture_metdata->frame)) { fprintf(stderr, "gsr error: gsr_capture_xcomposite_capture: vaapi_copy_egl_image_to_video_surface failed, falling back to opengl copy. Please report this as an issue at https://github.com/dec05eba/gpu-screen-recorder-issues\n"); self->fast_path_failed = true; } @@ -325,8 +317,7 @@ static uint64_t gsr_capture_xcomposite_get_window_id(gsr_capture *cap) { return self->window; } -static void gsr_capture_xcomposite_destroy(gsr_capture *cap, AVCodecContext *video_codec_context) { - (void)video_codec_context; +static void gsr_capture_xcomposite_destroy(gsr_capture *cap) { if(cap->priv) { gsr_capture_xcomposite_stop(cap->priv); free(cap->priv); |