aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO6
-rwxr-xr-xscripts/record-application-name.sh2
-rwxr-xr-xscripts/record-save-application-name.sh2
-rwxr-xr-xscripts/replay-application-name.sh2
-rw-r--r--src/egl.c2
-rw-r--r--src/main.cpp34
-rw-r--r--src/sound.cpp52
7 files changed, 53 insertions, 47 deletions
diff --git a/TODO b/TODO
index b72c030..ac352c4 100644
--- a/TODO
+++ b/TODO
@@ -178,6 +178,10 @@ Default to hevc if capture size is larger than 4096 in width or height.
Set low latency mode on vulkan encoding.
-Support pipewire audio capture which also allows capturing audio from a single application.
+Support pipewire audio capture which also allows capturing audio from a single application. This can also be done with pulseaudio by creating a virtual sink:
+ pactl load-module module-combine-sink sink_name=gsr2 slaves=$(pactl get-default-sink) sink_properties=device.description="gsr"
+ pactl move-sink-input 2944 gsr2 # 2944 comes from 'pactl list sink-inputs'
+ and then record gsr2.monitor.
+ Or use pa_stream_set_monitor_stream, which also takes the sink-input as input. However need to track when the sink disconnects to mute and then reconnect again.
Support recording/replay/livestreaming at the same time by allowing commands to be run on an existing gpu screen recorder instance.
diff --git a/scripts/record-application-name.sh b/scripts/record-application-name.sh
index 4139c9c..f8c9b0d 100755
--- a/scripts/record-application-name.sh
+++ b/scripts/record-application-name.sh
@@ -1,6 +1,6 @@
#!/bin/sh
window=$(xdotool selectwindow)
-window_name=$(xdotool getwindowclassname "$window" || xdotool getwindowname "$window" || echo "Game")
+window_name=$(xdotool getwindowname "$window" || xdotool getwindowclassname "$window" || echo "Game")
window_name="$(echo "$window_name" | tr '/\\' '_')"
gpu-screen-recorder -w "$window" -f 60 -a default_output -o "$HOME/Videos/recording/$window_name/$(date +"Video_%Y-%m-%d_%H-%M-%S.mp4")"
diff --git a/scripts/record-save-application-name.sh b/scripts/record-save-application-name.sh
index b814809..c95f398 100755
--- a/scripts/record-save-application-name.sh
+++ b/scripts/record-save-application-name.sh
@@ -4,7 +4,7 @@
# gpu-screen-recorder -w screen -f 60 -a default_output -r 60 -sc scripts/record-save-application-name.sh -c mp4 -o "$HOME/Videos"
window=$(xdotool getwindowfocus)
-window_name=$(xdotool getwindowclassname "$window" || xdotool getwindowname "$window" || echo "Game")
+window_name=$(xdotool getwindowname "$window" || xdotool getwindowclassname "$window" || echo "Game")
window_name="$(echo "$window_name" | tr '/\\' '_')"
video_dir="$HOME/Videos/Replays/$window_name"
diff --git a/scripts/replay-application-name.sh b/scripts/replay-application-name.sh
index 9f363f7..2a651bb 100755
--- a/scripts/replay-application-name.sh
+++ b/scripts/replay-application-name.sh
@@ -1,6 +1,6 @@
#!/bin/sh
window=$(xdotool selectwindow)
-window_name=$(xdotool getwindowclassname "$window" || xdotool getwindowname "$window" || echo "Game")
+window_name=$(xdotool getwindowname "$window" || xdotool getwindowclassname "$window" || echo "Game")
window_name="$(echo "$window_name" | tr '/\\' '_')"
gpu-screen-recorder -w "$window" -f 60 -c mkv -a default_output -r 60 -o "$HOME/Videos/Replays/$window_name"
diff --git a/src/egl.c b/src/egl.c
index 87c2b84..315cbab 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -223,7 +223,7 @@ static bool gsr_egl_create_window(gsr_egl *self, bool wayland) {
if(wayland) {
self->wayland.dpy = wl_display_connect(NULL);
if(!self->wayland.dpy) {
- fprintf(stderr, "gsr error: gsr_egl_create_window failed: wl_display_connect failed\n");
+ fprintf(stderr, "gsr error: gsr_egl_create_window failed: failed to connect to the Wayland server\n");
goto fail;
}
diff --git a/src/main.cpp b/src/main.cpp
index b8c8f71..2ce15ef 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -585,7 +585,7 @@ static AVCodecContext *create_video_codec_context(AVPixelFormat pix_fmt,
codec_context->global_quality = 120 * quality_multiply;
break;
case VideoQuality::VERY_HIGH:
- codec_context->global_quality = 100 * quality_multiply;
+ codec_context->global_quality = 115 * quality_multiply;
break;
case VideoQuality::ULTRA:
codec_context->global_quality = 90 * quality_multiply;
@@ -600,7 +600,7 @@ static AVCodecContext *create_video_codec_context(AVPixelFormat pix_fmt,
codec_context->global_quality = 30 * quality_multiply;
break;
case VideoQuality::VERY_HIGH:
- codec_context->global_quality = 20 * quality_multiply;
+ codec_context->global_quality = 25 * quality_multiply;
break;
case VideoQuality::ULTRA:
codec_context->global_quality = 10 * quality_multiply;
@@ -615,7 +615,7 @@ static AVCodecContext *create_video_codec_context(AVPixelFormat pix_fmt,
codec_context->global_quality = 30 * quality_multiply;
break;
case VideoQuality::VERY_HIGH:
- codec_context->global_quality = 20 * quality_multiply;
+ codec_context->global_quality = 25 * quality_multiply;
break;
case VideoQuality::ULTRA:
codec_context->global_quality = 10 * quality_multiply;
@@ -779,10 +779,10 @@ static void video_software_set_qp(AVCodecContext *codec_context, VideoQuality vi
av_dict_set_int(options, "qp", 30 * qp_multiply, 0);
break;
case VideoQuality::VERY_HIGH:
- av_dict_set_int(options, "qp", 23 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 25 * qp_multiply, 0);
break;
case VideoQuality::ULTRA:
- av_dict_set_int(options, "qp", 20 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 22 * qp_multiply, 0);
break;
}
} else {
@@ -873,7 +873,7 @@ static void video_hardware_set_qp(AVCodecContext *codec_context, VideoQuality vi
av_dict_set_int(options, "qp", 30 * qp_multiply, 0);
break;
case VideoQuality::VERY_HIGH:
- av_dict_set_int(options, "qp", 25 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 27 * qp_multiply, 0);
break;
case VideoQuality::ULTRA:
av_dict_set_int(options, "qp", 22 * qp_multiply, 0);
@@ -882,16 +882,16 @@ static void video_hardware_set_qp(AVCodecContext *codec_context, VideoQuality vi
} else if(codec_context->codec_id == AV_CODEC_ID_H264) {
switch(video_quality) {
case VideoQuality::MEDIUM:
- av_dict_set_int(options, "qp", 34 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 35 * qp_multiply, 0);
break;
case VideoQuality::HIGH:
av_dict_set_int(options, "qp", 30 * qp_multiply, 0);
break;
case VideoQuality::VERY_HIGH:
- av_dict_set_int(options, "qp", 23 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 27 * qp_multiply, 0);
break;
case VideoQuality::ULTRA:
- av_dict_set_int(options, "qp", 20 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 22 * qp_multiply, 0);
break;
}
} else if(codec_context->codec_id == AV_CODEC_ID_HEVC) {
@@ -903,7 +903,7 @@ static void video_hardware_set_qp(AVCodecContext *codec_context, VideoQuality vi
av_dict_set_int(options, "qp", 30 * qp_multiply, 0);
break;
case VideoQuality::VERY_HIGH:
- av_dict_set_int(options, "qp", 25 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 27 * qp_multiply, 0);
break;
case VideoQuality::ULTRA:
av_dict_set_int(options, "qp", 22 * qp_multiply, 0);
@@ -918,7 +918,7 @@ static void video_hardware_set_qp(AVCodecContext *codec_context, VideoQuality vi
av_dict_set_int(options, "qp", 30 * qp_multiply, 0);
break;
case VideoQuality::VERY_HIGH:
- av_dict_set_int(options, "qp", 25 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 27 * qp_multiply, 0);
break;
case VideoQuality::ULTRA:
av_dict_set_int(options, "qp", 22 * qp_multiply, 0);
@@ -931,16 +931,16 @@ static void video_hardware_set_qp(AVCodecContext *codec_context, VideoQuality vi
} else if(codec_context->codec_id == AV_CODEC_ID_H264) {
switch(video_quality) {
case VideoQuality::MEDIUM:
- av_dict_set_int(options, "qp", 34 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 35 * qp_multiply, 0);
break;
case VideoQuality::HIGH:
av_dict_set_int(options, "qp", 30 * qp_multiply, 0);
break;
case VideoQuality::VERY_HIGH:
- av_dict_set_int(options, "qp", 23 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 27 * qp_multiply, 0);
break;
case VideoQuality::ULTRA:
- av_dict_set_int(options, "qp", 20 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 22 * qp_multiply, 0);
break;
}
} else if(codec_context->codec_id == AV_CODEC_ID_HEVC) {
@@ -952,7 +952,7 @@ static void video_hardware_set_qp(AVCodecContext *codec_context, VideoQuality vi
av_dict_set_int(options, "qp", 30 * qp_multiply, 0);
break;
case VideoQuality::VERY_HIGH:
- av_dict_set_int(options, "qp", 25 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 27 * qp_multiply, 0);
break;
case VideoQuality::ULTRA:
av_dict_set_int(options, "qp", 22 * qp_multiply, 0);
@@ -967,7 +967,7 @@ static void video_hardware_set_qp(AVCodecContext *codec_context, VideoQuality vi
av_dict_set_int(options, "qp", 30 * qp_multiply, 0);
break;
case VideoQuality::VERY_HIGH:
- av_dict_set_int(options, "qp", 25 * qp_multiply, 0);
+ av_dict_set_int(options, "qp", 27 * qp_multiply, 0);
break;
case VideoQuality::ULTRA:
av_dict_set_int(options, "qp", 22 * qp_multiply, 0);
@@ -3108,7 +3108,7 @@ int main(int argc, char **argv) {
usage();
}
- video_bitrate *= 1000LL;
+ video_bitrate *= 1024LL * 8LL;
} else {
if(!quality_str)
quality_str = "very_high";
diff --git a/src/sound.cpp b/src/sound.cpp
index d0f2a80..aea5b91 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -340,16 +340,18 @@ static void pa_server_info_cb(pa_context*, const pa_server_info *server_info, vo
}
static void get_pulseaudio_default_inputs(AudioDevices &audio_devices) {
- pa_mainloop *main_loop = pa_mainloop_new();
-
- pa_context *ctx = pa_context_new(pa_mainloop_get_api(main_loop), "gpu-screen-recorder-gtk");
- pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
int state = 0;
int pa_ready = 0;
- pa_context_set_state_callback(ctx, pa_state_cb, &pa_ready);
-
pa_operation *pa_op = NULL;
+ pa_mainloop *main_loop = pa_mainloop_new();
+
+ pa_context *ctx = pa_context_new(pa_mainloop_get_api(main_loop), "gpu-screen-recorder");
+ if(pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
+ goto done;
+
+ pa_context_set_state_callback(ctx, pa_state_cb, &pa_ready);
+
for(;;) {
// Not ready
if(pa_ready == 0) {
@@ -366,23 +368,25 @@ static void get_pulseaudio_default_inputs(AudioDevices &audio_devices) {
}
// Couldn't get connection to the server
- if(pa_ready == 2 || (state == 1 && pa_op && pa_operation_get_state(pa_op) == PA_OPERATION_DONE)) {
- if(pa_op)
- pa_operation_unref(pa_op);
- pa_context_disconnect(ctx);
- pa_context_unref(ctx);
- pa_mainloop_free(main_loop);
- return;
- }
+ if(pa_ready == 2 || (state == 1 && pa_op && pa_operation_get_state(pa_op) == PA_OPERATION_DONE))
+ break;
pa_mainloop_iterate(main_loop, 1, NULL);
}
+ done:
+ if(pa_op)
+ pa_operation_unref(pa_op);
+ pa_context_disconnect(ctx);
+ pa_context_unref(ctx);
pa_mainloop_free(main_loop);
}
AudioDevices get_pulseaudio_inputs() {
AudioDevices audio_devices;
+ int state = 0;
+ int pa_ready = 0;
+ pa_operation *pa_op = NULL;
// TODO: Do this in the same connection below instead of two separate connections
get_pulseaudio_default_inputs(audio_devices);
@@ -390,12 +394,10 @@ AudioDevices get_pulseaudio_inputs() {
pa_mainloop *main_loop = pa_mainloop_new();
pa_context *ctx = pa_context_new(pa_mainloop_get_api(main_loop), "gpu-screen-recorder");
- pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
- int state = 0;
- int pa_ready = 0;
- pa_context_set_state_callback(ctx, pa_state_cb, &pa_ready);
+ if(pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
+ goto done;
- pa_operation *pa_op = NULL;
+ pa_context_set_state_callback(ctx, pa_state_cb, &pa_ready);
for(;;) {
// Not ready
@@ -413,17 +415,17 @@ AudioDevices get_pulseaudio_inputs() {
}
// Couldn't get connection to the server
- if(pa_ready == 2 || (state == 1 && pa_op && pa_operation_get_state(pa_op) == PA_OPERATION_DONE)) {
- if(pa_op)
- pa_operation_unref(pa_op);
- pa_context_disconnect(ctx);
- pa_context_unref(ctx);
+ if(pa_ready == 2 || (state == 1 && pa_op && pa_operation_get_state(pa_op) == PA_OPERATION_DONE))
break;
- }
pa_mainloop_iterate(main_loop, 1, NULL);
}
+ done:
+ if(pa_op)
+ pa_operation_unref(pa_op);
+ pa_context_disconnect(ctx);
+ pa_context_unref(ctx);
pa_mainloop_free(main_loop);
return audio_devices;
}