1 /*
2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <benchmark/benchmark.h>
17 #include <climits>
18 #include <gtest/gtest.h>
19 #include "hdf_base.h"
20 #include "osal_mem.h"
21 #include "v5_0/iaudio_manager.h"
22
23 using namespace testing::ext;
24 using namespace std;
25
26 #define AUDIO_CHANNELCOUNT 2
27 #define AUDIO_SAMPLE_RATE_48K 48000
28 #define DEEP_BUFFER_RENDER_PERIOD_SIZE 4096
29 #define INT_32_MAX 0x7fffffff
30 #define PCM_16_BIT 16
31 #define PCM_8_BIT 8
32
33 namespace {
34 static const uint32_t g_audioAdapterNumMax = 5;
35 const int32_t AUDIO_ADAPTER_BUF_TEST = 1024;
36 const int32_t ITERATION_FREQUENCY = 100;
37 const int32_t REPETITION_FREQUENCY = 3;
38
39 class AudioAdapterBenchmarkTest : public benchmark::Fixture {
40 public:
41 struct IAudioManager *manager_ = nullptr;
42 struct IAudioAdapter *adapter_ = nullptr;
43 struct AudioAdapterDescriptor *adapterDescs_ = nullptr;
44 uint32_t renderId_ = 0;
45 uint32_t captureId_ = 0;
46 void SetUp(const ::benchmark::State &state);
47 void TearDown(const ::benchmark::State &state);
48 void InitAttrs(struct AudioSampleAttributes &attrs);
49 void InitDevDesc(struct AudioDeviceDescriptor &devDesc);
50 void AudioAdapterDescriptorFree(struct AudioAdapterDescriptor *dataBlock, bool freeSelf);
51 void ReleaseAdapterDescs(struct AudioAdapterDescriptor *descs, uint32_t descsLen);
52 };
53
AudioAdapterDescriptorFree(struct AudioAdapterDescriptor * dataBlock,bool freeSelf)54 void AudioAdapterBenchmarkTest::AudioAdapterDescriptorFree(struct AudioAdapterDescriptor *dataBlock, bool freeSelf)
55 {
56 if (dataBlock == nullptr) {
57 return;
58 }
59
60 if (dataBlock->adapterName != nullptr) {
61 OsalMemFree(dataBlock->adapterName);
62 dataBlock->adapterName = nullptr;
63 }
64
65 if (dataBlock->ports != nullptr) {
66 OsalMemFree(dataBlock->ports);
67 }
68
69 if (freeSelf) {
70 OsalMemFree(dataBlock);
71 }
72 }
73
ReleaseAdapterDescs(struct AudioAdapterDescriptor * descs,uint32_t descsLen)74 void AudioAdapterBenchmarkTest::ReleaseAdapterDescs(struct AudioAdapterDescriptor *descs, uint32_t descsLen)
75 {
76 if ((descs == nullptr) || (descsLen == 0)) {
77 return;
78 }
79
80 for (uint32_t i = 0; i < descsLen; i++) {
81 AudioAdapterDescriptorFree(&descs[i], false);
82 }
83 }
84
InitAttrs(struct AudioSampleAttributes & attrs)85 void AudioAdapterBenchmarkTest::InitAttrs(struct AudioSampleAttributes &attrs)
86 {
87 attrs.format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
88 attrs.channelCount = AUDIO_CHANNELCOUNT;
89 attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
90 attrs.interleaved = 1;
91 attrs.type = AUDIO_IN_MEDIA;
92 attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
93 attrs.frameSize = PCM_16_BIT * attrs.channelCount / PCM_8_BIT;
94 attrs.isBigEndian = false;
95 attrs.isSignedData = true;
96 attrs.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (attrs.frameSize);
97 attrs.stopThreshold = INT_32_MAX;
98 }
99
InitDevDesc(struct AudioDeviceDescriptor & devDesc)100 void AudioAdapterBenchmarkTest::InitDevDesc(struct AudioDeviceDescriptor &devDesc)
101 {
102 ASSERT_NE(adapterDescs_, nullptr);
103 ASSERT_NE(adapterDescs_->ports, nullptr);
104 for (uint32_t index = 0; index < adapterDescs_->portsLen; index++) {
105 if (adapterDescs_->ports[index].dir == PORT_OUT) {
106 devDesc.portId = adapterDescs_->ports[index].portId;
107 return;
108 }
109 }
110 }
111
SetUp(const::benchmark::State & state)112 void AudioAdapterBenchmarkTest::SetUp(const ::benchmark::State &state)
113 {
114 uint32_t size = g_audioAdapterNumMax;
115 manager_ = IAudioManagerGet(false);
116 ASSERT_NE(manager_, nullptr);
117
118 adapterDescs_ = (struct AudioAdapterDescriptor *)OsalMemCalloc(
119 sizeof(struct AudioAdapterDescriptor) * (g_audioAdapterNumMax));
120 ASSERT_NE(adapterDescs_, nullptr);
121
122 ASSERT_EQ(HDF_SUCCESS, manager_->GetAllAdapters(manager_, adapterDescs_, &size));
123 if (size > g_audioAdapterNumMax) {
124 ReleaseAdapterDescs(adapterDescs_, g_audioAdapterNumMax);
125 ASSERT_LT(size, g_audioAdapterNumMax);
126 }
127
128 if (manager_->LoadAdapter(manager_, &adapterDescs_[0], &adapter_) != HDF_SUCCESS) {
129 ReleaseAdapterDescs(adapterDescs_, g_audioAdapterNumMax);
130 ASSERT_TRUE(false);
131 }
132
133 if (adapter_ == nullptr) {
134 ReleaseAdapterDescs(adapterDescs_, g_audioAdapterNumMax);
135 ASSERT_TRUE(false);
136 }
137 }
138
TearDown(const::benchmark::State & state)139 void AudioAdapterBenchmarkTest::TearDown(const ::benchmark::State &state)
140 {
141 ASSERT_NE(manager_, nullptr);
142 ASSERT_NE(adapter_, nullptr);
143
144 manager_->UnloadAdapter(manager_, adapterDescs_[0].adapterName);
145 ReleaseAdapterDescs(adapterDescs_, g_audioAdapterNumMax);
146 adapter_ = nullptr;
147 IAudioManagerRelease(manager_, false);
148 manager_ = nullptr;
149 }
150
BENCHMARK_F(AudioAdapterBenchmarkTest,InitAllPorts)151 BENCHMARK_F(AudioAdapterBenchmarkTest, InitAllPorts)(benchmark::State &state)
152 {
153 ASSERT_NE(adapter_, nullptr);
154 int32_t ret;
155 for (auto _ : state) {
156 ret = adapter_->InitAllPorts(adapter_);
157 EXPECT_EQ(ret, HDF_SUCCESS);
158 }
159 }
160
161 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, InitAllPorts)->
162 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
163
BENCHMARK_F(AudioAdapterBenchmarkTest,CreateRenderAndDestroyRender)164 BENCHMARK_F(AudioAdapterBenchmarkTest, CreateRenderAndDestroyRender)(benchmark::State &state)
165 {
166 ASSERT_NE(adapter_, nullptr);
167 int32_t ret;
168 struct IAudioRender *render = nullptr;
169 struct AudioDeviceDescriptor devicedesc = {};
170 struct AudioSampleAttributes attrs = {};
171 InitDevDesc(devicedesc);
172 devicedesc.desc = const_cast<char*>("primary");
173 devicedesc.pins = PIN_OUT_SPEAKER;
174 InitAttrs(attrs);
175 attrs.silenceThreshold = 0;
176 attrs.streamId = 0;
177
178 for (auto _ : state) {
179 ret = adapter_->CreateRender(adapter_, &devicedesc, &attrs, &render, &renderId_);
180 if (ret != HDF_SUCCESS) {
181 attrs.format = AUDIO_FORMAT_TYPE_PCM_32_BIT;
182 ASSERT_EQ(HDF_SUCCESS, adapter_->CreateRender(adapter_, &devicedesc, &attrs, &render, &renderId_));
183 }
184 ret = adapter_->DestroyRender(adapter_, renderId_);
185 EXPECT_EQ(HDF_SUCCESS, ret);
186 }
187 }
188
189 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, CreateRenderAndDestroyRender)->
190 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
191
BENCHMARK_F(AudioAdapterBenchmarkTest,CreateCaptureAndDestroyCapture)192 BENCHMARK_F(AudioAdapterBenchmarkTest, CreateCaptureAndDestroyCapture)(benchmark::State &state)
193 {
194 ASSERT_NE(adapter_, nullptr);
195 int32_t ret;
196 struct IAudioCapture *capture = nullptr;
197 struct AudioDeviceDescriptor devicedesc = {};
198 struct AudioSampleAttributes attrs = {};
199 InitDevDesc(devicedesc);
200 devicedesc.desc = const_cast<char*>("primary");
201 devicedesc.pins = PIN_IN_MIC;
202 InitAttrs(attrs);
203 attrs.silenceThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE;
204
205 for (auto _ : state) {
206 ret = adapter_->CreateCapture(adapter_, &devicedesc, &attrs, &capture, &captureId_);
207 if (ret != HDF_SUCCESS) {
208 attrs.format = AUDIO_FORMAT_TYPE_PCM_32_BIT;
209 ASSERT_EQ(HDF_SUCCESS, adapter_->CreateCapture(adapter_, &devicedesc, &attrs, &capture, &captureId_));
210 }
211 ret = adapter_->DestroyCapture(adapter_, captureId_);
212 EXPECT_EQ(HDF_SUCCESS, ret);
213 }
214 }
215
216 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, CreateCaptureAndDestroyCapture)->
217 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
218
BENCHMARK_F(AudioAdapterBenchmarkTest,GetPortCapability)219 BENCHMARK_F(AudioAdapterBenchmarkTest, GetPortCapability)(benchmark::State &state)
220 {
221 ASSERT_NE(adapter_, nullptr);
222 int32_t ret;
223 struct AudioPort port = {};
224 struct AudioPortCapability capability = {};
225 port.dir = PORT_OUT;
226 port.portId = 0;
227 port.portName = const_cast<char*>("primary");
228
229 for (auto _ : state) {
230 ret = adapter_->GetPortCapability(adapter_, &port, &capability);
231 #ifdef DISPLAY_COMMUNITY
232 ASSERT_TRUE(ret == HDF_SUCCESS);
233 #else
234 ASSERT_TRUE(ret == HDF_ERR_NOT_SUPPORT);
235 #endif
236 }
237 }
238
239 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetPortCapability)->
240 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
241
BENCHMARK_F(AudioAdapterBenchmarkTest,SetPassthroughMode)242 BENCHMARK_F(AudioAdapterBenchmarkTest, SetPassthroughMode)(benchmark::State &state)
243 {
244 ASSERT_NE(adapter_, nullptr);
245 int32_t ret;
246 struct AudioPort port = {};
247 port.dir = PORT_OUT;
248 port.portId = 0;
249 port.portName = const_cast<char*>("primary");
250 enum AudioPortPassthroughMode mode = PORT_PASSTHROUGH_LPCM;
251
252 for (auto _ : state) {
253 ret = adapter_->SetPassthroughMode(adapter_, &port, mode);
254 ASSERT_TRUE(ret == HDF_FAILURE);
255 }
256 }
257
258 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, SetPassthroughMode)->
259 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
260
BENCHMARK_F(AudioAdapterBenchmarkTest,GetPassthroughMode)261 BENCHMARK_F(AudioAdapterBenchmarkTest, GetPassthroughMode)(benchmark::State &state)
262 {
263 ASSERT_NE(adapter_, nullptr);
264 int32_t ret;
265 struct AudioPort port = {};
266 port.dir = PORT_OUT;
267 port.portId = 0;
268 port.portName = const_cast<char*>("primary");
269 enum AudioPortPassthroughMode mode;
270
271 for (auto _ : state) {
272 ret = adapter_->GetPassthroughMode(adapter_, &port, &mode);
273 ASSERT_TRUE(ret == HDF_FAILURE);
274 }
275 }
276
277 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetPassthroughMode)->
278 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
279
BENCHMARK_F(AudioAdapterBenchmarkTest,GetDeviceStatus)280 BENCHMARK_F(AudioAdapterBenchmarkTest, GetDeviceStatus)(benchmark::State &state)
281 {
282 ASSERT_NE(adapter_, nullptr);
283 int32_t ret;
284 struct AudioDeviceStatus status = {};
285
286 for (auto _ : state) {
287 ret = adapter_->GetDeviceStatus(adapter_, &status);
288 EXPECT_EQ(HDF_SUCCESS, ret);
289 }
290 }
291
292 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetDeviceStatus)->
293 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
294
BENCHMARK_F(AudioAdapterBenchmarkTest,SetMicMute)295 BENCHMARK_F(AudioAdapterBenchmarkTest, SetMicMute)(benchmark::State &state)
296 {
297 ASSERT_NE(adapter_, nullptr);
298 int32_t ret;
299 bool mute = false;
300
301 for (auto _ : state) {
302 ret = adapter_->SetMicMute(adapter_, mute);
303 #ifdef DISPLAY_COMMUNITY
304 ASSERT_TRUE(ret == HDF_ERR_NOT_SUPPORT);
305 #else
306 ASSERT_TRUE(ret == HDF_SUCCESS);
307 #endif
308 }
309 }
310
311 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, SetMicMute)->
312 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
313
BENCHMARK_F(AudioAdapterBenchmarkTest,GetMicMute)314 BENCHMARK_F(AudioAdapterBenchmarkTest, GetMicMute)(benchmark::State &state)
315 {
316 ASSERT_NE(adapter_, nullptr);
317 int32_t ret;
318 bool mute = false;
319
320 for (auto _ : state) {
321 ret = adapter_->GetMicMute(adapter_, &mute);
322 #ifdef DISPLAY_COMMUNITY
323 ASSERT_TRUE(ret == HDF_ERR_NOT_SUPPORT);
324 #else
325 ASSERT_TRUE(ret == HDF_SUCCESS);
326 #endif
327 }
328 }
329
330 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetMicMute)->
331 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
332
BENCHMARK_F(AudioAdapterBenchmarkTest,SetVoiceVolume)333 BENCHMARK_F(AudioAdapterBenchmarkTest, SetVoiceVolume)(benchmark::State &state)
334 {
335 ASSERT_NE(adapter_, nullptr);
336 int32_t ret;
337 float volume = 0;
338
339 for (auto _ : state) {
340 ret = adapter_->SetVoiceVolume(adapter_, volume);
341 #ifdef DISPLAY_COMMUNITY
342 ASSERT_TRUE(ret == HDF_ERR_NOT_SUPPORT);
343 #else
344 ASSERT_TRUE(ret == HDF_SUCCESS);
345 #endif
346 }
347 }
348
349 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, SetVoiceVolume)->
350 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
351
BENCHMARK_F(AudioAdapterBenchmarkTest,SetExtraParams)352 BENCHMARK_F(AudioAdapterBenchmarkTest, SetExtraParams)(benchmark::State &state)
353 {
354 ASSERT_NE(adapter_, nullptr);
355 int32_t ret;
356 enum AudioExtParamKey key = AUDIO_EXT_PARAM_KEY_LOWPOWER;
357 char condition[AUDIO_ADAPTER_BUF_TEST];
358 const char *value = "sup_sampling_rates=4800;sup_channels=1;sup_formats=2;";
359
360 for (auto _ : state) {
361 ret = adapter_->SetExtraParams(adapter_, key, condition, value);
362 #ifdef DISPLAY_COMMUNITY
363 ASSERT_TRUE(ret == HDF_ERR_NOT_SUPPORT);
364 #else
365 ASSERT_TRUE(ret == HDF_SUCCESS);
366 #endif
367 }
368 }
369
370 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, SetExtraParams)->
371 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
372
BENCHMARK_F(AudioAdapterBenchmarkTest,GetExtraParams)373 BENCHMARK_F(AudioAdapterBenchmarkTest, GetExtraParams)(benchmark::State &state)
374 {
375 ASSERT_NE(adapter_, nullptr);
376 int32_t ret;
377 enum AudioExtParamKey key = AUDIO_EXT_PARAM_KEY_NONE;
378 char condition[AUDIO_ADAPTER_BUF_TEST];
379 char value[AUDIO_ADAPTER_BUF_TEST];
380 uint32_t valueLen = AUDIO_ADAPTER_BUF_TEST;
381 for (auto _ : state) {
382 ret = adapter_->GetExtraParams(adapter_, key, condition, value, valueLen);
383 #ifdef DISPLAY_COMMUNITY
384 ASSERT_TRUE(ret == HDF_ERR_NOT_SUPPORT);
385 #else
386 ASSERT_TRUE(ret == HDF_FAILURE);
387 #endif
388 }
389 }
390
391 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetExtraParams)->
392 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
393
394
BENCHMARK_F(AudioAdapterBenchmarkTest,UpdateAudioRoute)395 BENCHMARK_F(AudioAdapterBenchmarkTest, UpdateAudioRoute)(benchmark::State &state)
396 {
397 ASSERT_NE(adapter_, nullptr);
398 int32_t ret;
399 struct AudioRoute route = {};
400 int32_t routeHandle = 0;
401
402 for (auto _ : state) {
403 ret = adapter_->UpdateAudioRoute(adapter_, &route, &routeHandle);
404 EXPECT_NE(HDF_SUCCESS, ret);
405 }
406 }
407
408 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, UpdateAudioRoute)->
409 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
410
BENCHMARK_F(AudioAdapterBenchmarkTest,ReleaseAudioRoute)411 BENCHMARK_F(AudioAdapterBenchmarkTest, ReleaseAudioRoute)(benchmark::State &state)
412 {
413 ASSERT_NE(adapter_, nullptr);
414 int32_t ret;
415 int32_t routeHandle = 0;
416
417 for (auto _ : state) {
418 ret = adapter_->ReleaseAudioRoute(adapter_, routeHandle);
419 EXPECT_NE(HDF_SUCCESS, ret);
420 }
421 }
422
423 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, ReleaseAudioRoute)->
424 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
425
BENCHMARK_F(AudioAdapterBenchmarkTest,RegExtraParamObserver)426 BENCHMARK_F(AudioAdapterBenchmarkTest, RegExtraParamObserver)(benchmark::State &state)
427 {
428 ASSERT_NE(adapter_, nullptr);
429 int32_t ret;
430 int8_t cookie = 0;
431 struct IAudioCallback *audioCallback = nullptr;
432
433 for (auto _ : state) {
434 ret = adapter_->RegExtraParamObserver(adapter_, audioCallback, cookie);
435 #ifdef DISPLAY_COMMUNITY
436 EXPECT_NE(ret, HDF_SUCCESS);
437 #else
438 ASSERT_TRUE(ret == HDF_ERR_INVALID_PARAM);
439 #endif
440 }
441 }
442
443 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, RegExtraParamObserver)->
444 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
445 }
446