Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgstreameraudioinput.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <common/qgstreameraudioinput_p.h>
5
6#include <QtCore/qloggingcategory.h>
7#include <QtMultimedia/qaudiodevice.h>
8#include <QtMultimedia/qaudioinput.h>
9
10#include <audio/qgstreameraudiodevice_p.h>
11#include <common/qgstpipeline_p.h>
12
13
15
16namespace {
17
18Q_STATIC_LOGGING_CATEGORY(qLcMediaAudioInput, "qt.multimedia.audioinput")
19
21 using namespace Qt::Literals;
22
23 if constexpr (QT_CONFIG(pulseaudio))
24 return "pulsesrc"_L1;
25 else if constexpr (QT_CONFIG(alsa))
26 return "alsasrc"_L1;
27 else
28 return "autoaudiosrc"_L1;
29}();
30
32{
33 using namespace Qt::Literals;
34 QLatin1String elementType = element.typeName();
35
36 if constexpr (QT_CONFIG(pulseaudio))
37 return elementType == "GstPulseSrc"_L1;
38
39 if constexpr (0 && QT_CONFIG(alsa)) // alsasrc has a "device" property, but it cannot be changed
40 // during playback
41 return elementType == "GstAlsaSrc"_L1;
42
43 return false;
44}
45
46} // namespace
47
48q23::expected<QPlatformAudioInput *, QString> QGstreamerAudioInput::create(QAudioInput *parent)
49{
50 static const auto error = qGstErrorMessageIfElementsNotAvailable("autoaudiosrc", "volume");
51 if (error)
52 return q23::unexpected{ *error };
53
54 return new QGstreamerAudioInput(parent);
55}
56
57QGstreamerAudioInput::QGstreamerAudioInput(QAudioInput *parent)
58 : QObject(parent),
59 QPlatformAudioInput(parent),
60 m_audioInputBin(QGstBin::create("audioInput")),
61 m_audioSrc{
62 QGstElement::createFromFactory(defaultSrcName.constData(), "autoaudiosrc"),
63 },
64 m_audioVolume{
65 QGstElement::createFromFactory("volume", "volume"),
66 }
67{
68 m_audioInputBin.add(m_audioSrc, m_audioVolume);
69 qLinkGstElements(m_audioSrc, m_audioVolume);
70
71 m_audioInputBin.addGhostPad(m_audioVolume, "src");
72}
73
74QGstElement QGstreamerAudioInput::createGstElement()
75{
76 const auto *customDevice =
77 QAudioDevicePrivate::handle<QGStreamerCustomAudioDeviceInfo>(m_audioDevice);
78
79 if (customDevice) {
80 qCDebug(qLcMediaAudioInput) << "requesting custom audio src element: " << customDevice->id;
81
83 /*name=*/nullptr,
84 /*ghostUnlinkedPads=*/true);
85 if (element)
86 return element;
87
88 qCWarning(qLcMediaAudioInput) << "Cannot create audio source element:" << customDevice->id;
89 }
90
91 const QByteArray &id = m_audioDevice.id();
92 if constexpr (QT_CONFIG(pulseaudio) || QT_CONFIG(alsa)) {
93 QGstElement newSrc = QGstElement::createFromFactory(defaultSrcName.constData(), "audiosrc");
94 if (newSrc) {
95 newSrc.set("device", id.constData());
96 return newSrc;
97 }
98
99 qWarning() << "Cannot create" << defaultSrcName;
100 }
101 qCWarning(qLcMediaAudioInput) << "Invalid audio device";
102 qCWarning(qLcMediaAudioInput)
103 << "Failed to create a gst element for the audio device, using a default audio source";
104 return QGstElement::createFromFactory("autoaudiosrc", "audiosrc");
105}
106
108{
109 m_audioInputBin.setStateSync(GST_STATE_NULL);
110}
111
113{
114 m_audioVolume.set("volume", volume);
115}
116
118{
119 m_audioVolume.set("mute", muted);
120}
121
122void QGstreamerAudioInput::setAudioDevice(const QAudioDevice &device)
123{
124 if (device == m_audioDevice)
125 return;
126 qCDebug(qLcMediaAudioInput) << "setAudioDevice" << device.description() << device.isNull();
127 m_audioDevice = device;
128
129 if (srcHasDeviceProperty(m_audioSrc) && !isCustomAudioDevice(m_audioDevice)) {
130 m_audioSrc.set("device", m_audioDevice.id().constData());
131 return;
132 }
133
134 QGstElement newSrc = createGstElement();
135
136 m_audioVolume.sink().modifyPipelineInIdleProbe([&] {
137 qUnlinkGstElements(m_audioSrc, m_audioVolume);
138 m_audioInputBin.stopAndRemoveElements(m_audioSrc);
139 m_audioSrc = std::move(newSrc);
140 m_audioInputBin.add(m_audioSrc);
141 qLinkGstElements(m_audioSrc, m_audioVolume);
142 m_audioSrc.syncStateWithParent();
143 });
144}
145
146QT_END_NAMESPACE
static QGstBin createFromPipelineDescription(const char *pipelineDescription, const char *name=nullptr, bool ghostUnlinkedPads=false)
Definition qgst.cpp:1321
static QGstElement createFromFactory(const char *factory, const char *name=nullptr)
Definition qgst.cpp:956
void setMuted(bool) override
void setAudioDevice(const QAudioDevice &) override
void setVolume(float) override
constexpr QLatin1String defaultSrcName
bool srcHasDeviceProperty(const QGstElement &element)