1 /*
2 * Copyright 2022 Shenzhen Kaihong DID 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 #include "codec_component_config.h"
16 #include <cinttypes>
17 #include <osal_mem.h>
18 #include "codec_log_wrapper.h"
19
20 namespace {
21 constexpr int32_t MASK_NUM_LIMIT = 32;
22 constexpr char NODE_VIDEO_HARDWARE_ENCODERS[] = "VideoHwEncoders";
23 constexpr char NODE_VIDEO_HARDWARE_DECODERS[] = "VideoHwDecoders";
24 constexpr char NODE_VIDEO_SOFTWARE_ENCODERS[] = "VideoSwEncoders";
25 constexpr char NODE_VIDEO_SOFTWARE_DECODERS[] = "VideoSwDecoders";
26 constexpr char NODE_AUDIO_HARDWARE_ENCODERS[] = "AudioHwEncoders";
27 constexpr char NODE_AUDIO_HARDWARE_DECODERS[] = "AudioHwDecoders";
28 constexpr char NODE_AUDIO_SOFTWARE_ENCODERS[] = "AudioSwEncoders";
29 constexpr char NODE_AUDIO_SOFTWARE_DECODERS[] = "AudioSwDecoders";
30
31 constexpr char CODEC_CONFIG_KEY_ROLE[] = "role";
32 constexpr char CODEC_CONFIG_KEY_TYPE[] = "type";
33 constexpr char CODEC_CONFIG_KEY_NAME[] = "name";
34 constexpr char CODEC_CONFIG_KEY_SUPPORT_PROFILES[] = "supportProfiles";
35 constexpr char CODEC_CONFIG_KEY_MAX_INST[] = "maxInst";
36 constexpr char CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC[] = "isSoftwareCodec";
37 constexpr char CODEC_CONFIG_KEY_PROCESS_MODE_MASK[] = "processModeMask";
38 constexpr char CODEC_CONFIG_KEY_CAPS_MASK[] = "capsMask";
39 constexpr char CODEC_CONFIG_KEY_MIN_BITRATE[] = "minBitRate";
40 constexpr char CODEC_CONFIG_KEY_MAX_BITRATE[] = "maxBitRate";
41
42 constexpr char CODEC_CONFIG_KEY_MIN_WIDTH[] = "minWidth";
43 constexpr char CODEC_CONFIG_KEY_MIN_HEIGHT[] = "minHeight";
44 constexpr char CODEC_CONFIG_KEY_MAX_WIDTH[] = "maxWidth";
45 constexpr char CODEC_CONFIG_KEY_MAX_HEIGHT[] = "maxHeight";
46 constexpr char CODEC_CONFIG_KEY_WIDTH_ALIGNMENT[] = "widthAlignment";
47 constexpr char CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT[] = "heightAlignment";
48 constexpr char CODEC_CONFIG_KEY_MIN_BLOCK_COUNT[] = "minBlockCount";
49 constexpr char CODEC_CONFIG_KEY_MAX_BLOCK_COUNT[] = "maxBlockCount";
50 constexpr char CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND[] = "minBlocksPerSecond";
51 constexpr char CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND[] = "maxBlocksPerSecond";
52 constexpr char CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS[] = "supportPixelFmts";
53 constexpr char CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH[] = "blockSizeWidth";
54 constexpr char CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT[] = "blockSizeHeight";
55 constexpr char CODEC_CONFIG_KEY_MIN_FRAME_RATE[] = "minFrameRate";
56 constexpr char CODEC_CONFIG_KEY_MAX_FRAME_RATE[] = "maxFrameRate";
57 constexpr char CODEC_CONFIG_KEY_BITE_RATE_MODE[] = "bitRateMode";
58 constexpr char CODEC_CONFIG_KEY_MESURED_FRAME_RATE[] = "measuredFrameRate";
59
60 constexpr char CODEC_CONFIG_KEY_SAMPLE_FORMATS[] = "sampleFormats";
61 constexpr char CODEC_CONFIG_KEY_SAMPLE_RATE[] = "sampleRate";
62 constexpr char CODEC_CONFIG_KEY_CHANNEL_LAYOUTS[] = "channelLayouts";
63 constexpr char CODEC_CONFIG_KEY_CHANNEL_COUNT[] = "channelCount";
64 }
65
66 using namespace OHOS::HDI::Codec::V1_0;
67 namespace OHOS {
68 namespace Codec {
69 namespace Omx {
70 CodecComponentConfig CodecComponentConfig::config_;
CodecComponentConfig()71 CodecComponentConfig::CodecComponentConfig()
72 {}
73
Init(const DeviceResourceNode & node)74 void CodecComponentConfig::Init(const DeviceResourceNode &node)
75 {
76 node_ = node;
77 std::string codecGroupsNodeName[] = {NODE_VIDEO_HARDWARE_ENCODERS, NODE_VIDEO_HARDWARE_DECODERS,
78 NODE_VIDEO_SOFTWARE_ENCODERS, NODE_VIDEO_SOFTWARE_DECODERS,
79 NODE_AUDIO_HARDWARE_ENCODERS, NODE_AUDIO_HARDWARE_DECODERS,
80 NODE_AUDIO_SOFTWARE_ENCODERS, NODE_AUDIO_SOFTWARE_DECODERS};
81 int count = sizeof(codecGroupsNodeName) / sizeof(std::string);
82 for (int index = 0; index < count; index++) {
83 if (GetGroupCapabilities(codecGroupsNodeName[index]) != HDF_SUCCESS) {
84 continue;
85 }
86 }
87 CODEC_LOGD("Init Run....capList_.size=%{public}zu", capList_.size());
88 }
89
GetInstance()90 CodecComponentConfig *CodecComponentConfig::GetInstance()
91 {
92 return &config_;
93 }
94
GetComponentNum(int32_t & count)95 int32_t CodecComponentConfig::GetComponentNum(int32_t &count)
96 {
97 count = capList_.size();
98 CODEC_LOGD("enter, count = %{public}d", count);
99 return HDF_SUCCESS;
100 }
101
GetComponentCapabilityList(std::vector<CodecCompCapability> & capList,int32_t count)102 int32_t CodecComponentConfig::GetComponentCapabilityList(std::vector<CodecCompCapability> &capList, int32_t count)
103 {
104 CODEC_LOGD("count[%{public}d], size[%{public}zu]", count, capList_.size());
105 if ((size_t)count > capList_.size()) {
106 CODEC_LOGW("count[%{public}d] is too large", count);
107 count = capList_.size();
108 }
109 auto first = capList_.begin();
110 auto last = capList_.begin() + count;
111 capList.assign(first, last);
112 return HDF_SUCCESS;
113 }
114
GetGroupCapabilitiesNumber(const std::string & nodeName,int32_t & num)115 int32_t CodecComponentConfig::GetGroupCapabilitiesNumber(const std::string &nodeName, int32_t &num)
116 {
117 int32_t result = 0;
118
119 const struct DeviceResourceNode *codecGroupNode = NULL;
120 struct DeviceResourceNode *childNode = NULL;
121 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
122 if (iface == NULL) {
123 CODEC_LOGE("failed, iface NULL!");
124 return HDF_FAILURE;
125 }
126
127 codecGroupNode = iface->GetChildNode(&node_, nodeName.c_str());
128 if (codecGroupNode == NULL) {
129 CODEC_LOGE("failed to get child node %{public}s,!", nodeName.c_str());
130 return HDF_FAILURE;
131 }
132 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode)
133 {
134 result++;
135 }
136 num = result;
137 return HDF_SUCCESS;
138 }
139
GetGroupCapabilities(const std::string & nodeName)140 int32_t CodecComponentConfig::GetGroupCapabilities(const std::string &nodeName)
141 {
142 bool isVideoGroup = true;
143 const struct DeviceResourceNode *codecGroupNode = NULL;
144 struct DeviceResourceNode *childNode = NULL;
145 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
146 if (iface == NULL) {
147 CODEC_LOGE(" failed, iface NULL!");
148 return HDF_ERR_INVALID_PARAM;
149 }
150
151 codecGroupNode = iface->GetChildNode(&node_, nodeName.c_str());
152 if (codecGroupNode == NULL) {
153 CODEC_LOGE("failed to get child node: %{public}s!", nodeName.c_str());
154 return HDF_FAILURE;
155 }
156
157 if (nodeName.find("Video") == std::string::npos) {
158 isVideoGroup = false;
159 }
160
161 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode)
162 {
163 CodecCompCapability cap;
164 if (GetOneCapability(*iface, *childNode, cap, isVideoGroup) != HDF_SUCCESS) {
165 CODEC_LOGE("GetOneCapability failed, role is %{public}d!", cap.role);
166 }
167 capList_.push_back(cap);
168 }
169
170 return HDF_SUCCESS;
171 }
172
GetOneCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap,bool isVideoGroup)173 int32_t CodecComponentConfig::GetOneCapability(const struct DeviceResourceIface &iface,
174 const struct DeviceResourceNode &childNode, CodecCompCapability &cap,
175 bool isVideoGroup)
176 {
177 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_ROLE, static_cast<uint32_t *>(&cap.role),
178 MEDIA_ROLETYPE_INVALID) != HDF_SUCCESS) {
179 cap.role = MEDIA_ROLETYPE_INVALID;
180 CODEC_LOGE("failed to get mime for: %{public}s! Discarded", childNode.name);
181 return HDF_FAILURE;
182 }
183
184 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_TYPE, static_cast<uint32_t *>(&cap.type), INVALID_TYPE) !=
185 HDF_SUCCESS) {
186 cap.role = MEDIA_ROLETYPE_INVALID;
187 cap.type = INVALID_TYPE;
188 CODEC_LOGE("failed to get type for: %{public}s! Discarded", childNode.name);
189 return HDF_FAILURE;
190 }
191
192 const char *compName = NULL;
193 if (iface.GetString(&childNode, CODEC_CONFIG_KEY_NAME, &compName, "") != HDF_SUCCESS) {
194 cap.role = MEDIA_ROLETYPE_INVALID;
195 CODEC_LOGE("get attr %{public}s err!", CODEC_CONFIG_KEY_NAME);
196 return HDF_FAILURE;
197 }
198 if (compName == NULL || strlen(compName) == 0) {
199 cap.role = MEDIA_ROLETYPE_INVALID;
200 CODEC_LOGE("compName is null or empty!");
201 return HDF_FAILURE;
202 }
203 cap.compName = compName;
204
205 cap.isSoftwareCodec = iface.GetBool(&childNode, CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC);
206
207 if (GetMiscOfCapability(iface, childNode, cap) != HDF_SUCCESS) {
208 cap.role = MEDIA_ROLETYPE_INVALID;
209 CODEC_LOGE("get misc cap err!");
210 return HDF_FAILURE;
211 }
212
213 if (isVideoGroup) {
214 if (GetVideoPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
215 cap.role = MEDIA_ROLETYPE_INVALID;
216 CODEC_LOGE("get video port cap err!");
217 return HDF_FAILURE;
218 }
219 } else {
220 if (GetAudioPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
221 cap.role = MEDIA_ROLETYPE_INVALID;
222 CODEC_LOGE("get audio port cap err!");
223 return HDF_FAILURE;
224 }
225 }
226
227 return HDF_SUCCESS;
228 }
229
GetMiscOfCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)230 int32_t CodecComponentConfig::GetMiscOfCapability(const struct DeviceResourceIface &iface,
231 const struct DeviceResourceNode &childNode, CodecCompCapability &cap)
232 {
233 ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PROFILES, cap.supportProfiles};
234 if (GetUintTableConfig(iface, childNode, attr) != HDF_SUCCESS) {
235 CODEC_LOGE("get uint table config [%{public}s] err!", attr.attrName.c_str());
236 return HDF_FAILURE;
237 }
238
239 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_INST, static_cast<uint32_t *>(&cap.maxInst), 0) !=
240 HDF_SUCCESS) {
241 CODEC_LOGE("get uint32 config [%{public}s] err!", attr.attrName.c_str());
242 return HDF_FAILURE;
243 }
244 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_PROCESS_MODE_MASK,
245 static_cast<uint32_t &>(cap.processModeMask)) != HDF_SUCCESS) {
246 CODEC_LOGE("get masked config [%{public}s] err!", attr.attrName.c_str());
247 return HDF_FAILURE;
248 }
249 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_CAPS_MASK, static_cast<uint32_t &>(cap.capsMask)) !=
250 HDF_SUCCESS) {
251 CODEC_LOGE("get masked config [%{public}s] err!", attr.attrName.c_str());
252 return HDF_FAILURE;
253 }
254 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MIN_BITRATE, static_cast<uint32_t *>(&cap.bitRate.min), 0) !=
255 HDF_SUCCESS) {
256 CODEC_LOGE("get uin32 config [%{public}s] err!", attr.attrName.c_str());
257 return HDF_FAILURE;
258 }
259 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_BITRATE, static_cast<uint32_t *>(&cap.bitRate.max), 0) !=
260 HDF_SUCCESS) {
261 CODEC_LOGE("get uin32 config [%{public}s] err!", attr.attrName.c_str());
262 return HDF_FAILURE;
263 }
264
265 return HDF_SUCCESS;
266 }
267
GetUintTableConfig(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & node,ConfigUintArrayNodeAttr & attr)268 int32_t CodecComponentConfig::GetUintTableConfig(const struct DeviceResourceIface &iface,
269 const struct DeviceResourceNode &node, ConfigUintArrayNodeAttr &attr)
270 {
271 if (attr.attrName.empty()) {
272 CODEC_LOGE("failed, invalid attr!");
273 return HDF_ERR_INVALID_PARAM;
274 }
275
276 int32_t count = iface.GetElemNum(&node, attr.attrName.c_str());
277 if (count < 0) {
278 CODEC_LOGE("%{public}s table size: count[%{public}d] < 0!", attr.attrName.c_str(), count);
279 return HDF_FAILURE;
280 }
281 if (count > 0) {
282 std::unique_ptr<int32_t[]> array = std::make_unique<int32_t[]>(count);
283 iface.GetUint32Array(&node, attr.attrName.c_str(), static_cast<uint32_t *>(array.get()), count, 0);
284 attr.vec.assign(array.get(), array.get() + count);
285 }
286 return HDF_SUCCESS;
287 }
288
GetMaskedConfig(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & node,const std::string & attrName,uint32_t & mask)289 int32_t CodecComponentConfig::GetMaskedConfig(const struct DeviceResourceIface &iface,
290 const struct DeviceResourceNode &node, const std::string &attrName,
291 uint32_t &mask)
292 {
293 int32_t count = iface.GetElemNum(&node, attrName.c_str());
294
295 mask = 0;
296 if (count < 0 || count > MASK_NUM_LIMIT) {
297 CODEC_LOGE("failed, count %{public}d incorrect!", count);
298 return HDF_FAILURE;
299 }
300
301 if (count > 0) {
302 std::unique_ptr<uint32_t[]> values = std::make_unique<uint32_t[]>(count);
303 iface.GetUint32Array(&node, attrName.c_str(), values.get(), count, 0);
304 for (int32_t index = 0; index < count; index++) {
305 mask |= values[index];
306 }
307 }
308
309 return HDF_SUCCESS;
310 }
311
GetVideoPortCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)312 int32_t CodecComponentConfig::GetVideoPortCapability(const struct DeviceResourceIface &iface,
313 const struct DeviceResourceNode &childNode,
314 CodecCompCapability &cap)
315 {
316 ConfigUintNodeAttr nodeAttrs[] = {
317 {CODEC_CONFIG_KEY_MIN_WIDTH, cap.port.video.minSize.width, 0},
318 {CODEC_CONFIG_KEY_MIN_HEIGHT, cap.port.video.minSize.height, 0},
319 {CODEC_CONFIG_KEY_MAX_WIDTH, cap.port.video.maxSize.width, 0},
320 {CODEC_CONFIG_KEY_MAX_HEIGHT, cap.port.video.maxSize.height, 0},
321 {CODEC_CONFIG_KEY_WIDTH_ALIGNMENT, cap.port.video.whAlignment.widthAlignment, 0},
322 {CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT, cap.port.video.whAlignment.heightAlignment, 0},
323 {CODEC_CONFIG_KEY_MIN_BLOCK_COUNT, cap.port.video.blockCount.min, 0},
324 {CODEC_CONFIG_KEY_MAX_BLOCK_COUNT, cap.port.video.blockCount.max, 0},
325 {CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND, cap.port.video.blocksPerSecond.min, 0},
326 {CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND, cap.port.video.blocksPerSecond.max, 0},
327 {CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH, cap.port.video.blockSize.width, 0},
328 {CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT, cap.port.video.blockSize.height, 0},
329 {CODEC_CONFIG_KEY_MIN_FRAME_RATE, cap.port.video.frameRate.min, 0},
330 {CODEC_CONFIG_KEY_MAX_FRAME_RATE, cap.port.video.frameRate.max, 0}};
331
332 int32_t count = sizeof(nodeAttrs) / sizeof(ConfigUintNodeAttr);
333 for (int32_t i = 0; i < count; i++) {
334 if (iface.GetUint32(&childNode, nodeAttrs[i].attrName.c_str(), static_cast<uint32_t *>(&nodeAttrs[i].value),
335 nodeAttrs[i].defaultValue) != HDF_SUCCESS) {
336 CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, nodeAttrs[i].attrName.c_str());
337 return HDF_FAILURE;
338 }
339 }
340 ConfigUintArrayNodeAttr arrayAttrs[] = {
341 {CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS, cap.port.video.supportPixFmts},
342 {CODEC_CONFIG_KEY_BITE_RATE_MODE, static_cast<std::vector<int32_t> &>(cap.port.video.bitRatemode)},
343 {CODEC_CONFIG_KEY_MESURED_FRAME_RATE, cap.port.video.measuredFrameRate}};
344
345 count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr);
346 for (int32_t i = 0; i < count; i++) {
347 if (GetUintTableConfig(iface, childNode, arrayAttrs[i]) != HDF_SUCCESS) {
348 CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, nodeAttrs[i].attrName.c_str());
349 return HDF_FAILURE;
350 }
351 }
352 return HDF_SUCCESS;
353 }
354
GetAudioPortCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)355 int32_t CodecComponentConfig::GetAudioPortCapability(const struct DeviceResourceIface &iface,
356 const struct DeviceResourceNode &childNode,
357 CodecCompCapability &cap)
358 {
359 ConfigUintArrayNodeAttr arrayAttrs[] = {{CODEC_CONFIG_KEY_SAMPLE_FORMATS, cap.port.audio.sampleFormats},
360 {CODEC_CONFIG_KEY_SAMPLE_RATE, cap.port.audio.sampleRate},
361 {CODEC_CONFIG_KEY_CHANNEL_LAYOUTS, cap.port.audio.channelLayouts},
362 {CODEC_CONFIG_KEY_CHANNEL_COUNT, cap.port.audio.channelCount}};
363
364 int32_t count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr);
365 for (int32_t i = 0; i < count; i++) {
366 if (GetUintTableConfig(iface, childNode, arrayAttrs[i]) != HDF_SUCCESS) {
367 CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, arrayAttrs[i].attrName.c_str());
368 return HDF_FAILURE;
369 }
370 }
371
372 return HDF_SUCCESS;
373 }
374 } // namespace Omx
375 } // namespace Codec
376 } // namespace OHOS