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