1 /*
2  * Copyright (C) 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 "memcpy_helper.h"
17 
18 #include "securec.h"
19 #include "effect_log.h"
20 #include "format_helper.h"
21 
22 namespace OHOS {
23 namespace Media {
24 namespace Effect {
CopyData(CopyInfo &src, CopyInfo &dst)25 void MemcpyHelper::CopyData(CopyInfo &src, CopyInfo &dst)
26 {
27     uint8_t *srcBuffet = src.data;
28     uint8_t *dstBuffer = dst.data;
29     CHECK_AND_RETURN_LOG(srcBuffet != nullptr && dstBuffer != nullptr,
30         "Input addr is null! srcAddr=%{public}p, dstAddr=%{public}p", srcBuffet, dstBuffer);
31     if (srcBuffet == dstBuffer) {
32         EFFECT_LOGD("Buffer is same, not need copy.");
33         return;
34     }
35 
36     BufferInfo &srcInfo = src.bufferInfo;
37     BufferInfo &dstInfo = dst.bufferInfo;
38     EFFECT_LOGD("CopyData: srcAddr=%{public}p, srcH=%{public}d, srcFormat=%{public}d, srcStride=%{public}d, "
39         "srcLen=%{public}d, dstAddr=%{public}p, dstH=%{public}d, dstFormat=%{public}d, dstStride=%{public}d, "
40         "dstLen=%{public}d", src.data, srcInfo.height_, srcInfo.formatType_, srcInfo.rowStride_, srcInfo.len_,
41         dst.data, dstInfo.height_, dstInfo.formatType_, dstInfo.rowStride_, dstInfo.len_);
42     uint32_t srcRowStride = srcInfo.rowStride_;
43     uint32_t dstRowStride = dstInfo.rowStride_;
44     uint32_t srcBufferLen = srcInfo.len_;
45     uint32_t dstBufferLen = dstInfo.len_;
46 
47     // direct copy the date while the size is same.
48     if (srcRowStride == dstRowStride && srcBufferLen == dstBufferLen) {
49         errno_t ret = memcpy_s(dstBuffer, dstBufferLen, srcBuffet, srcBufferLen);
50         if (ret != 0) {
51             EFFECT_LOGE("CopyData memcpy_s failed. ret=%{public}d, dstBuf=%{public}p, dstBufLen=%{public}d,"
52                 " srcBuf=%{public}p, srcBufLen=%{public}d", ret, dstBuffer, dstBufferLen, srcBuffet, srcBufferLen);
53         }
54         return;
55     }
56 
57     // copy by row
58     uint32_t srcRowCount = FormatHelper::CalculateDataRowCount(srcInfo.height_, srcInfo.formatType_);
59     uint32_t dstRowCount = FormatHelper::CalculateDataRowCount(dstInfo.height_, dstInfo.formatType_);
60     uint32_t rowCount = srcRowCount > dstRowCount ? dstRowCount : srcRowCount;
61     uint32_t count = srcRowStride > dstRowStride ? dstRowStride : srcRowStride;
62     if (rowCount * dstRowStride > dstBufferLen || rowCount * srcRowStride > srcBufferLen) {
63         EFFECT_LOGE("Out of buffer available range! Copy fail! srcH=%{public}d, srcFormat=%{public}d, "
64             "srcStride=%{public}d, srcLen=%{public}d, dstH=%{public}d, dstFormat=%{public}d, dstStride=%{public}d, "
65             "dstLen=%{public}d", srcInfo.height_, srcInfo.formatType_, srcInfo.rowStride_, srcInfo.len_,
66             dstInfo.height_, dstInfo.formatType_, dstInfo.rowStride_, dstInfo.len_);
67         return;
68     }
69     for (uint32_t i = 0; i < rowCount; i++) {
70         errno_t ret = memcpy_s(dstBuffer + i * dstRowStride, dstRowStride, srcBuffet + i * srcRowStride, count);
71         if (ret != 0) {
72             EFFECT_LOGE("CopyData: copy by row memcpy_s failed. ret=%{public}d, row=%{public}d, srcH=%{public}d, "
73                 "srcFormat=%{public}d, srcStride=%{public}d, srcLen=%{public}d, dstH=%{public}d, dstFormat=%{public}d, "
74                 "dstStride=%{public}d, dstLen=%{public}d", ret, i,
75                 srcInfo.height_, srcInfo.formatType_, srcInfo.rowStride_, srcInfo.len_,
76                 dstInfo.height_, dstInfo.formatType_, dstInfo.rowStride_, dstInfo.len_);
77             continue;
78         }
79     }
80 }
81 
CreateCopyInfoByEffectBuffer(EffectBuffer *buffer, CopyInfo &info)82 void CreateCopyInfoByEffectBuffer(EffectBuffer *buffer, CopyInfo &info)
83 {
84     info = {
85         .bufferInfo = *buffer->bufferInfo_,
86         .data = static_cast<uint8_t *>(buffer->buffer_),
87     };
88 }
89 
CopyData(EffectBuffer *src, EffectBuffer *dst)90 void MemcpyHelper::CopyData(EffectBuffer *src, EffectBuffer *dst)
91 {
92     CHECK_AND_RETURN_LOG(src != nullptr && dst != nullptr,
93         "Input effect buffer is null! src=%{public}p, dst=%{public}p", src, dst);
94 
95     if (src == dst) {
96         EFFECT_LOGD("EffectBuffer is same, not need copy.");
97         return;
98     }
99 
100     CopyInfo srcCopyInfo;
101     CreateCopyInfoByEffectBuffer(src, srcCopyInfo);
102 
103     CopyInfo dstCopyInfo;
104     CreateCopyInfoByEffectBuffer(dst, dstCopyInfo);
105 
106     CopyData(srcCopyInfo, dstCopyInfo);
107 }
108 
CopyData(EffectBuffer *src, CopyInfo &dst)109 void MemcpyHelper::CopyData(EffectBuffer *src, CopyInfo &dst)
110 {
111     CHECK_AND_RETURN_LOG(src != nullptr, "Input src effect buffer is null! src=%{public}p", src);
112     CopyInfo srcCopyInfo;
113     CreateCopyInfoByEffectBuffer(src, srcCopyInfo);
114 
115     CopyData(srcCopyInfo, dst);
116 }
117 
CopyData(CopyInfo &src, EffectBuffer *dst)118 void MemcpyHelper::CopyData(CopyInfo &src, EffectBuffer *dst)
119 {
120     CHECK_AND_RETURN_LOG(dst != nullptr, "Input dst effect buffer is null! dst=%{public}p", dst);
121     CopyInfo dstCopyInfo;
122     CreateCopyInfoByEffectBuffer(dst, dstCopyInfo);
123 
124     CopyData(src, dstCopyInfo);
125 }
126 
CreateCopyInfoByMemoryData(MemoryData *memoryData, CopyInfo &info)127 void CreateCopyInfoByMemoryData(MemoryData *memoryData, CopyInfo &info)
128 {
129     info = {
130         .bufferInfo = memoryData->memoryInfo.bufferInfo,
131         .data = static_cast<uint8_t *>(memoryData->data),
132     };
133 }
134 
CopyData(EffectBuffer *buffer, MemoryData *memoryData)135 void MemcpyHelper::CopyData(EffectBuffer *buffer, MemoryData *memoryData)
136 {
137     CHECK_AND_RETURN_LOG(buffer != nullptr && memoryData != nullptr,
138         "Input is null! buffer=%{public}p, memoryData=%{public}p", buffer, memoryData);
139     CopyInfo dstCopyInfo;
140     CreateCopyInfoByMemoryData(memoryData, dstCopyInfo);
141 
142     MemcpyHelper::CopyData(buffer, dstCopyInfo);
143 }
144 
CopyData(MemoryData *src, MemoryData *dst)145 void MemcpyHelper::CopyData(MemoryData *src, MemoryData *dst)
146 {
147     CHECK_AND_RETURN_LOG(src != nullptr && dst != nullptr,
148         "Input memory data is null! src=%{public}p, dst=%{public}p", src, dst);
149     if (src == dst) {
150         EFFECT_LOGD("MemoryData is same, not need copy.");
151         return;
152     }
153 
154     CopyInfo srcCopyInfo;
155     CreateCopyInfoByMemoryData(src, srcCopyInfo);
156 
157     CopyInfo dstCopyInfo;
158     CreateCopyInfoByMemoryData(dst, dstCopyInfo);
159 
160     CopyData(srcCopyInfo, dstCopyInfo);
161 }
162 } // namespace Effect
163 } // namespace Media
164 } // namespace OHOS