1// Copyright (C) 2016 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 <qgstreameraudiooutput_p.h>
5#include <qgstreameraudiodevice_p.h>
6#include <qaudiodevice.h>
7#include <qaudiooutput.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(qLcMediaAudioOutput, "qt.multimedia.audiooutput")
20
21QT_BEGIN_NAMESPACE
22
23QMaybe<QPlatformAudioOutput *> QGstreamerAudioOutput::create(QAudioOutput *parent)
24{
25 QGstElement audioconvert("audioconvert", "audioConvert");
26 if (!audioconvert)
27 return errorMessageCannotFindElement(element: "audioconvert");
28
29 QGstElement audioresample("audioresample", "audioResample");
30 if (!audioresample)
31 return errorMessageCannotFindElement(element: "audioresample");
32
33 QGstElement volume("volume", "volume");
34 if (!volume)
35 return errorMessageCannotFindElement(element: "volume");
36
37 QGstElement autoaudiosink("autoaudiosink", "autoAudioSink");
38 if (!autoaudiosink)
39 return errorMessageCannotFindElement(element: "autoaudiosink");
40
41 return new QGstreamerAudioOutput(audioconvert, audioresample, volume, autoaudiosink, parent);
42}
43
44QGstreamerAudioOutput::QGstreamerAudioOutput(QGstElement audioconvert, QGstElement audioresample,
45 QGstElement volume, QGstElement autoaudiosink,
46 QAudioOutput *parent)
47 : QObject(parent),
48 QPlatformAudioOutput(parent),
49 gstAudioOutput("audioOutput"),
50 audioConvert(std::move(audioconvert)),
51 audioResample(std::move(audioresample)),
52 audioVolume(std::move(volume)),
53 audioSink(std::move(autoaudiosink))
54{
55 audioQueue = QGstElement("queue", "audioQueue");
56 gstAudioOutput.add(e1: audioQueue, e2: audioConvert, e3: audioResample, e4: audioVolume, e5: audioSink);
57 audioQueue.link(n1: audioConvert, n2: audioResample, n3: audioVolume, n4: audioSink);
58
59 gstAudioOutput.addGhostPad(child: audioQueue, name: "sink");
60}
61
62QGstreamerAudioOutput::~QGstreamerAudioOutput()
63{
64 gstAudioOutput.setStateSync(GST_STATE_NULL);
65}
66
67void QGstreamerAudioOutput::setVolume(float vol)
68{
69 audioVolume.set(property: "volume", d: vol);
70}
71
72void QGstreamerAudioOutput::setMuted(bool muted)
73{
74 audioVolume.set(property: "mute", b: muted);
75}
76
77void QGstreamerAudioOutput::setPipeline(const QGstPipeline &pipeline)
78{
79 gstPipeline = pipeline;
80}
81
82void QGstreamerAudioOutput::setAudioDevice(const QAudioDevice &info)
83{
84 if (info == m_audioOutput)
85 return;
86 qCDebug(qLcMediaAudioOutput) << "setAudioOutput" << info.description() << info.isNull();
87 m_audioOutput = info;
88
89 QGstElement newSink;
90#if QT_CONFIG(pulseaudio)
91 auto id = m_audioOutput.id();
92 newSink = QGstElement("pulsesink", "audiosink");
93 if (!newSink.isNull())
94 newSink.set(property: "device", str: id.constData());
95 else
96 qCWarning(qLcMediaAudioOutput) << "Invalid audio device";
97#else
98 auto *deviceInfo = static_cast<const QGStreamerAudioDeviceInfo *>(m_audioOutput.handle());
99 if (deviceInfo && deviceInfo->gstDevice)
100 newSink = gst_device_create_element(deviceInfo->gstDevice , "audiosink");
101 else
102 qCWarning(qLcMediaAudioOutput) << "Invalid audio device";
103#endif
104
105 if (newSink.isNull()) {
106 qCWarning(qLcMediaAudioOutput) << "Failed to create a gst element for the audio device, using a default audio sink";
107 newSink = QGstElement("autoaudiosink", "audiosink");
108 }
109
110 audioVolume.staticPad(name: "src").doInIdleProbe(work: [&](){
111 audioVolume.unlink(next: audioSink);
112 gstAudioOutput.remove(element: audioSink);
113 gstAudioOutput.add(element: newSink);
114 newSink.syncStateWithParent();
115 audioVolume.link(next: newSink);
116 });
117
118 audioSink.setStateSync(GST_STATE_NULL);
119 audioSink = newSink;
120}
121
122QT_END_NAMESPACE
123
124#include "moc_qgstreameraudiooutput_p.cpp"
125

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