Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qohaudiostream.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
4
#
include
"qohaudiostream_p.h"
5
6
#
include
<
QtMultimedia
/
private
/
qmultimedia_enum_to_string_converter_p
.
h
>
7
8
#
include
<
QtCore
/
qloggingcategory
.
h
>
9
#
include
<
QtCore
/
qmutex
.
h
>
10
11
QT_BEGIN_NAMESPACE
12
13
// clang-format off
14
QT_MM_MAKE_STRING_RESOLVER(OH_AudioStream_Result, QtMultimediaPrivate::EnumName,
15
(AUDIOSTREAM_SUCCESS,
"AUDIOSTREAM_SUCCESS"
)
16
(AUDIOSTREAM_ERROR_INVALID_PARAM,
"AUDIOSTREAM_ERROR_INVALID_PARAM"
)
17
(AUDIOSTREAM_ERROR_ILLEGAL_STATE,
"AUDIOSTREAM_ERROR_ILLEGAL_STATE"
)
18
(AUDIOSTREAM_ERROR_SYSTEM,
"AUDIOSTREAM_ERROR_SYSTEM"
)
19
(AUDIOSTREAM_ERROR_UNSUPPORTED_FORMAT,
"AUDIOSTREAM_ERROR_UNSUPPORTED_FORMAT"
)
20
);
21
// clang-format on
22
23
QT_MM_DEFINE_QDEBUG_ENUM
(
OH_AudioStream_Result
);
24
25
namespace
QtOHAudio
{
26
27
Q_LOGGING_CATEGORY(qLcOHAudioStream,
"qt.multimedia.ohos.audiostream"
)
28
29
namespace
{
30
// OH_AudioStreamBuilder is not thread-safe: concurrent Create/Destroy and
31
// GenerateRenderer/GenerateCapturer calls from multiple threads crash inside
32
// the audio service. Serialize all builder lifecycle operations.
33
Q_CONSTINIT QBasicMutex g_streamBuilderMutex;
34
}
35
36
OH_AudioStream_SampleFormat
toOHSampleFormat
(QAudioFormat::SampleFormat fmt)
37
{
38
switch
(fmt) {
39
case
QAudioFormat::UInt8:
40
return
AUDIOSTREAM_SAMPLE_U8;
41
case
QAudioFormat::Int16:
42
return
AUDIOSTREAM_SAMPLE_S16LE;
43
case
QAudioFormat::Int32:
44
return
AUDIOSTREAM_SAMPLE_S32LE;
45
case
QAudioFormat::Float:
46
return
AUDIOSTREAM_SAMPLE_F32LE;
47
case
QAudioFormat::Unknown:
48
case
QAudioFormat::NSampleFormats:
49
break
;
50
}
51
return
AUDIOSTREAM_SAMPLE_S16LE;
52
}
53
54
QAudioFormat
::
SampleFormat
fromOHSampleFormat
(OH_AudioStream_SampleFormat fmt)
55
{
56
switch
(fmt) {
57
case
AUDIOSTREAM_SAMPLE_U8:
58
return
QAudioFormat::UInt8;
59
case
AUDIOSTREAM_SAMPLE_S16LE:
60
return
QAudioFormat::Int16;
61
case
AUDIOSTREAM_SAMPLE_S24LE:
62
return
QAudioFormat::Unknown;
63
case
AUDIOSTREAM_SAMPLE_S32LE:
64
return
QAudioFormat::Int32;
65
case
AUDIOSTREAM_SAMPLE_F32LE:
66
return
QAudioFormat::Float;
67
}
68
return
QAudioFormat::Unknown;
69
}
70
71
QAudioFormat
::
SampleFormat
preferredCompatibleSampleFormat
(QAudioFormat::SampleFormat requested)
72
{
73
switch
(requested) {
74
case
QAudioFormat::UInt8:
75
case
QAudioFormat::Int16:
76
case
QAudioFormat::Int32:
77
case
QAudioFormat::Float:
78
return
requested;
79
case
QAudioFormat::Unknown:
80
case
QAudioFormat::NSampleFormats:
81
break
;
82
}
83
return
QAudioFormat::Int16;
84
}
85
86
StreamBuilder
::
StreamBuilder
(QAudioFormat fmt, OH_AudioStream_Type direction)
87
:
format
{
fmt
}
88
{
89
params.direction = direction;
90
QMutexLocker lock{ &g_streamBuilderMutex };
91
OH_AudioStream_Result
result = OH_AudioStreamBuilder_Create(&m_builder, direction);
92
if
(result != AUDIOSTREAM_SUCCESS)
93
qCWarning(qLcOHAudioStream)
94
<<
"Failed to create stream builder:"
<< result;
95
}
96
97
StreamBuilder
::~
StreamBuilder
()
98
{
99
QMutexLocker lock{ &g_streamBuilderMutex };
100
if
(m_builder)
101
OH_AudioStreamBuilder_Destroy(m_builder);
102
}
103
104
void
StreamBuilder
::
setupBuilder
()
105
{
106
if
(!m_builder)
107
return
;
108
109
OH_AudioStreamBuilder_SetSamplingRate(m_builder, format.sampleRate());
110
OH_AudioStreamBuilder_SetChannelCount(m_builder, format.channelCount());
111
OH_AudioStreamBuilder_SetSampleFormat(m_builder, toOHSampleFormat(format.sampleFormat()));
112
OH_AudioStreamBuilder_SetEncodingType(m_builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
113
OH_AudioStreamBuilder_SetLatencyMode(m_builder, params.latencyMode);
114
115
// TODO: register the OH_AudioRenderer_Callbacks / OH_AudioCapturer_Callbacks
116
// error and interrupt-event handlers so the backend can react to focus loss,
117
// device changes and stream errors. See:
118
// https://developer.huawei.com/consumer/en/doc/harmonyos-references/capi-ohaudio-oh-audiorenderer-callbacks-struct
119
if
(params.direction == AUDIOSTREAM_TYPE_RENDERER) {
120
OH_AudioStreamBuilder_SetRendererInfo(m_builder, params.outputUsage);
121
if
(writeCallback) {
122
OH_AudioStreamBuilder_SetRendererWriteDataCallback(m_builder, writeCallback,
123
userData
);
124
}
125
}
else
{
126
OH_AudioStreamBuilder_SetCapturerInfo(m_builder, params.inputSourceType);
127
if
(readCallback) {
128
OH_AudioCapturer_Callbacks callbacks{};
129
callbacks.OH_AudioCapturer_OnReadData = readCallback;
130
OH_AudioStreamBuilder_SetCapturerCallback(m_builder, callbacks,
userData
);
131
}
132
}
133
}
134
135
Stream
::
Stream
(
StreamBuilder
&builder)
136
:
m_streamType
{
builder
.
params
.
direction
}
137
{
138
if
(!builder.m_builder) {
139
qCWarning(qLcOHAudioStream) <<
"Builder is invalid"
;
140
return
;
141
}
142
143
OH_AudioStream_Result
result = AUDIOSTREAM_SUCCESS;
144
{
145
QMutexLocker lock{ &g_streamBuilderMutex };
146
if
(m_streamType == AUDIOSTREAM_TYPE_RENDERER) {
147
result = OH_AudioStreamBuilder_GenerateRenderer(builder.m_builder, &m_renderer);
148
}
else
{
149
result = OH_AudioStreamBuilder_GenerateCapturer(builder.m_builder, &m_capturer);
150
}
151
}
152
153
if
(result != AUDIOSTREAM_SUCCESS) {
154
qCWarning(qLcOHAudioStream)
155
<<
"Failed to generate stream:"
<< result;
156
return
;
157
}
158
159
m_areStreamParametersRespected =
true
;
160
}
161
162
Stream
::~
Stream
()
163
{
164
if
(
isOpen
(
)
)
165
close();
166
}
167
168
bool
Stream
::
start
()
169
{
170
OH_AudioStream_Result
result = AUDIOSTREAM_SUCCESS;
171
if
(m_streamType == AUDIOSTREAM_TYPE_RENDERER)
172
result = OH_AudioRenderer_Start(m_renderer);
173
else
174
result = OH_AudioCapturer_Start(m_capturer);
175
176
if
(result != AUDIOSTREAM_SUCCESS)
177
qCWarning(qLcOHAudioStream) <<
"Failed to start stream:"
<< result;
178
179
return
result == AUDIOSTREAM_SUCCESS;
180
}
181
182
void
Stream
::
stop
()
183
{
184
if
(m_streamType == AUDIOSTREAM_TYPE_RENDERER)
185
OH_AudioRenderer_Stop(m_renderer);
186
else
187
OH_AudioCapturer_Stop(m_capturer);
188
}
189
190
void
Stream
::
pause
()
191
{
192
OH_AudioStream_Result
result = AUDIOSTREAM_SUCCESS;
193
if
(m_streamType == AUDIOSTREAM_TYPE_RENDERER)
194
result = OH_AudioRenderer_Pause(m_renderer);
195
else
196
result = OH_AudioCapturer_Pause(m_capturer);
197
if
(result != AUDIOSTREAM_SUCCESS)
198
qCWarning(qLcOHAudioStream)
199
<<
"Failed to pause stream:"
<< result;
200
}
201
202
void
Stream
::
flush
()
203
{
204
if
(m_streamType == AUDIOSTREAM_TYPE_RENDERER)
205
OH_AudioRenderer_Flush(m_renderer);
206
}
207
208
bool
Stream
::
isOpen
()
const
209
{
210
return
m_renderer !=
nullptr
|| m_capturer !=
nullptr
;
211
}
212
213
bool
Stream
::
areStreamParametersRespected
()
const
214
{
215
return
m_areStreamParametersRespected;
216
}
217
218
void
Stream
::close()
219
{
220
if
(m_streamType == AUDIOSTREAM_TYPE_RENDERER && m_renderer) {
221
OH_AudioRenderer_Release(m_renderer);
222
m_renderer =
nullptr
;
223
}
else
if
(m_capturer) {
224
OH_AudioCapturer_Release(m_capturer);
225
m_capturer =
nullptr
;
226
}
227
}
228
229
}
// namespace QtOHAudio
230
231
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QtOHAudio
Definition
qohaudiostream.cpp:25
QtOHAudio::fromOHSampleFormat
QAudioFormat::SampleFormat fromOHSampleFormat(OH_AudioStream_SampleFormat fmt)
Definition
qohaudiostream.cpp:54
QtOHAudio::toOHSampleFormat
OH_AudioStream_SampleFormat toOHSampleFormat(QAudioFormat::SampleFormat fmt)
Definition
qohaudiostream.cpp:36
QtOHAudio::preferredCompatibleSampleFormat
QAudioFormat::SampleFormat preferredCompatibleSampleFormat(QAudioFormat::SampleFormat requested)
Definition
qohaudiostream.cpp:71
QT_MM_DEFINE_QDEBUG_ENUM
QT_MM_DEFINE_QDEBUG_ENUM(OH_AudioStream_Result)
QtOHAudio::StreamBuilder
Definition
qohaudiostream_p.h:71
QtOHAudio::StreamBuilder::setupBuilder
void setupBuilder()
Definition
qohaudiostream.cpp:104
QtOHAudio::StreamBuilder::userData
void * userData
Definition
qohaudiostream_p.h:83
QtOHAudio::StreamBuilder::~StreamBuilder
~StreamBuilder()
Definition
qohaudiostream.cpp:97
QtOHAudio::StreamBuilder::StreamBuilder
StreamBuilder(QAudioFormat format, OH_AudioStream_Type direction)
Definition
qohaudiostream.cpp:86
QtOHAudio::Stream
Definition
qohaudiostream_p.h:36
QtOHAudio::Stream::flush
void flush()
Definition
qohaudiostream.cpp:202
QtOHAudio::Stream::areStreamParametersRespected
bool areStreamParametersRespected() const
Definition
qohaudiostream.cpp:213
QtOHAudio::Stream::~Stream
~Stream()
Definition
qohaudiostream.cpp:162
QtOHAudio::Stream::start
bool start()
Definition
qohaudiostream.cpp:168
QtOHAudio::Stream::pause
void pause()
Definition
qohaudiostream.cpp:190
QtOHAudio::Stream::stop
void stop()
Definition
qohaudiostream.cpp:182
QtOHAudio::Stream::Stream
Stream(StreamBuilder &builder)
Definition
qohaudiostream.cpp:135
QtOHAudio::Stream::isOpen
bool isOpen() const
Definition
qohaudiostream.cpp:208
qtmultimedia
src
multimedia
ohos
qohaudiostream.cpp
Generated on
for Qt by
1.18.0