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