mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-03-31 09:07:13 +09:00
Revert kde plasma 6.2 hdr workaround code
This commit is contained in:
@@ -181,5 +181,5 @@ You can record with desktop portal option (`-w portal`) instead which ignores ni
|
|||||||
## Kdenlive says that the video is not usable for editing because it has variable frame rate
|
## Kdenlive says that the video is not usable for editing because it has variable frame rate
|
||||||
To fix this you can either record the video in .mkv format or constant frame rate (-fm cfr).
|
To fix this you can either record the video in .mkv format or constant frame rate (-fm cfr).
|
||||||
## Colors look incorrect when recording HDR (with hevc_hdr/av1_hdr) or using an ICC profile
|
## Colors look incorrect when recording HDR (with hevc_hdr/av1_hdr) or using an ICC profile
|
||||||
KDE Plasma version 6.2 broke HDR and ICC profiles for screen recorders. This was changed in KDE plasma version 6.3 and recording HDR works now, as long as you set HDR brightness to 100% (which means setting Maximum SDR Brightness in KDE plasma display settings to 203). If you want to convert HDR to SDR then record with desktop portal option (`-w portal`) instead.
|
KDE Plasma version 6.2 broke HDR and ICC profiles for screen recorders. This was changed in KDE plasma version 6.3 and recording HDR works now, as long as you set HDR brightness to 100% (which means setting "Maximum SDR Brightness" in KDE plasma display settings to 203). If you want to convert HDR to SDR then record with desktop portal option (`-w portal`) instead.
|
||||||
I don't know how well recording HDR works in wayland compositors other than KDE plasma.
|
I don't know how well recording HDR works in wayland compositors other than KDE plasma.
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ typedef struct {
|
|||||||
|
|
||||||
gsr_color_range color_range;
|
gsr_color_range color_range;
|
||||||
bool load_external_image_shader;
|
bool load_external_image_shader;
|
||||||
|
|
||||||
bool kde_gamma_correction;
|
|
||||||
} gsr_color_conversion_params;
|
} gsr_color_conversion_params;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ struct gsr_window {
|
|||||||
void* (*get_display)(gsr_window *self);
|
void* (*get_display)(gsr_window *self);
|
||||||
void* (*get_window)(gsr_window *self);
|
void* (*get_window)(gsr_window *self);
|
||||||
void (*for_each_active_monitor_output_cached)(const gsr_window *self, active_monitor_callback callback, void *userdata);
|
void (*for_each_active_monitor_output_cached)(const gsr_window *self, active_monitor_callback callback, void *userdata);
|
||||||
bool (*is_compositor_kwin)(const gsr_window *self); /* can be NULL. Is currently only defined for Wayland */
|
|
||||||
void *priv;
|
void *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ static const char* color_format_range_get_transform_matrix(gsr_destination_color
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_shader_y(gsr_shader *shader, gsr_egl *egl, gsr_color_uniforms *uniforms, gsr_destination_color color_format, gsr_color_range color_range, bool external_texture, bool kde_gamma_correction) {
|
static int load_shader_y(gsr_shader *shader, gsr_egl *egl, gsr_color_uniforms *uniforms, gsr_destination_color color_format, gsr_color_range color_range, bool external_texture) {
|
||||||
const char *color_transform_matrix = color_format_range_get_transform_matrix(color_format, color_range);
|
const char *color_transform_matrix = color_format_range_get_transform_matrix(color_format, color_range);
|
||||||
|
|
||||||
char vertex_shader[2048];
|
char vertex_shader[2048];
|
||||||
@@ -93,25 +93,11 @@ static int load_shader_y(gsr_shader *shader, gsr_egl *egl, gsr_color_uniforms *u
|
|||||||
" gl_Position = vec4(offset.x, offset.y, 0.0, 0.0) + vec4(pos.x, pos.y, 0.0, 1.0); \n"
|
" gl_Position = vec4(offset.x, offset.y, 0.0, 0.0) + vec4(pos.x, pos.y, 0.0, 1.0); \n"
|
||||||
"} \n");
|
"} \n");
|
||||||
|
|
||||||
const char *main_code = NULL;
|
const char *main_code =
|
||||||
if(kde_gamma_correction) {
|
|
||||||
if(color_range == GSR_COLOR_RANGE_FULL) {
|
|
||||||
main_code =
|
|
||||||
" vec4 pixel = texture(tex1, texcoords_out); \n"
|
|
||||||
" FragColor.x = pow((RGBtoYUV * vec4(pixel.rgb, 1.0)).x, 0.55)*0.8; \n"
|
|
||||||
" FragColor.w = pixel.a; \n";
|
|
||||||
} else {
|
|
||||||
main_code =
|
|
||||||
" vec4 pixel = texture(tex1, texcoords_out); \n"
|
|
||||||
" FragColor.x = pow((RGBtoYUV * vec4(pixel.rgb, 1.0)).x, 0.6)*0.82; \n"
|
|
||||||
" FragColor.w = pixel.a; \n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
main_code =
|
main_code =
|
||||||
" vec4 pixel = texture(tex1, texcoords_out); \n"
|
" vec4 pixel = texture(tex1, texcoords_out); \n"
|
||||||
" FragColor.x = (RGBtoYUV * vec4(pixel.rgb, 1.0)).x; \n"
|
" FragColor.x = (RGBtoYUV * vec4(pixel.rgb, 1.0)).x; \n"
|
||||||
" FragColor.w = pixel.a; \n";
|
" FragColor.w = pixel.a; \n";
|
||||||
}
|
|
||||||
|
|
||||||
char fragment_shader[2048];
|
char fragment_shader[2048];
|
||||||
if(external_texture) {
|
if(external_texture) {
|
||||||
@@ -152,7 +138,7 @@ static int load_shader_y(gsr_shader *shader, gsr_egl *egl, gsr_color_uniforms *u
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int load_shader_uv(gsr_shader *shader, gsr_egl *egl, gsr_color_uniforms *uniforms, gsr_destination_color color_format, gsr_color_range color_range, bool external_texture, bool kde_gamma_correction) {
|
static unsigned int load_shader_uv(gsr_shader *shader, gsr_egl *egl, gsr_color_uniforms *uniforms, gsr_destination_color color_format, gsr_color_range color_range, bool external_texture) {
|
||||||
const char *color_transform_matrix = color_format_range_get_transform_matrix(color_format, color_range);
|
const char *color_transform_matrix = color_format_range_get_transform_matrix(color_format, color_range);
|
||||||
|
|
||||||
char vertex_shader[2048];
|
char vertex_shader[2048];
|
||||||
@@ -161,7 +147,7 @@ static unsigned int load_shader_uv(gsr_shader *shader, gsr_egl *egl, gsr_color_u
|
|||||||
"in vec2 pos; \n"
|
"in vec2 pos; \n"
|
||||||
"in vec2 texcoords; \n"
|
"in vec2 texcoords; \n"
|
||||||
"out vec2 texcoords_out; \n"
|
"out vec2 texcoords_out; \n"
|
||||||
"uniform vec2 offset; \n"
|
"uniform vec2 offset; \n"
|
||||||
"uniform float rotation; \n"
|
"uniform float rotation; \n"
|
||||||
ROTATE_Z
|
ROTATE_Z
|
||||||
"void main() \n"
|
"void main() \n"
|
||||||
@@ -170,25 +156,11 @@ static unsigned int load_shader_uv(gsr_shader *shader, gsr_egl *egl, gsr_color_u
|
|||||||
" gl_Position = (vec4(offset.x, offset.y, 0.0, 0.0) + vec4(pos.x, pos.y, 0.0, 1.0)) * vec4(0.5, 0.5, 1.0, 1.0) - vec4(0.5, 0.5, 0.0, 0.0); \n"
|
" gl_Position = (vec4(offset.x, offset.y, 0.0, 0.0) + vec4(pos.x, pos.y, 0.0, 1.0)) * vec4(0.5, 0.5, 1.0, 1.0) - vec4(0.5, 0.5, 0.0, 0.0); \n"
|
||||||
"} \n");
|
"} \n");
|
||||||
|
|
||||||
const char *main_code = NULL;
|
const char *main_code =
|
||||||
if(kde_gamma_correction) {
|
|
||||||
if(color_range == GSR_COLOR_RANGE_FULL) {
|
|
||||||
main_code =
|
|
||||||
" vec4 pixel = texture(tex1, texcoords_out); \n"
|
|
||||||
" FragColor.xy = (RGBtoYUV * vec4(pow(pixel.rgb, vec3(0.3)), 1.0)).yz; \n"
|
|
||||||
" FragColor.w = pixel.a; \n";
|
|
||||||
} else {
|
|
||||||
main_code =
|
|
||||||
" vec4 pixel = texture(tex1, texcoords_out); \n"
|
|
||||||
" FragColor.xy = (RGBtoYUV * vec4(pow(pixel.rgb, vec3(0.3)), 1.0)).yz; \n"
|
|
||||||
" FragColor.w = pixel.a; \n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
main_code =
|
main_code =
|
||||||
" vec4 pixel = texture(tex1, texcoords_out); \n"
|
" vec4 pixel = texture(tex1, texcoords_out); \n"
|
||||||
" FragColor.xy = (RGBtoYUV * vec4(pixel.rgb, 1.0)).yz; \n"
|
" FragColor.xy = (RGBtoYUV * vec4(pixel.rgb, 1.0)).yz; \n"
|
||||||
" FragColor.w = pixel.a; \n";
|
" FragColor.w = pixel.a; \n";
|
||||||
}
|
|
||||||
|
|
||||||
char fragment_shader[2048];
|
char fragment_shader[2048];
|
||||||
if(external_texture) {
|
if(external_texture) {
|
||||||
@@ -293,23 +265,23 @@ int gsr_color_conversion_init(gsr_color_conversion *self, const gsr_color_conver
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(load_shader_y(&self->shaders[0], self->params.egl, &self->uniforms[0], params->destination_color, params->color_range, false, params->kde_gamma_correction) != 0) {
|
if(load_shader_y(&self->shaders[0], self->params.egl, &self->uniforms[0], params->destination_color, params->color_range, false) != 0) {
|
||||||
fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load Y shader\n");
|
fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load Y shader\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(load_shader_uv(&self->shaders[1], self->params.egl, &self->uniforms[1], params->destination_color, params->color_range, false, params->kde_gamma_correction) != 0) {
|
if(load_shader_uv(&self->shaders[1], self->params.egl, &self->uniforms[1], params->destination_color, params->color_range, false) != 0) {
|
||||||
fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load UV shader\n");
|
fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load UV shader\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self->params.load_external_image_shader) {
|
if(self->params.load_external_image_shader) {
|
||||||
if(load_shader_y(&self->shaders[2], self->params.egl, &self->uniforms[2], params->destination_color, params->color_range, true, params->kde_gamma_correction) != 0) {
|
if(load_shader_y(&self->shaders[2], self->params.egl, &self->uniforms[2], params->destination_color, params->color_range, true) != 0) {
|
||||||
fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load Y shader\n");
|
fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load Y shader\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(load_shader_uv(&self->shaders[3], self->params.egl, &self->uniforms[3], params->destination_color, params->color_range, true, params->kde_gamma_correction) != 0) {
|
if(load_shader_uv(&self->shaders[3], self->params.egl, &self->uniforms[3], params->destination_color, params->color_range, true) != 0) {
|
||||||
fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load UV shader\n");
|
fprintf(stderr, "gsr error: gsr_color_conversion_init: failed to load UV shader\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|||||||
35
src/main.cpp
35
src/main.cpp
@@ -3007,40 +3007,6 @@ static AudioDeviceData create_application_audio_audio_input(const MergedAudioInp
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool is_kde_plasma_version_greater_than_6_1_90() {
|
|
||||||
const bool inside_flatpak = getenv("FLATPAK_ID") != NULL;
|
|
||||||
const char *cmd = nullptr;
|
|
||||||
if(inside_flatpak)
|
|
||||||
cmd = "flatpak-spawn --host -- plasmashell -v 2> /dev/null";
|
|
||||||
else
|
|
||||||
cmd = "plasmashell -v 2> /dev/null";
|
|
||||||
|
|
||||||
FILE *f = popen(cmd, "r");
|
|
||||||
if(!f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
char output[512];
|
|
||||||
const ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f);
|
|
||||||
if(bytes_read < 0 || ferror(f)) {
|
|
||||||
pclose(f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
output[bytes_read] = '\0';
|
|
||||||
|
|
||||||
bool is_above = false;
|
|
||||||
const char *version_start = strstr(output, "plasmashell ");
|
|
||||||
if(version_start) {
|
|
||||||
version_start += 12;
|
|
||||||
int major = 0;
|
|
||||||
int minor = 0;
|
|
||||||
int patch = 0;
|
|
||||||
is_above = sscanf(version_start, "%d.%d.%d", &major, &minor, &patch) == 3 && version_greater_than(major, minor, patch, 6, 1, 90);
|
|
||||||
}
|
|
||||||
|
|
||||||
pclose(f);
|
|
||||||
return is_above;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool arg_get_boolean_value(std::map<std::string, Arg> &args, const char *arg_name, bool default_value) {
|
static bool arg_get_boolean_value(std::map<std::string, Arg> &args, const char *arg_name, bool default_value) {
|
||||||
auto it = args.find(arg_name);
|
auto it = args.find(arg_name);
|
||||||
if(it == args.end() || !it->second.value()) {
|
if(it == args.end() || !it->second.value()) {
|
||||||
@@ -3769,7 +3735,6 @@ int main(int argc, char **argv) {
|
|||||||
color_conversion_params.color_range = color_range;
|
color_conversion_params.color_range = color_range;
|
||||||
color_conversion_params.egl = &egl;
|
color_conversion_params.egl = &egl;
|
||||||
color_conversion_params.load_external_image_shader = gsr_capture_uses_external_image(capture);
|
color_conversion_params.load_external_image_shader = gsr_capture_uses_external_image(capture);
|
||||||
color_conversion_params.kde_gamma_correction = false;//hdr && is_monitor_capture && window->is_compositor_kwin && window->is_compositor_kwin(window) && is_kde_plasma_version_greater_than_6_1_90();
|
|
||||||
gsr_video_encoder_get_textures(video_encoder, color_conversion_params.destination_textures, &color_conversion_params.num_destination_textures, &color_conversion_params.destination_color);
|
gsr_video_encoder_get_textures(video_encoder, color_conversion_params.destination_textures, &color_conversion_params.num_destination_textures, &color_conversion_params.destination_color);
|
||||||
|
|
||||||
gsr_color_conversion color_conversion;
|
gsr_color_conversion color_conversion;
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ typedef struct {
|
|||||||
void *compositor;
|
void *compositor;
|
||||||
gsr_wayland_output outputs[GSR_MAX_OUTPUTS];
|
gsr_wayland_output outputs[GSR_MAX_OUTPUTS];
|
||||||
int num_outputs;
|
int num_outputs;
|
||||||
bool is_compositor_kwin;
|
|
||||||
} gsr_window_wayland;
|
} gsr_window_wayland;
|
||||||
|
|
||||||
static void output_handle_geometry(void *data, struct wl_output *wl_output,
|
static void output_handle_geometry(void *data, struct wl_output *wl_output,
|
||||||
@@ -124,8 +123,6 @@ static void registry_add_object(void *data, struct wl_registry *registry, uint32
|
|||||||
.name = NULL,
|
.name = NULL,
|
||||||
};
|
};
|
||||||
wl_output_add_listener(gsr_output->output, &output_listener, gsr_output);
|
wl_output_add_listener(gsr_output->output, &output_listener, gsr_output);
|
||||||
} else if(strcmp(interface, "org_kde_plasma_shell") == 0) {
|
|
||||||
window_wayland->is_compositor_kwin = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,11 +289,6 @@ static void gsr_window_wayland_for_each_active_monitor_output_cached(const gsr_w
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gsr_window_wayland_is_compositor_kwin(const gsr_window *window) {
|
|
||||||
const gsr_window_wayland *self = window->priv;
|
|
||||||
return self->is_compositor_kwin;
|
|
||||||
}
|
|
||||||
|
|
||||||
gsr_window* gsr_window_wayland_create(void) {
|
gsr_window* gsr_window_wayland_create(void) {
|
||||||
gsr_window *window = calloc(1, sizeof(gsr_window));
|
gsr_window *window = calloc(1, sizeof(gsr_window));
|
||||||
if(!window)
|
if(!window)
|
||||||
@@ -322,7 +314,6 @@ gsr_window* gsr_window_wayland_create(void) {
|
|||||||
.get_display = gsr_window_wayland_get_display,
|
.get_display = gsr_window_wayland_get_display,
|
||||||
.get_window = gsr_window_wayland_get_window,
|
.get_window = gsr_window_wayland_get_window,
|
||||||
.for_each_active_monitor_output_cached = gsr_window_wayland_for_each_active_monitor_output_cached,
|
.for_each_active_monitor_output_cached = gsr_window_wayland_for_each_active_monitor_output_cached,
|
||||||
.is_compositor_kwin = gsr_window_wayland_is_compositor_kwin,
|
|
||||||
.priv = window_wayland
|
.priv = window_wayland
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user