1 /*
2 * Copyright (c) 2022-2023 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 <osal_mem.h>
17 #include <servmgr_hdi.h>
18 #include "codec_component_manager.h"
19 #include "codec_internal.h"
20 #include "codec_log_wrapper.h"
21 #include "codec_util.h"
22 #include "codec_types.h"
23
24 struct CodecComponentManagerProxy {
25 struct CodecComponentManager instance;
26 struct HdfRemoteService *remoteOmx;
27 };
28
29 static struct CodecComponentManagerProxy g_codecComponentManagerProxy = {
30 .instance = {
31 .GetComponentNum = NULL,
32 .GetComponentCapabilityList = NULL,
33 .CreateComponent = NULL,
34 .DestroyComponent = NULL,
35 .AsObject = NULL,
36 },
37 .remoteOmx = NULL,
38 };
39
ReleaseSbuf(struct HdfSBuf * data,struct HdfSBuf * reply)40 static void ReleaseSbuf(struct HdfSBuf *data, struct HdfSBuf *reply)
41 {
42 if (data != NULL) {
43 HdfSbufRecycle(data);
44 }
45 if (reply != NULL) {
46 HdfSbufRecycle(reply);
47 }
48 }
49
GetComponentNum()50 static int32_t GetComponentNum()
51 {
52 int32_t num = 0;
53 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
54 if (data == NULL) {
55 CODEC_LOGE("Failed to obtain");
56 return HDF_FAILURE;
57 }
58 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
59 if (reply == NULL) {
60 CODEC_LOGE("Failed to obtain reply");
61 HdfSbufRecycle(data);
62 return HDF_FAILURE;
63 }
64
65 if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) {
66 CODEC_LOGE("write interface token failed");
67 ReleaseSbuf(data, reply);
68 return HDF_FAILURE;
69 }
70
71 if (g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(
72 g_codecComponentManagerProxy.remoteOmx, CMD_CODEC_GET_COMPONENT_NUM, data, reply) != HDF_SUCCESS) {
73 CODEC_LOGE("dispatch request failed!");
74 ReleaseSbuf(data, reply);
75 return HDF_FAILURE;
76 }
77
78 if (!HdfSbufReadInt32(reply, &num)) {
79 CODEC_LOGE("read dataBlock->role failed!");
80 ReleaseSbuf(data, reply);
81 return HDF_FAILURE;
82 }
83
84 ReleaseSbuf(data, reply);
85 return num;
86 }
87
GetComponentCapabilityList(CodecCompCapability * capList,int32_t count)88 static int32_t GetComponentCapabilityList(CodecCompCapability *capList, int32_t count)
89 {
90 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
91 if (data == NULL) {
92 CODEC_LOGE("Failed to obtain");
93 return HDF_FAILURE;
94 }
95 int32_t num = GetComponentNum();
96 if (count <= 0 || count > num) {
97 CODEC_LOGE("Failed to get component");
98 HdfSbufRecycle(data);
99 return HDF_FAILURE;
100 }
101 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
102 if (reply == NULL) {
103 CODEC_LOGE("Failed to obtain reply");
104 HdfSbufRecycle(data);
105 return HDF_FAILURE;
106 }
107
108 if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) {
109 CODEC_LOGE("write interface token failed");
110 ReleaseSbuf(data, reply);
111 return HDF_FAILURE;
112 }
113
114 if (!HdfSbufWriteInt32(data, count)) {
115 CODEC_LOGE("write count failed!");
116 ReleaseSbuf(data, reply);
117 return HDF_ERR_INVALID_PARAM;
118 }
119
120 if (g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx,
121 CMD_CODEC_GET_COMPONENT_CAPABILITY_LIST, data,
122 reply) != HDF_SUCCESS) {
123 CODEC_LOGE("dispatch request failed!");
124 ReleaseSbuf(data, reply);
125 return HDF_FAILURE;
126 }
127
128 for (int32_t i = 0; i < count; i++) {
129 if (!CodecCompCapabilityBlockUnmarshalling(reply, &(capList)[i])) {
130 CODEC_LOGE("read capbility %{public}d from sbuf failed!", i);
131 ReleaseSbuf(data, reply);
132 return HDF_FAILURE;
133 }
134 }
135
136 ReleaseSbuf(data, reply);
137 return HDF_SUCCESS;
138 }
139
FillHdfSBufData(struct HdfSBuf * data,char * compName,int64_t appData,struct CodecCallbackType * callback)140 static int32_t FillHdfSBufData(struct HdfSBuf *data, char *compName, int64_t appData,
141 struct CodecCallbackType *callback)
142 {
143 if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) {
144 CODEC_LOGE("write interface token failed");
145 return HDF_FAILURE;
146 }
147 if (!HdfSbufWriteString(data, compName)) {
148 CODEC_LOGE("write paramName failed!");
149 return HDF_ERR_INVALID_PARAM;
150 }
151 if (!HdfSbufWriteInt64(data, appData)) {
152 CODEC_LOGE("write appData failed!");
153 return HDF_ERR_INVALID_PARAM;
154 }
155 if (HdfSbufWriteRemoteService(data, callback->remote) != 0) {
156 CODEC_LOGE("write callback failed!");
157 return HDF_ERR_INVALID_PARAM;
158 }
159 return HDF_SUCCESS;
160 }
161
CreateComponent(struct CodecComponentType ** component,uint32_t * componentId,char * compName,int64_t appData,struct CodecCallbackType * callback)162 static int32_t CreateComponent(struct CodecComponentType **component, uint32_t *componentId, char *compName,
163 int64_t appData, struct CodecCallbackType *callback)
164 {
165 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
166 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
167 if (data == NULL || reply == NULL || componentId == NULL) {
168 CODEC_LOGE("HdfSubf malloc failed!");
169 ReleaseSbuf(data, reply);
170 return HDF_ERR_MALLOC_FAIL;
171 }
172
173 int32_t ret = FillHdfSBufData(data, compName, appData, callback);
174 if (ret != HDF_SUCCESS) {
175 ReleaseSbuf(data, reply);
176 return ret;
177 }
178
179 ret = g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx,
180 CMD_CREATE_COMPONENT, data, reply);
181 if (ret != HDF_SUCCESS) {
182 CODEC_LOGE("call failed! error code is %{public}d", ret);
183 ReleaseSbuf(data, reply);
184 return ret;
185 }
186
187 struct HdfRemoteService *componentRemote = HdfSbufReadRemoteService(reply);
188 if (componentRemote == NULL) {
189 CODEC_LOGE("read componentRemote failed!");
190 ReleaseSbuf(data, reply);
191 return HDF_ERR_INVALID_PARAM;
192 }
193 if (!HdfSbufReadUint32(reply, componentId)) {
194 CODEC_LOGE("read componentId failed!");
195 ReleaseSbuf(data, reply);
196 return HDF_ERR_INVALID_PARAM;
197 }
198 *component = CodecComponentTypeGet(componentRemote);
199 ReleaseSbuf(data, reply);
200 #ifdef CONFIG_USE_JEMALLOC_DFX_INTF
201 ReleaseCodecCache();
202 #endif
203 return ret;
204 }
205
DestroyComponent(uint32_t componentId)206 static int32_t DestroyComponent(uint32_t componentId)
207 {
208 int32_t ret;
209
210 struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
211 struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
212 if (data == NULL || reply == NULL) {
213 CODEC_LOGE("HdfSubf malloc failed!");
214 ReleaseSbuf(data, reply);
215 return HDF_ERR_MALLOC_FAIL;
216 }
217
218 if (!HdfRemoteServiceWriteInterfaceToken(g_codecComponentManagerProxy.remoteOmx, data)) {
219 CODEC_LOGE("write interface token failed");
220 ReleaseSbuf(data, reply);
221 return HDF_FAILURE;
222 }
223
224 if (!HdfSbufWriteUint32(data, componentId)) {
225 CODEC_LOGE("write componentId failed!");
226 ReleaseSbuf(data, reply);
227 return HDF_ERR_INVALID_PARAM;
228 }
229
230 ret = g_codecComponentManagerProxy.remoteOmx->dispatcher->Dispatch(g_codecComponentManagerProxy.remoteOmx,
231 CMD_DESTROY_COMPONENT, data, reply);
232 if (ret != HDF_SUCCESS) {
233 CODEC_LOGE("call failed! error code is %{public}d", ret);
234 ReleaseSbuf(data, reply);
235 return ret;
236 }
237 ReleaseSbuf(data, reply);
238 #ifdef CONFIG_USE_JEMALLOC_DFX_INTF
239 ReleaseCodecCache();
240 #endif
241 return ret;
242 }
243
InitCodecComponentManagerProxy(void)244 static int32_t InitCodecComponentManagerProxy(void)
245 {
246 if (g_codecComponentManagerProxy.remoteOmx != NULL) {
247 return HDF_SUCCESS;
248 }
249
250 struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();
251 if (serviceMgr == NULL) {
252 CODEC_LOGE("HDIServiceManager not found!");
253 return HDF_FAILURE;
254 }
255
256 struct HdfRemoteService *remoteOmx = serviceMgr->GetService(serviceMgr, CODEC_HDI_OMX_SERVICE_NAME);
257 HDIServiceManagerRelease(serviceMgr);
258 if (remoteOmx == NULL) {
259 CODEC_LOGE("CodecComponentTypeService not found!");
260 return HDF_FAILURE;
261 }
262 if (!HdfRemoteServiceSetInterfaceDesc(remoteOmx, "ohos.hdi.codec_service")) {
263 CODEC_LOGE("failed to init interface desc");
264 HdfRemoteServiceRecycle(remoteOmx);
265 return HDF_FAILURE;
266 }
267
268 g_codecComponentManagerProxy.remoteOmx = remoteOmx;
269 g_codecComponentManagerProxy.instance.GetComponentNum = GetComponentNum;
270 g_codecComponentManagerProxy.instance.GetComponentCapabilityList = GetComponentCapabilityList;
271 g_codecComponentManagerProxy.instance.CreateComponent = CreateComponent;
272 g_codecComponentManagerProxy.instance.DestroyComponent = DestroyComponent;
273
274 return HDF_SUCCESS;
275 }
276
GetCodecComponentManager(void)277 struct CodecComponentManager *GetCodecComponentManager(void)
278 {
279 if (InitCodecComponentManagerProxy() != HDF_SUCCESS) {
280 return NULL;
281 }
282 return &g_codecComponentManagerProxy.instance;
283 }
284
CodecComponentManagerRelease(void)285 void CodecComponentManagerRelease(void)
286 {
287 if (g_codecComponentManagerProxy.remoteOmx != NULL) {
288 HdfRemoteServiceRecycle(g_codecComponentManagerProxy.remoteOmx);
289 g_codecComponentManagerProxy.remoteOmx = NULL;
290 }
291 }