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 <qgstreameraudioinput_p.h>
5#include <qgstreameraudiodevice_p.h>
6#include <qaudiodevice.h>
7#include <qaudioinput.h>
8
9#include <QtCore/qloggingcategory.h>
10#include <QtNetwork/qnetworkaccessmanager.h>
11#include <QtNetwork/qnetworkreply.h>
12
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16
17#include <utility>
18
19static Q_LOGGING_CATEGORY(qLcMediaAudioInput, "qt.multimedia.audioInput")
20
21QT_BEGIN_NAMESPACE
22
23QMaybe<QPlatformAudioInput *> QGstreamerAudioInput::create(QAudioInput *parent)
24{
25 QGstElement autoaudiosrc("autoaudiosrc", "autoaudiosrc");
26 if (!autoaudiosrc)
27 return errorMessageCannotFindElement(element: "autoaudiosrc");
28
29 QGstElement volume("volume", "volume");
30 if (!volume)
31 return errorMessageCannotFindElement(element: "volume");
32
33 return new QGstreamerAudioInput(autoaudiosrc, volume, parent);
34}
35
36QGstreamerAudioInput::QGstreamerAudioInput(QGstElement autoaudiosrc, QGstElement volume,
37 QAudioInput *parent)
38 : QObject(parent),
39 QPlatformAudioInput(parent),
40 gstAudioInput("audioInput"),
41 audioSrc(std::move(autoaudiosrc)),
42 audioVolume(std::move(volume))
43{
44 gstAudioInput.add(e1: audioSrc, e2: audioVolume);
45 audioSrc.link(next: audioVolume);
46
47 gstAudioInput.addGhostPad(child: audioVolume, name: "src");
48}
49
50QGstreamerAudioInput::~QGstreamerAudioInput()
51{
52 gstAudioInput.setStateSync(GST_STATE_NULL);
53}
54
55int QGstreamerAudioInput::volume() const
56{
57 return m_volume;
58}
59
60bool QGstreamerAudioInput::isMuted() const
61{
62 return m_muted;
63}
64
65void QGstreamerAudioInput::setVolume(float vol)
66{
67 if (vol == m_volume)
68 return;
69 m_volume = vol;
70 audioVolume.set(property: "volume", d: vol);
71 emit volumeChanged(m_volume);
72}
73
74void QGstreamerAudioInput::setMuted(bool muted)
75{
76 if (muted == m_muted)
77 return;
78 m_muted = muted;
79 audioVolume.set(property: "mute", b: muted);
80 emit mutedChanged(muted);
81}
82
83void QGstreamerAudioInput::setAudioDevice(const QAudioDevice &device)
84{
85 if (device == m_audioDevice)
86 return;
87 qCDebug(qLcMediaAudioInput) << "setAudioInput" << device.description() << device.isNull();
88 m_audioDevice = device;
89
90 QGstElement newSrc;
91#if QT_CONFIG(pulseaudio)
92 auto id = m_audioDevice.id();
93 newSrc = QGstElement("pulsesrc", "audiosrc");
94 if (!newSrc.isNull())
95 newSrc.set(property: "device", str: id.constData());
96 else
97 qCWarning(qLcMediaAudioInput) << "Invalid audio device";
98#else
99 auto *deviceInfo = static_cast<const QGStreamerAudioDeviceInfo *>(m_audioDevice.handle());
100 if (deviceInfo && deviceInfo->gstDevice)
101 newSrc = gst_device_create_element(deviceInfo->gstDevice, "audiosrc");
102 else
103 qCWarning(qLcMediaAudioInput) << "Invalid audio device";
104#endif
105
106 if (newSrc.isNull()) {
107 qCWarning(qLcMediaAudioInput) << "Failed to create a gst element for the audio device, using a default audio source";
108 newSrc = QGstElement("autoaudiosrc", "audiosrc");
109 }
110
111 // FIXME: most probably source can be disconnected outside of idle probe
112 audioSrc.staticPad(name: "src").doInIdleProbe(work: [&](){
113 audioSrc.unlink(next: audioVolume);
114 });
115 audioSrc.setStateSync(GST_STATE_NULL);
116 gstAudioInput.remove(element: audioSrc);
117 audioSrc = newSrc;
118 gstAudioInput.add(element: audioSrc);
119 audioSrc.link(next: audioVolume);
120 audioSrc.syncStateWithParent();
121}
122
123QAudioDevice QGstreamerAudioInput::audioInput() const
124{
125 return m_audioDevice;
126}
127
128QT_END_NAMESPACE
129
130#include "moc_qgstreameraudioinput_p.cpp"
131

source code of qtmultimedia/src/plugins/multimedia/gstreamer/common/qgstreameraudioinput.cpp