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 (codecNum > 0) {
195 codecExInfoGroup->num = codecNum;
196 codecExInfoGroup->exInfo = (CodecExInfo *)OsalMemAlloc(sizeof(CodecExInfo) * codecNum);
197 } else {
198 codecExInfoGroup->exInfo = NULL;
199 codecExInfoGroup->num = 0;
200 }
201 if (codecNum > 0 && codecExInfoGroup->exInfo == NULL) {
202 codecExInfoGroup->num = 0;
203 HDF_LOGE("%{public}s, MemAlloc for capability group failed!", __func__);
204 return HDF_FAILURE;
205 }
206 }
207 }
208
209 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
210 if (GetGroupExInfos(node, codecGroupsNodeName[index], codecExInfoGroups[index]) != HDF_SUCCESS) {
211 HDF_LOGE("%{public}s, GetGroupExInfos failed index: %{public}d!", __func__, index);
212 return HDF_FAILURE;
213 }
214 }
215
216 exInfos->inited = true;
217 return HDF_SUCCESS;
218 }
219
ClearExInfoGroup(CodecExInfoGroups * exInfos)220 int32_t ClearExInfoGroup(CodecExInfoGroups *exInfos)
221 {
222 if (exInfos == NULL) {
223 HDF_LOGE("%{public}s, failed, invalid param!", __func__);
224 return HDF_ERR_INVALID_PARAM;
225 }
226
227 int32_t index;
228 CodecExInfoGroup *codecExInfoGroup = NULL;
229 CodecExInfoGroup *codecExInfoGroups[] = {
230 &(exInfos->videoHwEncoderGroup), &(exInfos->videoHwDecoderGroup),
231 &(exInfos->videoSwEncoderGroup), &(exInfos->videoSwDecoderGroup),
232 &(exInfos->audioHwEncoderGroup), &(exInfos->audioHwDecoderGroup),
233 &(exInfos->audioSwEncoderGroup), &(exInfos->audioSwDecoderGroup)
234 };
235 for (index = 0; index < CODEC_CAPABLITY_GROUP_NUM; index++) {
236 codecExInfoGroup = codecExInfoGroups[index];
237 if (codecExInfoGroup->exInfo != NULL) {
238 OsalMemFree(codecExInfoGroup->exInfo);
239 codecExInfoGroup->exInfo = NULL;
240 }
241 }
242 exInfos->inited = false;
243 return HDF_SUCCESS;
244 }
245