• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #ifndef OHOS_CAMERA_SURFACE_BUFFER_UTIL_H
17 #define OHOS_CAMERA_SURFACE_BUFFER_UTIL_H
18 
19 #include "surface.h"
20 #include "video_key_info.h"
21 #include "metadata_helper.h"
22 
23 namespace OHOS {
24 namespace CameraStandard {
25 
26 class CameraSurfaceBufferUtil {
27 static constexpr uint8_t PIXEL_SIZE_HDR_YUV = 3;
28 static constexpr uint8_t HDR_PIXEL_SIZE = 2;
29 
30 public:
DeepCopyBuffer(sptr<SurfaceBuffer> surfaceBuffer)31     static sptr<SurfaceBuffer> DeepCopyBuffer(sptr<SurfaceBuffer> surfaceBuffer)
32     {
33         CAMERA_SYNC_TRACE;
34         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, nullptr, "DeepCopyBuffer surfaceBuffer is null");
35         uint32_t bufferSeqNum = surfaceBuffer->GetSeqNum();
36         MEDIA_DEBUG_LOG("DeepCopyBuffer E bufferSeqNum:%{public}u", bufferSeqNum);
37         DumpSurfaceBuffer(surfaceBuffer);
38         int32_t dataStride = GetDataStride(surfaceBuffer) == -1 ? 0x8 : GetDataStride(surfaceBuffer);
39         MEDIA_DEBUG_LOG("DeepCopyBuffer dataStride:%{public}d", dataStride);
40         // deep copy buffer
41         BufferRequestConfig requestConfig = {
42             .width = surfaceBuffer->GetWidth(),
43             .height = surfaceBuffer->GetHeight(),
44             .strideAlignment = 0x8, // default stride is 8 Bytes.
45             .format = surfaceBuffer->GetFormat(),
46             .usage = surfaceBuffer->GetUsage(),
47             .timeout = 0,
48             .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
49             .transform = surfaceBuffer->GetSurfaceBufferTransform(),
50         };
51         sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
52         auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
53         MEDIA_DEBUG_LOG("DeepCopyBuffer alloc ret: %{public}d", allocErrorCode);
54         if (memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
55             surfaceBuffer->GetVirAddr(), surfaceBuffer->GetSize()) != EOK) {
56             MEDIA_ERR_LOG("DeepCopyBuffer memcpy_s failed");
57         }
58 
59         // deep copy buffer extData
60         MessageParcel extParcl;
61         sptr<BufferExtraData> bufferExtraData = surfaceBuffer->GetExtraData();
62         GSError gsErr = bufferExtraData->WriteToParcel(extParcl);
63         MEDIA_DEBUG_LOG("DeepCopyBuffer WriteToParcel gsErr=%{public}d", gsErr);
64         sptr<BufferExtraData> newBufferExtraData = newSurfaceBuffer->GetExtraData();
65         gsErr = newBufferExtraData->ReadFromParcel(extParcl);
66         MEDIA_DEBUG_LOG("DeepCopyBuffer ReadFromParcel gsErr=%{public}d", gsErr);
67 
68         // deep metaData
69         CopyMetaData(surfaceBuffer, newSurfaceBuffer);
70         DumpSurfaceBuffer(newSurfaceBuffer);
71         MEDIA_DEBUG_LOG("DeepCopyBuffer X bufferSeqNum:%{public}u", bufferSeqNum);
72         return newSurfaceBuffer;
73     }
74 
DeepCopyThumbnailBuffer(sptr<SurfaceBuffer> surfaceBuffer)75     static sptr<SurfaceBuffer> DeepCopyThumbnailBuffer(sptr<SurfaceBuffer> surfaceBuffer)
76     {
77         CAMERA_SYNC_TRACE;
78         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, nullptr, "DeepCopyThumbnailBuffer surfaceBuffer is null");
79         uint32_t bufferSeqNum = surfaceBuffer->GetSeqNum();
80         MEDIA_DEBUG_LOG("DeepCopyThumbnailBuffer E bufferSeqNum:%{public}u", bufferSeqNum);
81         DumpSurfaceBuffer(surfaceBuffer);
82         int32_t thumbnailStride = GetDataStride(surfaceBuffer);
83         int32_t thumbnailHeight = GetDataHeight(surfaceBuffer);
84         MEDIA_DEBUG_LOG("DeepCopyThumbnailBuffer thumbnailStride:%{public}d", thumbnailStride);
85         // deep copy buffer
86         BufferRequestConfig requestConfig = {
87             .width = thumbnailStride,
88             .height = thumbnailHeight,
89             .strideAlignment = thumbnailStride,
90             .format = surfaceBuffer->GetFormat(),
91             .usage =
92                 BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_MMZ_CACHE,
93             .timeout = 0,
94         };
95         sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
96         auto allocRet = newSurfaceBuffer->Alloc(requestConfig);
97         if (allocRet != 0) {
98             MEDIA_ERR_LOG("DeepCopyThumbnailBuffer alloc ret: %{public}d", allocRet);
99             return newSurfaceBuffer;
100         }
101         int32_t colorLength = thumbnailStride * thumbnailHeight * PIXEL_SIZE_HDR_YUV;
102         HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceType colorSpaceType;
103         GSError gsErr = MetadataHelper::GetColorSpaceType(surfaceBuffer, colorSpaceType);
104         bool isHdr = colorSpaceType ==  HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceType::CM_BT2020_HLG_FULL;
105         MEDIA_ERR_LOG("DeepCopyThumbnailBuffer colorSpaceType:%{public}d isHdr:%{public}d", colorSpaceType, isHdr);
106         colorLength = isHdr ? colorLength : colorLength / HDR_PIXEL_SIZE;
107         if (memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
108             surfaceBuffer->GetVirAddr(), colorLength) != EOK) {
109             MEDIA_ERR_LOG("DeepCopyThumbnailBuffer memcpy_s failed");
110             return newSurfaceBuffer;
111         }
112 
113         // deep copy buffer extData
114         MessageParcel extParcl;
115         sptr<BufferExtraData> bufferExtraData = surfaceBuffer->GetExtraData();
116         gsErr = bufferExtraData->WriteToParcel(extParcl);
117         MEDIA_DEBUG_LOG("DeepCopyBuffer WriteToParcel gsErr=%{public}d", gsErr);
118         sptr<BufferExtraData> newBufferExtraData = newSurfaceBuffer->GetExtraData();
119         gsErr = newBufferExtraData->ReadFromParcel(extParcl);
120         MEDIA_DEBUG_LOG("DeepCopyBuffer ReadFromParcel gsErr=%{public}d", gsErr);
121 
122         // deep metaData
123         CopyMetaData(surfaceBuffer, newSurfaceBuffer);
124         DumpSurfaceBuffer(newSurfaceBuffer);
125         MEDIA_DEBUG_LOG("DeepCopyBuffer X bufferSeqNum:%{public}u", bufferSeqNum);
126         return newSurfaceBuffer;
127     }
128 
GetDataSize(sptr<SurfaceBuffer> surfaceBuffer)129     static int32_t GetDataSize(sptr<SurfaceBuffer> surfaceBuffer)
130     {
131         int32_t dataSize = 0;
132         surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, dataSize);
133         MEDIA_DEBUG_LOG("GetDataSize:%{public}d", dataSize);
134         return dataSize;
135     }
136 
GetCaptureId(sptr<SurfaceBuffer> surfaceBuffer)137     static int32_t GetCaptureId(sptr<SurfaceBuffer> surfaceBuffer)
138     {
139         int32_t captureId = 0;
140         surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
141         MEDIA_DEBUG_LOG("GetCaptureId:%{public}d", captureId);
142         return captureId;
143     }
144 
GetMaskCaptureId(sptr<SurfaceBuffer> surfaceBuffer)145     static int32_t GetMaskCaptureId(sptr<SurfaceBuffer> surfaceBuffer)
146     {
147         int32_t captureId;
148         int32_t burstSeqId = -1;
149         int32_t maskBurstSeqId = 0;
150         int32_t invalidSeqenceId = -1;
151         int32_t captureIdMask = 0x0000FFFF;
152         int32_t captureIdShit = 16;
153         surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
154         surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
155         if (burstSeqId != invalidSeqenceId && captureId >= 0) {
156             maskBurstSeqId = ((static_cast<uint32_t>(captureId) & static_cast<uint32_t>(captureIdMask)) <<
157                 static_cast<uint32_t>(captureIdShit)) | static_cast<uint32_t>(burstSeqId);
158             MEDIA_DEBUG_LOG("GetMaskCaptureId captureId:%{public}d, burstSeqId:%{public}d, maskBurstSeqId = %{public}d",
159                 captureId, burstSeqId, maskBurstSeqId);
160             return maskBurstSeqId;
161         }
162         MEDIA_DEBUG_LOG("GetMaskCaptureId captureId:%{public}d, burstSeqId:%{public}d", captureId, burstSeqId);
163         return captureId;
164     }
165 
GetBurstSequenceId(sptr<SurfaceBuffer> surfaceBuffer)166     static int32_t GetBurstSequenceId(sptr<SurfaceBuffer> surfaceBuffer)
167     {
168         int32_t burstSequenceId = 0;
169         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, burstSequenceId,
170             "GetBurstSequenceId: surfaceBuffer is nullptr");
171         sptr<BufferExtraData> extraData = surfaceBuffer->GetExtraData();
172         CHECK_RETURN_RET_ELOG(extraData == nullptr, burstSequenceId, "GetBurstSequenceId: extraData is nullptr");
173         extraData->ExtraGet(OHOS::Camera::burstSequenceId, burstSequenceId);
174         MEDIA_DEBUG_LOG("GetBurstSequenceId:%{public}d", burstSequenceId);
175         return burstSequenceId;
176     }
177 
GetImageCount(sptr<SurfaceBuffer> surfaceBuffer)178     static int32_t GetImageCount(sptr<SurfaceBuffer> surfaceBuffer)
179     {
180         int32_t imageCount = 0;
181         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, imageCount, "GetImageCount: surfaceBuffer is nullptr");
182         sptr<BufferExtraData> extraData = surfaceBuffer->GetExtraData();
183         CHECK_RETURN_RET_ELOG(extraData == nullptr, imageCount, "GetImageCount: extraData is nullptr");
184         extraData->ExtraGet(OHOS::Camera::imageCount, imageCount);
185         MEDIA_DEBUG_LOG("GetImageCount:%{public}d", imageCount);
186         return imageCount;
187     }
188 
GetImageId(sptr<SurfaceBuffer> surfaceBuffer)189     static int64_t GetImageId(sptr<SurfaceBuffer> surfaceBuffer)
190     {
191         int64_t imageId = 0;
192         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, imageId, "GetImageId: surfaceBuffer is nullptr");
193         sptr<BufferExtraData> extraData = surfaceBuffer->GetExtraData();
194         CHECK_RETURN_RET_ELOG(extraData == nullptr, imageId, "GetImageId: extraData is nullptr");
195         extraData->ExtraGet(OHOS::Camera::imageId, imageId);
196         MEDIA_DEBUG_LOG("GetImageId:%{public}s", std::to_string(imageId).c_str());
197         return imageId;
198     }
199 
GetIsDegradedImage(sptr<SurfaceBuffer> surfaceBuffer)200     static int32_t GetIsDegradedImage(sptr<SurfaceBuffer> surfaceBuffer)
201     {
202         int32_t isDegradedImage = 0;
203         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, isDegradedImage,
204             "GetIsDegradedImage: surfaceBuffer is nullptr");
205         sptr<BufferExtraData> extraData = surfaceBuffer->GetExtraData();
206         CHECK_RETURN_RET_ELOG(extraData == nullptr, isDegradedImage, "GetIsDegradedImage: extraData is nullptr");
207         extraData->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
208         MEDIA_DEBUG_LOG("GetIsDegradedImage:%{public}d", isDegradedImage);
209         return isDegradedImage;
210     }
211 
GetDeferredProcessingType(sptr<SurfaceBuffer> surfaceBuffer)212     static int32_t GetDeferredProcessingType(sptr<SurfaceBuffer> surfaceBuffer)
213     {
214         int32_t deferredProcessingType = 0;
215         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, deferredProcessingType,
216             "GetDeferredProcessingType: surfaceBuffer is nullptr");
217         sptr<BufferExtraData> extraData = surfaceBuffer->GetExtraData();
218         CHECK_RETURN_RET_ELOG(extraData == nullptr, deferredProcessingType,
219             "GetDeferredProcessingType: extraData is nullptr");
220         extraData->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
221         MEDIA_DEBUG_LOG("GetDeferredProcessingType:%{public}d", deferredProcessingType);
222         return deferredProcessingType;
223     }
224 
GetDataWidth(sptr<SurfaceBuffer> surfaceBuffer)225     static int32_t GetDataWidth(sptr<SurfaceBuffer> surfaceBuffer)
226     {
227         int32_t dataWidth = 0;
228         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, dataWidth, "GetDataWidth: surfaceBuffer is nullptr");
229         sptr<BufferExtraData> extraData = surfaceBuffer->GetExtraData();
230         CHECK_RETURN_RET_ELOG(extraData  == nullptr, dataWidth, "GetDataWidth: extraData is nullptr");
231         extraData->ExtraGet(OHOS::Camera::dataWidth, dataWidth);
232         MEDIA_DEBUG_LOG("GetDataWidth:%{public}d", dataWidth);
233         return dataWidth;
234     }
235 
GetDataHeight(sptr<SurfaceBuffer> surfaceBuffer)236     static int32_t GetDataHeight(sptr<SurfaceBuffer> surfaceBuffer)
237     {
238         int32_t dataHeight = 0;
239         surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataHeight, dataHeight);
240         MEDIA_DEBUG_LOG("GetDataHeight:%{public}d", dataHeight);
241         return dataHeight;
242     }
243 
GetDeferredImageFormat(sptr<SurfaceBuffer> surfaceBuffer)244     static int32_t GetDeferredImageFormat(sptr<SurfaceBuffer> surfaceBuffer)
245     {
246         int32_t deferredImageFormat = 0;
247         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, deferredImageFormat,
248             "GetDeferredImageFormat: surfaceBuffer is nullptr");
249         sptr<BufferExtraData> extraData = surfaceBuffer->GetExtraData();
250         CHECK_RETURN_RET_ELOG(extraData == nullptr, deferredImageFormat,
251             "GetDeferredImageFormat:extraData is nullptr");
252         extraData->ExtraGet(OHOS::Camera::deferredImageFormat, deferredImageFormat);
253         MEDIA_DEBUG_LOG("GetDeferredImageFormat:%{public}d", deferredImageFormat);
254         return deferredImageFormat;
255     }
256 
GetDataStride(sptr<SurfaceBuffer> surfaceBuffer)257     static int32_t GetDataStride(sptr<SurfaceBuffer> surfaceBuffer)
258     {
259         int32_t dataStride = -1;
260         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, dataStride, "GetDataStride: surfaceBuffer is nullptr");
261         sptr<BufferExtraData> extraData = surfaceBuffer->GetExtraData();
262         CHECK_RETURN_RET_ELOG(extraData == nullptr, dataStride, "GetDataStride: extraData is nullptr");
263         extraData->ExtraGet(OHOS::Camera::dataStride, dataStride);
264         MEDIA_DEBUG_LOG("GetDataStride:%{public}d", dataStride);
265         return dataStride;
266     }
267 
GetCloudImageEnhanceFlag(sptr<SurfaceBuffer> surfaceBuffer)268     static int32_t GetCloudImageEnhanceFlag(sptr<SurfaceBuffer> surfaceBuffer)
269     {
270         int32_t cloudImageEnhanceFlag = 0;
271         CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, cloudImageEnhanceFlag,
272             "GetCloudImageEnhanceFlag: surfaceBuffer is nullptr");
273         sptr<BufferExtraData> extraData = surfaceBuffer->GetExtraData();
274         CHECK_RETURN_RET_ELOG(extraData == nullptr, cloudImageEnhanceFlag,
275             "GetCloudImageEnhanceFlag: extraData is nullptr");
276         extraData->ExtraGet(OHOS::Camera::cloudImageEnhanceFlag, cloudImageEnhanceFlag);
277         MEDIA_DEBUG_LOG("GetCloudImageEnhanceFlag:%{public}d", cloudImageEnhanceFlag);
278         return cloudImageEnhanceFlag;
279     }
280 
DumpSurfaceBuffer(sptr<SurfaceBuffer> surfaceBuffer)281     static void DumpSurfaceBuffer(sptr<SurfaceBuffer> surfaceBuffer)
282     {
283         GetCaptureId(surfaceBuffer);
284         GetDataWidth(surfaceBuffer);
285         GetDataHeight(surfaceBuffer);
286         GetDeferredImageFormat(surfaceBuffer);
287         GetIsDegradedImage(surfaceBuffer);
288         GetImageId(surfaceBuffer);
289         GetImageCount(surfaceBuffer);
290         GetDeferredProcessingType(surfaceBuffer);
291         GetBurstSequenceId(surfaceBuffer);
292     }
293 
294 private:
CopyMetaData(sptr<SurfaceBuffer> & inBuffer,sptr<SurfaceBuffer> & outBuffer)295     static void CopyMetaData(sptr<SurfaceBuffer> &inBuffer, sptr<SurfaceBuffer> &outBuffer)
296     {
297         std::vector<uint32_t> keys = {};
298         CHECK_RETURN_ELOG(inBuffer == nullptr, "CopyMetaData: inBuffer is nullptr");
299         auto ret = inBuffer->ListMetadataKeys(keys);
300         CHECK_RETURN_ELOG(ret != GSError::GSERROR_OK, "CopyMetaData: ListMetadataKeys fail! res=%{public}d", ret);
301         for (uint32_t key : keys) {
302             std::vector<uint8_t> values;
303             ret = inBuffer->GetMetadata(key, values);
304             if (ret != 0) {
305                 MEDIA_INFO_LOG("GetMetadata fail! key = %{public}d res = %{public}d", key, ret);
306                 continue;
307             }
308             ret = outBuffer->SetMetadata(key, values);
309             if (ret != 0) {
310                 MEDIA_INFO_LOG("SetMetadata fail! key = %{public}d res = %{public}d", key, ret);
311                 continue;
312             }
313         }
314     }
315 };
316 }  // namespace CameraStandard
317 }  // namespace OHOS
318 #endif
319