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