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