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
16 #include "codec_callback_stub.h"
17 #include <hdf_log.h>
18 #include <osal_mem.h>
19 #include "stub_msgproc.h"
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif /* __cplusplus */
24
25 #define HDF_LOG_TAG codec_callback_stub
26
SerCodecOnEvent(struct ICodecCallback * serviceImpl,struct HdfSBuf * data,struct HdfSBuf * reply)27 static int32_t SerCodecOnEvent(struct ICodecCallback *serviceImpl, struct HdfSBuf *data, struct HdfSBuf *reply)
28 {
29 int32_t ret;
30 uint64_t userData = 0;
31 EventType event = 0;
32 uint32_t length = 0;
33 int32_t *eventData = NULL;
34
35 if (!HdfSbufReadUint64(data, &userData)) {
36 HDF_LOGE("%{public}s: read comp data failed!", __func__);
37 return HDF_ERR_INVALID_PARAM;
38 }
39 if (!HdfSbufReadUint32(data, (uint32_t *)&event)) {
40 HDF_LOGE("%{public}s: read event data failed!", __func__);
41 return HDF_ERR_INVALID_PARAM;
42 }
43 if (!HdfSbufReadUint32(data, &length)) {
44 HDF_LOGE("%{public}s: read data1 data failed!", __func__);
45 return HDF_ERR_INVALID_PARAM;
46 }
47 if (length > 0) {
48 eventData = (int32_t *)OsalMemCalloc(length);
49 if (eventData == NULL) {
50 HDF_LOGE("%{public}s: OsalMemAlloc eventData failed!", __func__);
51 return HDF_ERR_INVALID_PARAM;
52 }
53 for (uint32_t i = 0; i < length; i++) {
54 if (!HdfSbufReadInt32(data, &eventData[i])) {
55 HDF_LOGE("%{public}s: read eventData failed!", __func__);
56 OsalMemFree(eventData);
57 return HDF_ERR_INVALID_PARAM;
58 }
59 }
60 }
61 ret = serviceImpl->callback.OnEvent((UINTPTR)userData, event, length, eventData);
62 if (ret != HDF_SUCCESS) {
63 HDF_LOGE("%{public}s: call OnEvent fuc failed!", __func__);
64 OsalMemFree(eventData);
65 return ret;
66 }
67 OsalMemFree(eventData);
68 return ret;
69 }
70
SerCodecInputBufferAvailable(struct ICodecCallback * serviceImpl,struct HdfSBuf * data,struct HdfSBuf * reply)71 static int32_t SerCodecInputBufferAvailable(struct ICodecCallback *serviceImpl,
72 struct HdfSBuf *data, struct HdfSBuf *reply)
73 {
74 int32_t ret = HDF_FAILURE;
75 uint32_t bufCnt = 0;
76 uint64_t userData = 0;
77 CodecBuffer *inBuf = NULL;
78 int32_t acquireFd;
79
80 if (!HdfSbufReadUint64(data, &userData)) {
81 HDF_LOGE("%{public}s: read userData failed!", __func__);
82 return HDF_ERR_INVALID_PARAM;
83 }
84 if (!HdfSbufReadUint32(data, &bufCnt)) {
85 HDF_LOGE("%{public}s: read bufferCnt failed!", __func__);
86 return HDF_FAILURE;
87 }
88 if (bufCnt == 0) {
89 HDF_LOGE("%{public}s: invalid bufferCnt!", __func__);
90 return HDF_ERR_INVALID_PARAM;
91 }
92 inBuf = (CodecBuffer *)OsalMemAlloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * bufCnt);
93 if (inBuf == NULL) {
94 HDF_LOGE("%{public}s: OsalMemAlloc inBuf failed!", __func__);
95 return HDF_ERR_MALLOC_FAIL;
96 }
97 inBuf->bufferCnt = bufCnt;
98 if (CodecSerParseCodecBuffer(data, inBuf)) {
99 HDF_LOGE("%{public}s: read inBuf failed!", __func__);
100 OsalMemFree(inBuf);
101 return HDF_ERR_INVALID_PARAM;
102 }
103 ret = serviceImpl->callback.InputBufferAvailable((UINTPTR)userData, inBuf, &acquireFd);
104 if (ret != HDF_SUCCESS) {
105 HDF_LOGE("%{public}s: call InputBufferAvailable fuc failed!", __func__);
106 OsalMemFree(inBuf);
107 return ret;
108 }
109 OsalMemFree(inBuf);
110 return ret;
111 }
112
SerCodecOutputBufferAvailable(struct ICodecCallback * serviceImpl,struct HdfSBuf * data,struct HdfSBuf * reply)113 static int32_t SerCodecOutputBufferAvailable(struct ICodecCallback *serviceImpl,
114 struct HdfSBuf *data, struct HdfSBuf *reply)
115 {
116 int32_t ret = HDF_FAILURE;
117 uint32_t bufCnt = 0;
118 uint64_t userData = 0;
119 CodecBuffer *outBuf = NULL;
120 int32_t acquireFd;
121
122 if (!HdfSbufReadUint64(data, &userData)) {
123 HDF_LOGE("%{public}s: read userData failed!", __func__);
124 return HDF_ERR_INVALID_PARAM;
125 }
126 if (!HdfSbufReadUint32(data, (uint32_t *)&bufCnt)) {
127 HDF_LOGE("%{public}s: read bufferCnt failed!", __func__);
128 return HDF_ERR_INVALID_PARAM;
129 }
130 if (bufCnt == 0) {
131 HDF_LOGE("%{public}s: invalid bufferCnt!", __func__);
132 return HDF_ERR_INVALID_PARAM;
133 }
134 outBuf = (CodecBuffer *)OsalMemAlloc(sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * bufCnt);
135 if (outBuf == NULL) {
136 HDF_LOGE("%{public}s: OsalMemAlloc outBuf failed!", __func__);
137 return HDF_ERR_MALLOC_FAIL;
138 }
139 outBuf->bufferCnt = bufCnt;
140 if (CodecSerParseCodecBuffer(data, outBuf)) {
141 HDF_LOGE("%{public}s: read outBuf failed!", __func__);
142 OsalMemFree(outBuf);
143 return HDF_ERR_INVALID_PARAM;
144 }
145 ret = serviceImpl->callback.OutputBufferAvailable((UINTPTR)userData, outBuf, &acquireFd);
146 if (ret != HDF_SUCCESS) {
147 HDF_LOGE("%{public}s: call OutputBufferAvailable fuc failed!", __func__);
148 OsalMemFree(outBuf);
149 return ret;
150 }
151 OsalMemFree(outBuf);
152 return ret;
153 }
154
CodecCallbackServiceOnRemoteRequest(struct HdfRemoteService * service,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)155 static int32_t CodecCallbackServiceOnRemoteRequest(struct HdfRemoteService *service, int cmdId,
156 struct HdfSBuf *data, struct HdfSBuf *reply)
157 {
158 struct ICodecCallback *serviceImpl = (struct ICodecCallback *)service;
159 if (serviceImpl == NULL || serviceImpl->remote == NULL) {
160 HDF_LOGE("%{public}s: invalid service object", __func__);
161 return HDF_ERR_INVALID_OBJECT;
162 }
163 if (!HdfRemoteServiceCheckInterfaceToken(serviceImpl->remote, data)) {
164 HDF_LOGE("%{public}s: interface token check failed", __func__);
165 return HDF_ERR_INVALID_PARAM;
166 }
167 switch (cmdId) {
168 case CMD_CODEC_ON_EVENT:
169 return SerCodecOnEvent(serviceImpl, data, reply);
170 case CMD_CODEC_INPUT_BUFFER_AVAILABLE:
171 return SerCodecInputBufferAvailable(serviceImpl, data, reply);
172 case CMD_CODEC_OUTPUT_BUFFER_AVAILABLE:
173 return SerCodecOutputBufferAvailable(serviceImpl, data, reply);
174 default: {
175 HDF_LOGE("%{public}s: not support cmd %{public}d", __func__, cmdId);
176 return HDF_ERR_INVALID_PARAM;
177 }
178 }
179 }
180
CodecCallbackStubObtain(const CodecCallback * callback)181 struct CodecCallbackStub *CodecCallbackStubObtain(const CodecCallback *callback)
182 {
183 if (callback == NULL) {
184 HDF_LOGE("%{public}s: callback is null!", __func__);
185 return NULL;
186 }
187 struct CodecCallbackStub *stub = (struct CodecCallbackStub *)OsalMemAlloc(sizeof(struct CodecCallbackStub));
188 if (stub == NULL) {
189 HDF_LOGE("%{public}s: OsalMemAlloc CodecCallbackStub obj failed!", __func__);
190 return NULL;
191 }
192 stub->dispatcher.Dispatch = CodecCallbackServiceOnRemoteRequest;
193 stub->service.remote = HdfRemoteServiceObtain((struct HdfObject *)(&stub->service), &(stub->dispatcher));
194 if (stub->service.remote == NULL) {
195 HDF_LOGE("%{public}s: stub->service.remote is null", __func__);
196 OsalMemFree(stub);
197 return NULL;
198 }
199 if (!HdfRemoteServiceSetInterfaceDesc(stub->service.remote, CODEC_CALLBACK_DESC)) {
200 HDF_LOGE("%{public}s: set interface token failed!", __func__);
201 HdfRemoteServiceRecycle(stub->service.remote);
202 OsalMemFree(stub);
203 return NULL;
204 }
205
206 stub->service.callback = *callback;
207 return stub;
208 }
209
CodecCallbackStubRelease(struct CodecCallbackStub * stub)210 void CodecCallbackStubRelease(struct CodecCallbackStub *stub)
211 {
212 if (stub == NULL) {
213 return;
214 }
215 HdfRemoteServiceRecycle(stub->service.remote);
216 OsalMemFree(stub);
217 }
218
219 #ifdef __cplusplus
220 }
221 #endif /* __cplusplus */
222