Jelajahi Sumber

libobs: Fix Pulseaudio audio monitoring listing sources

The Pulseaudio implementation of audio monitoring was actually listing audio sources.
This change corrects that, so all possible outputs are available.
Jonathan Bennett 2 tahun lalu
induk
melakukan
73dea7c475

+ 4 - 4
libobs/audio-monitoring/pulse/pulseaudio-enum-devices.c

@@ -1,11 +1,11 @@
 #include <obs-internal.h>
 #include "pulseaudio-wrapper.h"
 
-static void pulseaudio_output_info(pa_context *c, const pa_source_info *i,
+static void pulseaudio_output_info(pa_context *c, const pa_sink_info *i,
 				   int eol, void *userdata)
 {
 	UNUSED_PARAMETER(c);
-	if (eol != 0 || i->monitor_of_sink == PA_INVALID_INDEX)
+	if (eol != 0)
 		goto skip;
 
 	struct enum_cb *ecb = (struct enum_cb *)userdata;
@@ -24,8 +24,8 @@ void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, void *data)
 	ecb->cont = 1;
 
 	pulseaudio_init();
-	pa_source_info_cb_t pa_cb = pulseaudio_output_info;
-	pulseaudio_get_source_info_list(pa_cb, (void *)ecb);
+	pa_sink_info_cb_t pa_cb = pulseaudio_output_info;
+	pulseaudio_get_sink_info_list(pa_cb, (void *)ecb);
 	pulseaudio_unref();
 
 	bfree(ecb);

+ 5 - 5
libobs/audio-monitoring/pulse/pulseaudio-output.c

@@ -294,8 +294,8 @@ static void pulseaudio_server_info(pa_context *c, const pa_server_info *i,
 	pulseaudio_signal(0);
 }
 
-static void pulseaudio_source_info(pa_context *c, const pa_source_info *i,
-				   int eol, void *userdata)
+static void pulseaudio_sink_info(pa_context *c, const pa_sink_info *i, int eol,
+				 void *userdata)
 {
 	UNUSED_PARAMETER(c);
 	PULSE_DATA(userdata);
@@ -409,9 +409,9 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
 		return false;
 	}
 
-	if (pulseaudio_get_source_info(pulseaudio_source_info, monitor->device,
-				       (void *)monitor) < 0) {
-		blog(LOG_ERROR, "Unable to get source info !");
+	if (pulseaudio_get_sink_info(pulseaudio_sink_info, monitor->device,
+				     (void *)monitor) < 0) {
+		blog(LOG_ERROR, "Unable to get sink info !");
 		return false;
 	}
 	if (monitor->format == PA_SAMPLE_INVALID) {

+ 51 - 3
libobs/audio-monitoring/pulse/pulseaudio-wrapper.c

@@ -77,10 +77,13 @@ bool devices_match(const char *id1, const char *id2)
 	}
 	if (strcmp(id2, "default") == 0) {
 		get_default_id(&name2);
-		id2 = name2;
+	} else {
+		name2 = bzalloc(strlen(id2) + 9);
+		strcat(name2, id2);
+		strcat(name2, ".monitor");
 	}
 
-	match = strcmp(id1, id2) == 0;
+	match = strcmp(id1, name2) == 0;
 	bfree(name1);
 	bfree(name2);
 	return match;
@@ -267,6 +270,51 @@ int_fast32_t pulseaudio_get_source_info(pa_source_info_cb_t cb,
 	return 0;
 }
 
+int_fast32_t pulseaudio_get_sink_info_list(pa_sink_info_cb_t cb, void *userdata)
+{
+	if (pulseaudio_context_ready() < 0)
+		return -1;
+
+	pulseaudio_lock();
+
+	pa_operation *op =
+		pa_context_get_sink_info_list(pulseaudio_context, cb, userdata);
+	if (!op) {
+		pulseaudio_unlock();
+		return -1;
+	}
+	while (pa_operation_get_state(op) == PA_OPERATION_RUNNING)
+		pulseaudio_wait();
+	pa_operation_unref(op);
+
+	pulseaudio_unlock();
+
+	return 0;
+}
+
+int_fast32_t pulseaudio_get_sink_info(pa_sink_info_cb_t cb, const char *name,
+				      void *userdata)
+{
+	if (pulseaudio_context_ready() < 0)
+		return -1;
+
+	pulseaudio_lock();
+
+	pa_operation *op = pa_context_get_sink_info_by_name(pulseaudio_context,
+							    name, cb, userdata);
+	if (!op) {
+		pulseaudio_unlock();
+		return -1;
+	}
+	while (pa_operation_get_state(op) == PA_OPERATION_RUNNING)
+		pulseaudio_wait();
+	pa_operation_unref(op);
+
+	pulseaudio_unlock();
+
+	return 0;
+}
+
 int_fast32_t pulseaudio_get_server_info(pa_server_info_cb_t cb, void *userdata)
 {
 	if (pulseaudio_context_ready() < 0)
@@ -312,7 +360,7 @@ int_fast32_t pulseaudio_connect_playback(pa_stream *s, const char *name,
 	if (pulseaudio_context_ready() < 0)
 		return -1;
 
-	size_t dev_len = strlen(name) - 8;
+	size_t dev_len = strlen(name);
 	char *device = bzalloc(dev_len + 1);
 	memcpy(device, name, dev_len);
 

+ 34 - 0
libobs/audio-monitoring/pulse/pulseaudio-wrapper.h

@@ -128,6 +128,40 @@ int_fast32_t pulseaudio_get_source_info_list(pa_source_info_cb_t cb,
 int_fast32_t pulseaudio_get_source_info(pa_source_info_cb_t cb,
 					const char *name, void *userdata);
 
+/**
+ * Request sink information
+ *
+ * The function will block until the operation was executed and the mainloop
+ * called the provided callback function.
+ *
+ * @return negative on error
+ *
+ * @note The function will block until the server context is ready.
+ *
+ * @warning call without active locks
+ */
+int_fast32_t pulseaudio_get_sink_info_list(pa_sink_info_cb_t cb,
+					   void *userdata);
+
+/**
+ * Request sink information from a specific sink
+ *
+ * The function will block until the operation was executed and the mainloop
+ * called the provided callback function.
+ *
+ * @param cb pointer to the callback function
+ * @param name the sink name to get information for
+ * @param userdata pointer to userdata the callback will be called with
+ *
+ * @return negative on error
+ *
+ * @note The function will block until the server context is ready.
+ *
+ * @warning call without active locks
+ */
+int_fast32_t pulseaudio_get_sink_info(pa_sink_info_cb_t cb, const char *name,
+				      void *userdata);
+
 /**
  * Request server information
  *