1 /*
2 * Copyright (c) 2022-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 "daudio_handler.h"
17
18 #include <vector>
19
20 #include "audio_system_manager.h"
21 #include "avcodec_list.h"
22 #include "nlohmann/json.hpp"
23 #include "string_ex.h"
24
25 #include "histreamer_query_tool.h"
26 #include "daudio_constants.h"
27 #include "daudio_errorcode.h"
28 #include "daudio_log.h"
29 #include "daudio_util.h"
30
31 #undef DH_LOG_TAG
32 #define DH_LOG_TAG "DAudioHandler"
33
34 using json = nlohmann::json;
35
36 namespace OHOS {
37 namespace DistributedHardware {
38 IMPLEMENT_SINGLE_INSTANCE(DAudioHandler);
39
DAudioHandler()40 DAudioHandler::DAudioHandler()
41 {
42 encoderInfos_.channelMaxVal = 0;
43 encoderInfos_.channelMinVal = 0;
44 decoderInfos_.channelMaxVal = 0;
45 decoderInfos_.channelMinVal = 0;
46 spkInfos_.channelMaxVal = 0;
47 spkInfos_.channelMinVal = 0;
48 micInfos_.channelMaxVal = 0;
49 micInfos_.channelMinVal = 0;
50 DHLOGD("Distributed audio handler constructed.");
51 }
52
~DAudioHandler()53 DAudioHandler::~DAudioHandler()
54 {
55 DHLOGD("Distributed audio handler deconstructed.");
56 }
57
Initialize()58 int32_t DAudioHandler::Initialize()
59 {
60 DHLOGI("Distributed audio handler initialize.");
61 int32_t ret = QueryCodecInfo();
62 if (ret != DH_SUCCESS) {
63 DHLOGE("Failed to query the codec information.");
64 return ret;
65 }
66 ret = QueryAudioInfo();
67 GetSupportAudioInfo(audioInfos_, encoderInfos_, decoderInfos_);
68 return ret;
69 }
70
Query()71 std::vector<DHItem> DAudioHandler::Query()
72 {
73 DHLOGI("Query distributed hardware information.");
74 auto audioSrv = AudioStandard::AudioSystemManager::GetInstance();
75 std::vector<DHItem> dhItemVec;
76 if (audioSrv == nullptr) {
77 DHLOGE("Unable to get audio system manager.");
78 return dhItemVec;
79 }
80
81 auto audioDevices = audioSrv->GetDevices(AudioStandard::DeviceFlag::ALL_DEVICES_FLAG);
82 for (auto dev : audioDevices) {
83 auto dhId = audioSrv->GetPinValueFromType(dev->deviceType_, dev->deviceRole_);
84
85 json infoJson;
86 DHItem dhItem;
87 int32_t deviceType = GetDevTypeByDHId(dhId);
88 if (deviceType == AUDIO_DEVICE_TYPE_MIC) {
89 dhItem.subtype = "mic";
90 infoJson["SampleRates"] = micInfos_.sampleRates;
91 infoJson["ChannelMasks"] = micInfos_.channels;
92 infoJson["Formats"] = micInfos_.formats;
93 } else if (deviceType == AUDIO_DEVICE_TYPE_SPEAKER) {
94 dhItem.subtype = "speaker";
95 infoJson["SampleRates"] = spkInfos_.sampleRates;
96 infoJson["ChannelMasks"] = spkInfos_.channels;
97 infoJson["Formats"] = spkInfos_.formats;
98 }
99 infoJson["INTERRUPT_GROUP_ID"] = dev->interruptGroupId_;
100 infoJson["VOLUME_GROUP_ID"] = dev->volumeGroupId_;
101
102 std::string audioEncoders =
103 HiStreamerQueryTool::GetInstance().QueryHiStreamerPluginInfo(HISTREAM_PLUGIN_TYPE::AUDIO_ENCODER);
104 DHLOGI("DAudio QueryAudioEncoderAbility info: %s", audioEncoders.c_str());
105 infoJson[KEY_HISTREAMER_AUDIO_ENCODER] = audioEncoders;
106
107 std::string audioDecoders =
108 HiStreamerQueryTool::GetInstance().QueryHiStreamerPluginInfo(HISTREAM_PLUGIN_TYPE::AUDIO_DECODER);
109 DHLOGI("DAudio QueryAudioDecoderAbility info: %s", audioDecoders.c_str());
110 infoJson[KEY_HISTREAMER_AUDIO_DECODER] = audioDecoders;
111
112 dhItem.dhId = std::to_string(dhId);
113 dhItem.attrs = infoJson.dump();
114 dhItemVec.push_back(dhItem);
115 DHLOGD("Query result: dhId: %d, subtype: %s, attrs: %s.", dhId, dhItem.subtype.c_str(),
116 infoJson.dump().c_str());
117 if (dhId == DEFAULT_RENDER_ID) {
118 dhItem.dhId = std::to_string(LOW_LATENCY_RENDER_ID);
119 dhItemVec.push_back(dhItem);
120 DHLOGD("Query result: dhId: %d, attrs: %s.", LOW_LATENCY_RENDER_ID, infoJson.dump().c_str());
121 }
122 }
123 ablityForDumpVec_ = dhItemVec;
124 return dhItemVec;
125 }
126
ablityForDump()127 std::vector<DHItem> DAudioHandler::ablityForDump()
128 {
129 DHLOGD("Get audio ablity for dump.");
130 if (ablityForDumpVec_.size() > 0) {
131 return ablityForDumpVec_;
132 }
133 Initialize();
134 Query();
135 return ablityForDumpVec_;
136 }
QueryCodecInfo()137 int32_t DAudioHandler::QueryCodecInfo()
138 {
139 DHLOGD("Query codec information.");
140 auto avCodecList = Media::AVCodecListFactory::CreateAVCodecList();
141 CHECK_NULL_RETURN(avCodecList, ERR_DH_AUDIO_NULLPTR);
142
143 bool queryFlag = false;
144 for (auto codec : avCodecList->GetAudioEncoderCaps()) {
145 if (codec == nullptr || codec->GetCodecInfo() == nullptr || codec->GetCodecInfo()->GetName() != AVENC_AAC) {
146 continue;
147 }
148 encoderInfos_.sampleRates = codec->GetSupportedSampleRates();
149 encoderInfos_.formats = codec->GetSupportedFormats();
150 encoderInfos_.channelMaxVal = codec->GetSupportedChannel().maxVal;
151 encoderInfos_.channelMinVal = codec->GetSupportedChannel().minVal;
152 queryFlag = true;
153 }
154
155 for (auto codec : avCodecList->GetAudioDecoderCaps()) {
156 if (codec == nullptr || codec->GetCodecInfo() == nullptr || codec->GetCodecInfo()->GetName() != AVENC_AAC) {
157 continue;
158 }
159 decoderInfos_.sampleRates = codec->GetSupportedSampleRates();
160 decoderInfos_.formats = codec->GetSupportedFormats();
161 decoderInfos_.channelMaxVal = codec->GetSupportedChannel().maxVal;
162 decoderInfos_.channelMinVal = codec->GetSupportedChannel().minVal;
163 queryFlag = true;
164 }
165
166 if (!queryFlag) {
167 DHLOGE("Failed to query the codec information.");
168 return ERR_DH_AUDIO_FAILED;
169 }
170 return DH_SUCCESS;
171 }
172
QueryAudioInfo()173 int32_t DAudioHandler::QueryAudioInfo()
174 {
175 DHLOGD("Start to query codec information.");
176 audioInfos_.sampleRates = OHOS::AudioStandard::AudioCapturer::GetSupportedSamplingRates();
177 audioInfos_.formats = OHOS::AudioStandard::AudioCapturer::GetSupportedFormats();
178 audioInfos_.channels = OHOS::AudioStandard::AudioCapturer::GetSupportedChannels();
179 return DH_SUCCESS;
180 }
181
GetSupportAudioInfo(AudioInfo & audioInfos,CoderInfo & encoderInfos,CoderInfo & decoderInfos)182 void DAudioHandler::GetSupportAudioInfo(AudioInfo &audioInfos, CoderInfo &encoderInfos,
183 CoderInfo &decoderInfos)
184 {
185 for (auto iter = audioInfos.sampleRates.begin(); iter != audioInfos.sampleRates.end(); iter++) {
186 if (std::find(encoderInfos.sampleRates.begin(), encoderInfos.sampleRates.end(), *iter) !=
187 encoderInfos.sampleRates.end()) {
188 micInfos_.sampleRates.push_back(*iter);
189 }
190 if (std::find(decoderInfos.sampleRates.begin(), decoderInfos.sampleRates.end(), *iter) !=
191 decoderInfos.sampleRates.end()) {
192 spkInfos_.sampleRates.push_back(*iter);
193 }
194 }
195
196 for (auto iter = audioInfos.formats.begin(); iter != audioInfos.formats.end(); iter++) {
197 if (std::find(encoderInfos.formats.begin(), encoderInfos.formats.end(), *iter) != encoderInfos.formats.end()) {
198 micInfos_.formats.push_back(*iter);
199 }
200 if (std::find(decoderInfos.formats.begin(), decoderInfos.formats.end(), *iter) != decoderInfos.formats.end()) {
201 spkInfos_.formats.push_back(*iter);
202 }
203 }
204
205 for (auto iter = audioInfos.channels.begin(); iter != audioInfos.channels.end(); iter++) {
206 if (*iter <= encoderInfos.channelMaxVal && *iter >= encoderInfos.channelMinVal) {
207 micInfos_.channels.push_back(*iter);
208 }
209 if (*iter <= decoderInfos.channelMaxVal && *iter >= decoderInfos.channelMinVal) {
210 spkInfos_.channels.push_back(*iter);
211 }
212 }
213 if (micInfos_.sampleRates.empty()) {
214 micInfos_.sampleRates.push_back(SAMPLE_RATE_DEFAULT);
215 }
216 if (spkInfos_.sampleRates.empty()) {
217 spkInfos_.sampleRates.push_back(SAMPLE_RATE_DEFAULT);
218 }
219 if (micInfos_.channels.empty()) {
220 micInfos_.channels.push_back(CHANNEL_COUNT_DEFAULT);
221 }
222 if (spkInfos_.channels.empty()) {
223 spkInfos_.channels.push_back(CHANNEL_COUNT_DEFAULT);
224 }
225 if (micInfos_.formats.empty()) {
226 micInfos_.formats.push_back(SAMPLE_FORMAT_DEFAULT);
227 }
228 if (spkInfos_.formats.empty()) {
229 spkInfos_.formats.push_back(SAMPLE_FORMAT_DEFAULT);
230 }
231 }
232
QueryExtraInfo()233 std::map<std::string, std::string> DAudioHandler::QueryExtraInfo()
234 {
235 DHLOGD("Query extra information");
236 std::map<std::string, std::string> extraInfo;
237 return extraInfo;
238 }
239
IsSupportPlugin()240 bool DAudioHandler::IsSupportPlugin()
241 {
242 DHLOGD("Is support plug in");
243 return false;
244 }
245
RegisterPluginListener(std::shared_ptr<PluginListener> listener)246 void DAudioHandler::RegisterPluginListener(std::shared_ptr<PluginListener> listener)
247 {
248 DHLOGI("Register plugin listener");
249 CHECK_NULL_VOID(listener);
250 listener_ = listener;
251 }
252
UnRegisterPluginListener()253 void DAudioHandler::UnRegisterPluginListener()
254 {
255 DHLOGI("UnRegister plugin listener");
256 listener_ = nullptr;
257 }
258
GetHardwareHandler()259 IHardwareHandler* GetHardwareHandler()
260 {
261 return &DAudioHandler::GetInstance();
262 }
263 } // namespace DistributedHardware
264 } // namespace OHOS
265