Index: media/audio/pulse/pulse_util.cc |
diff --git a/media/audio/pulse/pulse_util.cc b/media/audio/pulse/pulse_util.cc |
index d5c699a09e28a821fd1e7107ca1cd6be9858d24a..224e5066b0ebf19644a79f3edf62164640b196ee 100644 |
--- a/media/audio/pulse/pulse_util.cc |
+++ b/media/audio/pulse/pulse_util.cc |
@@ -5,6 +5,7 @@ |
#include "media/audio/pulse/pulse_util.h" |
#include <stdint.h> |
+#include <string.h> |
#include "base/logging.h" |
#include "base/macros.h" |
@@ -68,6 +69,76 @@ class ScopedPropertyList { |
DISALLOW_COPY_AND_ASSIGN(ScopedPropertyList); |
}; |
+struct InputBusData { |
+ InputBusData(pa_threaded_mainloop* loop, const std::string& name) |
+ : loop_(loop), name_(name), bus_() {} |
+ |
+ pa_threaded_mainloop* const loop_; |
+ const std::string& name_; |
+ std::string bus_; |
+}; |
+ |
+struct OutputBusData { |
+ OutputBusData(pa_threaded_mainloop* loop, const std::string& bus) |
+ : loop_(loop), name_(), bus_(bus) {} |
+ |
+ pa_threaded_mainloop* const loop_; |
+ std::string name_; |
+ const std::string& bus_; |
+}; |
+ |
+void InputBusCallback(pa_context* context, |
+ const pa_source_info* info, |
+ int error, |
+ void* user_data) { |
+ InputBusData* data = static_cast<InputBusData*>(user_data); |
+ |
+ if (error) { |
+ // We have checked all the devices now. |
+ pa_threaded_mainloop_signal(data->loop_, 0); |
+ return; |
+ } |
+ |
+ if (strcmp(info->name, data->name_.c_str()) == 0 && |
+ pa_proplist_contains(info->proplist, PA_PROP_DEVICE_BUS)) { |
+ data->bus_ = pa_proplist_gets(info->proplist, PA_PROP_DEVICE_BUS); |
+ } |
+} |
+ |
+void OutputBusCallback(pa_context* context, |
+ const pa_sink_info* info, |
+ int error, |
+ void* user_data) { |
+ OutputBusData* data = static_cast<OutputBusData*>(user_data); |
+ |
+ if (error) { |
+ // We have checked all the devices now. |
+ pa_threaded_mainloop_signal(data->loop_, 0); |
+ return; |
+ } |
+ |
+ if (pa_proplist_contains(info->proplist, PA_PROP_DEVICE_BUS) && |
+ strcmp(pa_proplist_gets(info->proplist, PA_PROP_DEVICE_BUS), |
+ data->bus_.c_str()) == 0) { |
+ data->name_ = info->name; |
+ } |
+} |
+ |
+struct DefaultDevicesData { |
+ DefaultDevicesData(pa_threaded_mainloop* loop) : loop_(loop) {} |
+ std::string input_; |
+ std::string output_; |
+ pa_threaded_mainloop* const loop_; |
+}; |
+ |
+void GetDefaultDeviceIdCallback(pa_context* c, |
+ const pa_server_info* info, |
+ void* userdata) { |
+ DefaultDevicesData* data = static_cast<DefaultDevicesData*>(userdata); |
+ data->input_ = info->default_source_name; |
+ data->output_ = info->default_sink_name; |
+ pa_threaded_mainloop_signal(data->loop_, 0); |
+} |
} // namespace |
// static, pa_stream_success_cb_t |
@@ -355,6 +426,42 @@ bool CreateOutputStream(pa_threaded_mainloop** mainloop, |
return true; |
} |
+std::string GetBusOfInput(pa_threaded_mainloop* mainloop, |
+ pa_context* context, |
+ const std::string& name) { |
+ DCHECK(mainloop); |
+ DCHECK(context); |
+ AutoPulseLock auto_lock(mainloop); |
+ InputBusData data(mainloop, name); |
+ pa_operation* operation = |
+ pa_context_get_source_info_list(context, InputBusCallback, &data); |
+ WaitForOperationCompletion(mainloop, operation); |
+ return data.bus_; |
+} |
+ |
+std::string GetOutputCorrespondingTo(pa_threaded_mainloop* mainloop, |
+ pa_context* context, |
+ const std::string& bus) { |
+ DCHECK(mainloop); |
+ DCHECK(context); |
+ AutoPulseLock auto_lock(mainloop); |
+ OutputBusData data(mainloop, bus); |
+ pa_operation* operation = |
+ pa_context_get_sink_info_list(context, OutputBusCallback, &data); |
+ WaitForOperationCompletion(mainloop, operation); |
+ return data.name_; |
+} |
+ |
+std::string GetRealDefaultDeviceId(pa_threaded_mainloop* mainloop, |
+ pa_context* context, |
+ RequestType type) { |
+ DefaultDevicesData data(mainloop); |
+ pa_operation* op = |
+ pa_context_get_server_info(context, &GetDefaultDeviceIdCallback, &data); |
+ WaitForOperationCompletion(mainloop, op); |
+ return (type == RequestType::INPUT) ? data.input_ : data.output_; |
+} |
+ |
#undef RETURN_ON_FAILURE |
} // namespace pulse |