Compare commits

..

4 Commits
5.9.2 ... 5.9.3

Author SHA1 Message Date
dec05eba
716dc0b736 5.9.3 2025-11-25 19:02:58 +01:00
dec05eba
059e3dbbc0 pipewire video: check if has modifier 2025-11-24 21:26:02 +01:00
dec05eba
990dfc7589 pipewire video: re-negotiate modifiers multiple times until we get a good one 2025-11-24 21:15:35 +01:00
dec05eba
2d551e7b1f Proper fallback for vulkan video 2025-11-23 14:40:54 +01:00
5 changed files with 19 additions and 46 deletions

View File

@@ -79,8 +79,8 @@ typedef struct {
struct spa_video_info format;
int server_version_sync;
bool negotiated;
bool renegotiated;
bool damaged;
bool has_modifier;
struct {
bool visible;

View File

@@ -1,4 +1,4 @@
project('gpu-screen-recorder', ['c', 'cpp'], version : '5.9.2', default_options : ['warning_level=2'])
project('gpu-screen-recorder', ['c', 'cpp'], version : '5.9.3', default_options : ['warning_level=2'])
add_project_arguments('-Wshadow', language : ['c', 'cpp'])
if get_option('buildtype') == 'debug'

View File

@@ -1,7 +1,7 @@
[package]
name = "gpu-screen-recorder"
type = "executable"
version = "5.9.2"
version = "5.9.3"
platforms = ["posix"]
[config]

View File

@@ -1645,41 +1645,6 @@ static bool get_supported_video_codecs(gsr_egl *egl, gsr_video_codec video_codec
return false;
}
static void force_cpu_encoding(args_parser *args_parser) {
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
args_parser->video_encoder = GSR_VIDEO_ENCODER_HW_CPU;
if(args_parser->bitrate_mode == GSR_BITRATE_MODE_VBR) {
fprintf(stderr, "gsr warning: bitrate mode has been forcefully set to qp because software encoding option doesn't support vbr option\n");
args_parser->bitrate_mode = GSR_BITRATE_MODE_QP;
}
}
static bool get_supported_video_codecs_with_cpu_fallback(gsr_egl *egl, args_parser *args_parser, bool cleanup, gsr_supported_video_codecs *video_codecs) {
if(get_supported_video_codecs(egl, args_parser->video_codec, args_parser->video_encoder == GSR_VIDEO_ENCODER_HW_CPU, cleanup, video_codecs)) {
if(args_parser->video_encoder == GSR_VIDEO_ENCODER_HW_CPU || !args_parser->fallback_cpu_encoding)
return true;
else if(args_parser->video_encoder == GSR_VIDEO_ENCODER_HW_GPU && video_codecs->h264.supported && (args_parser->video_codec == (gsr_video_codec)GSR_VIDEO_CODEC_AUTO || args_parser->video_codec == GSR_VIDEO_CODEC_H264))
return true;
}
if(args_parser->video_encoder == GSR_VIDEO_ENCODER_HW_CPU || !args_parser->fallback_cpu_encoding)
return false;
fprintf(stderr, "gsr warning: gpu encoding is not available on your system, trying cpu encoding instead because -fallback-cpu-encoding is enabled. Install the proper vaapi drivers on your system (if supported) if you experience performance issues\n");
if(get_supported_video_codecs(egl, GSR_VIDEO_CODEC_H264, true, cleanup, video_codecs)) {
if(args_parser->video_codec != (gsr_video_codec)GSR_VIDEO_CODEC_AUTO && args_parser->video_codec != GSR_VIDEO_CODEC_H264) {
fprintf(stderr, "gsr warning: cpu encoding is used but video codec isn't set to h264. Forcing video codec to h264\n");
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
}
force_cpu_encoding(args_parser);
return true;
}
return false;
}
static void xwayland_check_callback(const gsr_monitor *monitor, void *userdata) {
bool *xwayland_found = (bool*)userdata;
if(monitor->name_len >= 8 && strncmp(monitor->name, "XWAYLAND", 8) == 0)
@@ -2769,6 +2734,15 @@ static void print_codec_error(gsr_video_codec video_codec) {
" If your GPU doesn't support hardware accelerated video encoding then you can use '-fallback-cpu-encoding yes' option to encode with your cpu instead.\n", video_codec_name, video_codec_name, video_codec_name);
}
static void force_cpu_encoding(args_parser *args_parser) {
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
args_parser->video_encoder = GSR_VIDEO_ENCODER_HW_CPU;
if(args_parser->bitrate_mode == GSR_BITRATE_MODE_VBR) {
fprintf(stderr, "gsr warning: bitrate mode has been forcefully set to qp because software encoding option doesn't support vbr option\n");
args_parser->bitrate_mode = GSR_BITRATE_MODE_QP;
}
}
static const AVCodec* pick_video_codec(gsr_egl *egl, args_parser *args_parser, bool use_fallback_codec, bool *low_power, gsr_supported_video_codecs *supported_video_codecs) {
// TODO: software encoder for hevc, av1, vp8 and vp9
*low_power = false;
@@ -2806,7 +2780,7 @@ static const AVCodec* pick_video_codec(gsr_egl *egl, args_parser *args_parser, b
fprintf(stderr, "gsr warning: selected video codec h264_vulkan is not supported, trying h264 instead\n");
args_parser->video_codec = GSR_VIDEO_CODEC_H264;
// Need to do a query again because this time it's without vulkan
if(!get_supported_video_codecs_with_cpu_fallback(egl, args_parser, true, supported_video_codecs)) {
if(!get_supported_video_codecs(egl, args_parser->video_codec, false, true, supported_video_codecs)) {
fprintf(stderr, "gsr error: failed to query for supported video codecs\n");
print_codec_error(args_parser->video_codec);
_exit(11);
@@ -2817,7 +2791,7 @@ static const AVCodec* pick_video_codec(gsr_egl *egl, args_parser *args_parser, b
fprintf(stderr, "gsr warning: selected video codec hevc_vulkan is not supported, trying hevc instead\n");
args_parser->video_codec = GSR_VIDEO_CODEC_HEVC;
// Need to do a query again because this time it's without vulkan
if(!get_supported_video_codecs_with_cpu_fallback(egl, args_parser, true, supported_video_codecs)) {
if(!get_supported_video_codecs(egl, args_parser->video_codec, false, true, supported_video_codecs)) {
fprintf(stderr, "gsr error: failed to query for supported video codecs\n");
print_codec_error(args_parser->video_codec);
_exit(11);

View File

@@ -280,7 +280,8 @@ static void on_param_changed_cb(void *user_data, uint32_t id, const struct spa_p
self->format.info.raw.format,
spa_debug_type_find_name(spa_type_video_format, self->format.info.raw.format));
if(has_modifier) {
self->has_modifier = has_modifier;
if(self->has_modifier) {
fprintf(stderr, "gsr info: pipewire: Modifier: 0x%" PRIx64 "\n", self->format.info.raw.modifier);
}
@@ -736,7 +737,6 @@ void gsr_pipewire_video_deinit(gsr_pipewire_video *self) {
self->dmabuf_num_planes = 0;
self->negotiated = false;
self->renegotiated = false;
if(self->mutex_initialized) {
pthread_mutex_destroy(&self->mutex);
@@ -783,21 +783,20 @@ static EGLImage gsr_pipewire_video_create_egl_image_with_fallback(gsr_pipewire_v
}
EGLImage image = NULL;
if(self->no_modifiers_fallback) {
if(self->no_modifiers_fallback || !self->has_modifier) {
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false);
} else {
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, true);
if(!image) {
if(self->renegotiated || self->format.info.raw.modifier == DRM_FORMAT_MOD_INVALID) {
if(self->format.info.raw.modifier == DRM_FORMAT_MOD_INVALID) {
fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers\n");
self->no_modifiers_fallback = true;
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false);
} else {
fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, renegotiating with a different modifier\n");
self->negotiated = false;
self->renegotiated = true;
gsr_pipewire_video_remove_modifier(self, self->format.info.raw.modifier);
pw_thread_loop_lock(self->thread_loop);
gsr_pipewire_video_remove_modifier(self, self->format.info.raw.modifier);
pw_loop_signal_event(pw_thread_loop_get_loop(self->thread_loop), self->reneg);
pw_thread_loop_unlock(self->thread_loop);
}