• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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