diff options
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | include/sound.hpp | 1 | ||||
-rw-r--r-- | meson.build | 2 | ||||
-rw-r--r-- | project.conf | 2 | ||||
-rw-r--r-- | src/main.cpp | 13 | ||||
-rw-r--r-- | src/pipewire_audio.c | 15 | ||||
-rw-r--r-- | src/sound.cpp | 53 |
7 files changed, 81 insertions, 9 deletions
@@ -190,4 +190,6 @@ Support transposing (rotating) with vaapi. This isn't supported on many devices Cleanup pipewire_audio.c (proper error handling and memory cleanup of proxies). -Hide application audio module-null-sink by using sink_properties=media.class="Audio/Sink/Internal".
\ No newline at end of file +Hide application audio module-null-sink by using sink_properties=media.class="Audio/Sink/Internal". + +Improve software encoding performance. diff --git a/include/sound.hpp b/include/sound.hpp index 048246b..f71b84d 100644 --- a/include/sound.hpp +++ b/include/sound.hpp @@ -74,5 +74,6 @@ void sound_device_close(SoundDevice *device); int sound_device_read_next_chunk(SoundDevice *device, void **buffer, double timeout_sec, double *latency_seconds); AudioDevices get_pulseaudio_inputs(); +bool pulseaudio_server_is_pipewire(); #endif /* GPU_SCREEN_RECORDER_H */ diff --git a/meson.build b/meson.build index f5c9214..4d0e5c1 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('gpu-screen-recorder', ['c', 'cpp'], version : '4.2.6', default_options : ['warning_level=2']) +project('gpu-screen-recorder', ['c', 'cpp'], version : '4.3.0', default_options : ['warning_level=2']) add_project_arguments('-Wshadow', language : ['c', 'cpp']) if get_option('buildtype') == 'debug' diff --git a/project.conf b/project.conf index 776df96..fdc0280 100644 --- a/project.conf +++ b/project.conf @@ -1,7 +1,7 @@ [package] name = "gpu-screen-recorder" type = "executable" -version = "4.2.6" +version = "4.3.0" platforms = ["posix"] [config] diff --git a/src/main.cpp b/src/main.cpp index 56687cf..98215be 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1901,11 +1901,7 @@ static void list_system_info(bool wayland) { printf("display_server|%s\n", wayland ? "wayland" : "x11"); bool supports_app_audio = false; #ifdef GSR_APP_AUDIO - gsr_pipewire_audio audio; - if(gsr_pipewire_audio_init(&audio)) { - supports_app_audio = true; - gsr_pipewire_audio_deinit(&audio); - } + supports_app_audio = pulseaudio_server_is_pipewire(); #endif printf("supports_app_audio|%s\n", supports_app_audio ? "yes" : "no"); } @@ -3201,7 +3197,12 @@ int main(int argc, char **argv) { memset(&pipewire_audio, 0, sizeof(pipewire_audio)); if(uses_app_audio) { if(!gsr_pipewire_audio_init(&pipewire_audio)) { - fprintf(stderr, "gsr error: failed to setup PipeWire audio for application audio capture. The likely reason for this failure is that your sound server is not PipeWire\n"); + fprintf(stderr, "gsr error: failed to setup PipeWire audio for application audio capture. The likely reason for this failure is that your sound server is not PipeWire. The options -aa and -aai are only available when running PipeWire audio server.\n"); + _exit(2); + } + + if(!pulseaudio_server_is_pipewire()) { + fprintf(stderr, "gsr error: your sound server is not PipeWire. The options -aa and -aai are only available when running PipeWire audio server.\n"); _exit(2); } diff --git a/src/pipewire_audio.c b/src/pipewire_audio.c index 122895a..49de50b 100644 --- a/src/pipewire_audio.c +++ b/src/pipewire_audio.c @@ -398,6 +398,21 @@ void gsr_pipewire_audio_for_each_app(gsr_pipewire_audio *self, gsr_pipewire_audi if(node->type != GSR_PIPEWIRE_AUDIO_NODE_TYPE_STREAM_OUTPUT) continue; + bool duplicate_app = false; + for(int j = i - 1; j >= 0; --j) { + const gsr_pipewire_audio_node *prev_node = &self->stream_nodes[j]; + if(prev_node->type != GSR_PIPEWIRE_AUDIO_NODE_TYPE_STREAM_OUTPUT) + continue; + + if(strcasecmp(node->name, prev_node->name) == 0) { + duplicate_app = true; + break; + } + } + + if(duplicate_app) + continue; + if(!callback(node->name, userdata)) break; } diff --git a/src/sound.cpp b/src/sound.cpp index bd26d89..b500a57 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -399,6 +399,12 @@ static void pa_server_info_cb(pa_context*, const pa_server_info *server_info, vo audio_devices->default_input = server_info->default_source_name; } +static void server_info_callback(pa_context*, const pa_server_info *server_info, void *userdata) { + bool *is_server_pipewire = (bool*)userdata; + if(server_info->server_name && strstr(server_info->server_name, "PipeWire")) + *is_server_pipewire = true; +} + static void get_pulseaudio_default_inputs(AudioDevices &audio_devices) { int state = 0; int pa_ready = 0; @@ -493,3 +499,50 @@ AudioDevices get_pulseaudio_inputs() { pa_mainloop_free(main_loop); return audio_devices; } + +bool pulseaudio_server_is_pipewire() { + int state = 0; + int pa_ready = 0; + pa_operation *pa_op = NULL; + bool is_server_pipewire = false; + + pa_mainloop *main_loop = pa_mainloop_new(); + if(!main_loop) + return is_server_pipewire; + + 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) { + pa_mainloop_iterate(main_loop, 1, NULL); + continue; + } + + switch(state) { + case 0: { + pa_op = pa_context_get_server_info(ctx, server_info_callback, &is_server_pipewire); + ++state; + break; + } + } + + // Couldn't get connection to the server + 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 is_server_pipewire; +} |