• 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_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 }