diff options
Diffstat (limited to 'src/multimedia/alsa/qalsamediadevices.cpp')
-rw-r--r-- | src/multimedia/alsa/qalsamediadevices.cpp | 150 |
1 files changed, 76 insertions, 74 deletions
diff --git a/src/multimedia/alsa/qalsamediadevices.cpp b/src/multimedia/alsa/qalsamediadevices.cpp index e2561e66a..9466fa0cd 100644 --- a/src/multimedia/alsa/qalsamediadevices.cpp +++ b/src/multimedia/alsa/qalsamediadevices.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qalsamediadevices_p.h" #include "qmediadevices.h" @@ -49,6 +13,26 @@ QT_BEGIN_NAMESPACE +namespace { + +struct free_char +{ + void operator()(char *c) const { ::free(c); } +}; + +using unique_str = std::unique_ptr<char, free_char>; + +bool operator==(const unique_str &str, std::string_view sv) +{ + return std::string_view{ str.get() } == sv; +} +bool operator!=(const unique_str &str, std::string_view sv) +{ + return !(str == sv); +} + +} // namespace + QAlsaMediaDevices::QAlsaMediaDevices() : QPlatformMediaDevices() { @@ -58,45 +42,66 @@ static QList<QAudioDevice> availableDevices(QAudioDevice::Mode mode) { QList<QAudioDevice> devices; - QByteArray filter; - // Create a list of all current audio devices that support mode - void **hints, **n; - char *name, *descr, *io; - - if(snd_device_name_hint(-1, "pcm", &hints) < 0) { + void **hints; + if (snd_device_name_hint(-1, "pcm", &hints) < 0) { qWarning() << "no alsa devices available"; return devices; } - n = hints; - if(mode == QAudioDevice::Input) { - filter = "Input"; - } else { - filter = "Output"; - } + std::string_view filter = (mode == QAudioDevice::Input) ? "Input" : "Output"; + + QAlsaAudioDeviceInfo *sysdefault = nullptr; + auto makeDeviceInfo = [&filter, mode](void *entry) -> QAlsaAudioDeviceInfo * { + unique_str name{ snd_device_name_get_hint(entry, "NAME") }; + if (name && name != "null") { + unique_str descr{ snd_device_name_get_hint(entry, "DESC") }; + unique_str io{ snd_device_name_get_hint(entry, "IOID") }; + + if (descr && (!io || (io == filter))) { + auto *infop = new QAlsaAudioDeviceInfo{ + name.get(), + QString::fromUtf8(descr.get()), + mode, + }; + return infop; + } + } + return nullptr; + }; + + bool hasDefault = false; + void **n = hints; while (*n != NULL) { - name = snd_device_name_get_hint(*n, "NAME"); - if (name != 0 && qstrcmp(name, "null") != 0) { - descr = snd_device_name_get_hint(*n, "DESC"); - io = snd_device_name_get_hint(*n, "IOID"); - - if ((descr != NULL) && ((io == NULL) || (io == filter))) { - auto *infop = new QAlsaAudioDeviceInfo(name, QString::fromUtf8(descr), mode); - devices.append(infop->create()); - if (strcmp(name, "default") == 0) - infop->isDefault = true; + QAlsaAudioDeviceInfo *infop = makeDeviceInfo(*n++); + + if (infop) { + devices.append(infop->create()); + if (!hasDefault && infop->id.startsWith("default")) { + infop->isDefault = true; + hasDefault = true; } + if (!sysdefault && infop->id.startsWith("sysdefault")) + sysdefault = infop; + } + } - free(descr); - free(io); + if (!hasDefault && sysdefault) { + // Make "sysdefault" the default device if there is no "default" device exists + sysdefault->isDefault = true; + hasDefault = true; + } + if (!hasDefault && devices.size() > 0) { + // forcefully declare the first device as "default" + QAlsaAudioDeviceInfo *infop = makeDeviceInfo(hints[0]); + if (infop) { + infop->isDefault = true; + devices.prepend(infop->create()); } - free(name); - ++n; } - snd_device_name_free_hint(hints); + snd_device_name_free_hint(hints); return devices; } @@ -110,19 +115,16 @@ QList<QAudioDevice> QAlsaMediaDevices::audioOutputs() const return availableDevices(QAudioDevice::Output); } -QList<QCameraDevice> QAlsaMediaDevices::videoInputs() const -{ - return {}; -} - -QPlatformAudioSource *QAlsaMediaDevices::createAudioSource(const QAudioDevice &deviceInfo) +QPlatformAudioSource *QAlsaMediaDevices::createAudioSource(const QAudioDevice &deviceInfo, + QObject *parent) { - return new QAlsaAudioSource(deviceInfo.id()); + return new QAlsaAudioSource(deviceInfo.id(), parent); } -QPlatformAudioSink *QAlsaMediaDevices::createAudioSink(const QAudioDevice &deviceInfo) +QPlatformAudioSink *QAlsaMediaDevices::createAudioSink(const QAudioDevice &deviceInfo, + QObject *parent) { - return new QAlsaAudioSink(deviceInfo.id()); + return new QAlsaAudioSink(deviceInfo.id(), parent); } QT_END_NAMESPACE |