aboutsummaryrefslogtreecommitdiff
path: root/src/capture/kms.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/capture/kms.c')
-rw-r--r--src/capture/kms.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/src/capture/kms.c b/src/capture/kms.c
index 16b20b7..ec83cab 100644
--- a/src/capture/kms.c
+++ b/src/capture/kms.c
@@ -10,6 +10,10 @@
#define HDMI_STATIC_METADATA_TYPE1 0
#define HDMI_EOTF_SMPTE_ST2084 2
+static int max_int(int a, int b) {
+ return a > b ? a : b;
+}
+
/* TODO: On monitor reconfiguration, find monitor x, y, width and height again. Do the same for nvfbc. */
typedef struct {
@@ -35,10 +39,6 @@ static void monitor_callback(const gsr_monitor *monitor, void *userdata) {
fprintf(stderr, "gsr warning: reached max connector ids\n");
}
-static int max_int(int a, int b) {
- return a > b ? a : b;
-}
-
int gsr_capture_kms_start(gsr_capture_kms *self, const char *display_to_capture, gsr_egl *egl, AVCodecContext *video_codec_context, AVFrame *frame) {
memset(self, 0, sizeof(*self));
self->base.video_codec_context = video_codec_context;
@@ -77,8 +77,25 @@ int gsr_capture_kms_start(gsr_capture_kms *self, const char *display_to_capture,
/* Disable vsync */
egl->eglSwapInterval(egl->egl_display, 0);
- self->base.video_codec_context->width = max_int(2, even_number_ceil(self->capture_size.x));
- self->base.video_codec_context->height = max_int(2, even_number_ceil(self->capture_size.y));
+ // TODO: Move this and xcomposite equivalent to a common section unrelated to capture method
+ if(egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && video_codec_context->codec_id == AV_CODEC_ID_HEVC) {
+ // TODO: dont do this if using ffmpeg reports that this is not needed (AMD driver bug that was fixed recently)
+ self->base.video_codec_context->width = FFALIGN(self->capture_size.x, 64);
+ self->base.video_codec_context->height = FFALIGN(self->capture_size.y, 16);
+ } else if(egl->gpu_info.vendor == GSR_GPU_VENDOR_AMD && video_codec_context->codec_id == AV_CODEC_ID_AV1) {
+ // TODO: Dont do this for VCN 5 and forward which should fix this hardware bug
+ self->base.video_codec_context->width = FFALIGN(self->capture_size.x, 64);
+ // AMD driver has special case handling for 1080 height to set it to 1082 instead of 1088 (1080 aligned to 16).
+ // TODO: Set height to 1082 in this case, but it wont work because it will be aligned to 1088.
+ if(self->capture_size.y == 1080) {
+ self->base.video_codec_context->height = 1080;
+ } else {
+ self->base.video_codec_context->height = FFALIGN(self->capture_size.y, 16);
+ }
+ } else {
+ self->base.video_codec_context->width = FFALIGN(self->capture_size.x, 2);
+ self->base.video_codec_context->height = FFALIGN(self->capture_size.y, 2);
+ }
frame->width = self->base.video_codec_context->width;
frame->height = self->base.video_codec_context->height;
@@ -295,8 +312,11 @@ bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bo
const float texture_rotation = monitor_rotation_to_radians(self->monitor_rotation);
+ const int target_x = max_int(0, frame->width / 2 - self->capture_size.x / 2);
+ const int target_y = max_int(0, frame->height / 2 - self->capture_size.y / 2);
+
gsr_color_conversion_draw(&self->base.color_conversion, self->base.input_texture,
- (vec2i){0, 0}, self->capture_size,
+ (vec2i){target_x, target_y}, self->capture_size,
capture_pos, self->capture_size,
texture_rotation, false);
@@ -327,6 +347,9 @@ bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bo
break;
}
+ cursor_pos.x += target_x;
+ cursor_pos.y += target_y;
+
const intptr_t img_attr_cursor[] = {
EGL_LINUX_DRM_FOURCC_EXT, cursor_drm_fd->pixel_format,
EGL_WIDTH, cursor_drm_fd->width,
@@ -346,10 +369,15 @@ bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bo
self->base.egl->eglDestroyImage(self->base.egl->egl_display, cursor_image);
self->base.egl->glBindTexture(target, 0);
+ self->base.egl->glEnable(GL_SCISSOR_TEST);
+ self->base.egl->glScissor(target_x, target_y, self->capture_size.x, self->capture_size.y);
+
gsr_color_conversion_draw(&self->base.color_conversion, self->base.cursor_texture,
cursor_pos, cursor_size,
(vec2i){0, 0}, cursor_size,
texture_rotation, cursor_texture_is_external);
+
+ self->base.egl->glDisable(GL_SCISSOR_TEST);
}
self->base.egl->eglSwapBuffers(self->base.egl->egl_display, self->base.egl->egl_surface);