1 /*
2  * Copyright (c) 2023-2024 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 <buffer_handle.h>
17 #include <cstdlib>
18 #include <securec.h>
19 #include <stdint.h>
20 #include <unistd.h>
21 
22 #include "buffer_handle_utils.h"
23 #include "camera_log.h"
24 #include "dps_metadata_info.h"
25 
26 
27 namespace OHOS {
28 namespace CameraStandard {
29 #define RESERVE_MAX_SIZE 1024
30 
CameraAllocateBufferHandle(uint32_t reserveFds,uint32_t reserveInts)31 BufferHandle *CameraAllocateBufferHandle(uint32_t reserveFds, uint32_t reserveInts)
32 {
33     CHECK_ERROR_RETURN_RET_LOG(reserveFds > RESERVE_MAX_SIZE || reserveInts > RESERVE_MAX_SIZE, nullptr,
34         "CameraAllocateBufferHandle reserveFds or reserveInts too lager");
35     size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts));
36     BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize));
37     if (handle != nullptr) {
38         (void)memset_s(handle, handleSize, 0, handleSize);
39         handle->fd = -1;
40         for (uint32_t i = 0; i < reserveFds; i++) {
41             handle->reserve[i] = -1;
42         }
43         handle->reserveFds = reserveFds;
44         handle->reserveInts = reserveInts;
45     } else {
46         MEDIA_ERR_LOG("InitBufferHandle malloc %zu failed", handleSize);
47     }
48     return handle;
49 }
50 
CameraFreeBufferHandle(BufferHandle * handle)51 int32_t CameraFreeBufferHandle(BufferHandle *handle)
52 {
53     CHECK_ERROR_RETURN_RET_LOG(handle == nullptr, 0, "CameraFreeBufferHandle with nullptr handle");
54     if (handle->fd >= 0) {
55         close(handle->fd);
56         handle->fd = -1;
57     }
58     const uint32_t reserveFds = handle->reserveFds;
59     for (uint32_t i = 0; i < reserveFds; i++) {
60         if (handle->reserve[i] >= 0) {
61             close(handle->reserve[i]);
62             handle->reserve[i] = -1;
63         }
64     }
65     free(handle);
66     return 0;
67 }
68 
CameraCloneBufferHandle(const BufferHandle * handle)69 BufferHandle *CameraCloneBufferHandle(const BufferHandle *handle)
70 {
71     CHECK_ERROR_RETURN_RET_LOG(handle == nullptr, nullptr, "CameraCloneBufferHandle with nullptr handle");
72     BufferHandle *newHandle = CameraAllocateBufferHandle(handle->reserveFds, handle->reserveInts);
73     CHECK_ERROR_RETURN_RET_LOG(newHandle == nullptr, nullptr,
74         "CameraCloneBufferHandle alloc buffer failed, newHandle is nullptr");
75     if (handle->fd == -1) {
76         newHandle->fd = handle->fd;
77     } else {
78         newHandle->fd = dup(handle->fd);
79         if (newHandle->fd == -1) {
80             MEDIA_ERR_LOG("CameraCloneBufferHandle dup failed");
81             CameraFreeBufferHandle(newHandle);
82             return nullptr;
83         }
84     }
85     newHandle->width = handle->width;
86     newHandle->stride = handle->stride;
87     newHandle->height = handle->height;
88     newHandle->size = handle->size;
89     newHandle->format = handle->format;
90     newHandle->usage = handle->usage;
91     newHandle->phyAddr = handle->phyAddr;
92 
93     // 此处当前缺乏reserveFds中各个fd的dup,原因在于surfacebuffer中reserveFds fd不合法。且相机流程中reserveFds暂时无用
94 
95     if (handle->reserveInts == 0) {
96         MEDIA_INFO_LOG("There is no reserved integer value in old handle, no need to copy");
97         return newHandle;
98     }
99 
100     if (memcpy_s(&newHandle->reserve[newHandle->reserveFds], sizeof(int32_t) * newHandle->reserveInts,
101         &handle->reserve[handle->reserveFds], sizeof(int32_t) * handle->reserveInts) != EOK) {
102         MEDIA_ERR_LOG("CameraCloneBufferHandle memcpy_s failed");
103         CameraFreeBufferHandle(newHandle);
104         return nullptr;
105     }
106     return newHandle;
107 }
108 
109 } // namespace CameraStandard
110 } // namespace OHOS