1 /*
2 * Copyright (c) 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
16 #include "codec_config_parser.h"
17 #include <hdf_log.h>
18 #include <osal_mem.h>
19 #include <securec.h>
20 #include <OMX_IVCommon.h>
21
22 #define HDF_LOG_TAG codec_config_parser
23 #ifdef __ARM64__
24 #define MASK_NUM_LIMIT 64
25 #else
26 #define MASK_NUM_LIMIT 32
27 #endif
28
GetGroupCapabilitiesNumber(const struct DeviceResourceNode * node,const char * nodeName,int32_t * num)29 static int32_t GetGroupCapabilitiesNumber(const struct DeviceResourceNode *node,
30 const char *nodeName, int32_t *num)
31 {
32 if (node == NULL || nodeName == NULL || num == NULL) {
33 HDF_LOGE("%{public}s, failed for codec %{public}s, invalid param!", __func__, nodeName);
34 return HDF_ERR_INVALID_PARAM;
35 }
36
37 int32_t result = 0;
38 *num = result;
39 const struct DeviceResourceNode *codecGroupNode = NULL;
40 struct DeviceResourceNode *childNode = NULL;
41 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
42 if (iface ==NULL) {
43 HDF_LOGE("%{public}s, failed, iface NULL!", __func__);
44 return HDF_FAILURE;
45 }
46
47 codecGroupNode = iface->GetChildNode(node, nodeName);
48 if (codecGroupNode == NULL) {
49 HDF_LOGE("%{public}s, failed to get child node %{public}s,!", __func__, nodeName);
50 return HDF_FAILURE;
51 }
52 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode) {
53 result++;
54 }
55 *num = result;
56
57 return HDF_SUCCESS;
58 }
59
GetUintTableConfig(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * node,ConfigUintArrayNodeAttr * attr)60 static int32_t GetUintTableConfig(const struct DeviceResourceIface *iface,
61 const struct DeviceResourceNode *node, ConfigUintArrayNodeAttr *attr)
62 {
63 if (iface == NULL || node == NULL || attr == NULL) {
64 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
65 return HDF_ERR_INVALID_PARAM;
66 }
67 if (attr->array == NULL || attr->attrName == NULL) {
68 HDF_LOGE("%{public}s, failed, invalid attr!", __func__);
69 return HDF_ERR_INVALID_PARAM;
70 }
71
72 int32_t count = iface->GetElemNum(node, attr->attrName);
73 if (count < 0 || count >= attr->length) {
74 HDF_LOGE("%{public}s, %{public}s table size: %{public}d incorrect or exceed max size %{public}d!",
75 __func__, attr->attrName, count, attr->length - 1);
76 return HDF_FAILURE;
77 }
78
79 if (count > 0) {
80 iface->GetUint32Array(node, attr->attrName, (uint32_t *)attr->array, count, 0);
81 }
82 attr->array[count] = attr->endValue;
83
84 return HDF_SUCCESS;
85 }
86
GetMaskedConfig(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * node,const char * attrName,uint32_t * mask)87 static int32_t GetMaskedConfig(const struct DeviceResourceIface *iface,
88 const struct DeviceResourceNode *node, const char *attrName, uint32_t *mask)
89 {
90 if (iface == NULL || node == NULL || attrName == NULL || mask == NULL) {
91 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
92 return HDF_ERR_INVALID_PARAM;
93 }
94
95 uint32_t *values = NULL;
96 int32_t count = iface->GetElemNum(node, attrName);
97
98 *mask = 0;
99 if (count < 0 || count > MASK_NUM_LIMIT) {
100 HDF_LOGE("%{public}s, failed, count %{public}d incorrect!", __func__, count);
101 return HDF_FAILURE;
102 }
103
104 if (count > 0) {
105 values = (uint32_t *)OsalMemAlloc(sizeof(uint32_t) * count);
106 if (values == NULL) {
107 HDF_LOGE("%{public}s, failed to allocate mem for %{public}s!", __func__, attrName);
108 return HDF_FAILURE;
109 }
110 iface->GetUint32Array(node, attrName, values, count, 0);
111 for (int32_t index = 0; index < count; index++) {
112 *mask |= values[index];
113 }
114 OsalMemFree(values);
115 }
116
117 return HDF_SUCCESS;
118 }
119
GetVideoPortCapability(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecCompCapability * cap)120 static int32_t GetVideoPortCapability(const struct DeviceResourceIface *iface,
121 const struct DeviceResourceNode *childNode, CodecCompCapability *cap)
122 {
123 if (iface == NULL || childNode == NULL || cap == NULL) {
124 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
125 return HDF_ERR_INVALID_PARAM;
126 }
127
128 ConfigUintNodeAttr nodeAttrs[] = {
129 {CODEC_CONFIG_KEY_MIN_WIDTH, (uint32_t*)&cap->port.video.minSize.width, 0},
130 {CODEC_CONFIG_KEY_MIN_HEIGHT, (uint32_t*)&cap->port.video.minSize.height, 0},
131 {CODEC_CONFIG_KEY_MAX_WIDTH, (uint32_t*)&cap->port.video.maxSize.width, 0},
132 {CODEC_CONFIG_KEY_MAX_HEIGHT, (uint32_t*)&cap->port.video.maxSize.height, 0},
133 {CODEC_CONFIG_KEY_WIDTH_ALGINMENT, (uint32_t*)&cap->port.video.whAlignment.widthAlginment, 0},
134 {CODEC_CONFIG_KEY_HEIGHT_ALGINMENT, (uint32_t*)&cap->port.video.whAlignment.heightAlginment, 0},
135 {CODEC_CONFIG_KEY_MIN_BLOCK_COUNT, (uint32_t*)&cap->port.video.blockCount.min, 0},
136 {CODEC_CONFIG_KEY_MAX_BLOCK_COUNT, (uint32_t*)&cap->port.video.blockCount.max, 0},
137 {CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND, (uint32_t*)&cap->port.video.blocksPerSecond.min, 0},
138 {CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND, (uint32_t*)&cap->port.video.blocksPerSecond.max, 0},
139 {CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH, (uint32_t*)&cap->port.video.blockSize.width, 0},
140 {CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT, (uint32_t*)&cap->port.video.blockSize.height, 0}
141 };
142
143 int32_t count = sizeof(nodeAttrs) / sizeof(ConfigUintNodeAttr);
144 for (int32_t i = 0; i < count; i++) {
145 if (iface->GetUint32(childNode, nodeAttrs[i].attrName, nodeAttrs[i].valueAddr,
146 nodeAttrs[i].defaultValue) != HDF_SUCCESS) {
147 HDF_LOGE("%{public}s, failed to get %{public}s.%{public}s!",
148 __func__, childNode->name, nodeAttrs[i].attrName);
149 return HDF_FAILURE;
150 }
151 }
152
153 ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS,
154 cap->port.video.supportPixFmts, PIX_FORMAT_NUM, OMX_COLOR_FormatUnused};
155 if (GetUintTableConfig(iface, childNode, &attr) != HDF_SUCCESS) {
156 HDF_LOGE("%{public}s, failed to get %{public}s.%{public}s!",
157 __func__, childNode->name, CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS);
158 return HDF_FAILURE;
159 }
160
161 return HDF_SUCCESS;
162 }
163
GetAudioPortCapability(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecCompCapability * cap)164 static int32_t GetAudioPortCapability(const struct DeviceResourceIface *iface,
165 const struct DeviceResourceNode *childNode, CodecCompCapability *cap)
166 {
167 if (iface == NULL || childNode == NULL || cap == NULL) {
168 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
169 return HDF_ERR_INVALID_PARAM;
170 }
171
172 ConfigUintArrayNodeAttr arrayAttrs[] = {
173 {CODEC_CONFIG_KEY_SAMPLE_FORMATS, cap->port.audio.sampleFormats, SAMPLE_FMT_NUM, AUDIO_SAMPLE_FMT_INVALID},
174 {CODEC_CONFIG_KEY_SAMPLE_RATE, cap->port.audio.sampleRate, SAMPLE_RATE_NUM, AUD_SAMPLE_RATE_INVALID},
175 {CODEC_CONFIG_KEY_CHANNEL_LAYOUTS, cap->port.audio.channelLayouts, CHANNEL_NUM, -1},
176 {CODEC_CONFIG_KEY_CHANNEL_COUNT, cap->port.audio.channelCount, CHANNEL_NUM, -1}
177 };
178
179 int32_t count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr);
180 for (int32_t i = 0; i < count; i++) {
181 if (GetUintTableConfig(iface, childNode, &arrayAttrs[i]) != HDF_SUCCESS) {
182 HDF_LOGE("%{public}s, failed to get %{public}s.%{public}s!",
183 __func__, childNode->name, arrayAttrs[i].attrName);
184 return HDF_FAILURE;
185 }
186 }
187
188 return HDF_SUCCESS;
189 }
190
GetMiscOfCapability(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecCompCapability * cap)191 static int32_t GetMiscOfCapability(const struct DeviceResourceIface *iface,
192 const struct DeviceResourceNode *childNode, CodecCompCapability *cap)
193 {
194 if (iface == NULL || childNode == NULL || cap == NULL) {
195 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
196 return HDF_ERR_INVALID_PARAM;
197 }
198
199 ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PROFILES,
200 cap->supportProfiles, PROFILE_NUM, INVALID_PROFILE};
201 if (GetUintTableConfig(iface, childNode, &attr) != HDF_SUCCESS) {
202 return HDF_FAILURE;
203 }
204 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_MAX_INST, (uint32_t*)&cap->maxInst, 0) != HDF_SUCCESS) {
205 return HDF_FAILURE;
206 }
207 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_PROCESS_MODE_MASK,
208 (uint32_t *)&cap->processModeMask) != HDF_SUCCESS) {
209 return HDF_FAILURE;
210 }
211 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_CAPS_MASK, &cap->capsMask) != HDF_SUCCESS) {
212 return HDF_FAILURE;
213 }
214 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_MIN_BITRATE, (uint32_t*)&(cap->bitRate.min), 0) != HDF_SUCCESS) {
215 return HDF_FAILURE;
216 }
217 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_MAX_BITRATE, (uint32_t*)&(cap->bitRate.max), 0) != HDF_SUCCESS) {
218 return HDF_FAILURE;
219 }
220
221 return HDF_SUCCESS;
222 }
223
GetOneCapability(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecCompCapability * cap,bool isVideoGroup)224 static int32_t GetOneCapability(const struct DeviceResourceIface *iface,
225 const struct DeviceResourceNode *childNode, CodecCompCapability *cap, bool isVideoGroup)
226 {
227 if (iface == NULL || childNode == NULL || cap == NULL) {
228 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
229 return HDF_ERR_INVALID_PARAM;
230 }
231
232 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_ROLE,
233 (uint32_t*)&cap->role, MEDIA_ROLETYPE_INVALID) != HDF_SUCCESS) {
234 cap->role = MEDIA_ROLETYPE_INVALID;
235 HDF_LOGE("%{public}s, failed to get mime for: %{public}s! Discarded", __func__, childNode->name);
236 return HDF_FAILURE;
237 }
238
239 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_TYPE, (uint32_t*)&cap->type, INVALID_TYPE) != HDF_SUCCESS) {
240 cap->role = MEDIA_ROLETYPE_INVALID;
241 cap->type = INVALID_TYPE;
242 HDF_LOGE("%{public}s, failed to get type for: %{public}s! Discarded", __func__, childNode->name);
243 return HDF_FAILURE;
244 }
245
246 const char *compName = NULL;
247 if (iface->GetString(childNode, CODEC_CONFIG_KEY_NAME, &compName, "") != HDF_SUCCESS) {
248 cap->role = MEDIA_ROLETYPE_INVALID;
249 return HDF_FAILURE;
250 }
251 if (compName == NULL || strlen(compName) >= NAME_LENGTH || strlen(compName) == 0) {
252 cap->role = MEDIA_ROLETYPE_INVALID;
253 return HDF_FAILURE;
254 }
255 int32_t ret = strcpy_s(cap->compName, NAME_LENGTH, compName);
256 if (ret != EOK) {
257 HDF_LOGE("%{public}s, strcpy_s is failed, error code: %{public}d!", __func__, ret);
258 return HDF_FAILURE;
259 }
260 cap->isSoftwareCodec = iface->GetBool(childNode, CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC);
261
262 if (GetMiscOfCapability(iface, childNode, cap) != HDF_SUCCESS) {
263 cap->role = MEDIA_ROLETYPE_INVALID;
264 return HDF_FAILURE;
265 }
266
267 if (isVideoGroup) {
268 if (GetVideoPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
269 cap->role = MEDIA_ROLETYPE_INVALID;
270 return HDF_FAILURE;
271 }
272 } else {
273 if (GetAudioPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
274 cap->role = MEDIA_ROLETYPE_INVALID;
275 return HDF_FAILURE;
276 }
277 }
278
279 return HDF_SUCCESS;
280 }
281
GetGroupCapabilities(const struct DeviceResourceNode * node,const char * nodeName,CodecCapablityGroup * capsGroup)282 static int32_t GetGroupCapabilities(const struct DeviceResourceNode *node,
283 const char *nodeName, CodecCapablityGroup *capsGroup)
284 {
285 if (node == NULL || nodeName == NULL || capsGroup == NULL) {
286 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
287 return HDF_ERR_INVALID_PARAM;
288 }
289
290 CodecCompCapability *cap = NULL;
291 int32_t index = 0;
292 bool isVideoGroup = true;
293 const struct DeviceResourceNode *codecGroupNode = NULL;
294 struct DeviceResourceNode *childNode = NULL;
295 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
296 if (iface ==NULL) {
297 HDF_LOGE("%{public}s, failed, iface NULL!", __func__);
298 return HDF_ERR_INVALID_PARAM;
299 }
300
301 codecGroupNode = iface->GetChildNode(node, nodeName);
302 if (codecGroupNode == NULL) {
303 HDF_LOGE("%{public}s, failed to get child node: %{public}s!", __func__, nodeName);
304 return HDF_FAILURE;
305 }
306
307 if (strstr(nodeName, "Video") == NULL) {
308 isVideoGroup = false;
309 }
310 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode) {
311 cap = &(capsGroup->capablitis[index++]);
312 if (GetOneCapability(iface, childNode, cap, isVideoGroup) != HDF_SUCCESS) {
313 HDF_LOGE("%{public}s, GetOneCapability failed, role is %{public}d!", __func__, cap->role);
314 }
315 }
316
317 return HDF_SUCCESS;
318 }
319
LoadCodecCapabilityFromHcs(const struct DeviceResourceNode * node,CodecCapablites * caps)320 int32_t LoadCodecCapabilityFromHcs(const struct DeviceResourceNode *node, CodecCapablites *caps)
321 {
322 if (node == NULL || caps == NULL) {
323 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
324 return HDF_ERR_INVALID_PARAM;
325 }
326
327 CodecCapablityGroup *codecCapGroup = NULL;
328 int32_t index;
329 int32_t codecNum = 0;
330
331 char *codecGroupsNodeName[] = {
332 NODE_VIDEO_HARDWARE_ENCODERS, NODE_VIDEO_HARDWARE_DECODERS,
333 NODE_VIDEO_SOFTWARE_ENCODERS, NODE_VIDEO_SOFTWARE_DECODERS,
334 NODE_AUDIO_HARDWARE_ENCODERS, NODE_AUDIO_HARDWARE_DECODERS,
335 NODE_AUDIO_SOFTWARE_ENCODERS, NODE_AUDIO_SOFTWARE_DECODERS
336 };
337 CodecCapablityGroup *codecCapGroups[] = {
338 &(caps->videoHwEncoderGroup), &(caps->videoHwDecoderGroup),
339 &(caps->videoSwEncoderGroup), &(caps->videoSwDecoderGroup),
340 &(caps->audioHwEncoderGroup), &(caps->audioHwDecoderGroup),
341 &(caps->audioSwEncoderGroup), &(caps->audioSwDecoderGroup)
342 };
343
344 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
345 if (GetGroupCapabilitiesNumber(node, codecGroupsNodeName[index], &codecNum) == HDF_SUCCESS) {
346 codecCapGroup = codecCapGroups[index];
347 if (codecNum <= 0) {
348 codecCapGroup->capablitis = NULL;
349 codecCapGroup->num = 0;
350 continue;
351 }
352 size_t capablitisSize = sizeof(CodecCompCapability) * codecNum;
353 codecCapGroup->capablitis = (CodecCompCapability *)OsalMemAlloc(capablitisSize);
354 if (codecCapGroup->capablitis == NULL) {
355 codecCapGroup->num = 0;
356 HDF_LOGE("%{public}s, MemAlloc for capability group failed!", __func__);
357 return HDF_FAILURE;
358 }
359 int32_t ret = memset_s(codecCapGroup->capablitis, capablitisSize, 0, capablitisSize);
360 if (ret != EOK) {
361 codecCapGroup->num = 0;
362 OsalMemFree(codecCapGroup->capablitis);
363 HDF_LOGE("%{public}s, memset_s for capability group failed!", __func__);
364 return HDF_FAILURE;
365 }
366 caps->total += codecCapGroup->num;
367 }
368 }
369
370 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
371 if (GetGroupCapabilities(node, codecGroupsNodeName[index], codecCapGroups[index]) != HDF_SUCCESS) {
372 HDF_LOGE("%{public}s, GetGroupCapabilities failed index: %{public}d!", __func__, index);
373 return HDF_FAILURE;
374 }
375 }
376
377 caps->inited = true;
378 return HDF_SUCCESS;
379 }
380
ClearCapabilityGroup(CodecCapablites * caps)381 int32_t ClearCapabilityGroup(CodecCapablites *caps)
382 {
383 if (caps == NULL) {
384 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
385 return HDF_ERR_INVALID_PARAM;
386 }
387
388 int32_t index;
389 CodecCapablityGroup *codecCapGroup = NULL;
390 CodecCapablityGroup *codecCapGroups[] = {
391 &(caps->videoHwEncoderGroup), &(caps->videoHwDecoderGroup),
392 &(caps->videoSwEncoderGroup), &(caps->videoSwDecoderGroup),
393 &(caps->audioHwEncoderGroup), &(caps->audioHwDecoderGroup),
394 &(caps->audioSwEncoderGroup), &(caps->audioSwDecoderGroup)
395 };
396 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
397 codecCapGroup = codecCapGroups[index];
398 if (codecCapGroup->capablitis != NULL) {
399 OsalMemFree(codecCapGroup->capablitis);
400 codecCapGroup->num = 0;
401 codecCapGroup->capablitis = NULL;
402 }
403 }
404 caps->inited = false;
405 caps->total = 0;
406 return HDF_SUCCESS;
407 }
408