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