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..0209edc35a58bbf7c0c1cb2411aa8e0835324694 100644 |
--- a/media/audio/pulse/pulse_util.cc |
+++ b/media/audio/pulse/pulse_util.cc |
@@ -12,6 +12,8 @@ |
#include "media/audio/audio_device_description.h" |
#include "media/base/audio_parameters.h" |
+int strcmp(const char* s1, const char* s2); |
+ |
namespace media { |
namespace pulse { |
@@ -68,6 +70,60 @@ 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* 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* 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 = reinterpret_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 = reinterpret_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; |
+ } |
+} |
} // namespace |
// static, pa_stream_success_cb_t |
@@ -355,6 +411,32 @@ bool CreateOutputStream(pa_threaded_mainloop** mainloop, |
return true; |
} |
+std::string GetBusOfInput(const std::string& name, |
+ pa_threaded_mainloop* input_mainloop, |
+ pa_context* input_context) { |
+ DCHECK(input_mainloop); |
+ DCHECK(input_context); |
+ AutoPulseLock auto_lock(input_mainloop); |
+ InputBusData data(input_mainloop, name); |
+ pa_operation* operation = |
+ pa_context_get_source_info_list(input_context, InputBusCallback, &data); |
+ WaitForOperationCompletion(input_mainloop, operation); |
+ return data.bus_; |
+} |
+ |
+std::string GetOutputCorrespondingTo(const std::string& input_bus, |
+ pa_threaded_mainloop* input_mainloop, |
+ pa_context* input_context) { |
+ DCHECK(input_mainloop); |
+ DCHECK(input_context); |
+ AutoPulseLock auto_lock(input_mainloop); |
+ OutputBusData data(input_mainloop, input_bus); |
+ pa_operation* operation = |
+ pa_context_get_sink_info_list(input_context, OutputBusCallback, &data); |
+ WaitForOperationCompletion(input_mainloop, operation); |
+ return data.name_; |
+} |
+ |
#undef RETURN_ON_FAILURE |
} // namespace pulse |