• 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 <hdf_remote_service.h>
18 #include <osal_mem.h>
19 #include <servmgr_hdi.h>
20 #include "codec_callback_if.h"
21 #include "codec_internal.h"
22 #include "codec_types.h"
23 
24 #define HDF_LOG_TAG codec_hdi_cb_client
25 
26 struct CodecCallbackTypeProxy {
27     struct CodecCallbackType instance;
28     struct HdfRemoteService *remote;
29 };
30 
ReleaseSbuf(struct HdfSBuf * data,struct HdfSBuf * reply)31 static void ReleaseSbuf(struct HdfSBuf *data, struct HdfSBuf *reply)
32 {
33     if (data != NULL) {
34         HdfSbufRecycle(data);
35     }
36     if (reply != NULL) {
37         HdfSbufRecycle(reply);
38     }
39 }
40 
CodecCallbackTypeProxyCall(struct CodecCallbackType * self,int32_t id,struct HdfSBuf * data,struct HdfSBuf * reply)41 static int32_t CodecCallbackTypeProxyCall(struct CodecCallbackType *self, int32_t id, struct HdfSBuf *data,
42     struct HdfSBuf *reply)
43 {
44     if (self->remote == NULL ||
45         self->remote->dispatcher == NULL ||
46         self->remote->dispatcher->Dispatch == NULL) {
47         HDF_LOGE("%{public}s: obj is null", __func__);
48         return HDF_ERR_INVALID_OBJECT;
49     }
50     return self->remote->dispatcher->Dispatch(self->remote, id, data, reply);
51 }
52 
WriteArray(struct HdfSBuf * data,int8_t * array,uint32_t arrayLen)53 static int32_t WriteArray(struct HdfSBuf *data, int8_t *array, uint32_t arrayLen)
54 {
55     if (!HdfSbufWriteUint32(data, arrayLen)) {
56         HDF_LOGE("%{public}s: write appData failed!", __func__);
57         return HDF_ERR_INVALID_PARAM;
58     }
59     for (uint32_t i = 0; i < arrayLen; i++) {
60         if (!HdfSbufWriteInt8(data, array[i])) {
61             HDF_LOGE("%{public}s: write array[i] failed!", __func__);
62             return HDF_ERR_INVALID_PARAM;
63         }
64     }
65     return HDF_SUCCESS;
66 }
67 
WriteEventData(struct HdfSBuf * data,enum OMX_EVENTTYPE eEvent,uint32_t data1,uint32_t data2)68 static int32_t WriteEventData(struct HdfSBuf *data, enum OMX_EVENTTYPE eEvent, uint32_t data1, uint32_t data2)
69 {
70     if (!HdfSbufWriteUint32(data, (uint32_t)eEvent)) {
71         HDF_LOGE("%{public}s: write eEvent failed!", __func__);
72         return HDF_ERR_INVALID_PARAM;
73     }
74 
75     if (!HdfSbufWriteUint32(data, data1)) {
76         HDF_LOGE("%{public}s: write data1 failed!", __func__);
77         return HDF_ERR_INVALID_PARAM;
78     }
79 
80     if (!HdfSbufWriteUint32(data, data2)) {
81         HDF_LOGE("%{public}s: write data2 failed!", __func__);
82         return HDF_ERR_INVALID_PARAM;
83     }
84 
85     return HDF_SUCCESS;
86 }
87 
CodecCallbackTypeProxyEventHandler(struct CodecCallbackType * self,int8_t * appData,uint32_t appDataLen,enum OMX_EVENTTYPE eEvent,uint32_t data1,uint32_t data2,int8_t * eventData,uint32_t eventDataLen)88 static int32_t CodecCallbackTypeProxyEventHandler(struct CodecCallbackType *self,
89     int8_t *appData, uint32_t appDataLen, enum OMX_EVENTTYPE eEvent, uint32_t data1,
90     uint32_t data2, int8_t *eventData, uint32_t eventDataLen)
91 {
92     int32_t ret;
93 
94     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
95     struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
96     if (data == NULL || reply == NULL) {
97         HDF_LOGE("%{public}s: HdfSubf malloc failed!", __func__);
98         ReleaseSbuf(data, reply);
99         return HDF_ERR_MALLOC_FAIL;
100     }
101 
102     if (!HdfRemoteServiceWriteInterfaceToken(self->remote, data)) {
103         HDF_LOGE("%{public}s: write interface token failed", __func__);
104         ReleaseSbuf(data, reply);
105         return HDF_FAILURE;
106     }
107 
108     ret = WriteArray(data, appData, appDataLen);
109     if (ret != HDF_SUCCESS) {
110         HDF_LOGE("%{public}s: write appData failed!", __func__);
111         ReleaseSbuf(data, reply);
112         return ret;
113     }
114 
115     ret = WriteEventData(data, eEvent, data1, data2);
116     if (ret != HDF_SUCCESS) {
117         ReleaseSbuf(data, reply);
118         return ret;
119     }
120 
121     ret = WriteArray(data, eventData, eventDataLen);
122     if (ret != HDF_SUCCESS) {
123         HDF_LOGE("%{public}s: write eventData failed!", __func__);
124         ReleaseSbuf(data, reply);
125         return ret;
126     }
127 
128     for (uint32_t i = 0; i < eventDataLen; i++) {
129         if (!HdfSbufWriteInt8(data, eventData[i])) {
130             HDF_LOGE("%{public}s: write eventData[i] failed!", __func__);
131             ReleaseSbuf(data, reply);
132             return HDF_ERR_INVALID_PARAM;
133         }
134     }
135 
136     ret = CodecCallbackTypeProxyCall(self, CMD_EVENT_HANDLER, data, reply);
137     if (ret != HDF_SUCCESS) {
138         HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret);
139         ReleaseSbuf(data, reply);
140         return ret;
141     }
142 
143     ReleaseSbuf(data, reply);
144     return ret;
145 }
146 
CodecCallbackTypeProxyEmptyBufferDone(struct CodecCallbackType * self,int8_t * appData,uint32_t appDataLen,const struct OmxCodecBuffer * buffer)147 static int32_t CodecCallbackTypeProxyEmptyBufferDone(struct CodecCallbackType *self,
148     int8_t *appData, uint32_t appDataLen, const struct OmxCodecBuffer *buffer)
149 {
150     int32_t ret;
151 
152     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
153     struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
154     if (data == NULL || reply == NULL) {
155         HDF_LOGE("%{public}s: HdfSubf malloc failed!", __func__);
156         ReleaseSbuf(data, reply);
157         return HDF_ERR_MALLOC_FAIL;
158     }
159 
160     if (!HdfRemoteServiceWriteInterfaceToken(self->remote, data)) {
161         HDF_LOGE("%{public}s: write interface token failed", __func__);
162         ReleaseSbuf(data, reply);
163         return HDF_FAILURE;
164     }
165 
166     if (!HdfSbufWriteUint32(data, appDataLen)) {
167         HDF_LOGE("%{public}s: write appData failed!", __func__);
168         ReleaseSbuf(data, reply);
169         return HDF_ERR_INVALID_PARAM;
170     }
171     for (uint32_t i = 0; i < appDataLen; i++) {
172         if (!HdfSbufWriteInt8(data, appData[i])) {
173             HDF_LOGE("%{public}s: write appData[i] failed!", __func__);
174             ReleaseSbuf(data, reply);
175             return HDF_ERR_INVALID_PARAM;
176         }
177     }
178 
179     if (!OmxCodecBufferBlockMarshalling(data, buffer)) {
180         HDF_LOGE("%{public}s: write buffer failed!", __func__);
181         ReleaseSbuf(data, reply);
182         return HDF_ERR_INVALID_PARAM;
183     }
184 
185     ret = CodecCallbackTypeProxyCall(self, CMD_EMPTY_BUFFER_DONE, data, reply);
186     if (ret != HDF_SUCCESS) {
187         HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret);
188         ReleaseSbuf(data, reply);
189         return ret;
190     }
191 
192     ReleaseSbuf(data, reply);
193     return ret;
194 }
195 
CodecCallbackTypeProxyFillBufferDone(struct CodecCallbackType * self,int8_t * appData,uint32_t appDataLen,struct OmxCodecBuffer * buffer)196 static int32_t CodecCallbackTypeProxyFillBufferDone(struct CodecCallbackType *self,
197     int8_t* appData, uint32_t appDataLen, struct OmxCodecBuffer* buffer)
198 {
199     int32_t ret;
200 
201     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
202     struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC);
203     if (data == NULL || reply == NULL) {
204         HDF_LOGE("%{public}s: HdfSubf malloc failed!", __func__);
205         ReleaseSbuf(data, reply);
206         return HDF_ERR_MALLOC_FAIL;
207     }
208 
209     if (!HdfRemoteServiceWriteInterfaceToken(self->remote, data)) {
210         HDF_LOGE("%{public}s: write interface token failed", __func__);
211         ReleaseSbuf(data, reply);
212         return HDF_FAILURE;
213     }
214 
215     if (!HdfSbufWriteUint32(data, appDataLen)) {
216         HDF_LOGE("%{public}s: write appData failed!", __func__);
217         ReleaseSbuf(data, reply);
218         return HDF_ERR_INVALID_PARAM;
219     }
220     for (uint32_t i = 0; i < appDataLen; i++) {
221         if (!HdfSbufWriteInt8(data, appData[i])) {
222             HDF_LOGE("%{public}s: write appData[i] failed!", __func__);
223             ReleaseSbuf(data, reply);
224             return HDF_ERR_INVALID_PARAM;
225         }
226     }
227 
228     if (!OmxCodecBufferBlockMarshalling(data, buffer)) {
229         HDF_LOGE("%{public}s: write buffer failed!", __func__);
230         ReleaseSbuf(data, reply);
231         return HDF_ERR_INVALID_PARAM;
232     }
233 
234     ret = CodecCallbackTypeProxyCall(self, CMD_FILL_BUFFER_DONE, data, reply);
235     if (ret != HDF_SUCCESS) {
236         HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret);
237         ReleaseSbuf(data, reply);
238         return ret;
239     }
240 
241     ReleaseSbuf(data, reply);
242     return ret;
243 }
244 
CodecCallbackTypeProxyConstruct(struct CodecCallbackType * instance)245 static void CodecCallbackTypeProxyConstruct(struct CodecCallbackType *instance)
246 {
247     instance->EventHandler = CodecCallbackTypeProxyEventHandler;
248     instance->EmptyBufferDone = CodecCallbackTypeProxyEmptyBufferDone;
249     instance->FillBufferDone = CodecCallbackTypeProxyFillBufferDone;
250 }
251 
CodecCallbackTypeGet(struct HdfRemoteService * remote)252 struct CodecCallbackType *CodecCallbackTypeGet(struct HdfRemoteService *remote)
253 {
254     if (remote == NULL) {
255         HDF_LOGE("%{public}s: remote is null", __func__);
256         return NULL;
257     }
258 
259     struct CodecCallbackType *instance = (struct CodecCallbackType*)OsalMemAlloc(sizeof(struct CodecCallbackType));
260     if (instance == NULL) {
261         HDF_LOGE("%{public}s: OsalMemAlloc failed!", __func__);
262         return NULL;
263     }
264 
265     if (!HdfRemoteServiceSetInterfaceDesc(remote, "ohos.hdi.codec_service")) {
266         HDF_LOGE("%{public}s: failed to init interface desc", __func__);
267         return NULL;
268     }
269 
270     instance->remote = remote;
271     CodecCallbackTypeProxyConstruct(instance);
272     return instance;
273 }
274 
CodecCallbackTypeRelease(struct CodecCallbackType * instance)275 void CodecCallbackTypeRelease(struct CodecCallbackType *instance)
276 {
277     if (instance == NULL) {
278         HDF_LOGE("%{public}s: instance is null", __func__);
279         return;
280     }
281     OsalMemFree(instance);
282 }
283