aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp13
-rw-r--r--src/pipewire_audio.c15
-rw-r--r--src/sound.cpp53
3 files changed, 75 insertions, 6 deletions
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;
+}