1 /*
2 * Copyright (c) 2022 Huawei Device 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_capability_parser.h"
17 #include <hdf_log.h>
18 #include <OMX_IVCommon.h>
19 #include <osal_mem.h>
20 #include <securec.h>
21
22 #define HDF_LOG_TAG codec_capability_parser
23 #ifdef __ARCH64__
24 #define MASK_NUM_LIMIT 64
25 #else
26 #define MASK_NUM_LIMIT 32
27 #endif
28
GetGroupExInfosNumber(const struct DeviceResourceNode * node,const char * nodeName,int32_t * num)29 static int32_t GetGroupExInfosNumber(const struct DeviceResourceNode *node, const char *nodeName, int32_t *num)
30 {
31 if (node == NULL || nodeName == NULL || num == NULL) {
32 HDF_LOGE("%{public}s, failed for codec %{public}s, invalid param!", __func__, 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 HDF_LOGE("%{public}s, failed, iface NULL!", __func__);
43 return HDF_FAILURE;
44 }
45
46 codecGroupNode = iface->GetChildNode(node, nodeName);
47 if (codecGroupNode == NULL) {
48 HDF_LOGE("%{public}s, failed to get child node %{public}s!", __func__, 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
GetBasicInfo(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecExInfo * info)59 static int32_t GetBasicInfo(
60 const struct DeviceResourceIface *iface, const struct DeviceResourceNode *childNode, CodecExInfo *info)
61 {
62 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_TYPE, (uint32_t *)&info->type, INVALID_TYPE) != HDF_SUCCESS) {
63 HDF_LOGE("%{public}s, failed to get type.", __func__);
64 return HDF_FAILURE;
65 }
66
67 const char *compName = NULL;
68 if (iface->GetString(childNode, CODEC_CONFIG_KEY_NAME, &compName, "") != HDF_SUCCESS) {
69 HDF_LOGE("%{public}s, failed to get compName.", __func__);
70 return HDF_FAILURE;
71 }
72 if (compName == NULL || strlen(compName) >= NAME_LENGTH || strlen(compName) == 0) {
73 HDF_LOGE("%{public}s, compName is invalid.", __func__);
74 return HDF_FAILURE;
75 }
76
77 int32_t ret = strcpy_s(info->compName, NAME_LENGTH, compName);
78 if (ret != EOK) {
79 HDF_LOGE("%{public}s, failed to strcpy_s compName.", __func__);
80 return HDF_FAILURE;
81 }
82
83 return HDF_SUCCESS;
84 }
85
GetBufferInfo(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecExInfo * info)86 static int32_t GetBufferInfo(
87 const struct DeviceResourceIface *iface, const struct DeviceResourceNode *childNode, CodecExInfo *info)
88 {
89 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_INPUT_BUFFER_COUNT, (uint32_t *)&info->inputBufferCount, 0) !=
90 HDF_SUCCESS) {
91 HDF_LOGE("%{public}s, failed to get inputBufferCount.", __func__);
92 return HDF_FAILURE;
93 }
94 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_INPUT_BUFFER_SIZE, (uint32_t *)&info->inputBufferSize, 0) !=
95 HDF_SUCCESS) {
96 HDF_LOGE("%{public}s, failed to get inputBufferSize.", __func__);
97 return HDF_FAILURE;
98 }
99 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_OUTPUT_BUFFER_COUNT, (uint32_t *)&info->outputBufferCount, 0) !=
100 HDF_SUCCESS) {
101 HDF_LOGE("%{public}s, failed to get outputBufferCount.", __func__);
102 return HDF_FAILURE;
103 }
104 if (iface->GetUint32(childNode, CODEC_CONFIG_KEY_OUTPUT_BUFFER_SIZE, (uint32_t *)&info->outputBufferSize, 0) !=
105 HDF_SUCCESS) {
106 HDF_LOGE("%{public}s, failed to get outputBufferSize.", __func__);
107 return HDF_FAILURE;
108 }
109
110 return HDF_SUCCESS;
111 }
112
GetOneExInfo(const struct DeviceResourceIface * iface,const struct DeviceResourceNode * childNode,CodecExInfo * info)113 static int32_t GetOneExInfo(
114 const struct DeviceResourceIface *iface, const struct DeviceResourceNode *childNode, CodecExInfo *info)
115 {
116 if (iface == NULL || childNode == NULL || info == NULL) {
117 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
118 return HDF_ERR_INVALID_PARAM;
119 }
120
121 if (GetBasicInfo(iface, childNode, info) != HDF_SUCCESS) {
122 HDF_LOGE("%{public}s, GetBasicInfo failed!", __func__);
123 return HDF_FAILURE;
124 }
125 if (GetBufferInfo(iface, childNode, info) != HDF_SUCCESS) {
126 HDF_LOGE("%{public}s, GetBufferInfo failed!", __func__);
127 return HDF_FAILURE;
128 }
129
130 return HDF_SUCCESS;
131 }
132
GetGroupExInfos(const struct DeviceResourceNode * node,const char * nodeName,CodecExInfoGroup * exInfoGroup)133 static int32_t GetGroupExInfos(
134 const struct DeviceResourceNode *node, const char *nodeName, CodecExInfoGroup *exInfoGroup)
135 {
136 if (node == NULL || nodeName == NULL || exInfoGroup == NULL) {
137 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
138 return HDF_ERR_INVALID_PARAM;
139 }
140
141 CodecExInfo *info = NULL;
142 int32_t index = 0;
143 const struct DeviceResourceNode *codecGroupNode = NULL;
144 struct DeviceResourceNode *childNode = NULL;
145 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
146 if (iface == NULL) {
147 HDF_LOGE("%{public}s, failed, iface NULL!", __func__);
148 return HDF_ERR_INVALID_PARAM;
149 }
150
151 codecGroupNode = iface->GetChildNode(node, nodeName);
152 if (codecGroupNode == NULL) {
153 HDF_LOGE("%{public}s, failed to get child node: %{public}s!", __func__, nodeName);
154 return HDF_FAILURE;
155 }
156
157 DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode) {
158 info = &(exInfoGroup->exInfo[index++]);
159 if (GetOneExInfo(iface, childNode, info) != HDF_SUCCESS) {
160 HDF_LOGE("%{public}s, GetOneExInfo failed !", __func__);
161 }
162 }
163
164 return HDF_SUCCESS;
165 }
166
LoadCodecExInfoFromHcs(const struct DeviceResourceNode * node,CodecExInfoGroups * exInfos)167 int32_t LoadCodecExInfoFromHcs(const struct DeviceResourceNode *node, CodecExInfoGroups *exInfos)
168 {
169 if (node == NULL || exInfos == NULL) {
170 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
171 return HDF_ERR_INVALID_PARAM;
172 }
173
174 CodecExInfoGroup *codecExInfoGroup = NULL;
175 int32_t index;
176 int32_t codecNum = 0;
177
178 char *codecGroupsNodeName[] = {
179 NODE_VIDEO_HARDWARE_ENCODERS, NODE_VIDEO_HARDWARE_DECODERS,
180 NODE_VIDEO_SOFTWARE_ENCODERS, NODE_VIDEO_SOFTWARE_DECODERS,
181 NODE_AUDIO_HARDWARE_ENCODERS, NODE_AUDIO_HARDWARE_DECODERS,
182 NODE_AUDIO_SOFTWARE_ENCODERS, NODE_AUDIO_SOFTWARE_DECODERS
183 };
184 CodecExInfoGroup *codecExInfoGroups[] = {
185 &(exInfos->videoHwEncoderGroup), &(exInfos->videoHwDecoderGroup),
186 &(exInfos->videoSwEncoderGroup), &(exInfos->videoSwDecoderGroup),
187 &(exInfos->audioHwEncoderGroup), &(exInfos->audioHwDecoderGroup),
188 &(exInfos->audioSwEncoderGroup), &(exInfos->audioSwDecoderGroup)
189 };
190
191 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
192 if (GetGroupExInfosNumber(node, codecGroupsNodeName[index], &codecNum) == HDF_SUCCESS) {
193 codecExInfoGroup = codecExInfoGroups[index];
194 if (codecExInfoGroup == NULL) {
195 continue;
196 }
197 if (codecNum > 0) {
198 codecExInfoGroup->num = codecNum;
199 codecExInfoGroup->exInfo = (CodecExInfo *)OsalMemAlloc(sizeof(CodecExInfo) * codecNum);
200 } else {
201 codecExInfoGroup->exInfo = NULL;
202 codecExInfoGroup->num = 0;
203 }
204 if (codecNum > 0 && codecExInfoGroup->exInfo == NULL) {
205 codecExInfoGroup->num = 0;
206 HDF_LOGE("%{public}s, MemAlloc for capability group failed!", __func__);
207 return HDF_FAILURE;
208 }
209 }
210 }
211
212 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
213 if (GetGroupExInfos(node, codecGroupsNodeName[index], codecExInfoGroups[index]) != HDF_SUCCESS) {
214 HDF_LOGE("%{public}s, GetGroupExInfos failed index: %{public}d!", __func__, index);
215 return HDF_FAILURE;
216 }
217 }
218
219 exInfos->inited = true;
220 return HDF_SUCCESS;
221 }
222
ClearExInfoGroup(CodecExInfoGroups * exInfos)223 int32_t ClearExInfoGroup(CodecExInfoGroups *exInfos)
224 {
225 if (exInfos == NULL) {
226 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
227 return HDF_ERR_INVALID_PARAM;
228 }
229
230 int32_t index;
231 CodecExInfoGroup *codecExInfoGroup = NULL;
232 CodecExInfoGroup *codecExInfoGroups[] = {
233 &(exInfos->videoHwEncoderGroup), &(exInfos->videoHwDecoderGroup),
234 &(exInfos->videoSwEncoderGroup), &(exInfos->videoSwDecoderGroup),
235 &(exInfos->audioHwEncoderGroup), &(exInfos->audioHwDecoderGroup),
236 &(exInfos->audioSwEncoderGroup), &(exInfos->audioSwDecoderGroup)
237 };
238 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
239 codecExInfoGroup = codecExInfoGroups[index];
240 if (codecExInfoGroup == NULL) {
241 continue;
242 }
243 if (codecExInfoGroup->exInfo != NULL) {
244 OsalMemFree(codecExInfoGroup->exInfo);
245 codecExInfoGroup->exInfo = NULL;
246 }
247 }
248 exInfos->inited = false;
249 return HDF_SUCCESS;
250 }
251