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