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_ALIGNMENT, (uint32_t*)&cap->port.video.whAlignment.widthAlignment, 0},
134 {CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT, (uint32_t*)&cap->port.video.whAlignment.heightAlignment, 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 {CODEC_CONFIG_KEY_MIN_FRAME_RATE, (uint32_t *)&cap->port.video.frameRate.min, 0},
142 {CODEC_CONFIG_KEY_MAX_FRAME_RATE, (uint32_t *)&cap->port.video.frameRate.max, 0}
143 };
144
145 int32_t count = sizeof(nodeAttrs) / sizeof(ConfigUintNodeAttr);
146 for (int32_t i = 0; i < count; i++) {
147 if (iface->GetUint32(childNode, nodeAttrs[i].attrName, nodeAttrs[i].valueAddr,
148 nodeAttrs[i].defaultValue) != HDF_SUCCESS) {
149 HDF_LOGE("%{public}s, failed to get %{public}s.%{public}s!",
150 __func__, childNode->name, nodeAttrs[i].attrName);
151 return HDF_FAILURE;
152 }
153 }
154
155 ConfigUintArrayNodeAttr arrayAttrs[] = {
156 {CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS, cap->port.video.supportPixFmts, PIX_FORMAT_NUM, OMX_COLOR_FormatUnused},
157 {CODEC_CONFIG_KEY_BITE_RATE_MODE, (int32_t *)cap->port.video.bitRatemode, BIT_RATE_MODE_NUM,
158 BIT_RATE_MODE_INVALID},
159 {CODEC_CONFIG_KEY_MESURED_FRAME_RATE, cap->port.video.measuredFrameRate, MEASURED_FRAME_RATE_NUM, 0}
160 };
161
162 count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr);
163 for (int32_t i = 0; i < count; i++) {
164 if (GetUintTableConfig(iface, childNode, &arrayAttrs[i]) != HDF_SUCCESS) {
165 HDF_LOGE("%{public}s, failed to get %{public}s.%{public}s!", __func__, childNode->name,
166 nodeAttrs[i].attrName);
167 return HDF_FAILURE;
168 }
169 }
170 return HDF_SUCCESS;
171 }
172
GetAudioPortCapability(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecCompCapability * cap)173 static int32_t GetAudioPortCapability(const struct DeviceResourceIface *iface,
174 const struct DeviceResourceNode *childNode, CodecCompCapability *cap)
175 {
176 if (iface == NULL || childNode == NULL || cap == NULL) {
177 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
178 return HDF_ERR_INVALID_PARAM;
179 }
180
181 ConfigUintArrayNodeAttr arrayAttrs[] = {
182 {CODEC_CONFIG_KEY_SAMPLE_FORMATS, cap->port.audio.sampleFormats, SAMPLE_FMT_NUM, AUDIO_SAMPLE_FMT_INVALID},
183 {CODEC_CONFIG_KEY_SAMPLE_RATE, cap->port.audio.sampleRate, SAMPLE_RATE_NUM, AUD_SAMPLE_RATE_INVALID},
184 {CODEC_CONFIG_KEY_CHANNEL_LAYOUTS, cap->port.audio.channelLayouts, CHANNEL_NUM, -1},
185 {CODEC_CONFIG_KEY_CHANNEL_COUNT, cap->port.audio.channelCount, CHANNEL_NUM, -1}
186 };
187
188 int32_t count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr);
189 for (int32_t i = 0; i < count; i++) {
190 if (GetUintTableConfig(iface, childNode, &arrayAttrs[i]) != HDF_SUCCESS) {
191 HDF_LOGE("%{public}s, failed to get %{public}s.%{public}s!",
192 __func__, childNode->name, arrayAttrs[i].attrName);
193 return HDF_FAILURE;
194 }
195 }
196
197 return HDF_SUCCESS;
198 }
199
GetMiscOfCapability(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecCompCapability * cap)200 static int32_t GetMiscOfCapability(const struct DeviceResourceIface *iface,
201 const struct DeviceResourceNode *childNode, CodecCompCapability *cap)
202 {
203 if (iface == NULL || childNode == NULL || cap == NULL) {
204 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
205 return HDF_ERR_INVALID_PARAM;
206 }
207
208 ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PROFILES,
209 cap->supportProfiles, PROFILE_NUM, INVALID_PROFILE};
210 if (GetUintTableConfig(iface, childNode, &attr) != HDF_SUCCESS) {
211 return HDF_FAILURE;
212 }
213 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_MAX_INST, (uint32_t*)&cap->maxInst, 0) != HDF_SUCCESS) {
214 return HDF_FAILURE;
215 }
216 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_PROCESS_MODE_MASK,
217 (uint32_t *)&cap->processModeMask) != HDF_SUCCESS) {
218 return HDF_FAILURE;
219 }
220 if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_CAPS_MASK, &cap->capsMask) != HDF_SUCCESS) {
221 return HDF_FAILURE;
222 }
223 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_MIN_BITRATE, (uint32_t*)&(cap->bitRate.min), 0) != HDF_SUCCESS) {
224 return HDF_FAILURE;
225 }
226 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_MAX_BITRATE, (uint32_t*)&(cap->bitRate.max), 0) != HDF_SUCCESS) {
227 return HDF_FAILURE;
228 }
229
230 return HDF_SUCCESS;
231 }
232
GetOneCapability(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecCompCapability * cap,bool isVideoGroup)233 static int32_t GetOneCapability(const struct DeviceResourceIface *iface,
234 const struct DeviceResourceNode *childNode, CodecCompCapability *cap, bool isVideoGroup)
235 {
236 if (iface == NULL || childNode == NULL || cap == NULL) {
237 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
238 return HDF_ERR_INVALID_PARAM;
239 }
240
241 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_ROLE,
242 (uint32_t*)&cap->role, MEDIA_ROLETYPE_INVALID) != HDF_SUCCESS) {
243 cap->role = MEDIA_ROLETYPE_INVALID;
244 HDF_LOGE("%{public}s, failed to get mime for: %{public}s! Discarded", __func__, childNode->name);
245 return HDF_FAILURE;
246 }
247
248 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_TYPE, (uint32_t*)&cap->type, INVALID_TYPE) != HDF_SUCCESS) {
249 cap->role = MEDIA_ROLETYPE_INVALID;
250 cap->type = INVALID_TYPE;
251 HDF_LOGE("%{public}s, failed to get type for: %{public}s! Discarded", __func__, childNode->name);
252 return HDF_FAILURE;
253 }
254
255 const char *compName = NULL;
256 if (iface->GetString(childNode, CODEC_CONFIG_KEY_NAME, &compName, "") != HDF_SUCCESS) {
257 cap->role = MEDIA_ROLETYPE_INVALID;
258 return HDF_FAILURE;
259 }
260 if (compName == NULL || strlen(compName) >= NAME_LENGTH || strlen(compName) == 0) {
261 cap->role = MEDIA_ROLETYPE_INVALID;
262 return HDF_FAILURE;
263 }
264 int32_t ret = strcpy_s(cap->compName, NAME_LENGTH, compName);
265 if (ret != EOK) {
266 HDF_LOGE("%{public}s, strcpy_s is failed, error code: %{public}d!", __func__, ret);
267 return HDF_FAILURE;
268 }
269 cap->isSoftwareCodec = iface->GetBool(childNode, CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC);
270
271 if (GetMiscOfCapability(iface, childNode, cap) != HDF_SUCCESS) {
272 cap->role = MEDIA_ROLETYPE_INVALID;
273 return HDF_FAILURE;
274 }
275
276 if (isVideoGroup) {
277 if (GetVideoPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
278 cap->role = MEDIA_ROLETYPE_INVALID;
279 return HDF_FAILURE;
280 }
281 } else {
282 if (GetAudioPortCapability(iface, childNode, cap) != HDF_SUCCESS) {
283 cap->role = MEDIA_ROLETYPE_INVALID;
284 return HDF_FAILURE;
285 }
286 }
287
288 return HDF_SUCCESS;
289 }
290
GetGroupCapabilities(const struct DeviceResourceNode * node,const char * nodeName,CodecCapablityGroup * capsGroup)291 static int32_t GetGroupCapabilities(const struct DeviceResourceNode *node,
292 const char *nodeName, CodecCapablityGroup *capsGroup)
293 {
294 if (node == NULL || nodeName == NULL || capsGroup == NULL) {
295 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
296 return HDF_ERR_INVALID_PARAM;
297 }
298
299 CodecCompCapability *cap = NULL;
300 int32_t index = 0;
301 bool isVideoGroup = true;
302 const struct DeviceResourceNode *codecGroupNode = NULL;
303 struct DeviceResourceNode *childNode = NULL;
304 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
305 if (iface ==NULL) {
306 HDF_LOGE("%{public}s, failed, iface NULL!", __func__);
307 return HDF_ERR_INVALID_PARAM;
308 }
309
310 codecGroupNode = iface->GetChildNode(node, nodeName);
311 if (codecGroupNode == NULL) {
312 HDF_LOGE("%{public}s, failed to get child node: %{public}s!", __func__, nodeName);
313 return HDF_FAILURE;
314 }
315
316 if (strstr(nodeName, "Video") == NULL) {
317 isVideoGroup = false;
318 }
319 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode) {
320 cap = &(capsGroup->capablitis[index++]);
321 if (GetOneCapability(iface, childNode, cap, isVideoGroup) != HDF_SUCCESS) {
322 HDF_LOGE("%{public}s, GetOneCapability failed, role is %{public}d!", __func__, 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 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
333 return HDF_ERR_INVALID_PARAM;
334 }
335
336 CodecCapablityGroup *codecCapGroup = NULL;
337 int32_t index;
338 int32_t codecNum = 0;
339
340 char *codecGroupsNodeName[] = {
341 NODE_VIDEO_HARDWARE_ENCODERS, NODE_VIDEO_HARDWARE_DECODERS,
342 NODE_VIDEO_SOFTWARE_ENCODERS, NODE_VIDEO_SOFTWARE_DECODERS,
343 NODE_AUDIO_HARDWARE_ENCODERS, NODE_AUDIO_HARDWARE_DECODERS,
344 NODE_AUDIO_SOFTWARE_ENCODERS, NODE_AUDIO_SOFTWARE_DECODERS
345 };
346 CodecCapablityGroup *codecCapGroups[] = {
347 &(caps->videoHwEncoderGroup), &(caps->videoHwDecoderGroup),
348 &(caps->videoSwEncoderGroup), &(caps->videoSwDecoderGroup),
349 &(caps->audioHwEncoderGroup), &(caps->audioHwDecoderGroup),
350 &(caps->audioSwEncoderGroup), &(caps->audioSwDecoderGroup)
351 };
352
353 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
354 if (GetGroupCapabilitiesNumber(node, codecGroupsNodeName[index], &codecNum) == HDF_SUCCESS) {
355 codecCapGroup = codecCapGroups[index];
356 if (codecNum > 0) {
357 codecCapGroup->num = codecNum;
358 codecCapGroup->capablitis
359 = (CodecCompCapability *)OsalMemAlloc(sizeof(CodecCompCapability) * codecNum);
360 } else {
361 codecCapGroup->capablitis = NULL;
362 codecCapGroup->num = 0;
363 }
364 if (codecNum > 0 && codecCapGroup->capablitis == NULL) {
365 codecCapGroup->num = 0;
366 HDF_LOGE("%{public}s, MemAlloc for capability group failed!", __func__);
367 return HDF_FAILURE;
368 }
369 caps->total += codecCapGroup->num;
370 }
371 }
372
373 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
374 if (GetGroupCapabilities(node, codecGroupsNodeName[index], codecCapGroups[index]) != HDF_SUCCESS) {
375 HDF_LOGE("%{public}s, GetGroupCapabilities failed index: %{public}d!", __func__, index);
376 return HDF_FAILURE;
377 }
378 }
379
380 caps->inited = true;
381 return HDF_SUCCESS;
382 }
383
ClearCapabilityGroup(CodecCapablites * caps)384 int32_t ClearCapabilityGroup(CodecCapablites *caps)
385 {
386 if (caps == NULL) {
387 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
388 return HDF_ERR_INVALID_PARAM;
389 }
390
391 int32_t index;
392 CodecCapablityGroup *codecCapGroup = NULL;
393 CodecCapablityGroup *codecCapGroups[] = {
394 &(caps->videoHwEncoderGroup), &(caps->videoHwDecoderGroup),
395 &(caps->videoSwEncoderGroup), &(caps->videoSwDecoderGroup),
396 &(caps->audioHwEncoderGroup), &(caps->audioHwDecoderGroup),
397 &(caps->audioSwEncoderGroup), &(caps->audioSwDecoderGroup)
398 };
399 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
400 codecCapGroup = codecCapGroups[index];
401 if (codecCapGroup->capablitis != NULL) {
402 OsalMemFree(codecCapGroup->capablitis);
403 codecCapGroup->num = 0;
404 codecCapGroup->capablitis = NULL;
405 }
406 }
407 caps->inited = false;
408 caps->total = 0;
409 return HDF_SUCCESS;
410 }