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