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