1 /*
2 * Copyright (c) 2021 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 <hdf_sbuf.h>
17 #include <hdf_device_desc.h>
18 #include <hdf_device_object.h>
19 #include "hdf_base.h"
20 #include "hdf_log.h"
21 #include "codec_type.h"
22 #include "config_parser.h"
23 #include "codec_utils.h"
24
25 #define HDF_LOG_TAG "codec_config_service"
26
27 static CodecCapablites codecCapabilites = {0};
28 static const struct DeviceResourceNode *resourceNode;
29
SerializeCapAlginment(struct HdfSBuf * reply,Alginment * alginment)30 static int32_t SerializeCapAlginment(struct HdfSBuf *reply, Alginment *alginment)
31 {
32 if (reply == NULL || alginment == NULL) {
33 HDF_LOGE("%{public}s: params null!", __func__);
34 return HDF_ERR_INVALID_PARAM;
35 }
36 if (!HdfSbufWriteInt32(reply, alginment->widthAlginment)) {
37 HDF_LOGE("%{public}s: Write widthAlginment failed!", __func__);
38 return HDF_FAILURE;
39 }
40 if (!HdfSbufWriteInt32(reply, alginment->heightAlginment)) {
41 HDF_LOGE("%{public}s: Write heightAlginment failed!", __func__);
42 return HDF_FAILURE;
43 }
44 return HDF_SUCCESS;
45 }
46
SerializeCapRect(struct HdfSBuf * reply,Rect * rectangle)47 static int32_t SerializeCapRect(struct HdfSBuf *reply, Rect *rectangle)
48 {
49 if (reply == NULL || rectangle == NULL) {
50 HDF_LOGE("%{public}s: params null!", __func__);
51 return HDF_ERR_INVALID_PARAM;
52 }
53 if (!HdfSbufWriteInt32(reply, rectangle->width)) {
54 HDF_LOGE("%{public}s: Write width failed!", __func__);
55 return HDF_FAILURE;
56 }
57 if (!HdfSbufWriteInt32(reply, rectangle->height)) {
58 HDF_LOGE("%{public}s: Write height failed!", __func__);
59 return HDF_FAILURE;
60 }
61 return HDF_SUCCESS;
62 }
63
SerializeCapArray(struct HdfSBuf * reply,ResizableArray * resArr)64 static int32_t SerializeCapArray(struct HdfSBuf *reply, ResizableArray *resArr)
65 {
66 if (reply == NULL || resArr == NULL) {
67 HDF_LOGE("%{public}s: params null!", __func__);
68 return HDF_ERR_INVALID_PARAM;
69 }
70
71 if (!HdfSbufWriteUint32(reply, resArr->actualLen)) {
72 HDF_LOGE("%{public}s: Write actualLen failed!", __func__);
73 return HDF_FAILURE;
74 }
75 for (uint32_t i = 0; i < resArr->actualLen; i++) {
76 if (!HdfSbufWriteUint32(reply, resArr->element[i])) {
77 HDF_LOGE("%{public}s: Write HdfSubf failed!", __func__);
78 return HDF_FAILURE;
79 }
80 }
81 return HDF_SUCCESS;
82 }
83
SerializeCodecCapbility(struct HdfSBuf * reply,CodecCapbility * cap)84 static int32_t SerializeCodecCapbility(struct HdfSBuf *reply, CodecCapbility *cap)
85 {
86 if (reply == NULL || cap == NULL) {
87 HDF_LOGE("%{public}s: params NULL!", __func__);
88 return HDF_ERR_INVALID_PARAM;
89 }
90 if (!HdfSbufWriteUint32(reply, (uint32_t)cap->mime)) {
91 return HDF_FAILURE;
92 }
93 if (!HdfSbufWriteUint32(reply, (uint32_t)cap->type)) {
94 return HDF_FAILURE;
95 }
96 if (SerializeCapAlginment(reply, &cap->whAlignment) != HDF_SUCCESS) {
97 return HDF_FAILURE;
98 }
99 if (SerializeCapRect(reply, &cap->minSize) != HDF_SUCCESS) {
100 return HDF_FAILURE;
101 }
102 if (SerializeCapRect(reply, &cap->maxSize) != HDF_SUCCESS) {
103 return HDF_FAILURE;
104 }
105 if (!HdfSbufWriteUint64(reply, cap->minBitRate)) {
106 return HDF_FAILURE;
107 }
108 if (!HdfSbufWriteUint64(reply, cap->maxBitRate)) {
109 return HDF_FAILURE;
110 }
111 if (SerializeCapArray(reply, &cap->supportProfiles) != HDF_SUCCESS) {
112 return HDF_FAILURE;
113 }
114 if (SerializeCapArray(reply, &cap->supportLevels) != HDF_SUCCESS) {
115 return HDF_FAILURE;
116 }
117 if (SerializeCapArray(reply, &cap->supportPixelFormats) != HDF_SUCCESS) {
118 return HDF_FAILURE;
119 }
120 if (!HdfSbufWriteUint32(reply, cap->minInputBufferNum)) {
121 return HDF_FAILURE;
122 }
123 if (!HdfSbufWriteUint32(reply, cap->minOutputBufferNum)) {
124 return HDF_FAILURE;
125 }
126 if (!HdfSbufWriteUint32(reply, cap->allocateMask)) {
127 return HDF_FAILURE;
128 }
129 if (!HdfSbufWriteUint32(reply, cap->capsMask)) {
130 return HDF_FAILURE;
131 }
132 return HDF_SUCCESS;
133 }
134
EnumrateCapablity(int32_t index,CodecCapbility ** capability)135 static int32_t EnumrateCapablity(int32_t index, CodecCapbility **capability)
136 {
137 int32_t loopIndex;
138 int32_t cursor = index;
139 CodecCapablityGroup *codeCapGroups[] = {&(codecCapabilites.videoHwEncoderGroup),
140 &(codecCapabilites.videoHwDecoderGroup),
141 &(codecCapabilites.videoSwEncoderGroup),
142 &(codecCapabilites.videoSwDecoderGroup),
143 &(codecCapabilites.audioHwEncoderGroup),
144 &(codecCapabilites.audioHwDecoderGroup),
145 &(codecCapabilites.audioSwEncoderGroup),
146 &(codecCapabilites.audioSwDecoderGroup)};
147
148 for (loopIndex = 0; loopIndex < CODEC_CAPABLITY_GROUP_NUM; loopIndex++) {
149 if (cursor + 1 <= codeCapGroups[loopIndex]->num) {
150 *capability = &(codeCapGroups[loopIndex]->capablitis[cursor]);
151 return HDF_SUCCESS;
152 } else {
153 cursor -= codeCapGroups[loopIndex]->num;
154 }
155 }
156
157 return HDF_FAILURE;
158 }
159
GetCapability(AvCodecMime mime,CodecType type,uint32_t flag,CodecCapbility ** capability)160 static int32_t GetCapability(AvCodecMime mime, CodecType type, uint32_t flag, CodecCapbility **capability)
161 {
162 int32_t groupIndex;
163 int32_t capIndex;
164 CodecCapablityGroup *group;
165 CodecCapbility *cap;
166 bool flagMatched = false;
167 CodecCapablityGroup *codeCapGroups[] = {&(codecCapabilites.videoHwEncoderGroup),
168 &(codecCapabilites.videoHwDecoderGroup),
169 &(codecCapabilites.audioHwEncoderGroup),
170 &(codecCapabilites.audioHwDecoderGroup),
171 &(codecCapabilites.videoSwEncoderGroup),
172 &(codecCapabilites.videoSwDecoderGroup),
173 &(codecCapabilites.audioSwEncoderGroup),
174 &(codecCapabilites.audioSwDecoderGroup)};
175 const int32_t hardAndSoftSplitNumber = 4;
176
177 for (groupIndex = 0; groupIndex < CODEC_CAPABLITY_GROUP_NUM; groupIndex++) {
178 group = codeCapGroups[groupIndex];
179 for (capIndex = 0; capIndex < group->num; capIndex++) {
180 cap = &group->capablitis[capIndex];
181 flagMatched = flag == 0 ? groupIndex < hardAndSoftSplitNumber : groupIndex >= hardAndSoftSplitNumber;
182 if (mime == cap->mime && type == cap->type && flagMatched) {
183 *capability = &group->capablitis[capIndex];
184 return HDF_SUCCESS;
185 }
186 }
187 }
188
189 return HDF_FAILURE;
190 }
191
ReloadCapabilities()192 static int32_t ReloadCapabilities()
193 {
194 ClearCapabilityGroup(&codecCapabilites);
195 LoadCodecCapabilityFromHcs(resourceNode, &codecCapabilites);
196 return HDF_SUCCESS;
197 }
198
HandleEnumrateCmd(struct HdfSBuf * data,struct HdfSBuf * reply)199 static int32_t HandleEnumrateCmd(struct HdfSBuf *data, struct HdfSBuf *reply)
200 {
201 CodecCapbility *capbility = NULL;
202 uint32_t index;
203
204 if (!HdfSbufReadUint32(data, &index)) {
205 HDF_LOGE("%{public}s: read index failed!", __func__);
206 return HDF_FAILURE;
207 }
208 if (!codecCapabilites.inited) {
209 return HDF_FAILURE;
210 }
211 if (EnumrateCapablity(index, &capbility) != HDF_SUCCESS) {
212 HDF_LOGE("%{public}s: EnumrateCapablity - no more capability to Enumrate!", __func__);
213 return HDF_FAILURE;
214 }
215 if (capbility->mime == MEDIA_MIMETYPE_INVALID) {
216 HDF_LOGE("%{public}s: Capablity invalid, discard!", __func__);
217 return HDF_FAILURE;
218 }
219 if (SerializeCodecCapbility(reply, capbility) != HDF_SUCCESS) {
220 HDF_LOGE("%{public}s: write capbility to sbuf failed!", __func__);
221 return HDF_FAILURE;
222 }
223
224 return HDF_SUCCESS;
225 }
226
HandleGetCmd(struct HdfSBuf * data,struct HdfSBuf * reply)227 static int32_t HandleGetCmd(struct HdfSBuf *data, struct HdfSBuf *reply)
228 {
229 CodecCapbility *capbility = NULL;
230 AvCodecMime mime;
231 CodecType type;
232 uint32_t flags;
233
234 if (!HdfSbufReadUint32(data, (uint32_t*)&mime)) {
235 HDF_LOGE("%{public}s: read input mime failed!", __func__);
236 return HDF_FAILURE;
237 }
238 if (!HdfSbufReadUint32(data, (uint32_t*)&type)) {
239 HDF_LOGE("%{public}s: read input type failed!", __func__);
240 return HDF_FAILURE;
241 }
242 if (!HdfSbufReadUint32(data, &flags)) {
243 HDF_LOGE("%{public}s: read input flags failed!", __func__);
244 return HDF_FAILURE;
245 }
246 if (GetCapability(mime, type, flags, &capbility) != HDF_SUCCESS) {
247 HDF_LOGE("%{public}s: GetCapability - got nothing!", __func__);
248 return HDF_FAILURE;
249 }
250 if (SerializeCodecCapbility(reply, capbility) != HDF_SUCCESS) {
251 HDF_LOGE("%{public}s: write capbility to sbuf failed!", __func__);
252 return HDF_FAILURE;
253 }
254
255 return HDF_SUCCESS;
256 }
257
CodecCapabilityDispatch(struct HdfDeviceIoClient * client,int id,struct HdfSBuf * data,struct HdfSBuf * reply)258 static int32_t CodecCapabilityDispatch(struct HdfDeviceIoClient *client, int id,
259 struct HdfSBuf *data, struct HdfSBuf *reply)
260 {
261 int32_t result = HDF_SUCCESS;
262
263 if (client == NULL || data == NULL || reply == NULL) {
264 HDF_LOGE("%{public}s: params NULL!", __func__);
265 return HDF_ERR_INVALID_PARAM;
266 }
267 if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) {
268 HDF_LOGE("check interface token failed");
269 return HDF_ERR_INVALID_PARAM;
270 }
271 if (!codecCapabilites.inited) {
272 ReloadCapabilities();
273 }
274
275 switch (id) {
276 case CODEC_CONFIG_CMD_ENUMERATE_CAP: {
277 result = HandleEnumrateCmd(data, reply);
278 break;
279 }
280
281 case CODEC_CONFIG_CMD_GET_CAP: {
282 result = HandleGetCmd(data, reply);
283 break;
284 }
285
286 default:
287 break;
288 }
289
290 return result;
291 }
292
CodecCapabilityBind(struct HdfDeviceObject * deviceObject)293 static int32_t CodecCapabilityBind(struct HdfDeviceObject *deviceObject)
294 {
295 if (deviceObject == NULL) {
296 return HDF_FAILURE;
297 }
298
299 static struct IDeviceIoService deviceIoService = {
300 .Dispatch = CodecCapabilityDispatch,
301 };
302 deviceObject->service = &deviceIoService;
303
304 return HDF_SUCCESS;
305 }
306
CodecCapabilityInit(struct HdfDeviceObject * deviceObject)307 static int32_t CodecCapabilityInit(struct HdfDeviceObject *deviceObject)
308 {
309 if (deviceObject == NULL) {
310 return HDF_FAILURE;
311 }
312 resourceNode = deviceObject->property;
313 if (LoadCodecCapabilityFromHcs(deviceObject->property, &codecCapabilites) != HDF_SUCCESS) {
314 ClearCapabilityGroup(&codecCapabilites);
315 }
316 return HDF_SUCCESS;
317 }
318
CodecCapabilityRelease(struct HdfDeviceObject * deviceObject)319 static void CodecCapabilityRelease(struct HdfDeviceObject *deviceObject)
320 {
321 ClearCapabilityGroup(&codecCapabilites);
322 return;
323 }
324
325 struct HdfDriverEntry g_codecConfigDriverEntry = {
326 .moduleVersion = 1,
327 .moduleName = "codec_capability_config", // corresponding serviceName is "codec_capability_config_service";
328 .Bind = CodecCapabilityBind,
329 .Init = CodecCapabilityInit,
330 .Release = CodecCapabilityRelease,
331 };
332
333 HDF_INIT(g_codecConfigDriverEntry);
334