summaryrefslogtreecommitdiffstats
path: root/src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp')
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp b/src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp
new file mode 100644
index 000000000..7c620da39
--- /dev/null
+++ b/src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp
@@ -0,0 +1,137 @@
+// 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 <QtMultimedia/qaudiodevice.h>
+#include <QtMultimedia/qaudioinput.h>
+
+#include <QtCore/qloggingcategory.h>
+
+#include <audio/qgstreameraudiodevice_p.h>
+#include <common/qgstreameraudioinput_p.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <utility>
+
+static Q_LOGGING_CATEGORY(qLcMediaAudioInput, "qt.multimedia.audioInput")
+
+QT_BEGIN_NAMESPACE
+
+QMaybe<QPlatformAudioInput *> QGstreamerAudioInput::create(QAudioInput *parent)
+{
+ static const auto error = qGstErrorMessageIfElementsNotAvailable("autoaudiosrc", "volume");
+ if (error)
+ return *error;
+
+ return new QGstreamerAudioInput(parent);
+}
+
+QGstreamerAudioInput::QGstreamerAudioInput(QAudioInput *parent)
+ : QObject(parent),
+ QPlatformAudioInput(parent),
+ gstAudioInput(QGstBin::create("audioInput")),
+ audioSrc{
+ QGstElement::createFromFactory("autoaudiosrc", "autoaudiosrc"),
+ },
+ audioVolume{
+ QGstElement::createFromFactory("volume", "volume"),
+ }
+{
+ gstAudioInput.add(audioSrc, audioVolume);
+ qLinkGstElements(audioSrc, audioVolume);
+
+ gstAudioInput.addGhostPad(audioVolume, "src");
+}
+
+QGstElement QGstreamerAudioInput::createGstElement()
+{
+ const auto *customDeviceInfo =
+ dynamic_cast<const QGStreamerCustomAudioDeviceInfo *>(m_audioDevice.handle());
+
+ if (customDeviceInfo) {
+ qCDebug(qLcMediaAudioInput)
+ << "requesting custom audio src element: " << customDeviceInfo->id;
+
+ QGstElement element = QGstBin::createFromPipelineDescription(customDeviceInfo->id,
+ /*name=*/nullptr,
+ /*ghostUnlinkedPads=*/true);
+ if (element)
+ return element;
+
+ qCWarning(qLcMediaAudioInput)
+ << "Cannot create audio source element:" << customDeviceInfo->id;
+ }
+
+ const QByteArray &id = m_audioDevice.id();
+ if constexpr (QT_CONFIG(pulseaudio)) {
+ QGstElement newSrc = QGstElement::createFromFactory("pulsesrc", "audiosrc");
+ if (newSrc) {
+ newSrc.set("device", id.constData());
+ return newSrc;
+ } else {
+ qWarning() << "Cannot create pulsesrc";
+ }
+ } else if constexpr (QT_CONFIG(alsa)) {
+ QGstElement newSrc = QGstElement::createFromFactory("alsasrc", "audiosrc");
+ if (newSrc) {
+ newSrc.set("device", id.constData());
+ return newSrc;
+ } else {
+ qWarning() << "Cannot create alsasrc";
+ }
+ } else {
+ auto *deviceInfo = dynamic_cast<const QGStreamerAudioDeviceInfo *>(m_audioDevice.handle());
+ if (deviceInfo && deviceInfo->gstDevice) {
+ QGstElement element = QGstElement::createFromDevice(deviceInfo->gstDevice, "audiosrc");
+ if (element)
+ return element;
+ }
+ }
+ qCWarning(qLcMediaAudioInput) << "Invalid audio device";
+ qCWarning(qLcMediaAudioInput)
+ << "Failed to create a gst element for the audio device, using a default audio source";
+ return QGstElement::createFromFactory("autoaudiosrc", "audiosrc");
+}
+
+QGstreamerAudioInput::~QGstreamerAudioInput()
+{
+ gstAudioInput.setStateSync(GST_STATE_NULL);
+}
+
+void QGstreamerAudioInput::setVolume(float volume)
+{
+ audioVolume.set("volume", volume);
+}
+
+void QGstreamerAudioInput::setMuted(bool muted)
+{
+ audioVolume.set("mute", muted);
+}
+
+void QGstreamerAudioInput::setAudioDevice(const QAudioDevice &device)
+{
+ if (device == m_audioDevice)
+ return;
+ qCDebug(qLcMediaAudioInput) << "setAudioInput" << device.description() << device.isNull();
+ m_audioDevice = device;
+
+ QGstElement newSrc = createGstElement();
+
+ QGstPipeline::modifyPipelineWhileNotRunning(gstAudioInput.getPipeline(), [&] {
+ qUnlinkGstElements(audioSrc, audioVolume);
+ gstAudioInput.stopAndRemoveElements(audioSrc);
+ audioSrc = std::move(newSrc);
+ gstAudioInput.add(audioSrc);
+ qLinkGstElements(audioSrc, audioVolume);
+ audioSrc.syncStateWithParent();
+ });
+}
+
+QAudioDevice QGstreamerAudioInput::audioInput() const
+{
+ return m_audioDevice;
+}
+
+QT_END_NAMESPACE