1 /*
2 * Copyright (c) 2022-2023 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 <unistd.h>
19 #include <map>
20 #include "codec_log_wrapper.h"
21 #include "codec_hcb_util.h"
22 #define CODEC_CONFIG_NAME "media_codec_capabilities"
23
24 namespace {
25 constexpr int32_t MASK_NUM_LIMIT = 32;
26 constexpr char NODE_VIDEO_HARDWARE_ENCODERS[] = "VideoHwEncoders";
27 constexpr char NODE_VIDEO_HARDWARE_DECODERS[] = "VideoHwDecoders";
28 constexpr char NODE_VIDEO_SOFTWARE_ENCODERS[] = "VideoSwEncoders";
29 constexpr char NODE_VIDEO_SOFTWARE_DECODERS[] = "VideoSwDecoders";
30 constexpr char NODE_AUDIO_HARDWARE_ENCODERS[] = "AudioHwEncoders";
31 constexpr char NODE_AUDIO_HARDWARE_DECODERS[] = "AudioHwDecoders";
32 constexpr char NODE_AUDIO_SOFTWARE_ENCODERS[] = "AudioSwEncoders";
33 constexpr char NODE_AUDIO_SOFTWARE_DECODERS[] = "AudioSwDecoders";
34
35 constexpr char CODEC_CONFIG_KEY_ROLE[] = "role";
36 constexpr char CODEC_CONFIG_KEY_TYPE[] = "type";
37 constexpr char CODEC_CONFIG_KEY_NAME[] = "name";
38 constexpr char CODEC_CONFIG_KEY_SUPPORT_PROFILES[] = "supportProfiles";
39 constexpr char CODEC_CONFIG_KEY_MAX_INST[] = "maxInst";
40 constexpr char CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC[] = "isSoftwareCodec";
41 constexpr char CODEC_CONFIG_KEY_PROCESS_MODE_MASK[] = "processModeMask";
42 constexpr char CODEC_CONFIG_KEY_CAPS_MASK[] = "capsMask";
43 constexpr char CODEC_CONFIG_KEY_MIN_BITRATE[] = "minBitRate";
44 constexpr char CODEC_CONFIG_KEY_MAX_BITRATE[] = "maxBitRate";
45
46 constexpr char CODEC_CONFIG_KEY_MIN_WIDTH[] = "minWidth";
47 constexpr char CODEC_CONFIG_KEY_MIN_HEIGHT[] = "minHeight";
48 constexpr char CODEC_CONFIG_KEY_MAX_WIDTH[] = "maxWidth";
49 constexpr char CODEC_CONFIG_KEY_MAX_HEIGHT[] = "maxHeight";
50 constexpr char CODEC_CONFIG_KEY_WIDTH_ALIGNMENT[] = "widthAlignment";
51 constexpr char CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT[] = "heightAlignment";
52 constexpr char CODEC_CONFIG_KEY_MIN_BLOCK_COUNT[] = "minBlockCount";
53 constexpr char CODEC_CONFIG_KEY_MAX_BLOCK_COUNT[] = "maxBlockCount";
54 constexpr char CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND[] = "minBlocksPerSecond";
55 constexpr char CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND[] = "maxBlocksPerSecond";
56 constexpr char CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS[] = "supportPixelFmts";
57 constexpr char CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH[] = "blockSizeWidth";
58 constexpr char CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT[] = "blockSizeHeight";
59 constexpr char CODEC_CONFIG_KEY_MIN_FRAME_RATE[] = "minFrameRate";
60 constexpr char CODEC_CONFIG_KEY_MAX_FRAME_RATE[] = "maxFrameRate";
61 constexpr char CODEC_CONFIG_KEY_BITE_RATE_MODE[] = "bitRateMode";
62 constexpr char CODEC_CONFIG_KEY_MESURED_FRAME_RATE[] = "measuredFrameRate";
63 constexpr char CODEC_CONFIG_KEY_CAN_SWAP_WIDTH_HEIGHT[] = "canSwapWidthHeight";
64
65 constexpr char CODEC_CONFIG_KEY_IS_SUPPORT_PASSTHROUGH[] = "isSupportPassthrough";
66 constexpr char CODEC_CONFIG_KEY_IS_SUPPORT_LOW_LATENCY[] = "isSupportLowLatency";
67 constexpr char CODEC_CONFIG_KEY_IS_SUPPORT_TSVC[] = "isSupportTSVC";
68 constexpr char CODEC_CONFIG_KEY_IS_SUPPORT_WATERMARK[] = "isSupportWaterMark";
69 constexpr char CODEC_CONFIG_KEY_IS_SUPPORT_SEEK_WITHOUT_FLUSH[] = "isSupportSeekWithoutFlush";
70 constexpr char CODEC_CONFIG_KEY_IS_SUPPORT_QP_MAP[] = "isSupportQPMap";
71 constexpr char CODEC_CONFIG_KEY_IS_SUPPORT_LTR[] = "isSupportLTR";
72 constexpr char CODEC_CONFIG_KEY_MAX_LTR_FRAME_NUM[] = "maxLTRFrameNum";
73 constexpr char CODEC_CONFIG_KEY_IS_SUPPORT_B_FRAME[] = "isSupportBFrame";
74 constexpr char CODEC_CONFIG_KEY_MAX_SUPPORT_B_FRAME_CNT[] = "maxSupportBFrameCnt";
75
76 constexpr char CODEC_CONFIG_KEY_SAMPLE_FORMATS[] = "sampleFormats";
77 constexpr char CODEC_CONFIG_KEY_SAMPLE_RATE[] = "sampleRate";
78 constexpr char CODEC_CONFIG_KEY_CHANNEL_LAYOUTS[] = "channelLayouts";
79 constexpr char CODEC_CONFIG_KEY_CHANNEL_COUNT[] = "channelCount";
80 }
81
82 using namespace OHOS::HDI::Codec::V4_0;
83 namespace OHOS {
84 namespace Codec {
85 namespace Omx {
86 CodecComponentConfig CodecComponentConfig::config_;
CodecComponentConfig()87 CodecComponentConfig::CodecComponentConfig()
88 {
89 node_.name = nullptr;
90 node_.hashValue = 0;
91 node_.attrData = nullptr;
92 node_.parent = nullptr;
93 node_.child = nullptr;
94 node_.sibling = nullptr;
95 }
96
Init(const DeviceResourceNode & node)97 void CodecComponentConfig::Init(const DeviceResourceNode &node)
98 {
99 node_ = node;
100 const std::string codecGroupsNodeName[] = { NODE_VIDEO_HARDWARE_ENCODERS, NODE_VIDEO_HARDWARE_DECODERS,
101 NODE_VIDEO_SOFTWARE_ENCODERS, NODE_VIDEO_SOFTWARE_DECODERS,
102 NODE_AUDIO_HARDWARE_ENCODERS, NODE_AUDIO_HARDWARE_DECODERS,
103 NODE_AUDIO_SOFTWARE_ENCODERS, NODE_AUDIO_SOFTWARE_DECODERS };
104 int count = sizeof(codecGroupsNodeName) / sizeof(std::string);
105 for (int index = 0; index < count; index++) {
106 GetGroupCapabilities(codecGroupsNodeName[index]);
107 }
108 CODEC_LOGD("Init Run....capList_.size=%{public}zu", capList_.size());
109 }
110
CodecCompCapabilityInit()111 int32_t CodecComponentConfig::CodecCompCapabilityInit()
112 {
113 const struct DeviceResourceNode *rootNode = HdfGetHcsRootNode();
114 if (rootNode == nullptr) {
115 CODEC_LOGE("GetRootNode failed");
116 return HDF_FAILURE;
117 }
118 const struct DeviceResourceNode *codecNode = HcsGetNodeByMatchAttr(rootNode, CODEC_CONFIG_NAME);
119 if (codecNode == nullptr) {
120 CODEC_LOGE("codecNode is nullptr");
121 return HDF_FAILURE;
122 }
123 OHOS::Codec::Omx::CodecComponentConfig::GetInstance()->Init(*codecNode);
124 return HDF_SUCCESS;
125 }
126
GetInstance()127 CodecComponentConfig *CodecComponentConfig::GetInstance()
128 {
129 return &config_;
130 }
131
GetComponentNum(int32_t & count)132 int32_t CodecComponentConfig::GetComponentNum(int32_t &count)
133 {
134 count = static_cast<int32_t>(capList_.size());
135 CODEC_LOGD("enter, count = %{public}d", count);
136 return HDF_SUCCESS;
137 }
138
GetComponentCapabilityList(std::vector<CodecCompCapability> & capList,int32_t count)139 int32_t CodecComponentConfig::GetComponentCapabilityList(std::vector<CodecCompCapability> &capList, int32_t count)
140 {
141 CODEC_LOGD("count[%{public}d], size[%{public}zu]", count, capList_.size());
142 if (count <= 0) {
143 CODEC_LOGE("count[%{public}d] is invalid", count);
144 return HDF_FAILURE;
145 }
146 if (count > static_cast<int32_t>(capList_.size())) {
147 CODEC_LOGW("count[%{public}d] is too large", count);
148 count = static_cast<int32_t>(capList_.size());
149 }
150 auto first = capList_.begin();
151 auto last = capList_.begin() + count;
152 capList.assign(first, last);
153 return HDF_SUCCESS;
154 }
155
GetGroupCapabilities(const std::string & nodeName)156 int32_t CodecComponentConfig::GetGroupCapabilities(const std::string &nodeName)
157 {
158 bool isVideoGroup = true;
159 const struct DeviceResourceNode *codecGroupNode = nullptr;
160 struct DeviceResourceNode *childNode = nullptr;
161 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
162 if ((iface == nullptr) || (iface->GetUint32 == nullptr) ||
163 (iface->GetBool == nullptr) || (iface->GetString == nullptr)) {
164 CODEC_LOGE(" failed, iface or its GetUint32 or GetBool or GetString is nullptr!");
165 return HDF_ERR_INVALID_PARAM;
166 }
167
168 codecGroupNode = iface->GetChildNode(&node_, nodeName.c_str());
169 if (codecGroupNode == nullptr) {
170 CODEC_LOGE("failed to get child node: %{public}s!", nodeName.c_str());
171 return HDF_FAILURE;
172 }
173
174 if (nodeName.find("Video") == std::string::npos) {
175 isVideoGroup = false;
176 }
177
178 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode)
179 {
180 CodecCompCapability cap;
181 if (GetOneCapability(*iface, *childNode, cap, isVideoGroup) != HDF_SUCCESS) {
182 CODEC_LOGE("GetOneCapability failed, role is %{public}d!", cap.role);
183 }
184 CODEC_LOGI("role=%{public}d, type=%{public}d, name=%{public}s",
185 cap.role, cap.type, cap.compName.c_str());
186 const char *devPath = nullptr;
187 if (iface->GetString(childNode, "devPath", &devPath, "") == HDF_SUCCESS &&
188 devPath != nullptr && strlen(devPath) != 0 &&
189 access(devPath, F_OK) < 0) {
190 CODEC_LOGW("access %{public}s failed, ignore", devPath);
191 continue;
192 }
193 capList_.push_back(cap);
194 }
195
196 return HDF_SUCCESS;
197 }
198
GetOneCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap,bool isVideoGroup)199 int32_t CodecComponentConfig::GetOneCapability(const struct DeviceResourceIface &iface,
200 const struct DeviceResourceNode &childNode,
201 CodecCompCapability &cap, bool isVideoGroup)
202 {
203 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_ROLE, reinterpret_cast<uint32_t *>(&cap.role),
204 MEDIA_ROLETYPE_INVALID) != HDF_SUCCESS) {
205 cap.role = MEDIA_ROLETYPE_INVALID;
206 CODEC_LOGE("failed to get mime for: %{public}s! Discarded", childNode.name);
207 return HDF_FAILURE;
208 }
209 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_TYPE, reinterpret_cast<uint32_t *>(&cap.type), INVALID_TYPE) !=
210 HDF_SUCCESS) {
211 cap.role = MEDIA_ROLETYPE_INVALID;
212 cap.type = INVALID_TYPE;
213 CODEC_LOGE("failed to get type for: %{public}s! Discarded", childNode.name);
214 return HDF_FAILURE;
215 }
216
217 const char *compName = nullptr;
218 if (iface.GetString(&childNode, CODEC_CONFIG_KEY_NAME, &compName, "") != HDF_SUCCESS) {
219 cap.role = MEDIA_ROLETYPE_INVALID;
220 CODEC_LOGE("get attr %{public}s err!", CODEC_CONFIG_KEY_NAME);
221 return HDF_FAILURE;
222 }
223 if (compName == nullptr || strlen(compName) == 0) {
224 cap.role = MEDIA_ROLETYPE_INVALID;
225 CODEC_LOGE("compName is nullptr or empty!");
226 return HDF_FAILURE;
227 }
228 cap.compName = compName;
229
230 cap.isSoftwareCodec = iface.GetBool(&childNode, CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC);
231 cap.canSwapWidthHeight = iface.GetBool(&childNode, CODEC_CONFIG_KEY_CAN_SWAP_WIDTH_HEIGHT);
232
233 if (GetMiscOfCapability(iface, childNode, cap) != HDF_SUCCESS) {
234 cap.role = MEDIA_ROLETYPE_INVALID;
235 CODEC_LOGE("get misc cap err!");
236 return HDF_FAILURE;
237 }
238 if (isVideoGroup) {
239 if (GetVideoPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
240 cap.role = MEDIA_ROLETYPE_INVALID;
241 CODEC_LOGE("get video port cap err!");
242 return HDF_FAILURE;
243 }
244 } else {
245 if (GetAudioPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
246 cap.role = MEDIA_ROLETYPE_INVALID;
247 CODEC_LOGE("get audio port cap err!");
248 return HDF_FAILURE;
249 }
250 }
251
252 return HDF_SUCCESS;
253 }
254
GetMiscOfCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)255 int32_t CodecComponentConfig::GetMiscOfCapability(const struct DeviceResourceIface &iface,
256 const struct DeviceResourceNode &childNode, CodecCompCapability &cap)
257 {
258 ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PROFILES, cap.supportProfiles};
259 if (GetUintTableConfig(iface, childNode, attr) != HDF_SUCCESS) {
260 CODEC_LOGE("get uint table config [%{public}s] err!", attr.attrName.c_str());
261 return HDF_FAILURE;
262 }
263
264 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_INST, reinterpret_cast<uint32_t *>(&cap.maxInst), 0) !=
265 HDF_SUCCESS) {
266 CODEC_LOGE("get uint32 config [%{public}s] err!", attr.attrName.c_str());
267 return HDF_FAILURE;
268 }
269 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_PROCESS_MODE_MASK,
270 reinterpret_cast<uint32_t &>(cap.processModeMask)) != HDF_SUCCESS) {
271 CODEC_LOGE("get masked config [%{public}s] err!", attr.attrName.c_str());
272 return HDF_FAILURE;
273 }
274 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_CAPS_MASK, static_cast<uint32_t &>(cap.capsMask)) !=
275 HDF_SUCCESS) {
276 CODEC_LOGE("get masked config [%{public}s] err!", attr.attrName.c_str());
277 return HDF_FAILURE;
278 }
279 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MIN_BITRATE, reinterpret_cast<uint32_t *>(&cap.bitRate.min), 0) !=
280 HDF_SUCCESS) {
281 CODEC_LOGE("get uin32 config [%{public}s] err!", attr.attrName.c_str());
282 return HDF_FAILURE;
283 }
284 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_BITRATE, reinterpret_cast<uint32_t *>(&cap.bitRate.max), 0) !=
285 HDF_SUCCESS) {
286 CODEC_LOGE("get uin32 config [%{public}s] err!", attr.attrName.c_str());
287 return HDF_FAILURE;
288 }
289
290 return HDF_SUCCESS;
291 }
292
GetUintTableConfig(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & node,ConfigUintArrayNodeAttr & attr)293 int32_t CodecComponentConfig::GetUintTableConfig(const struct DeviceResourceIface &iface,
294 const struct DeviceResourceNode &node, ConfigUintArrayNodeAttr &attr)
295 {
296 if (attr.attrName.empty()) {
297 CODEC_LOGE("failed, invalid attr!");
298 return HDF_ERR_INVALID_PARAM;
299 }
300
301 int32_t count = iface.GetElemNum(&node, attr.attrName.c_str());
302 if (count < 0) {
303 CODEC_LOGE("%{public}s table size: count[%{public}d] < 0!", attr.attrName.c_str(), count);
304 return HDF_FAILURE;
305 }
306 if (count > 0) {
307 std::unique_ptr<int32_t[]> array = std::make_unique<int32_t[]>(count);
308 iface.GetUint32Array(&node, attr.attrName.c_str(), reinterpret_cast<uint32_t *>(array.get()), count, 0);
309 attr.vec.assign(array.get(), array.get() + count);
310 }
311 return HDF_SUCCESS;
312 }
313
GetMaskedConfig(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & node,const std::string & attrName,uint32_t & mask)314 int32_t CodecComponentConfig::GetMaskedConfig(const struct DeviceResourceIface &iface,
315 const struct DeviceResourceNode &node, const std::string &attrName,
316 uint32_t &mask)
317 {
318 int32_t count = iface.GetElemNum(&node, attrName.c_str());
319
320 mask = 0;
321 if (count < 0 || count > MASK_NUM_LIMIT) {
322 CODEC_LOGE("failed, count %{public}d incorrect!", count);
323 return HDF_FAILURE;
324 }
325
326 if (count > 0) {
327 std::unique_ptr<uint32_t[]> values = std::make_unique<uint32_t[]>(count);
328 iface.GetUint32Array(&node, attrName.c_str(), values.get(), count, 0);
329 for (int32_t index = 0; index < count; index++) {
330 mask |= values[index];
331 }
332 }
333
334 return HDF_SUCCESS;
335 }
336
GetVideoPortCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)337 int32_t CodecComponentConfig::GetVideoPortCapability(const struct DeviceResourceIface &iface,
338 const struct DeviceResourceNode &childNode,
339 CodecCompCapability &cap)
340 {
341 ConfigUintNodeAttr nodeAttrs[] = {
342 {CODEC_CONFIG_KEY_MIN_WIDTH, cap.port.video.minSize.width, 0},
343 {CODEC_CONFIG_KEY_MIN_HEIGHT, cap.port.video.minSize.height, 0},
344 {CODEC_CONFIG_KEY_MAX_WIDTH, cap.port.video.maxSize.width, 0},
345 {CODEC_CONFIG_KEY_MAX_HEIGHT, cap.port.video.maxSize.height, 0},
346 {CODEC_CONFIG_KEY_WIDTH_ALIGNMENT, cap.port.video.whAlignment.widthAlignment, 0},
347 {CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT, cap.port.video.whAlignment.heightAlignment, 0},
348 {CODEC_CONFIG_KEY_MIN_BLOCK_COUNT, cap.port.video.blockCount.min, 0},
349 {CODEC_CONFIG_KEY_MAX_BLOCK_COUNT, cap.port.video.blockCount.max, 0},
350 {CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND, cap.port.video.blocksPerSecond.min, 0},
351 {CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND, cap.port.video.blocksPerSecond.max, 0},
352 {CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH, cap.port.video.blockSize.width, 0},
353 {CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT, cap.port.video.blockSize.height, 0},
354 {CODEC_CONFIG_KEY_MIN_FRAME_RATE, cap.port.video.frameRate.min, 0},
355 {CODEC_CONFIG_KEY_MAX_FRAME_RATE, cap.port.video.frameRate.max, 0}};
356
357 int32_t count = sizeof(nodeAttrs) / sizeof(ConfigUintNodeAttr);
358 for (int32_t i = 0; i < count; i++) {
359 if (iface.GetUint32(&childNode, nodeAttrs[i].attrName.c_str(),
360 reinterpret_cast<uint32_t *>(&nodeAttrs[i].value),
361 nodeAttrs[i].defaultValue) != HDF_SUCCESS) {
362 CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, nodeAttrs[i].attrName.c_str());
363 return HDF_FAILURE;
364 }
365 }
366 ConfigUintArrayNodeAttr arrayAttrs[] = {
367 {CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS, cap.port.video.supportPixFmts},
368 {CODEC_CONFIG_KEY_BITE_RATE_MODE, reinterpret_cast<std::vector<int32_t> &>(cap.port.video.bitRatemode)},
369 {CODEC_CONFIG_KEY_MESURED_FRAME_RATE, cap.port.video.measuredFrameRate}};
370
371 count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr);
372 for (int32_t i = 0; i < count; i++) {
373 if (GetUintTableConfig(iface, childNode, arrayAttrs[i]) != HDF_SUCCESS) {
374 CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, nodeAttrs[i].attrName.c_str());
375 return HDF_FAILURE;
376 }
377 }
378
379 GetVideoPortFeature(iface, childNode, cap);
380 return HDF_SUCCESS;
381 }
382
GetVideoPortFeature(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)383 void CodecComponentConfig::GetVideoPortFeature(const struct DeviceResourceIface &iface,
384 const struct DeviceResourceNode &childNode,
385 CodecCompCapability &cap)
386 {
387 std::vector<VideoFeature> &features = cap.port.video.features;
388
389 // ltr
390 bool ltrSupport = iface.GetBool(&childNode, CODEC_CONFIG_KEY_IS_SUPPORT_LTR);
391 if (ltrSupport) {
392 int32_t maxLtrNum {0};
393 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_LTR_FRAME_NUM,
394 reinterpret_cast<uint32_t *>(&maxLtrNum), 0) == HDF_SUCCESS) {
395 std::vector<int32_t> ltrExtends(1, maxLtrNum);
396 features.push_back(VideoFeature{VIDEO_FEATURE_LTR, ltrSupport, ltrExtends});
397 } else {
398 CODEC_LOGE("failed to get %{public}s maxLTRFrameNum!", childNode.name);
399 }
400 }
401
402 // b frame
403 bool bSupport = iface.GetBool(&childNode, CODEC_CONFIG_KEY_IS_SUPPORT_B_FRAME);
404 if (bSupport) {
405 int32_t maxBCount {0};
406 if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_SUPPORT_B_FRAME_CNT,
407 reinterpret_cast<uint32_t *>(&maxBCount), 0) == HDF_SUCCESS) {
408 std::vector<int32_t> bFrameExtends(1, maxBCount);
409 features.push_back(VideoFeature{VIDEO_FEATURE_ENCODE_B_FRAME, bSupport, bFrameExtends});
410 } else {
411 CODEC_LOGE("failed to get %{public}s maxSupportBFrameCnt!", childNode.name);
412 }
413 }
414
415 std::vector<int32_t> defaultExtends(0);
416 std::map<enum VideoFeatureKey, std::string> boolKeys = {
417 { VIDEO_FEATURE_PASS_THROUGH, CODEC_CONFIG_KEY_IS_SUPPORT_PASSTHROUGH },
418 { VIDEO_FEATURE_LOW_LATENCY, CODEC_CONFIG_KEY_IS_SUPPORT_LOW_LATENCY },
419 { VIDEO_FEATURE_TSVC, CODEC_CONFIG_KEY_IS_SUPPORT_TSVC },
420 { VIDEO_FEATURE_WATERMARK, CODEC_CONFIG_KEY_IS_SUPPORT_WATERMARK },
421 { VIDEO_FEATURE_SEEK_WITHOUT_FLUSH, CODEC_CONFIG_KEY_IS_SUPPORT_SEEK_WITHOUT_FLUSH },
422 { VIDEO_FEATURE_QP_MAP, CODEC_CONFIG_KEY_IS_SUPPORT_QP_MAP },
423 };
424 for (auto key: boolKeys) {
425 bool support = iface.GetBool(&childNode, key.second.c_str());
426 if (support) {
427 features.push_back(VideoFeature{key.first, support, defaultExtends});
428 }
429 }
430 }
431
GetAudioPortCapability(const struct DeviceResourceIface & iface,const struct DeviceResourceNode & childNode,CodecCompCapability & cap)432 int32_t CodecComponentConfig::GetAudioPortCapability(const struct DeviceResourceIface &iface,
433 const struct DeviceResourceNode &childNode,
434 CodecCompCapability &cap)
435 {
436 ConfigUintArrayNodeAttr arrayAttrs[] = {{CODEC_CONFIG_KEY_SAMPLE_FORMATS, cap.port.audio.sampleFormats},
437 {CODEC_CONFIG_KEY_SAMPLE_RATE, cap.port.audio.sampleRate},
438 {CODEC_CONFIG_KEY_CHANNEL_LAYOUTS, cap.port.audio.channelLayouts},
439 {CODEC_CONFIG_KEY_CHANNEL_COUNT, cap.port.audio.channelCount}};
440
441 int32_t count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr);
442 for (int32_t i = 0; i < count; i++) {
443 if (GetUintTableConfig(iface, childNode, arrayAttrs[i]) != HDF_SUCCESS) {
444 CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, arrayAttrs[i].attrName.c_str());
445 return HDF_FAILURE;
446 }
447 }
448
449 return HDF_SUCCESS;
450 }
451 } // namespace Omx
452 } // namespace Codec
453 } // namespace OHOS
454