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