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