summaryrefslogtreecommitdiffstats
path: root/src/plugins/pulseaudio
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-06-29 16:11:26 +0200
committerLiang Qi <liang.qi@qt.io>2016-06-30 07:33:04 +0200
commit27681cba4695355f2a0a6b01b85c429186d11a34 (patch)
treef11df2ec52d983b552f2e1b673e0845bc7e3ef05 /src/plugins/pulseaudio
parentf7a93757c709e8b2902bc4707752edb8649d009c (diff)
parentbc53bb7913bbf68519508a0ab76c513335b3e5bb (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7
Blacklisted a few functions in tst_QAudioInput. Conflicts: .qmake.conf src/plugins/avfoundation/camera/avfcameracontrol.mm src/plugins/avfoundation/camera/avfcameraservice.h src/plugins/avfoundation/camera/avfcameraservice.mm src/plugins/avfoundation/camera/avfcamerasession.h src/plugins/avfoundation/camera/avfcamerasession.mm src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.h src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm src/plugins/avfoundation/camera/avfimagecapturecontrol.mm src/plugins/avfoundation/camera/avfimageencodercontrol.mm src/plugins/avfoundation/camera/avfmediarecordercontrol.h src/plugins/avfoundation/camera/avfmediarecordercontrol.mm tests/auto/integration/qaudioinput/BLACKLIST Task-number: QTBUG-54459 Task-number: QTBUG-49736 Change-Id: I3a1fe8cef50b44d5c2785aaf4cf69fe3f16728e6
Diffstat (limited to 'src/plugins/pulseaudio')
-rw-r--r--src/plugins/pulseaudio/qpulseaudioengine.cpp118
-rw-r--r--src/plugins/pulseaudio/qpulseaudioengine.h9
2 files changed, 103 insertions, 24 deletions
diff --git a/src/plugins/pulseaudio/qpulseaudioengine.cpp b/src/plugins/pulseaudio/qpulseaudioengine.cpp
index 19ba7472f..286f310bc 100644
--- a/src/plugins/pulseaudio/qpulseaudioengine.cpp
+++ b/src/plugins/pulseaudio/qpulseaudioengine.cpp
@@ -81,8 +81,10 @@ static void serverInfoCallback(pa_context *context, const pa_server_info *info,
#endif
QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata);
+ pulseEngine->m_serverLock.lockForWrite();
pulseEngine->m_defaultSink = info->default_sink_name;
pulseEngine->m_defaultSource = info->default_source_name;
+ pulseEngine->m_serverLock.unlock();
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
}
@@ -90,11 +92,6 @@ static void serverInfoCallback(pa_context *context, const pa_server_info *info,
static void sinkInfoCallback(pa_context *context, const pa_sink_info *info, int isLast, void *userdata)
{
QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata);
- QMap<pa_sink_state, QString> stateMap;
- stateMap[PA_SINK_INVALID_STATE] = "n/a";
- stateMap[PA_SINK_RUNNING] = "RUNNING";
- stateMap[PA_SINK_IDLE] = "IDLE";
- stateMap[PA_SINK_SUSPENDED] = "SUSPENDED";
if (isLast < 0) {
qWarning() << QString("Failed to get sink information: %s").arg(pa_strerror(pa_context_errno(context)));
@@ -109,6 +106,12 @@ static void sinkInfoCallback(pa_context *context, const pa_sink_info *info, int
Q_ASSERT(info);
#ifdef DEBUG_PULSE
+ QMap<pa_sink_state, QString> stateMap;
+ stateMap[PA_SINK_INVALID_STATE] = "n/a";
+ stateMap[PA_SINK_RUNNING] = "RUNNING";
+ stateMap[PA_SINK_IDLE] = "IDLE";
+ stateMap[PA_SINK_SUSPENDED] = "SUSPENDED";
+
qDebug() << QString("Sink #%1\n"
"\tState: %2\n"
"\tName: %3\n"
@@ -120,8 +123,10 @@ static void sinkInfoCallback(pa_context *context, const pa_sink_info *info, int
#endif
QAudioFormat format = QPulseAudioInternal::sampleSpecToAudioFormat(info->sample_spec);
+
+ QWriteLocker locker(&pulseEngine->m_sinkLock);
pulseEngine->m_preferredFormats.insert(info->name, format);
- pulseEngine->m_sinks.append(info->name);
+ pulseEngine->m_sinks.insert(info->index, info->name);
}
static void sourceInfoCallback(pa_context *context, const pa_source_info *info, int isLast, void *userdata)
@@ -129,12 +134,6 @@ static void sourceInfoCallback(pa_context *context, const pa_source_info *info,
Q_UNUSED(context)
QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata);
- QMap<pa_source_state, QString> stateMap;
- stateMap[PA_SOURCE_INVALID_STATE] = "n/a";
- stateMap[PA_SOURCE_RUNNING] = "RUNNING";
- stateMap[PA_SOURCE_IDLE] = "IDLE";
- stateMap[PA_SOURCE_SUSPENDED] = "SUSPENDED";
-
if (isLast) {
pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
return;
@@ -143,6 +142,12 @@ static void sourceInfoCallback(pa_context *context, const pa_source_info *info,
Q_ASSERT(info);
#ifdef DEBUG_PULSE
+ QMap<pa_source_state, QString> stateMap;
+ stateMap[PA_SOURCE_INVALID_STATE] = "n/a";
+ stateMap[PA_SOURCE_RUNNING] = "RUNNING";
+ stateMap[PA_SOURCE_IDLE] = "IDLE";
+ stateMap[PA_SOURCE_SUSPENDED] = "SUSPENDED";
+
qDebug() << QString("Source #%1\n"
"\tState: %2\n"
"\tName: %3\n"
@@ -154,8 +159,57 @@ static void sourceInfoCallback(pa_context *context, const pa_source_info *info,
#endif
QAudioFormat format = QPulseAudioInternal::sampleSpecToAudioFormat(info->sample_spec);
+
+ QWriteLocker locker(&pulseEngine->m_sourceLock);
pulseEngine->m_preferredFormats.insert(info->name, format);
- pulseEngine->m_sources.append(info->name);
+ pulseEngine->m_sources.insert(info->index, info->name);
+}
+
+static void event_cb(pa_context* context, pa_subscription_event_type_t t, uint32_t index, void* userdata)
+{
+ QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata);
+
+ int type = t & PA_SUBSCRIPTION_EVENT_TYPE_MASK;
+ int facility = t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;
+
+ switch (type) {
+ case PA_SUBSCRIPTION_EVENT_NEW:
+ case PA_SUBSCRIPTION_EVENT_CHANGE:
+ switch (facility) {
+ case PA_SUBSCRIPTION_EVENT_SERVER:
+ pa_operation_unref(pa_context_get_server_info(context, serverInfoCallback, userdata));
+ break;
+ case PA_SUBSCRIPTION_EVENT_SINK:
+ pa_operation_unref(pa_context_get_sink_info_by_index(context, index, sinkInfoCallback, userdata));
+ break;
+ case PA_SUBSCRIPTION_EVENT_SOURCE:
+ pa_operation_unref(pa_context_get_source_info_by_index(context, index, sourceInfoCallback, userdata));
+ break;
+ default:
+ break;
+ }
+ break;
+ case PA_SUBSCRIPTION_EVENT_REMOVE:
+ switch (facility) {
+ case PA_SUBSCRIPTION_EVENT_SINK:
+ pulseEngine->m_sinkLock.lockForWrite();
+ pulseEngine->m_preferredFormats.remove(pulseEngine->m_sinks.value(index));
+ pulseEngine->m_sinks.remove(index);
+ pulseEngine->m_sinkLock.unlock();
+ break;
+ case PA_SUBSCRIPTION_EVENT_SOURCE:
+ pulseEngine->m_sourceLock.lockForWrite();
+ pulseEngine->m_preferredFormats.remove(pulseEngine->m_sources.value(index));
+ pulseEngine->m_sources.remove(index);
+ pulseEngine->m_sourceLock.unlock();
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
}
static void contextStateCallbackInit(pa_context *context, void *userdata)
@@ -278,6 +332,13 @@ void QPulseAudioEngine::prepare()
if (ok) {
pa_context_set_state_callback(m_context, contextStateCallback, this);
+
+ pa_context_set_subscribe_callback(m_context, event_cb, this);
+ pa_operation_unref(pa_context_subscribe(m_context,
+ pa_subscription_mask_t(PA_SUBSCRIPTION_MASK_SINK |
+ PA_SUBSCRIPTION_MASK_SOURCE |
+ PA_SUBSCRIPTION_MASK_SERVER),
+ NULL, NULL));
} else {
pa_context_unref(m_context);
m_context = 0;
@@ -338,14 +399,6 @@ void QPulseAudioEngine::updateDevices()
pa_operation_unref(operation);
unlock();
-
- // Swap the default output to index 0
- m_sinks.removeOne(m_defaultSink);
- m_sinks.prepend(m_defaultSink);
-
- // Swap the default input to index 0
- m_sources.removeOne(m_defaultSource);
- m_sources.prepend(m_defaultSource);
}
void QPulseAudioEngine::onContextFailed()
@@ -366,7 +419,28 @@ QPulseAudioEngine *QPulseAudioEngine::instance()
QList<QByteArray> QPulseAudioEngine::availableDevices(QAudio::Mode mode) const
{
- return mode == QAudio::AudioOutput ? m_sinks : m_sources;
+ QList<QByteArray> devices;
+ QByteArray defaultDevice;
+
+ m_serverLock.lockForRead();
+
+ if (mode == QAudio::AudioOutput) {
+ QReadLocker locker(&m_sinkLock);
+ devices = m_sinks.values();
+ defaultDevice = m_defaultSink;
+ } else {
+ QReadLocker locker(&m_sourceLock);
+ devices = m_sources.values();
+ defaultDevice = m_defaultSource;
+ }
+
+ m_serverLock.unlock();
+
+ // Swap the default device to index 0
+ devices.removeOne(defaultDevice);
+ devices.prepend(defaultDevice);
+
+ return devices;
}
QT_END_NAMESPACE
diff --git a/src/plugins/pulseaudio/qpulseaudioengine.h b/src/plugins/pulseaudio/qpulseaudioengine.h
index 5eb96bf00..f03dbfd16 100644
--- a/src/plugins/pulseaudio/qpulseaudioengine.h
+++ b/src/plugins/pulseaudio/qpulseaudioengine.h
@@ -53,6 +53,7 @@
#include <QtCore/qmap.h>
#include <QtCore/qbytearray.h>
+#include <QtCore/qreadwritelock.h>
#include <qaudiosystemplugin.h>
#include <pulse/pulseaudio.h>
#include "qpulsehelpers.h"
@@ -104,13 +105,17 @@ private:
void release();
public:
- QList<QByteArray> m_sinks;
- QList<QByteArray> m_sources;
+ QMap<int, QByteArray> m_sinks;
+ QMap<int, QByteArray> m_sources;
QMap<QByteArray, QAudioFormat> m_preferredFormats;
QByteArray m_defaultSink;
QByteArray m_defaultSource;
+ mutable QReadWriteLock m_sinkLock;
+ mutable QReadWriteLock m_sourceLock;
+ mutable QReadWriteLock m_serverLock;
+
private:
pa_mainloop_api *m_mainLoopApi;
pa_threaded_mainloop *m_mainLoop;