1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include <benchmark/benchmark.h> 17094332d3Sopenharmony_ci#include <climits> 18094332d3Sopenharmony_ci#include <gtest/gtest.h> 19094332d3Sopenharmony_ci#include "hdf_base.h" 20094332d3Sopenharmony_ci#include "osal_mem.h" 21094332d3Sopenharmony_ci#include "v4_0/audio_types.h" 22094332d3Sopenharmony_ci#include "v4_0/iaudio_manager.h" 23094332d3Sopenharmony_ci#include "v4_0/iaudio_render.h" 24094332d3Sopenharmony_ci 25094332d3Sopenharmony_ciusing namespace std; 26094332d3Sopenharmony_ciusing namespace testing::ext; 27094332d3Sopenharmony_ci 28094332d3Sopenharmony_cinamespace { 29094332d3Sopenharmony_ciconst int BUFFER_LENTH = 1024 * 16; 30094332d3Sopenharmony_ciconst int DEEP_BUFFER_RENDER_PERIOD_SIZE = 4 * 1024; 31094332d3Sopenharmony_ciconst int MOVE_LEFT_NUM = 8; 32094332d3Sopenharmony_ciconst int32_t AUDIO_RENDER_CHANNELCOUNT = 2; 33094332d3Sopenharmony_ciconst int32_t AUDIO_SAMPLE_RATE_48K = 48000; 34094332d3Sopenharmony_ciconst int32_t MAX_AUDIO_ADAPTER_DESC = 5; 35094332d3Sopenharmony_ciconst int32_t MMAP_SUGGEST_BUFFER_SIZE = 1920; 36094332d3Sopenharmony_ciconst int32_t ITERATION_FREQUENCY = 100; 37094332d3Sopenharmony_ciconst int32_t REPETITION_FREQUENCY = 3; 38094332d3Sopenharmony_ci 39094332d3Sopenharmony_ciclass AudioRenderMmapBenchmarkTest : public benchmark::Fixture { 40094332d3Sopenharmony_cipublic: 41094332d3Sopenharmony_ci struct IAudioManager *manager_ = nullptr; 42094332d3Sopenharmony_ci struct AudioAdapterDescriptor descs_[MAX_AUDIO_ADAPTER_DESC]; 43094332d3Sopenharmony_ci struct AudioAdapterDescriptor *desc_; 44094332d3Sopenharmony_ci struct IAudioAdapter *adapter_ = nullptr; 45094332d3Sopenharmony_ci struct IAudioRender *render_ = nullptr; 46094332d3Sopenharmony_ci struct AudioDeviceDescriptor devDescRender_ = {}; 47094332d3Sopenharmony_ci struct AudioSampleAttributes attrsRender_ = {}; 48094332d3Sopenharmony_ci uint32_t renderId_ = 0; 49094332d3Sopenharmony_ci char *devDescriptorName_ = nullptr; 50094332d3Sopenharmony_ci uint32_t size_ = MAX_AUDIO_ADAPTER_DESC; 51094332d3Sopenharmony_ci virtual void SetUp(const ::benchmark::State &state); 52094332d3Sopenharmony_ci virtual void TearDown(const ::benchmark::State &state); 53094332d3Sopenharmony_ci void InitRenderAttrs(struct AudioSampleAttributes &attrs); 54094332d3Sopenharmony_ci void InitRenderDevDesc(struct AudioDeviceDescriptor &devDesc); 55094332d3Sopenharmony_ci void FreeAdapterElements(struct AudioAdapterDescriptor *dataBlock, bool freeSelf); 56094332d3Sopenharmony_ci void ReleaseAllAdapterDescs(struct AudioAdapterDescriptor *descs, uint32_t descsLen); 57094332d3Sopenharmony_ci}; 58094332d3Sopenharmony_ci 59094332d3Sopenharmony_civoid AudioRenderMmapBenchmarkTest::InitRenderAttrs(struct AudioSampleAttributes &attrs) 60094332d3Sopenharmony_ci{ 61094332d3Sopenharmony_ci attrs.channelCount = AUDIO_RENDER_CHANNELCOUNT; 62094332d3Sopenharmony_ci attrs.sampleRate = AUDIO_SAMPLE_RATE_48K; 63094332d3Sopenharmony_ci attrs.interleaved = 0; 64094332d3Sopenharmony_ci attrs.type = AUDIO_MMAP_NOIRQ; 65094332d3Sopenharmony_ci attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE; 66094332d3Sopenharmony_ci attrs.frameSize = AUDIO_FORMAT_TYPE_PCM_16_BIT * AUDIO_RENDER_CHANNELCOUNT / MOVE_LEFT_NUM; 67094332d3Sopenharmony_ci attrs.isBigEndian = false; 68094332d3Sopenharmony_ci attrs.isSignedData = true; 69094332d3Sopenharmony_ci attrs.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (attrs.format * attrs.channelCount / MOVE_LEFT_NUM); 70094332d3Sopenharmony_ci attrs.stopThreshold = INT_MAX; 71094332d3Sopenharmony_ci attrs.silenceThreshold = BUFFER_LENTH; 72094332d3Sopenharmony_ci} 73094332d3Sopenharmony_ci 74094332d3Sopenharmony_civoid AudioRenderMmapBenchmarkTest::InitRenderDevDesc(struct AudioDeviceDescriptor &devDesc) 75094332d3Sopenharmony_ci{ 76094332d3Sopenharmony_ci devDesc.pins = PIN_OUT_SPEAKER; 77094332d3Sopenharmony_ci devDescriptorName_ = strdup("cardname"); 78094332d3Sopenharmony_ci devDesc.desc = devDescriptorName_; 79094332d3Sopenharmony_ci 80094332d3Sopenharmony_ci ASSERT_NE(desc_, nullptr); 81094332d3Sopenharmony_ci ASSERT_NE(desc_->ports, nullptr); 82094332d3Sopenharmony_ci for (uint32_t index = 0; index < desc_->portsLen; index++) { 83094332d3Sopenharmony_ci if (desc_->ports[index].dir == PORT_OUT) { 84094332d3Sopenharmony_ci devDesc.portId = desc_->ports[index].portId; 85094332d3Sopenharmony_ci return; 86094332d3Sopenharmony_ci } 87094332d3Sopenharmony_ci } 88094332d3Sopenharmony_ci free(devDesc.desc); 89094332d3Sopenharmony_ci devDesc.desc = nullptr; 90094332d3Sopenharmony_ci} 91094332d3Sopenharmony_ci 92094332d3Sopenharmony_civoid AudioRenderMmapBenchmarkTest::FreeAdapterElements(struct AudioAdapterDescriptor *dataBlock, bool freeSelf) 93094332d3Sopenharmony_ci{ 94094332d3Sopenharmony_ci if (dataBlock == nullptr) { 95094332d3Sopenharmony_ci return; 96094332d3Sopenharmony_ci } 97094332d3Sopenharmony_ci 98094332d3Sopenharmony_ci OsalMemFree(dataBlock->adapterName); 99094332d3Sopenharmony_ci 100094332d3Sopenharmony_ci OsalMemFree(dataBlock->ports); 101094332d3Sopenharmony_ci 102094332d3Sopenharmony_ci if (freeSelf) { 103094332d3Sopenharmony_ci OsalMemFree(dataBlock); 104094332d3Sopenharmony_ci } 105094332d3Sopenharmony_ci} 106094332d3Sopenharmony_ci 107094332d3Sopenharmony_civoid AudioRenderMmapBenchmarkTest::ReleaseAllAdapterDescs(struct AudioAdapterDescriptor *descs, uint32_t descsLen) 108094332d3Sopenharmony_ci{ 109094332d3Sopenharmony_ci if (descs == nullptr || descsLen == 0) { 110094332d3Sopenharmony_ci return; 111094332d3Sopenharmony_ci } 112094332d3Sopenharmony_ci 113094332d3Sopenharmony_ci for (uint32_t i = 0; i < descsLen; i++) { 114094332d3Sopenharmony_ci FreeAdapterElements(&descs[i], false); 115094332d3Sopenharmony_ci } 116094332d3Sopenharmony_ci} 117094332d3Sopenharmony_ci 118094332d3Sopenharmony_civoid AudioRenderMmapBenchmarkTest::SetUp(const ::benchmark::State &state) 119094332d3Sopenharmony_ci{ 120094332d3Sopenharmony_ci manager_ = IAudioManagerGet(false); 121094332d3Sopenharmony_ci ASSERT_NE(manager_, nullptr); 122094332d3Sopenharmony_ci 123094332d3Sopenharmony_ci ASSERT_EQ(HDF_SUCCESS, manager_->GetAllAdapters(manager_, descs_, &size_)); 124094332d3Sopenharmony_ci ASSERT_NE(descs_, nullptr); 125094332d3Sopenharmony_ci EXPECT_GE(MAX_AUDIO_ADAPTER_DESC, size_); 126094332d3Sopenharmony_ci desc_ = &descs_[0]; 127094332d3Sopenharmony_ci ASSERT_EQ(HDF_SUCCESS, manager_->LoadAdapter(manager_, desc_, &adapter_)); 128094332d3Sopenharmony_ci ASSERT_NE(adapter_, nullptr); 129094332d3Sopenharmony_ci InitRenderDevDesc(devDescRender_); 130094332d3Sopenharmony_ci InitRenderAttrs(attrsRender_); 131094332d3Sopenharmony_ci 132094332d3Sopenharmony_ci attrsRender_.format = AUDIO_FORMAT_TYPE_PCM_16_BIT; 133094332d3Sopenharmony_ci int32_t ret = adapter_->CreateRender(adapter_, &devDescRender_, &attrsRender_, &render_, &renderId_); 134094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 135094332d3Sopenharmony_ci attrsRender_.format = AUDIO_FORMAT_TYPE_PCM_32_BIT; 136094332d3Sopenharmony_ci ASSERT_EQ(HDF_SUCCESS, adapter_->CreateRender(adapter_, &devDescRender_, &attrsRender_, &render_, &renderId_)); 137094332d3Sopenharmony_ci } 138094332d3Sopenharmony_ci ASSERT_NE(render_, nullptr); 139094332d3Sopenharmony_ci} 140094332d3Sopenharmony_ci 141094332d3Sopenharmony_civoid AudioRenderMmapBenchmarkTest::TearDown(const ::benchmark::State &state) 142094332d3Sopenharmony_ci{ 143094332d3Sopenharmony_ci ASSERT_NE(devDescriptorName_, nullptr); 144094332d3Sopenharmony_ci free(devDescriptorName_); 145094332d3Sopenharmony_ci 146094332d3Sopenharmony_ci if (adapter_ != nullptr) { 147094332d3Sopenharmony_ci adapter_->DestroyRender(adapter_, renderId_); 148094332d3Sopenharmony_ci render_ = nullptr; 149094332d3Sopenharmony_ci } 150094332d3Sopenharmony_ci if (manager_ != nullptr) { 151094332d3Sopenharmony_ci manager_->UnloadAdapter(manager_, desc_->adapterName); 152094332d3Sopenharmony_ci adapter_ = nullptr; 153094332d3Sopenharmony_ci ReleaseAllAdapterDescs(descs_, size_); 154094332d3Sopenharmony_ci 155094332d3Sopenharmony_ci IAudioManagerRelease(manager_, false); 156094332d3Sopenharmony_ci } 157094332d3Sopenharmony_ci} 158094332d3Sopenharmony_ci 159094332d3Sopenharmony_ciBENCHMARK_F(AudioRenderMmapBenchmarkTest, ReqMmapBuffer)(benchmark::State &state) 160094332d3Sopenharmony_ci{ 161094332d3Sopenharmony_ci ASSERT_NE(render_, nullptr); 162094332d3Sopenharmony_ci int32_t ret; 163094332d3Sopenharmony_ci uint64_t frames = 0; 164094332d3Sopenharmony_ci struct AudioTimeStamp time; 165094332d3Sopenharmony_ci time.tvNSec = 0; 166094332d3Sopenharmony_ci time.tvSec = 0; 167094332d3Sopenharmony_ci int32_t reqSize = MMAP_SUGGEST_BUFFER_SIZE; 168094332d3Sopenharmony_ci struct AudioMmapBufferDescriptor desc; 169094332d3Sopenharmony_ci 170094332d3Sopenharmony_ci for (auto _ : state) { 171094332d3Sopenharmony_ci ret = render_->ReqMmapBuffer(render_, reqSize, &desc); 172094332d3Sopenharmony_ci ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_ERR_INVALID_PARAM); 173094332d3Sopenharmony_ci 174094332d3Sopenharmony_ci ret = render_->Start(render_); 175094332d3Sopenharmony_ci ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_FAILURE); 176094332d3Sopenharmony_ci 177094332d3Sopenharmony_ci ret = render_->GetMmapPosition(render_, &frames, &time); 178094332d3Sopenharmony_ci ASSERT_TRUE(ret == HDF_SUCCESS); 179094332d3Sopenharmony_ci 180094332d3Sopenharmony_ci ret = render_->Stop(render_); 181094332d3Sopenharmony_ci ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_FAILURE); 182094332d3Sopenharmony_ci } 183094332d3Sopenharmony_ci} 184094332d3Sopenharmony_ci 185094332d3Sopenharmony_ciBENCHMARK_REGISTER_F(AudioRenderMmapBenchmarkTest, ReqMmapBuffer)-> 186094332d3Sopenharmony_ci Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly(); 187094332d3Sopenharmony_ci} 188