1 /*
2 * Copyright (c) 2023 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 <climits>
20 #include "osal_mem.h"
21 #include "v1_0/iaudio_capture.h"
22 #include "v1_0/iaudio_manager.h"
23
24 using namespace std;
25 using namespace testing::ext;
26 namespace {
27 static const uint32_t MAX_AUDIO_ADAPTER_NUM = 5;
28 const int32_t BUFFER_LENTH = 1024 * 16;
29 const int32_t DEEP_BUFFER_CAPTURE_PERIOD_SIZE = 4 * 1024;
30 const int32_t MMAP_SUGGUEST_REQ_SIZE = 1920;
31 const int32_t MOVE_LEFT_NUM = 8;
32 const int32_t TEST_SAMPLE_RATE_MASK_48000 = 48000;
33 const int32_t TEST_CHANNEL_COUNT_STERO = 2;
34 const int32_t ITERATION_FREQUENCY = 100;
35 const int32_t REPETITION_FREQUENCY = 3;
36
37 class AudioCaptureMmapBenchmarkTest : public benchmark::Fixture {
38 public:
39 struct IAudioManager *manager_ = nullptr;;
40 struct IAudioAdapter *adapter_ = nullptr;
41 struct IAudioCapture *mmapCapture_ = nullptr;
42 uint32_t captureId_ = 0;
43 char *devDescriptorName_ = nullptr;
44 struct AudioAdapterDescriptor adapterDescs_[MAX_AUDIO_ADAPTER_NUM];
45 uint32_t adapterSize_ = 0;
46 virtual void SetUp(const ::benchmark::State &state);
47 virtual void TearDown(const ::benchmark::State &state);
48 void InitCaptureDevDesc(struct AudioDeviceDescriptor &devDesc);
49 void InitCaptureAttrs(struct AudioSampleAttributes &attrs);
50 void FreeAdapterElements(struct AudioAdapterDescriptor *dataBlock, bool freeSelf);
51 void ReleaseAllAdapterDescs(struct AudioAdapterDescriptor *descs, uint32_t descsLen);
52 };
53
InitCaptureDevDesc(struct AudioDeviceDescriptor & devDesc)54 void AudioCaptureMmapBenchmarkTest::InitCaptureDevDesc(struct AudioDeviceDescriptor &devDesc)
55 {
56 ASSERT_NE(adapterDescs_, nullptr);
57 ASSERT_NE(adapterDescs_->ports, nullptr);
58
59 devDesc.pins = (enum AudioPortPin)PIN_IN_MIC;
60 devDescriptorName_ = strdup("cardname");
61 devDesc.desc = devDescriptorName_;
62
63 for (uint32_t index = 0; index < adapterDescs_->portsLen; index++) {
64 if (adapterDescs_->ports[index].dir == PORT_IN) {
65 devDesc.portId = adapterDescs_->ports[index].portId;
66 return;
67 }
68 }
69 }
70
InitCaptureAttrs(struct AudioSampleAttributes & attrs)71 void AudioCaptureMmapBenchmarkTest::InitCaptureAttrs(struct AudioSampleAttributes &attrs)
72 {
73 attrs.format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
74 attrs.channelCount = TEST_CHANNEL_COUNT_STERO;
75 attrs.sampleRate = TEST_SAMPLE_RATE_MASK_48000;
76 attrs.interleaved = 1;
77 attrs.type = AUDIO_MMAP_NOIRQ;
78 attrs.period = DEEP_BUFFER_CAPTURE_PERIOD_SIZE;
79 attrs.frameSize = AUDIO_FORMAT_TYPE_PCM_16_BIT * TEST_CHANNEL_COUNT_STERO / MOVE_LEFT_NUM;
80 attrs.isBigEndian = false;
81 attrs.isSignedData = true;
82 attrs.startThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (attrs.format * attrs.channelCount / MOVE_LEFT_NUM);
83 attrs.stopThreshold = INT_MAX;
84 attrs.silenceThreshold = BUFFER_LENTH;
85 }
86
FreeAdapterElements(struct AudioAdapterDescriptor * dataBlock,bool freeSelf)87 void AudioCaptureMmapBenchmarkTest::FreeAdapterElements(struct AudioAdapterDescriptor *dataBlock, bool freeSelf)
88 {
89 if (dataBlock == nullptr) {
90 return;
91 }
92
93 if (dataBlock->adapterName != nullptr) {
94 OsalMemFree(dataBlock->adapterName);
95 dataBlock->adapterName = nullptr;
96 }
97
98 if (dataBlock->ports != nullptr) {
99 OsalMemFree(dataBlock->ports);
100 }
101 }
102
ReleaseAllAdapterDescs(struct AudioAdapterDescriptor * descs,uint32_t descsLen)103 void AudioCaptureMmapBenchmarkTest::ReleaseAllAdapterDescs(struct AudioAdapterDescriptor *descs, uint32_t descsLen)
104 {
105 if (descs == nullptr || descsLen == 0) {
106 return;
107 }
108
109 for (uint32_t i = 0; i < descsLen; i++) {
110 FreeAdapterElements(&descs[i], false);
111 }
112 }
113
SetUp(const::benchmark::State & state)114 void AudioCaptureMmapBenchmarkTest::SetUp(const ::benchmark::State &state)
115 {
116 adapterSize_ = MAX_AUDIO_ADAPTER_NUM;
117 manager_ = IAudioManagerGet(false);
118 ASSERT_NE(manager_, nullptr);
119
120 EXPECT_EQ(HDF_SUCCESS, manager_->GetAllAdapters(manager_, adapterDescs_, &adapterSize_));
121 if (adapterSize_ > MAX_AUDIO_ADAPTER_NUM) {
122 ReleaseAllAdapterDescs(adapterDescs_, adapterSize_);
123 ASSERT_LT(adapterSize_, MAX_AUDIO_ADAPTER_NUM);
124 }
125
126 EXPECT_EQ(HDF_SUCCESS, manager_->LoadAdapter(manager_, &adapterDescs_[0], &adapter_));
127 if (adapter_ == nullptr) {
128 ReleaseAllAdapterDescs(adapterDescs_, adapterSize_);
129 EXPECT_NE(adapter_, nullptr);
130 }
131
132 struct AudioDeviceDescriptor devDesc = {};
133 struct AudioSampleAttributes attrs = {};
134 InitCaptureDevDesc(devDesc);
135 InitCaptureAttrs(attrs);
136 EXPECT_EQ(HDF_SUCCESS, adapter_->CreateCapture(adapter_, &devDesc, &attrs, &mmapCapture_, &captureId_));
137 if (mmapCapture_ == nullptr) {
138 (void)manager_->UnloadAdapter(manager_, adapterDescs_[0].adapterName);
139 ReleaseAllAdapterDescs(adapterDescs_, adapterSize_);
140 }
141 ASSERT_NE(mmapCapture_, nullptr);
142 }
143
TearDown(const::benchmark::State & state)144 void AudioCaptureMmapBenchmarkTest::TearDown(const ::benchmark::State &state)
145 {
146 ASSERT_NE(devDescriptorName_, nullptr);
147 free(devDescriptorName_);
148 devDescriptorName_ = nullptr;
149
150 ASSERT_NE(mmapCapture_, nullptr);
151 EXPECT_EQ(HDF_SUCCESS, adapter_->DestroyCapture(adapter_, captureId_));
152
153 ASSERT_NE(manager_, nullptr);
154 EXPECT_EQ(HDF_SUCCESS, manager_->UnloadAdapter(manager_, adapterDescs_[0].adapterName));
155 ReleaseAllAdapterDescs(adapterDescs_, adapterSize_);
156
157 IAudioManagerRelease(manager_, false);
158 }
159
BENCHMARK_F(AudioCaptureMmapBenchmarkTest,ReqMmapBuffer)160 BENCHMARK_F(AudioCaptureMmapBenchmarkTest, ReqMmapBuffer)(benchmark::State &state)
161 {
162 ASSERT_NE(mmapCapture_, nullptr);
163 int32_t ret;
164 struct AudioMmapBufferDescriptor desc = {0};
165 uint64_t frames = 0;
166 struct AudioTimeStamp time = {0};
167
168 for (auto _ : state) {
169 ret = mmapCapture_->ReqMmapBuffer(mmapCapture_, MMAP_SUGGUEST_REQ_SIZE, &desc);
170 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT || ret == HDF_ERR_INVALID_PARAM);
171
172 ret = mmapCapture_->Start(mmapCapture_);
173 EXPECT_EQ(ret, HDF_SUCCESS);
174
175 ret = mmapCapture_->GetMmapPosition(mmapCapture_, &frames, &time);
176 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT || ret == HDF_ERR_INVALID_PARAM);
177
178 ret = mmapCapture_->Stop(mmapCapture_);
179 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT);
180 }
181 }
182
183 BENCHMARK_REGISTER_F(AudioCaptureMmapBenchmarkTest, ReqMmapBuffer)->
184 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
185 }
186