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