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
qohosaudiosink.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 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
5
6#include <QtMultimedia/private/qaudiohelpers_p.h>
7
8#include <QtCore/qloggingcategory.h>
9
11
12namespace QtOHAudio {
13
14Q_STATIC_LOGGING_CATEGORY(qLcOhosAudioSink, "qt.multimedia.ohos.audiosink")
15
16QOhosAudioSinkStream::QOhosAudioSinkStream(QAudioDevice device, const QAudioFormat &format,
17 std::optional<qsizetype> ringbufferSize,
18 QOhosAudioSink *parent, float volume,
19 std::optional<QtMultimediaPrivate::NativePeriodFrames> hardwareBufferFrames,
20 AudioEndpointRole role)
25{
32 }
33
35
36 qCDebug(qLcOhosAudioSink) << "Creating sink for device id:" << m_audioDevice.id()
37 << "description:" << m_audioDevice.description();
38
39 switch (m_role) {
42 break;
45 break;
49 break;
50 }
51
52 builder.userData = this;
55 auto *stream = reinterpret_cast<QOhosAudioSinkStream *>(userData);
60 };
61
64}
65
66bool QOhosAudioSinkStream::open()
67{
68 if (!m_stream || !m_stream->isOpen()) {
69 qCWarning(qLcOhosAudioSink) << "Stream creation failed";
70 requestStop();
71 return false;
72 }
73 return true;
74}
75
76bool QOhosAudioSinkStream::start(QIODevice *device)
77{
78 Q_ASSERT(thread()->isCurrentThread());
79 setQIODevice(device);
80 pullFromQIODevice();
81 createQIODeviceConnections(device);
82
83 if (!m_stream->start()) {
84 requestStop();
85 return false;
86 }
87 return true;
88}
89
90QIODevice *QOhosAudioSinkStream::start()
91{
92 auto *writer = createRingbufferWriterDevice();
93 return start(writer) ? writer : nullptr;
94}
95
96bool QOhosAudioSinkStream::start(AudioCallback cb)
97{
98 Q_ASSERT(thread()->isCurrentThread());
99 m_audioCallback = std::move(cb);
100
101 if (!m_stream->start()) {
102 requestStop();
103 return false;
104 }
105 return true;
106}
107
108void QOhosAudioSinkStream::suspend()
109{
110 Q_ASSERT(thread()->isCurrentThread());
111 m_stream->pause();
112}
113
114void QOhosAudioSinkStream::resume()
115{
116 Q_ASSERT(thread()->isCurrentThread());
117 m_stream->start();
118}
119
120void QOhosAudioSinkStream::stop(ShutdownPolicy policy)
121{
122 requestStop();
123 disconnectQIODeviceConnections();
124
125 switch (policy) {
126 case ShutdownPolicy::DrainRingbuffer:
127 stop();
128 break;
129 case ShutdownPolicy::DiscardRingbuffer:
130 reset();
131 break;
132 default:
133 Q_UNREACHABLE_RETURN();
134 }
135}
136
137void QOhosAudioSinkStream::stop()
138{
139 if (isIdle() || m_audioCallback)
140 return reset();
141
142 stopIdleDetection();
143 connectIdleHandler([this] {
144 Q_ASSERT(thread()->isCurrentThread());
145 if (!isIdle())
146 return;
147 m_stream->stop();
148 m_self = nullptr;
149 });
150
151 m_parent = nullptr;
152 m_self = shared_from_this();
153}
154
155void QOhosAudioSinkStream::reset()
156{
157 // Note: reset() can be invoked on the engine's destruction thread when the
158 // owning QRtAudioEngine was moved across threads after stream construction
159 // (the stream's idle-detection notifier does not follow the sink across
160 // moveToThread). OH_AudioRenderer_Stop is documented thread-safe, so we
161 // intentionally do not assert thread()->isCurrentThread() here.
162 m_stream->stop();
163}
164
165void QOhosAudioSinkStream::updateStreamIdle(bool arg)
166{
167 if (m_parent)
168 m_parent->updateStreamIdle(arg);
169}
170
171QSpan<std::byte>
174{
175 return QSpan<std::byte>{ reinterpret_cast<std::byte *>(audioData),
176 static_cast<qsizetype>(numBytes) };
177}
178
182{
185
191
192 if (consumedFrames != static_cast<uint64_t>(numFrames) && isStopRequested())
194
196}
197
200{
201 if (isStopRequested())
203
204 if (m_hostFormat)
206 *m_hostFormat);
207 else
209
211}
212
217
218QOhosAudioSink::~QOhosAudioSink() = default;
219
220} // namespace QtOHAudio
221
222QT_END_NAMESPACE
void stop(ShutdownPolicy policy)
bool start(QIODevice *device)
void updateStreamIdle(bool arg) override
Combined button and popup list for selecting options.