diff options
author | Liang Qi <liang.qi@qt.io> | 2016-06-29 16:11:26 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-06-30 07:33:04 +0200 |
commit | 27681cba4695355f2a0a6b01b85c429186d11a34 (patch) | |
tree | f11df2ec52d983b552f2e1b673e0845bc7e3ef05 /src/plugins/pulseaudio | |
parent | f7a93757c709e8b2902bc4707752edb8649d009c (diff) | |
parent | bc53bb7913bbf68519508a0ab76c513335b3e5bb (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.cpp | 118 | ||||
-rw-r--r-- | src/plugins/pulseaudio/qpulseaudioengine.h | 9 |
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; |