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