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 "codec_config_reader.h"
17 #include <hdf_log.h>
18 #include <hdf_sbuf.h>
19 #include <servmgr_hdi.h>
20 #include "config_parser.h"
21 #include "codec_utils.h"
22
23 #ifdef __cplusplus
24 extern "C" {
25 #endif /* __cplusplus */
26
27 #define HDF_LOG_TAG "codec_config_client"
28
DeserializeCapAlignment(struct HdfSBuf * reply,Alginment * alginment)29 static int32_t DeserializeCapAlignment(struct HdfSBuf *reply, Alginment *alginment)
30 {
31 if (reply == NULL || alginment == NULL) {
32 HDF_LOGE("%{public}s: params NULL!", __func__);
33 return HDF_ERR_INVALID_PARAM;
34 }
35 if (!HdfSbufReadInt32(reply, &alginment->widthAlginment)) {
36 HDF_LOGE("%{public}s: read widthAlginment failed!", __func__);
37 return HDF_FAILURE;
38 }
39 if (!HdfSbufReadInt32(reply, &alginment->heightAlginment)) {
40 HDF_LOGE("%{public}s: read heightAlginment failed!", __func__);
41 return HDF_FAILURE;
42 }
43 return HDF_SUCCESS;
44 }
45
DeserializeCapRect(struct HdfSBuf * reply,Rect * rectangle)46 static int32_t DeserializeCapRect(struct HdfSBuf *reply, Rect *rectangle)
47 {
48 if (reply == NULL || rectangle == NULL) {
49 HDF_LOGE("%{public}s: params NULL!", __func__);
50 return HDF_ERR_INVALID_PARAM;
51 }
52 if (!HdfSbufReadInt32(reply, &rectangle->width)) {
53 HDF_LOGE("%{public}s: read width failed!", __func__);
54 return HDF_FAILURE;
55 }
56 if (!HdfSbufReadInt32(reply, &rectangle->height)) {
57 HDF_LOGE("%{public}s: read height failed!", __func__);
58 return HDF_FAILURE;
59 }
60 return HDF_SUCCESS;
61 }
62
DeserializeCapArray(struct HdfSBuf * reply,ResizableArray * resArr)63 static int32_t DeserializeCapArray(struct HdfSBuf *reply, ResizableArray *resArr)
64 {
65 if (reply == NULL || resArr == NULL) {
66 HDF_LOGE("%{public}s: params NULL!", __func__);
67 return HDF_ERR_INVALID_PARAM;
68 }
69
70 resArr->actualLen = 0;
71 if (!HdfSbufReadUint32(reply, &resArr->actualLen)) {
72 HDF_LOGE("%{public}s: read actualLen failed!", __func__);
73 return HDF_FAILURE;
74 }
75 for (uint32_t i = 0; i < resArr->actualLen; i++) {
76 if (!HdfSbufReadUint32(reply, &resArr->element[i])) {
77 HDF_LOGE("%{public}s: read element failed!", __func__);
78 return HDF_FAILURE;
79 }
80 }
81 return HDF_SUCCESS;
82 }
83
DeserializeCodecCapability(struct HdfSBuf * reply,CodecCapbility * cap)84 static int32_t DeserializeCodecCapability(struct HdfSBuf *reply, CodecCapbility *cap)
85 {
86 if (reply == NULL || cap == NULL) {
87 return HDF_ERR_INVALID_PARAM;
88 }
89 if (!HdfSbufReadUint32(reply, (uint32_t*)&cap->mime)) {
90 return HDF_FAILURE;
91 }
92 if (!HdfSbufReadUint32(reply, (uint32_t*)&cap->type)) {
93 return HDF_FAILURE;
94 }
95 if (DeserializeCapAlignment(reply, &cap->whAlignment) != HDF_SUCCESS) {
96 return HDF_FAILURE;
97 }
98 if (DeserializeCapRect(reply, &cap->minSize) != HDF_SUCCESS) {
99 return HDF_FAILURE;
100 }
101 if (DeserializeCapRect(reply, &cap->maxSize) != HDF_SUCCESS) {
102 return HDF_FAILURE;
103 }
104 if (!HdfSbufReadUint64(reply, &cap->minBitRate)) {
105 return HDF_FAILURE;
106 }
107 if (!HdfSbufReadUint64(reply, &cap->maxBitRate)) {
108 return HDF_FAILURE;
109 }
110 if (DeserializeCapArray(reply, &cap->supportProfiles) != HDF_SUCCESS) {
111 return HDF_FAILURE;
112 }
113 if (DeserializeCapArray(reply, &cap->supportLevels) != HDF_SUCCESS) {
114 return HDF_FAILURE;
115 }
116 if (DeserializeCapArray(reply, &cap->supportPixelFormats) != HDF_SUCCESS) {
117 return HDF_FAILURE;
118 }
119 if (!HdfSbufReadUint32(reply, &cap->minInputBufferNum)) {
120 return HDF_FAILURE;
121 }
122 if (!HdfSbufReadUint32(reply, &cap->minOutputBufferNum)) {
123 return HDF_FAILURE;
124 }
125 if (!HdfSbufReadUint32(reply, &cap->allocateMask)) {
126 return HDF_FAILURE;
127 }
128 if (!HdfSbufReadUint32(reply, &cap->capsMask)) {
129 return HDF_FAILURE;
130 }
131
132 return HDF_SUCCESS;
133 }
134
GetConfigService(void)135 struct HdfRemoteService *GetConfigService(void)
136 {
137 struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();
138 if (serviceMgr == NULL) {
139 HDF_LOGE("%{public}s: HDIServiceManager not found!", __func__);
140 return NULL;
141 }
142
143 struct HdfRemoteService *remote = serviceMgr->GetService(serviceMgr, "codec_capability_config_service");
144 if (remote == NULL) {
145 HDF_LOGE("%{public}s: HdfRemoteService not found!", __func__);
146 return NULL;
147 }
148 if (!HdfRemoteServiceSetInterfaceDesc(remote, "ohos.hdi.codec_service")) {
149 HDF_LOGE("%{public}s: failed to init interface desc", __func__);
150 HdfRemoteServiceRecycle(remote);
151 return NULL;
152 }
153
154 return remote;
155 }
156
ReleaseSbuf(struct HdfSBuf * data,struct HdfSBuf * reply)157 static void ReleaseSbuf(struct HdfSBuf *data, struct HdfSBuf *reply)
158 {
159 if (data != NULL) {
160 HdfSbufRecycle(data);
161 }
162 if (reply != NULL) {
163 HdfSbufRecycle(reply);
164 }
165 }
166
EnumrateCapability(struct HdfRemoteService * remote,int index,CodecCapbility * cap)167 int32_t EnumrateCapability(struct HdfRemoteService *remote, int index, CodecCapbility *cap)
168 {
169 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
170 if (data == NULL) {
171 HDF_LOGE("%{public}s: Failed to obtain", __func__);
172 return HDF_FAILURE;
173 }
174 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
175 if (reply == NULL) {
176 HDF_LOGE("%{public}s: Failed to obtain reply", __func__);
177 HdfSbufRecycle(data);
178 return HDF_FAILURE;
179 }
180 if (!HdfRemoteServiceWriteInterfaceToken(remote, data)) {
181 HDF_LOGE("write interface token failed");
182 ReleaseSbuf(data, reply);
183 return HDF_FAILURE;
184 }
185 if (!HdfSbufWriteUint32(data, index)) {
186 HDF_LOGE("%{public}s: write input index failed!", __func__);
187 ReleaseSbuf(data, reply);
188 return HDF_FAILURE;
189 }
190
191 if (remote->dispatcher->Dispatch(remote, CODEC_CONFIG_CMD_ENUMERATE_CAP, data, reply) != HDF_SUCCESS) {
192 HDF_LOGE("%{public}s: dispatch request failed!", __func__);
193 ReleaseSbuf(data, reply);
194 return HDF_FAILURE;
195 }
196
197 if (DeserializeCodecCapability(reply, cap) != HDF_SUCCESS) {
198 HDF_LOGE("%{public}s: DeserializeCodecCapbility failed!", __func__);
199 ReleaseSbuf(data, reply);
200 return HDF_FAILURE;
201 }
202
203 ReleaseSbuf(data, reply);
204 return HDF_SUCCESS;
205 }
206
GetCapability(struct HdfRemoteService * remote,AvCodecMime mime,CodecType type,uint32_t flags,CodecCapbility * cap)207 int32_t GetCapability(struct HdfRemoteService *remote,
208 AvCodecMime mime, CodecType type, uint32_t flags, CodecCapbility *cap)
209 {
210 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
211 if (data == NULL) {
212 HDF_LOGE("%{public}s: Failed to obtain", __func__);
213 return HDF_FAILURE;
214 }
215 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
216 if (reply == NULL) {
217 HDF_LOGE("%{public}s: Failed to obtain reply", __func__);
218 HdfSbufRecycle(data);
219 return HDF_FAILURE;
220 }
221 if (!HdfRemoteServiceWriteInterfaceToken(remote, data)) {
222 HDF_LOGE("write interface token failed");
223 ReleaseSbuf(data, reply);
224 return HDF_FAILURE;
225 }
226 if (!HdfSbufWriteUint32(data, (uint32_t)mime)) {
227 HDF_LOGE("%{public}s: write input mime failed!", __func__);
228 ReleaseSbuf(data, reply);
229 return HDF_FAILURE;
230 }
231
232 if (!HdfSbufWriteUint32(data, (uint32_t)type)) {
233 HDF_LOGE("%{public}s: write input type failed!", __func__);
234 ReleaseSbuf(data, reply);
235 return HDF_FAILURE;
236 }
237
238 if (!HdfSbufWriteUint32(data, flags)) {
239 HDF_LOGE("%{public}s: write input flags failed!", __func__);
240 ReleaseSbuf(data, reply);
241 return HDF_FAILURE;
242 }
243
244 if (remote->dispatcher->Dispatch(remote, CODEC_CONFIG_CMD_GET_CAP, data, reply) != HDF_SUCCESS) {
245 HDF_LOGE("%{public}s: dispatch request failed!", __func__);
246 ReleaseSbuf(data, reply);
247 return HDF_FAILURE;
248 }
249
250 if (DeserializeCodecCapability(reply, cap) != HDF_SUCCESS) {
251 HDF_LOGE("%{public}s: DeserializeCodecCapbility failed!", __func__);
252 ReleaseSbuf(data, reply);
253 return HDF_FAILURE;
254 }
255
256 ReleaseSbuf(data, reply);
257 return HDF_SUCCESS;
258 }
259
260 #ifdef __cplusplus
261 }
262 #endif /* __cplusplus */
263