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 #include "codec_types.h"
16 #include <buffer_handle.h>
17 #include <buffer_handle_utils.h>
18 #include <osal_mem.h>
19 #include <securec.h>
20 #include <unistd.h>
21 #include "codec_omx_ext.h"
22 #include "codec_log_wrapper.h"
23 
24 #define IF_FALSE_PRINT_MSG_RETURN_FALSE(cond, msg) \
25     if (!(cond)) { \
26         CODEC_LOGE(msg); \
27         return false; \
28     }
29 
BufferHandleMarshalling(struct HdfSBuf * data,BufferHandle * handle)30 static bool BufferHandleMarshalling(struct HdfSBuf *data, BufferHandle *handle)
31 {
32     if (handle == NULL) {
33         CODEC_LOGE("handle is NULL!");
34         return false;
35     }
36 
37     uint8_t validFd = 0;
38     if (!HdfSbufWriteUint32(data, handle->reserveFds) || !HdfSbufWriteUint32(data, handle->reserveInts) ||
39         !HdfSbufWriteInt32(data, handle->width) || !HdfSbufWriteInt32(data, handle->stride) ||
40         !HdfSbufWriteInt32(data, handle->height) || !HdfSbufWriteInt32(data, handle->size) ||
41         !HdfSbufWriteInt32(data, handle->format) || !HdfSbufWriteInt64(data, handle->usage) ||
42         !HdfSbufWriteUint64(data, handle->phyAddr)) {
43         CODEC_LOGE("write handle failed!");
44         return false;
45     }
46     if (handle->fd >= 0) {
47         validFd = 1;
48     }
49     if (!HdfSbufWriteUint8(data, validFd)) {
50         CODEC_LOGE("write uint8_t failed!");
51         return false;
52     }
53     if ((validFd != 0) && !HdfSbufWriteFileDescriptor(data, handle->fd)) {
54         CODEC_LOGE("write fd failed!");
55         return false;
56     }
57 
58     for (uint32_t i = 0; i < handle->reserveFds; i++) {
59         if (!HdfSbufWriteFileDescriptor(data, handle->reserve[i])) {
60             CODEC_LOGE("write handle->reserve[%{public}d] failed!", i);
61             return false;
62         }
63     }
64 
65     for (uint32_t i = 0; i < handle->reserveInts; i++) {
66         if (!HdfSbufWriteInt32(data, handle->reserve[i + handle->reserveFds])) {
67             CODEC_LOGE("write handle->reserve[%{public}d] failed!", i + handle->reserveFds);
68             return false;
69         }
70     }
71 
72     return true;
73 }
74 
BufferHandleUnmarshalling(struct HdfSBuf * data,BufferHandle ** handle)75 static bool BufferHandleUnmarshalling(struct HdfSBuf *data, BufferHandle **handle)
76 {
77     uint8_t validFd = 0;
78     uint32_t reserveFds = 0;
79     uint32_t reserveInts = 0;
80     if (!HdfSbufReadUint32(data, &reserveFds) || !HdfSbufReadUint32(data, &reserveInts)) {
81         CODEC_LOGE("read reserveFds or reserveInts failed!");
82         return false;
83     }
84 
85     BufferHandle *tmpHandle = AllocateBufferHandle(reserveFds, reserveInts);
86     if (tmpHandle == NULL) {
87         CODEC_LOGE("allocate buffer handle failed!");
88         return false;
89     }
90 
91     if (!HdfSbufReadInt32(data, &tmpHandle->width) || !HdfSbufReadInt32(data, &tmpHandle->stride) ||
92         !HdfSbufReadInt32(data, &tmpHandle->height) || !HdfSbufReadInt32(data, &tmpHandle->size) ||
93         !HdfSbufReadInt32(data, &tmpHandle->format) || !HdfSbufReadUint64(data, &tmpHandle->usage) ||
94         !HdfSbufReadUint64(data, &tmpHandle->phyAddr)) {
95         CODEC_LOGE("read handle failed!");
96         FreeBufferHandle(tmpHandle);
97         return false;
98     }
99 
100     if (!HdfSbufReadUint8(data, &validFd)) {
101         CODEC_LOGE("read handle bool value failed!");
102         FreeBufferHandle(tmpHandle);
103         return false;
104     }
105 
106     if (validFd != 0) {
107         tmpHandle->fd = HdfSbufReadFileDescriptor(data);
108     }
109 
110     for (uint32_t i = 0; i < tmpHandle->reserveFds; i++) {
111         tmpHandle->reserve[i] = HdfSbufReadFileDescriptor(data);
112     }
113 
114     for (uint32_t i = 0; i < tmpHandle->reserveInts; i++) {
115         if (!HdfSbufReadInt32(data, &tmpHandle->reserve[tmpHandle->reserveFds + i])) {
116             CODEC_LOGE("read reserve bool value failed!");
117             FreeBufferHandle(tmpHandle);
118             return false;
119         }
120     }
121     *handle = tmpHandle;
122     return true;
123 }
124 
OMX_TUNNELSETUPTYPEBlockMarshalling(struct HdfSBuf * data,const struct OMX_TUNNELSETUPTYPE * dataBlock)125 bool OMX_TUNNELSETUPTYPEBlockMarshalling(struct HdfSBuf *data, const struct OMX_TUNNELSETUPTYPE *dataBlock)
126 {
127     if (!HdfSbufWriteUint32(data, dataBlock->nTunnelFlags)) {
128         CODEC_LOGE("write dataBlock->nTunnelFlags failed!");
129         return false;
130     }
131 
132     if (!HdfSbufWriteInt32(data, (int32_t)dataBlock->eSupplier)) {
133         CODEC_LOGE("write dataBlock->eSupplier failed!");
134         return false;
135     }
136 
137     return true;
138 }
139 
OMX_TUNNELSETUPTYPEBlockUnmarshalling(struct HdfSBuf * data,struct OMX_TUNNELSETUPTYPE * dataBlock)140 bool OMX_TUNNELSETUPTYPEBlockUnmarshalling(struct HdfSBuf *data, struct OMX_TUNNELSETUPTYPE *dataBlock)
141 {
142     if (dataBlock == NULL) {
143         return false;
144     }
145     if (!HdfSbufReadUint32(data, &dataBlock->nTunnelFlags)) {
146         CODEC_LOGE("read dataBlock->nTunnelFlags failed!");
147         return false;
148     }
149 
150     if (!HdfSbufReadInt32(data, (int32_t *)&dataBlock->eSupplier)) {
151         CODEC_LOGE("read dataBlock->eSupplier failed!");
152         return false;
153     }
154 
155     return true;
156 }
157 
OMX_TUNNELSETUPTYPEFree(struct OMX_TUNNELSETUPTYPE * dataBlock,bool freeSelf)158 void OMX_TUNNELSETUPTYPEFree(struct OMX_TUNNELSETUPTYPE *dataBlock, bool freeSelf)
159 {
160     if (dataBlock == NULL) {
161         return;
162     }
163 
164     if (freeSelf) {
165         OsalMemFree(dataBlock);
166     }
167 }
168 
CodecBufferMarshalling(struct HdfSBuf * data,const struct OmxCodecBuffer * dataBlock)169 static bool CodecBufferMarshalling(struct HdfSBuf *data, const struct OmxCodecBuffer *dataBlock)
170 {
171     if (!HdfSbufWriteInt32(data, (int32_t)dataBlock->bufferType)) {
172         CODEC_LOGE("write dataBlock->bufferType failed!");
173         return false;
174     }
175 
176     if (!HdfSbufWriteUint32(data, dataBlock->bufferLen)) {
177         CODEC_LOGE("write dataBlock->bufferLen failed!");
178         return false;
179     }
180     if (dataBlock->bufferLen <= 0) {
181         return true;
182     }
183 
184     if (dataBlock->buffer == NULL) {
185         CODEC_LOGE("dataBlock->buffer is null");
186         return false;
187     }
188 
189     if (dataBlock->bufferType == CODEC_BUFFER_TYPE_AVSHARE_MEM_FD) {
190         int fd = (int)(uintptr_t)dataBlock->buffer;
191         if (!HdfSbufWriteFileDescriptor(data, fd)) {
192             CODEC_LOGE("write fd failed!");
193             return false;
194         }
195     } else if (dataBlock->bufferType == CODEC_BUFFER_TYPE_HANDLE ||
196                dataBlock->bufferType == CODEC_BUFFER_TYPE_DYNAMIC_HANDLE) {
197         BufferHandle *handle = (BufferHandle *)dataBlock->buffer;
198         if (!BufferHandleMarshalling(data, handle)) {
199             CODEC_LOGE("write handle failed!");
200             return false;
201         }
202     } else {
203         CODEC_LOGE("unsupported bufferType %{public}d!", dataBlock->bufferType);
204         return false;
205     }
206     return true;
207 }
208 
OmxCodecBufferBlockMarshalling(struct HdfSBuf * data,const struct OmxCodecBuffer * dataBlock)209 bool OmxCodecBufferBlockMarshalling(struct HdfSBuf *data, const struct OmxCodecBuffer *dataBlock)
210 {
211     uint8_t validFd = 0;
212     if (dataBlock == NULL) {
213         CODEC_LOGE("dataBlock is NULL!");
214         return false;
215     }
216 
217     if (!HdfSbufWriteUint32(data, dataBlock->bufferId) || !HdfSbufWriteUint32(data, dataBlock->size)) {
218         CODEC_LOGE("write dataBlock:bufferId or size failed!");
219         return false;
220     }
221 
222     if (!HdfSbufWriteUnpadBuffer(data, (const uint8_t *)&dataBlock->version, sizeof(union OMX_VERSIONTYPE))) {
223         CODEC_LOGE("write dataBlock->version failed!");
224         return false;
225     }
226 
227     if (!CodecBufferMarshalling(data, dataBlock)) {
228         return false;
229     }
230 
231     if (!HdfSbufWriteUint32(data, dataBlock->allocLen) || !HdfSbufWriteUint32(data, dataBlock->filledLen) ||
232         !HdfSbufWriteUint32(data, dataBlock->offset)) {
233         CODEC_LOGE("write dataBlock:allocLen, filledLen or offset failed!");
234         return false;
235     }
236 
237     validFd = dataBlock->fenceFd >= 0;
238     if (!HdfSbufWriteUint8(data, validFd)) {
239         CODEC_LOGE("write validFd failed!");
240         return false;
241     }
242     if (validFd != 0 && !HdfSbufWriteFileDescriptor(data, dataBlock->fenceFd)) {
243         CODEC_LOGE("write dataBlock->fenceFd failed!");
244         return false;
245     }
246 
247     if (!HdfSbufWriteInt32(data, (int32_t)dataBlock->type) || !HdfSbufWriteInt64(data, dataBlock->pts) ||
248         !HdfSbufWriteUint32(data, dataBlock->flag)) {
249         CODEC_LOGE("write dataBlock:type, pts or flag failed!");
250         return false;
251     }
252     return true;
253 }
254 
CodecBufferUnmarshalling(struct HdfSBuf * data,struct OmxCodecBuffer * dataBlock)255 static bool CodecBufferUnmarshalling(struct HdfSBuf *data, struct OmxCodecBuffer *dataBlock)
256 {
257     if (dataBlock == NULL) {
258         CODEC_LOGE("dataBlock is NULL!");
259         return false;
260     }
261     if (!HdfSbufReadInt32(data, (int32_t *)&dataBlock->bufferType)) {
262         CODEC_LOGE("read dataBlock->bufferType failed!");
263         return false;
264     }
265 
266     uint32_t bufferCpLen = 0;
267     if (!HdfSbufReadUint32(data, &bufferCpLen)) {
268         CODEC_LOGE("read bufferCpLen failed!");
269         return false;
270     }
271     dataBlock->bufferLen = bufferCpLen;
272     if (dataBlock->bufferLen <= 0) {
273         dataBlock->buffer = NULL;
274         return true;
275     }
276     if (dataBlock->bufferType == CODEC_BUFFER_TYPE_AVSHARE_MEM_FD) {
277         int fd = HdfSbufReadFileDescriptor(data);
278         if (fd < 0) {
279             CODEC_LOGE("read fd failed!");
280             return false;
281         }
282         dataBlock->buffer = (uint8_t *)(unsigned long)fd;
283     } else if (dataBlock->bufferType == CODEC_BUFFER_TYPE_HANDLE ||
284                dataBlock->bufferType == CODEC_BUFFER_TYPE_DYNAMIC_HANDLE) {
285         BufferHandle *handle = NULL;
286         if (!BufferHandleUnmarshalling(data, &handle)) {
287             CODEC_LOGE("read bufferhandle failed!");
288             return false;
289         }
290         dataBlock->buffer = (uint8_t *)handle;
291     } else {
292         CODEC_LOGE("unsupported bufferType %{public}d", dataBlock->bufferType);
293         return false;
294     }
295     return true;
296 }
297 
ReleaseOmxCodecBuffer(struct OmxCodecBuffer * codecBuffer)298 void ReleaseOmxCodecBuffer(struct OmxCodecBuffer *codecBuffer)
299 {
300     if (codecBuffer == NULL) {
301         return;
302     }
303 
304     if (codecBuffer->fenceFd >= 0) {
305         close(codecBuffer->fenceFd);
306         codecBuffer->fenceFd = -1;
307     }
308     if (codecBuffer->buffer == NULL || codecBuffer->bufferLen == 0) {
309         return;
310     }
311 
312     if (codecBuffer->bufferType == CODEC_BUFFER_TYPE_DYNAMIC_HANDLE ||
313         codecBuffer->bufferType == CODEC_BUFFER_TYPE_HANDLE) {
314         FreeBufferHandle((BufferHandle *)codecBuffer->buffer);
315     } else if (codecBuffer->bufferType != CODEC_BUFFER_TYPE_AVSHARE_MEM_FD) {
316         OsalMemFree(codecBuffer->buffer);
317     } else {
318         int fd = (uintptr_t)codecBuffer->buffer;
319         close(fd);
320     }
321     codecBuffer->buffer = NULL;
322     codecBuffer->bufferLen = 0;
323 }
324 
InitOmxCodecBuffer(struct OmxCodecBuffer * codecBuffer)325 void InitOmxCodecBuffer(struct OmxCodecBuffer *codecBuffer)
326 {
327     if (codecBuffer != NULL) {
328         int32_t ret = memset_s(codecBuffer, sizeof(struct OmxCodecBuffer), 0, sizeof(struct OmxCodecBuffer));
329         if (ret != EOK) {
330             CODEC_LOGE("memset_s codecBuffer err [%{public}d].", ret);
331             return;
332         }
333         codecBuffer->fenceFd = -1;
334     }
335 }
OmxCodecBufferBlockUnmarshalling(struct HdfSBuf * data,struct OmxCodecBuffer * dataBlock)336 bool OmxCodecBufferBlockUnmarshalling(struct HdfSBuf *data, struct OmxCodecBuffer *dataBlock)
337 {
338     uint8_t validFd = 0;
339     if (dataBlock == NULL || data == NULL) {
340         CODEC_LOGE("dataBlock or data is NULL!");
341         return false;
342     }
343     if (!HdfSbufReadUint32(data, &dataBlock->bufferId) || !HdfSbufReadUint32(data, &dataBlock->size)) {
344         CODEC_LOGE("read dataBlock:bufferId or size failed!");
345         return false;
346     }
347     const union OMX_VERSIONTYPE *versionCp =
348         (const union OMX_VERSIONTYPE *)HdfSbufReadUnpadBuffer(data, sizeof(union OMX_VERSIONTYPE));
349     if (versionCp == NULL) {
350         CODEC_LOGE("read versionCp failed!");
351         return false;
352     }
353     (void)memcpy_s(&dataBlock->version, sizeof(union OMX_VERSIONTYPE), versionCp, sizeof(union OMX_VERSIONTYPE));
354     if (!CodecBufferUnmarshalling(data, dataBlock)) {
355         return false;
356     }
357     if (!HdfSbufReadUint32(data, &dataBlock->allocLen) || !HdfSbufReadUint32(data, &dataBlock->filledLen) ||
358         !HdfSbufReadUint32(data, &dataBlock->offset)) {
359         CODEC_LOGE("read dataBlock:allocLen, filledLen or offset failed!");
360         return false;
361     }
362 
363     if (!HdfSbufReadUint8(data, &validFd)) {
364         CODEC_LOGE("read validFd failed!");
365         return false;
366     }
367 
368     if (validFd != 0) {
369         dataBlock->fenceFd = HdfSbufReadFileDescriptor(data);
370     }
371 
372     if (!HdfSbufReadInt32(data, (int32_t *)&dataBlock->type) || !HdfSbufReadInt64(data, &dataBlock->pts) ||
373         !HdfSbufReadUint32(data, &dataBlock->flag)) {
374         CODEC_LOGE("read dataBlock:type, pts or flag failed!");
375         return false;
376     }
377     return true;
378 }
379 
RangeValueBlockMarshalling(struct HdfSBuf * data,const RangeValue * dataBlock)380 bool RangeValueBlockMarshalling(struct HdfSBuf *data, const RangeValue *dataBlock)
381 {
382     if (!HdfSbufWriteInt32(data, dataBlock->min)) {
383         CODEC_LOGE("write dataBlock->min failed!");
384         return false;
385     }
386 
387     if (!HdfSbufWriteInt32(data, dataBlock->max)) {
388         CODEC_LOGE("write dataBlock->max failed!");
389         return false;
390     }
391 
392     return true;
393 }
394 
RangeValueBlockUnmarshalling(struct HdfSBuf * data,RangeValue * dataBlock)395 bool RangeValueBlockUnmarshalling(struct HdfSBuf *data, RangeValue *dataBlock)
396 {
397     if (dataBlock == NULL) {
398         return false;
399     }
400     if (!HdfSbufReadInt32(data, &dataBlock->min)) {
401         CODEC_LOGE("read dataBlock->min failed!");
402         return false;
403     }
404 
405     if (!HdfSbufReadInt32(data, &dataBlock->max)) {
406         CODEC_LOGE("read dataBlock->max failed!");
407         return false;
408     }
409 
410     return true;
411 }
412 
CodecCompCapabilityBlockMarshalling(struct HdfSBuf * data,const CodecCompCapability * dataBlock)413 bool CodecCompCapabilityBlockMarshalling(struct HdfSBuf *data, const CodecCompCapability *dataBlock)
414 {
415     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteInt32(data, (int32_t)dataBlock->role),
416         "write dataBlock->role failed!");
417     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteInt32(data, (int32_t)dataBlock->type),
418         "write dataBlock->type failed!");
419     for (uint32_t i = 0; i < NAME_LENGTH; i++) {
420         IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteUint8(data, (uint8_t)(dataBlock->compName)[i]),
421             "write (dataBlock->compName)[i] failed!");
422     }
423     for (uint32_t i = 0; i < PROFILE_NUM; i++) {
424         IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteInt32(data, (dataBlock->supportProfiles)[i]),
425             "write (dataBlock->supportProfiles)[i] failed!");
426     }
427     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteInt32(data, dataBlock->maxInst),
428         "write dataBlock->maxInst failed!");
429     int8_t isSoftwareCodec = dataBlock->isSoftwareCodec ? 1 : 0;
430     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteInt8(data, isSoftwareCodec),
431         "write dataBlock->isSoftwareCodec failed!");
432     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteInt32(data, dataBlock->processModeMask),
433         "write dataBlock->processModeMask failed!");
434     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteUint32(data, dataBlock->capsMask),
435         "write dataBlock->capsMask failed!");
436     IF_FALSE_PRINT_MSG_RETURN_FALSE(RangeValueBlockMarshalling(data, &dataBlock->bitRate),
437         "write dataBlock->bitRate failed!");
438     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteUnpadBuffer(data, (const uint8_t *)&dataBlock->port, sizeof(PortCap)),
439         "write dataBlock->port failed!");
440     int8_t canSwapWidthHeight = dataBlock->canSwapWidthHeight ? 1 : 0;
441     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufWriteInt8(data, canSwapWidthHeight),
442         "write dataBlock->canSwapWidthHeight failed!");
443 
444     CODEC_LOGI("write HdfSBuf data success!");
445     return true;
446 }
447 
CodecCompCapabilityBlockUnmarshalling(struct HdfSBuf * data,CodecCompCapability * dataBlock)448 bool CodecCompCapabilityBlockUnmarshalling(struct HdfSBuf *data, CodecCompCapability *dataBlock)
449 {
450     if (dataBlock == NULL) {
451         return false;
452     }
453 
454     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufReadInt32(data, (int32_t *)&dataBlock->role) &&
455                                     HdfSbufReadInt32(data, (int32_t *)&dataBlock->type),
456                                     "read dataBlock->role or dataBlock->type failed!");
457     for (uint32_t i = 0; i < NAME_LENGTH; i++) {
458         IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufReadUint8(data, (uint8_t *)&(dataBlock->compName)[i]),
459             "read compName[i] failed!");
460     }
461     for (uint32_t j = 0; j < PROFILE_NUM; j++) {
462         IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufReadInt32(data, &(dataBlock->supportProfiles)[j]),
463             "read supportProfiles[i] failed!");
464     }
465     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufReadInt32(data, &dataBlock->maxInst),
466         "read dataBlock->maxInst failed!");
467     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufReadInt8(data, (int8_t *)&dataBlock->isSoftwareCodec),
468         "read dataBlock->isSoftwareCodec failed!");
469     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufReadInt32(data, &dataBlock->processModeMask),
470         "read dataBlock->processModeMask failed!");
471     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufReadUint32(data, &dataBlock->capsMask),
472         "read dataBlock->capsMask failed!");
473     IF_FALSE_PRINT_MSG_RETURN_FALSE(RangeValueBlockUnmarshalling(data, &dataBlock->bitRate),
474         "read &dataBlock->bitRate failed!");
475     const PortCap *portCp = (const PortCap *)HdfSbufReadUnpadBuffer(data, sizeof(PortCap));
476     IF_FALSE_PRINT_MSG_RETURN_FALSE(portCp != NULL, "read portCp failed!");
477     IF_FALSE_PRINT_MSG_RETURN_FALSE(memcpy_s(&dataBlock->port, sizeof(PortCap), portCp, sizeof(PortCap)) == EOK,
478         "memcpy_s dataBlock->port failed!");
479     IF_FALSE_PRINT_MSG_RETURN_FALSE(HdfSbufReadInt8(data, (int8_t *)&dataBlock->canSwapWidthHeight),
480         "read dataBlock->canSwapWidthHeight failed!");
481 
482     CODEC_LOGI("read HdfSBuf data success!");
483     return true;
484 }
485