1 /*
2 * Copyright (c) 2021-2023 Huawei Device 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 #include "codec_callback_proxy.h"
16 #include <hdf_log.h>
17 #include <hdf_remote_service.h>
18 #include <osal_mem.h>
19 #include <servmgr_hdi.h>
20 #include "proxy_msgproc.h"
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif /* __cplusplus */
25
26 #define HDF_LOG_TAG codec_callback_proxy
27
CodecCallbackProxyCall(struct ICodecCallbackProxy * self,int32_t id,struct HdfSBuf * data,struct HdfSBuf * reply)28 static int32_t CodecCallbackProxyCall(struct ICodecCallbackProxy *self, int32_t id,
29 struct HdfSBuf *data, struct HdfSBuf *reply)
30 {
31 if (self->remote == NULL || self->remote->dispatcher == NULL ||
32 self->remote->dispatcher->Dispatch == NULL) {
33 HDF_LOGE("%{public}s: obj is null", __func__);
34 return HDF_ERR_INVALID_OBJECT;
35 }
36 return self->remote->dispatcher->Dispatch(self->remote, id, data, reply);
37 }
38
CodecCallbackProxyReqSBuf(struct HdfSBuf ** data,struct HdfSBuf ** reply)39 static int32_t CodecCallbackProxyReqSBuf(struct HdfSBuf **data, struct HdfSBuf **reply)
40 {
41 *data = HdfSbufTypedObtain(SBUF_IPC);
42 if (*data == NULL) {
43 HDF_LOGE("%{public}s: Failed to obtain", __func__);
44 return HDF_ERR_MALLOC_FAIL;
45 }
46 *reply = HdfSbufTypedObtain(SBUF_IPC);
47 if (*reply == NULL) {
48 HDF_LOGE("%{public}s: Failed to obtain reply", __func__);
49 HdfSbufRecycle(*data);
50 return HDF_ERR_MALLOC_FAIL;
51 }
52 return HDF_SUCCESS;
53 }
54
CodecCallbackProxySBufRecycle(struct HdfSBuf * data,struct HdfSBuf * reply)55 static void CodecCallbackProxySBufRecycle(struct HdfSBuf *data, struct HdfSBuf *reply)
56 {
57 if (data != NULL) {
58 HdfSbufRecycle(data);
59 }
60 if (reply != NULL) {
61 HdfSbufRecycle(reply);
62 }
63 return;
64 }
65
CodecCallbackProxyOnEvent(struct ICodecCallbackProxy * self,UINTPTR userData,EventType event,uint32_t length,int32_t eventData[])66 static int CodecCallbackProxyOnEvent(struct ICodecCallbackProxy *self, UINTPTR userData,
67 EventType event, uint32_t length, int32_t eventData[])
68 {
69 int32_t ret;
70 struct HdfSBuf *data = NULL;
71 struct HdfSBuf *reply = NULL;
72 if (self == NULL) {
73 HDF_LOGE("%{public}s: self is NULL!", __func__);
74 return HDF_ERR_INVALID_PARAM;
75 }
76 if (CodecCallbackProxyReqSBuf(&data, &reply) != HDF_SUCCESS) {
77 HDF_LOGE("%{public}s: HdfSubf malloc failed!", __func__);
78 return HDF_ERR_INVALID_PARAM;
79 }
80 if (!HdfRemoteServiceWriteInterfaceToken(self->remote, data)) {
81 HDF_LOGE("write interface token failed");
82 CodecCallbackProxySBufRecycle(data, reply);
83 return HDF_ERR_INVALID_PARAM;
84 }
85 if (!HdfSbufWriteUint64(data, (uint64_t)userData)) {
86 HDF_LOGE("%{public}s: write input userData failed!", __func__);
87 CodecCallbackProxySBufRecycle(data, reply);
88 return HDF_ERR_INVALID_PARAM;
89 }
90 if (!HdfSbufWriteUint32(data, (uint32_t)event)) {
91 HDF_LOGE("%{public}s: write input event failed!", __func__);
92 CodecCallbackProxySBufRecycle(data, reply);
93 return HDF_ERR_INVALID_PARAM;
94 }
95 if (!HdfSbufWriteUint32(data, (uint32_t)length)) {
96 HDF_LOGE("%{public}s: write input length failed!", __func__);
97 CodecCallbackProxySBufRecycle(data, reply);
98 return HDF_ERR_INVALID_PARAM;
99 }
100 for (uint32_t i = 0; i < length; i++) {
101 if (!HdfSbufWriteInt32(data, eventData[i])) {
102 HDF_LOGE("%{public}s: write eventData failed!", __func__);
103 CodecCallbackProxySBufRecycle(data, reply);
104 return HDF_ERR_INVALID_PARAM;
105 }
106 }
107 ret = CodecCallbackProxyCall(self, CMD_CODEC_ON_EVENT, data, reply);
108 if (ret != HDF_SUCCESS) {
109 HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret);
110 CodecCallbackProxySBufRecycle(data, reply);
111 return ret;
112 }
113 CodecCallbackProxySBufRecycle(data, reply);
114 return ret;
115 }
116
CodecCallbackProxyInputBufferAvailable(struct ICodecCallbackProxy * self,UINTPTR userData,CodecBuffer * inBuf,int32_t * acquireFd)117 static int CodecCallbackProxyInputBufferAvailable(struct ICodecCallbackProxy *self, UINTPTR userData,
118 CodecBuffer *inBuf, int32_t *acquireFd)
119 {
120 int32_t ret;
121 struct HdfSBuf *data = NULL;
122 struct HdfSBuf *reply = NULL;
123 if (inBuf == NULL || self == NULL) {
124 HDF_LOGE("%{public}s: self or inBuf is NULL!", __func__);
125 return HDF_ERR_INVALID_PARAM;
126 }
127 if (CodecCallbackProxyReqSBuf(&data, &reply) != HDF_SUCCESS) {
128 HDF_LOGE("%{public}s: HdfSubf malloc failed!", __func__);
129 return HDF_ERR_INVALID_PARAM;
130 }
131 if (!HdfRemoteServiceWriteInterfaceToken(self->remote, data)) {
132 HDF_LOGE("write interface token failed");
133 CodecCallbackProxySBufRecycle(data, reply);
134 return HDF_ERR_INVALID_PARAM;
135 }
136 if (!HdfSbufWriteUint64(data, (uint64_t)userData)) {
137 HDF_LOGE("%{public}s: write input userData failed!", __func__);
138 CodecCallbackProxySBufRecycle(data, reply);
139 return HDF_ERR_INVALID_PARAM;
140 }
141 if (CodecProxyPackCodecBuffer(data, inBuf)) {
142 HDF_LOGE("%{public}s: write input buffer failed!", __func__);
143 CodecCallbackProxySBufRecycle(data, reply);
144 return HDF_ERR_INVALID_PARAM;
145 }
146 ret = CodecCallbackProxyCall(self, CMD_CODEC_INPUT_BUFFER_AVAILABLE, data, reply);
147 if (ret != HDF_SUCCESS) {
148 HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret);
149 CodecCallbackProxySBufRecycle(data, reply);
150 return ret;
151 }
152 CodecCallbackProxySBufRecycle(data, reply);
153 return ret;
154 }
155
CodecCallbackProxyOutputBufferAvailable(struct ICodecCallbackProxy * self,UINTPTR userData,CodecBuffer * outBuf,int32_t * acquireFd)156 static int CodecCallbackProxyOutputBufferAvailable(struct ICodecCallbackProxy *self, UINTPTR userData,
157 CodecBuffer *outBuf, int32_t *acquireFd)
158 {
159 int32_t ret;
160 struct HdfSBuf *data = NULL;
161 struct HdfSBuf *reply = NULL;
162 if (outBuf == NULL || self == NULL) {
163 HDF_LOGE("%{public}s: self or outBuf is NULL!", __func__);
164 return HDF_ERR_INVALID_PARAM;
165 }
166 if (CodecCallbackProxyReqSBuf(&data, &reply) != HDF_SUCCESS) {
167 HDF_LOGE("%{public}s: HdfSubf malloc failed!", __func__);
168 return HDF_ERR_INVALID_PARAM;
169 }
170 if (!HdfRemoteServiceWriteInterfaceToken(self->remote, data)) {
171 HDF_LOGE("write interface token failed");
172 CodecCallbackProxySBufRecycle(data, reply);
173 return HDF_ERR_INVALID_PARAM;
174 }
175 if (!HdfSbufWriteUint64(data, (uint64_t)userData)) {
176 HDF_LOGE("%{public}s: write input userData failed!", __func__);
177 CodecCallbackProxySBufRecycle(data, reply);
178 return HDF_ERR_INVALID_PARAM;
179 }
180 if (CodecProxyPackCodecBuffer(data, outBuf)) {
181 HDF_LOGE("%{public}s: write output buffer failed!", __func__);
182 CodecCallbackProxySBufRecycle(data, reply);
183 return HDF_ERR_INVALID_PARAM;
184 }
185 ret = CodecCallbackProxyCall(self, CMD_CODEC_OUTPUT_BUFFER_AVAILABLE, data, reply);
186 if (ret != HDF_SUCCESS) {
187 HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret);
188 CodecCallbackProxySBufRecycle(data, reply);
189 return ret;
190 }
191 CodecCallbackProxySBufRecycle(data, reply);
192 return ret;
193 }
194
CodecCallbackProxyConstruct(struct ICodecCallbackProxy * callback)195 static void CodecCallbackProxyConstruct(struct ICodecCallbackProxy *callback)
196 {
197 callback->OnEvent = CodecCallbackProxyOnEvent;
198 callback->InputBufferAvailable = CodecCallbackProxyInputBufferAvailable;
199 callback->OutputBufferAvailable = CodecCallbackProxyOutputBufferAvailable;
200 }
201
CodecCallbackProxyObtain(struct HdfRemoteService * remote)202 struct ICodecCallbackProxy *CodecCallbackProxyObtain(struct HdfRemoteService *remote)
203 {
204 if (remote == NULL) {
205 HDF_LOGE("%{public}s: remote is null", __func__);
206 return NULL;
207 }
208
209 if (!HdfRemoteServiceSetInterfaceDesc(remote, CODEC_CALLBACK_DESC)) {
210 HDF_LOGE("%{public}s: set interface token failed!", __func__);
211 return NULL;
212 }
213
214 struct ICodecCallbackProxy *callback =
215 (struct ICodecCallbackProxy *)OsalMemAlloc(sizeof(struct ICodecCallbackProxy));
216 if (callback == NULL) {
217 HDF_LOGE("%{public}s: OsalMemAlloc failed!", __func__);
218 return NULL;
219 }
220 callback->remote = remote;
221 CodecCallbackProxyConstruct(callback);
222 return callback;
223 }
224
CodecProxyCallbackRelease(struct ICodecCallbackProxy * callback)225 void CodecProxyCallbackRelease(struct ICodecCallbackProxy *callback)
226 {
227 if (callback == NULL) {
228 return;
229 }
230 if (callback->remote != NULL) {
231 HdfRemoteServiceRecycle(callback->remote);
232 }
233 OsalMemFree(callback);
234 }
235
236 #ifdef __cplusplus
237 }
238 #endif /* __cplusplus */
239