diff options
author | Val Doroshchuk <valentyn.doroshchuk@qt.io> | 2020-06-24 15:38:31 +0200 |
---|---|---|
committer | Val Doroshchuk <valentyn.doroshchuk@qt.io> | 2020-06-24 22:48:37 +0200 |
commit | e03b89d72e1fd16c099e12e5dfaaf9906a162ebc (patch) | |
tree | 4f3debe37aec4224497abef83cf5d7c75a04f8d1 /src/plugins/wasapi/qwasapiutils.cpp | |
parent | baed166f741a5558596850619a79f863c0f53448 (diff) | |
download | qtmultimedia-e03b89d72e1fd16c099e12e5dfaaf9906a162ebc.tar.gz |
Remove wasapi plugin
Requires WinRT support
Task-number: QTBUG-74423
Change-Id: Ice9788df3e503c4c111bc6524c509e93dbf407c5
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/plugins/wasapi/qwasapiutils.cpp')
-rw-r--r-- | src/plugins/wasapi/qwasapiutils.cpp | 344 |
1 files changed, 0 insertions, 344 deletions
diff --git a/src/plugins/wasapi/qwasapiutils.cpp b/src/plugins/wasapi/qwasapiutils.cpp deleted file mode 100644 index 497e5fa6e..000000000 --- a/src/plugins/wasapi/qwasapiutils.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwasapiutils.h" - -#include <QtCore/QCoreApplication> -#include <QtCore/private/qeventdispatcher_winrt_p.h> - -// For Desktop Win32 support -#ifdef CLASSIC_APP_BUILD -#define Q_OS_WINRT -#endif -#include <QtCore/qfunctions_winrt.h> - -#include <QtMultimedia/QAudioDeviceInfo> -#include <Audioclient.h> -#include <windows.devices.enumeration.h> -#include <windows.foundation.collections.h> -#include <windows.media.devices.h> - -#include <functional> - -using namespace ABI::Windows::Devices::Enumeration; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Foundation::Collections; -using namespace ABI::Windows::Media::Devices; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; - -#define RETURN_EMPTY_LIST_IF_FAILED(msg) RETURN_IF_FAILED(msg, return QList<QByteArray>()) - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(lcMmAudioInterface, "qt.multimedia.audiointerface") -Q_LOGGING_CATEGORY(lcMmUtils, "qt.multimedia.utils") - -#ifdef CLASSIC_APP_BUILD -// Opening bracket has to be in the same line as MSVC2013 and 2015 complain on -// different lines otherwise -#pragma warning (suppress: 4273) -HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT()> &delegate, bool waitForRun) { - Q_UNUSED(waitForRun) - return delegate(); -} -#endif - -namespace QWasapiUtils { -struct DeviceMapping { - QList<QByteArray> outputDeviceNames; - QList<QString> outputDeviceIds; - QList<QByteArray> inputDeviceNames; - QList<QString> inputDeviceIds; -}; -Q_GLOBAL_STATIC(DeviceMapping, gMapping) -} - -struct CoInitializer -{ - CoInitializer() - { - CoInitializeEx(NULL, COINIT_MULTITHREADED); - } - - ~CoInitializer() - { - CoUninitialize(); - } -}; - -static void CoInitIfNeeded() -{ - static CoInitializer initializer; -} - -AudioInterface::AudioInterface() -{ - qCDebug(lcMmAudioInterface) << __FUNCTION__; - m_currentState = Initialized; -} - -AudioInterface::~AudioInterface() -{ - qCDebug(lcMmAudioInterface) << __FUNCTION__; -} - -HRESULT AudioInterface::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *op) -{ - qCDebug(lcMmAudioInterface) << __FUNCTION__; - - IUnknown *aInterface; - HRESULT hr; - HRESULT hrActivate; - hr = op->GetActivateResult(&hrActivate, &aInterface); - if (FAILED(hr) || FAILED(hrActivate)) { - qCDebug(lcMmAudioInterface) << __FUNCTION__ << "Could not query activate results."; - m_currentState = Error; - return hr; - } - - hr = aInterface->QueryInterface(IID_PPV_ARGS(&m_client)); - if (FAILED(hr)) { - qCDebug(lcMmAudioInterface) << __FUNCTION__ << "Could not access AudioClient interface."; - m_currentState = Error; - return hr; - } - - WAVEFORMATEX *format; - hr = m_client->GetMixFormat(&format); - if (FAILED(hr)) { - qCDebug(lcMmAudioInterface) << __FUNCTION__ << "Could not get mix format."; - m_currentState = Error; - return hr; - } - - QWasapiUtils::convertFromNativeFormat(format, &m_mixFormat); - - m_currentState = Activated; - return S_OK; -} - -bool QWasapiUtils::convertToNativeFormat(const QAudioFormat &qt, WAVEFORMATEX *native) -{ - if (!native - || !qt.isValid() - || qt.codec() != QStringLiteral("audio/pcm") - || qt.sampleRate() <= 0 - || qt.channelCount() <= 0 - || qt.sampleSize() <= 0 - || qt.byteOrder() != QAudioFormat::LittleEndian) { - return false; - } - - native->nSamplesPerSec = qt.sampleRate(); - native->wBitsPerSample = qt.sampleSize(); - native->nChannels = qt.channelCount(); - native->nBlockAlign = (native->wBitsPerSample * native->nChannels) / 8; - native->nAvgBytesPerSec = native->nBlockAlign * native->nSamplesPerSec; - native->cbSize = 0; - - if (qt.sampleType() == QAudioFormat::Float) - native->wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - else - native->wFormatTag = WAVE_FORMAT_PCM; - - return true; -} - -bool QWasapiUtils::convertFromNativeFormat(const WAVEFORMATEX *native, QAudioFormat *qt) -{ - if (!native || !qt) - return false; - - qt->setByteOrder(QAudioFormat::LittleEndian); - qt->setChannelCount(native->nChannels); - qt->setCodec(QStringLiteral("audio/pcm")); - qt->setSampleRate(native->nSamplesPerSec); - qt->setSampleSize(native->wBitsPerSample); - qt->setSampleType(native->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ? QAudioFormat::Float : QAudioFormat::SignedInt); - - return true; -} - -QByteArray QWasapiUtils::defaultDevice(QAudio::Mode mode) -{ - qCDebug(lcMmUtils) << __FUNCTION__ << mode; - - CoInitIfNeeded(); - QList<QByteArray> &deviceNames = mode == QAudio::AudioInput ? gMapping->inputDeviceNames : gMapping->outputDeviceNames; - QList<QString> &deviceIds = mode == QAudio::AudioInput ? gMapping->inputDeviceIds : gMapping->outputDeviceIds; - if (deviceNames.isEmpty() || deviceIds.isEmpty()) // Initialize - availableDevices(mode); - if (deviceNames.isEmpty() || deviceIds.isEmpty()) // No audio devices at all - return QByteArray(); - - ComPtr<IMediaDeviceStatics> mediaDeviceStatics; - HRESULT hr; - - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_Devices_MediaDevice).Get(), &mediaDeviceStatics); - Q_ASSERT_SUCCEEDED(hr); - - HString defaultAudioDevice; - quint32 dADSize = 0; - - if (mode == QAudio::AudioOutput) - hr = mediaDeviceStatics->GetDefaultAudioRenderId(AudioDeviceRole_Default, defaultAudioDevice.GetAddressOf()); - else - hr = mediaDeviceStatics->GetDefaultAudioCaptureId(AudioDeviceRole_Default, defaultAudioDevice.GetAddressOf()); - - const wchar_t *dadWStr = defaultAudioDevice.GetRawBuffer(&dADSize); - const QString defaultAudioDeviceId = QString::fromWCharArray(dadWStr, dADSize); - Q_ASSERT(deviceIds.indexOf(defaultAudioDeviceId) != -1); - - return deviceNames.at(deviceIds.indexOf(defaultAudioDeviceId)); -} - -QList<QByteArray> QWasapiUtils::availableDevices(QAudio::Mode mode) -{ - qCDebug(lcMmUtils) << __FUNCTION__ << mode; - - CoInitIfNeeded(); - ComPtr<IDeviceInformationStatics> statics; - HRESULT hr; - - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(), - &statics); - Q_ASSERT_SUCCEEDED(hr); - - DeviceClass dc = mode == QAudio::AudioInput ? DeviceClass_AudioCapture : DeviceClass_AudioRender; - - QList<QByteArray> &deviceNames = mode == QAudio::AudioInput ? gMapping->inputDeviceNames : gMapping->outputDeviceNames; - QList<QString> &deviceIds = mode == QAudio::AudioInput ? gMapping->inputDeviceIds : gMapping->outputDeviceIds; - - // We need to refresh due to plugable devices (ie USB) - deviceNames.clear(); - deviceIds.clear(); - - ComPtr<IAsyncOperation<ABI::Windows::Devices::Enumeration::DeviceInformationCollection *>> op; - hr = statics->FindAllAsyncDeviceClass(dc, &op ); - RETURN_EMPTY_LIST_IF_FAILED("Could not query audio devices."); - - ComPtr<IVectorView<DeviceInformation *>> resultVector; - hr = QWinRTFunctions::await(op, resultVector.GetAddressOf()); - RETURN_EMPTY_LIST_IF_FAILED("Could not receive audio device list."); - - quint32 deviceCount; - hr = resultVector->get_Size(&deviceCount); - RETURN_EMPTY_LIST_IF_FAILED("Could not access audio device count."); - qCDebug(lcMmUtils) << "Found " << deviceCount << " audio devices for" << mode; - - for (quint32 i = 0; i < deviceCount; ++i) { - ComPtr<IDeviceInformation> item; - hr = resultVector->GetAt(i, &item); - if (FAILED(hr)) { - qErrnoWarning(hr, "Could not access audio device item."); - continue; - } - - HString hString; - quint32 size; - - hr = item->get_Name(hString.GetAddressOf()); - if (FAILED(hr)) { - qErrnoWarning(hr, "Could not access audio device name."); - continue; - } - const wchar_t *nameWStr = hString.GetRawBuffer(&size); - const QString deviceName = QString::fromWCharArray(nameWStr, size); - - hr = item->get_Id(hString.GetAddressOf()); - if (FAILED(hr)) { - qErrnoWarning(hr, "Could not access audio device id."); - continue; - } - const wchar_t *idWStr = hString.GetRawBuffer(&size); - const QString deviceId = QString::fromWCharArray(idWStr, size); - - boolean enabled; - hr = item->get_IsEnabled(&enabled); - if (FAILED(hr)) { - qErrnoWarning(hr, "Could not access audio device enabled."); - continue; - } - - qCDebug(lcMmUtils) << "Audio Device:" << deviceName << " ID:" << deviceId - << " Enabled:" << enabled; - - deviceNames.append(deviceName.toLocal8Bit()); - deviceIds.append(deviceId); - } - return deviceNames; -} - -Microsoft::WRL::ComPtr<AudioInterface> QWasapiUtils::createOrGetInterface(const QByteArray &dev, QAudio::Mode mode) -{ - qCDebug(lcMmUtils) << __FUNCTION__ << dev << mode; - Q_ASSERT((mode == QAudio::AudioInput ? gMapping->inputDeviceNames.indexOf(dev) : gMapping->outputDeviceNames.indexOf(dev)) != -1); - CoInitIfNeeded(); - - Microsoft::WRL::ComPtr<AudioInterface> result; - HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([dev, mode, &result]() { - HRESULT hr; - QString id = mode == QAudio::AudioInput ? gMapping->inputDeviceIds.at(gMapping->inputDeviceNames.indexOf(dev)) : - gMapping->outputDeviceIds.at(gMapping->outputDeviceNames.indexOf(dev)); - - result = Make<AudioInterface>(); - - ComPtr<IActivateAudioInterfaceAsyncOperation> op; - - // We cannot use QWinRTFunctions::await here as that will return - // E_NO_INTERFACE. Instead we leave the lambda and wait for the - // status to get out of Activating - result->setState(AudioInterface::Activating); - hr = ActivateAudioInterfaceAsync(reinterpret_cast<LPCWSTR>(id.utf16()), __uuidof(IAudioClient), NULL, result.Get(), op.GetAddressOf()); - if (FAILED(hr)) { - qErrnoWarning(hr, "Could not invoke audio interface activation."); - result->setState(AudioInterface::Error); - } - return hr; - }); - qCDebug(lcMmUtils) << "Activation stated:" << hr; - while (result->state() == AudioInterface::Activating) { - QThread::yieldCurrentThread(); - } - qCDebug(lcMmUtils) << "Activation done:" << hr; - return result; -} - -QT_END_NAMESPACE |