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