• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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 andPhotoProcessResult
13  * limitations under the License.
14  */
15 
16 #include "photo_process_result.h"
17 
18 #include "buffer_extra_data_impl.h"
19 #include "dp_log.h"
20 #include "dps.h"
21 #include "dps_event_report.h"
22 #include "events_monitor.h"
23 #include "photo_process_command.h"
24 #include "picture_proxy.h"
25 #include "securec.h"
26 #include "service_died_command.h"
27 #include <optional>
28 
29 namespace OHOS {
30 namespace CameraStandard {
31 namespace DeferredProcessing {
PhotoProcessResult(const int32_t userId)32 PhotoProcessResult::PhotoProcessResult(const int32_t userId) : userId_(userId)
33 {
34     DP_DEBUG_LOG("entered.");
35 }
36 
~PhotoProcessResult()37 PhotoProcessResult::~PhotoProcessResult()
38 {
39     DP_INFO_LOG("entered.");
40 }
41 
OnProcessDone(const std::string & imageId,std::unique_ptr<ImageInfo> imageInfo)42 void PhotoProcessResult::OnProcessDone(const std::string& imageId, std::unique_ptr<ImageInfo> imageInfo)
43 {
44     DP_DEBUG_LOG("DPS_PHOTO: OnProcessDone imageId: %{public}s", imageId.c_str());
45     ReportEvent(imageId);
46     auto ret = DPS_SendCommand<PhotoProcessSuccessCommand>(userId_, imageId, std::move(imageInfo));
47     DP_CHECK_ERROR_RETURN_LOG(ret != DP_OK,
48         "process success imageId: %{public}s failed. ret: %{public}d", imageId.c_str(), ret);
49 }
50 
OnError(const std::string & imageId,DpsError errorCode)51 void PhotoProcessResult::OnError(const std::string& imageId, DpsError errorCode)
52 {
53     DP_DEBUG_LOG("DPS_PHOTO: OnError imageId: %{public}s, error: %{public}d", imageId.c_str(), errorCode);
54     auto ret = DPS_SendCommand<PhotoProcessFailedCommand>(userId_, imageId, errorCode);
55     DP_CHECK_ERROR_RETURN_LOG(ret != DP_OK,
56         "processExt success imageId: %{public}s failed. ret: %{public}d", imageId.c_str(), ret);
57 }
58 
OnStateChanged(HdiStatus hdiStatus)59 void PhotoProcessResult::OnStateChanged(HdiStatus hdiStatus)
60 {
61     DP_DEBUG_LOG("DPS_PHOTO: OnStateChanged hdiStatus: %{public}d", hdiStatus);
62     EventsMonitor::GetInstance().NotifyImageEnhanceStatus(hdiStatus);
63 }
64 
OnPhotoSessionDied()65 void PhotoProcessResult::OnPhotoSessionDied()
66 {
67     DP_ERR_LOG("DPS_PHOTO: OnPhotoSessionDied");
68     auto ret = DPS_SendCommand<PhotoDiedCommand>(userId_);
69     DP_CHECK_ERROR_RETURN_LOG(ret != DP_OK, "process photoSessionDied. ret: %{public}d", ret);
70 }
71 
72 
ProcessPictureInfoV1_3(const std::string & imageId,const HDI::Camera::V1_3::ImageBufferInfoExt & buffer)73 int32_t PhotoProcessResult::ProcessPictureInfoV1_3(const std::string& imageId,
74     const HDI::Camera::V1_3::ImageBufferInfoExt& buffer)
75 {
76     auto bufferHandle = buffer.imageHandle->GetBufferHandle();
77     DP_CHECK_ERROR_RETURN_RET_LOG(bufferHandle == nullptr, DPS_ERROR_IMAGE_PROC_FAILED, "bufferHandle is nullptr.");
78 
79     int32_t deferredFormat = 0;
80     GetMetadataValue(buffer.metadata, MetadataKeys::DEFERRED_FORMAT, deferredFormat);
81     if (deferredFormat != static_cast<int32_t>(PhotoFormat::YUV)) {
82         return ProcessBufferInfo(imageId, buffer);
83     }
84 
85     auto imageInfo = CreateFromMeta(bufferHandle->size, buffer.metadata);
86     std::shared_ptr<PictureIntf> picture = AssemblePicture(buffer);
87     DP_CHECK_ERROR_RETURN_RET_LOG(picture == nullptr, DPS_ERROR_IMAGE_PROC_FAILED, "failed to AssemblePicture.");
88 
89     imageInfo->SetPicture(picture);
90     OnProcessDone(imageId, std::move(imageInfo));
91     return DP_OK;
92 }
93 
CreateFromMeta(int32_t defaultSize,const sptr<HDI::Camera::V1_0::MapDataSequenceable> & metadata)94 std::unique_ptr<ImageInfo> PhotoProcessResult::CreateFromMeta(int32_t defaultSize,
95     const sptr<HDI::Camera::V1_0::MapDataSequenceable>& metadata)
96 {
97     int32_t dataSize = defaultSize;
98     int32_t isDegradedImage = 0;
99     uint32_t cloudFlag = 0;
100     GetMetadataValue(metadata, MetadataKeys::DATA_SIZE, dataSize);
101     GetMetadataValue(metadata, MetadataKeys::DEGRADED_IMAGE, isDegradedImage);
102     GetMetadataValue(metadata, MetadataKeys::CLOUD_FLAG, cloudFlag);
103     bool isHighQuality = isDegradedImage == 0;
104     DP_INFO_LOG("DPS_PHOTO: bufferHandle param size: %{public}d, dataSize: %{public}d, "
105         "isDegradedImage: %{public}d, cloudFlag: %{public}u", defaultSize, dataSize, isDegradedImage, cloudFlag);
106     return std::make_unique<ImageInfo>(dataSize, isHighQuality, cloudFlag);
107 }
108 
AssemblePicture(const HDI::Camera::V1_3::ImageBufferInfoExt & buffer)109 std::shared_ptr<PictureIntf> PhotoProcessResult::AssemblePicture(const HDI::Camera::V1_3::ImageBufferInfoExt& buffer)
110 {
111     int32_t exifDataSize = 0;
112     int32_t rotationInIps = false;
113     GetMetadataValue(buffer.metadata, MetadataKeys::EXIF_SIZE, exifDataSize);
114     GetMetadataValue(buffer.metadata, MetadataKeys::ROTATION_IN_IPS, rotationInIps);
115     auto imageBuffer = TransBufferHandleToSurfaceBuffer(buffer.imageHandle->GetBufferHandle());
116     DP_CHECK_ERROR_RETURN_RET_LOG(imageBuffer == nullptr, nullptr, "bufferHandle is nullptr.");
117 
118     DP_INFO_LOG("DPS_PHOTO: AssemblePicture: gainMap(%{public}d), depthMap(%{public}d), unrefocusMap(%{public}d), "
119         "linearMap(%{public}d), exif(%{public}d), makeInfo(%{public}d), exifDataSize(%{public}d)",
120         buffer.isGainMapValid, buffer.isDepthMapValid, buffer.isUnrefocusImageValid,
121         buffer.isHighBitDepthLinearImageValid, buffer.isExifValid, buffer.isMakerInfoValid, exifDataSize);
122     std::shared_ptr<PictureIntf> picture = PictureProxy::CreatePictureProxy();
123     DP_CHECK_ERROR_RETURN_RET_LOG(picture == nullptr, nullptr, "picture is nullptr.");
124     picture->CreateWithDeepCopySurfaceBuffer(imageBuffer);
125 
126     if (buffer.isExifValid) {
127         auto exifBuffer = TransBufferHandleToSurfaceBuffer(buffer.exifHandle->GetBufferHandle());
128         sptr<BufferExtraData> extraData = sptr<BufferExtraDataImpl>::MakeSptr();
129         extraData->ExtraSet(MetadataKeys::EXIF_SIZE, exifDataSize);
130         if (exifBuffer) {
131             exifBuffer->SetExtraData(extraData);
132         }
133         picture->SetExifMetadata(exifBuffer);
134     }
135 
136     AssemleAuxilaryPicture(buffer, picture);
137     DP_CHECK_ERROR_RETURN_RET_LOG(rotationInIps, picture, "HAL rotationInIps");
138     picture->RotatePicture();
139     return picture;
140 }
141 
TransBufferHandleToSurfaceBuffer(const BufferHandle * bufferHandle)142 sptr<SurfaceBuffer> PhotoProcessResult::TransBufferHandleToSurfaceBuffer(const BufferHandle *bufferHandle)
143 {
144     DP_CHECK_ERROR_RETURN_RET_LOG(bufferHandle == nullptr, nullptr, "bufferHandle is nullptr.");
145     sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
146     DP_CHECK_ERROR_RETURN_RET_LOG(surfaceBuffer == nullptr, nullptr, "surfaceBuffer is nullptr.");
147     auto surfaceBufferHandle = CloneBufferHandle(bufferHandle);
148     DP_CHECK_ERROR_RETURN_RET_LOG(surfaceBufferHandle == nullptr, nullptr, "surfaceBufferHandle is nullptr.");
149     surfaceBuffer->SetBufferHandle(surfaceBufferHandle);
150     DP_INFO_LOG("TransBufferHandleToSurfaceBuffer w=%{public}d, h=%{public}d, f=%{public}d",
151         surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), surfaceBuffer->GetFormat());
152     return DpCopyBuffer(surfaceBuffer);
153 }
154 
CloneBufferHandle(const BufferHandle * handle)155 BufferHandle* PhotoProcessResult::CloneBufferHandle(const BufferHandle* handle)
156 {
157     DP_CHECK_ERROR_RETURN_RET_LOG(handle == nullptr, nullptr, "bufferHandle is nullptr.");
158 
159     BufferHandleGuard newHandleGuard(AllocateBufferHandle(handle->reserveFds, handle->reserveInts));
160     DP_CHECK_ERROR_RETURN_RET_LOG(newHandleGuard.handle_ == nullptr, nullptr,
161         "AllocateBufferHandle failed, newHandle is nullptr.");
162 
163     BufferHandle* newHandle = newHandleGuard.handle_;
164     // 基础字段拷贝
165     static constexpr size_t BASE_FIELDS_SIZE = offsetof(BufferHandle, reserve);
166     auto ret = memcpy_s(newHandle, BASE_FIELDS_SIZE, handle, BASE_FIELDS_SIZE);
167     DP_CHECK_ERROR_RETURN_RET_LOG(ret != EOK, nullptr, "CloneBufferHandle: Base fields copy failed");
168 
169     if (handle->fd != -1) {
170         newHandle->fd = dup(handle->fd);
171         DP_CHECK_ERROR_RETURN_RET_LOG(newHandle->fd == -1, nullptr,
172             "CloneBufferHandle: FD dup failed (errno:%{public}d)", errno);
173     }
174 
175     for (uint32_t i = 0; i < newHandle->reserveFds; i++) {
176         newHandle->reserve[i] = dup(handle->reserve[i]);
177         DP_CHECK_ERROR_RETURN_RET_LOG(newHandle->reserve[i] == -1, nullptr, "CloneBufferHandle dup reserveFds failed");
178     }
179 
180     if (handle->reserveInts > 0) {
181         const size_t intsSize = sizeof(int32_t) * handle->reserveInts;
182         const void* src = &handle->reserve[handle->reserveFds];
183         void* dest = &newHandle->reserve[newHandle->reserveFds];
184         ret = memcpy_s(dest, intsSize, src, intsSize);
185         DP_CHECK_ERROR_RETURN_RET_LOG(ret != EOK, nullptr, "CloneBufferHandle: Reserve ints copy failed");
186     }
187 
188     return newHandleGuard.release();
189 }
190 
DpCopyBuffer(const sptr<SurfaceBuffer> & surfaceBuffer)191 sptr<SurfaceBuffer> PhotoProcessResult::DpCopyBuffer(const sptr<SurfaceBuffer>& surfaceBuffer)
192 {
193     DP_CHECK_ERROR_RETURN_RET_LOG(surfaceBuffer == nullptr, nullptr, "surfaceBuffer is nullptr");
194     DP_DEBUG_LOG("DpCopyBuffer w=%{public}d, h=%{public}d, f=%{public}d",
195         surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), surfaceBuffer->GetFormat());
196     BufferRequestConfig requestConfig = {
197         .width = surfaceBuffer->GetWidth(),
198         .height = surfaceBuffer->GetHeight(),
199         .strideAlignment = 0x8, // default stride is 8 Bytes.
200         .format = surfaceBuffer->GetFormat(),
201         .usage = surfaceBuffer->GetUsage(),
202         .timeout = 0,
203         .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
204         .transform = surfaceBuffer->GetSurfaceBufferTransform(),
205     };
206     sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
207     DP_CHECK_ERROR_RETURN_RET_LOG(newSurfaceBuffer == nullptr, nullptr, "newSurfaceBuffer is nullptr.");
208     auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
209     DP_DEBUG_LOG("DpCopyBuffer SurfaceBuffer alloc ret: %{public}d", allocErrorCode);
210     DP_CHECK_ERROR_RETURN_RET_LOG(allocErrorCode != GSError::GSERROR_OK, nullptr,
211         "DpCopyBuffer Alloc faled!, errCode:%{public}d", static_cast<int32_t>(allocErrorCode));
212 
213     errno_t errNo = memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
214         surfaceBuffer->GetVirAddr(), surfaceBuffer->GetSize());
215     DP_CHECK_ERROR_RETURN_RET_LOG(errNo != EOK, nullptr, "DpCopyBuffer memcpy_s failed");
216     DpCopyMetaData(surfaceBuffer, newSurfaceBuffer);
217     DP_DEBUG_LOG("DpCopyBuffer memcpy end");
218     return newSurfaceBuffer;
219 }
220 
DpCopyMetaData(const sptr<SurfaceBuffer> & inBuffer,sptr<SurfaceBuffer> & outBuffer)221 void PhotoProcessResult::DpCopyMetaData(const sptr<SurfaceBuffer>& inBuffer, sptr<SurfaceBuffer>& outBuffer)
222 {
223     std::vector<uint32_t> keys = {};
224     DP_CHECK_ERROR_RETURN_LOG(inBuffer == nullptr || outBuffer == nullptr,
225         "DpCopyMetaData: inBuffer or outBuffer is nullptr.");
226     auto ret = inBuffer->ListMetadataKeys(keys);
227     DP_CHECK_ERROR_RETURN_LOG(ret != GSError::GSERROR_OK, "DpCopyMetaData: ListMetadataKeys fail!");
228     for (uint32_t key : keys) {
229         std::vector<uint8_t> values;
230         ret = inBuffer->GetMetadata(key, values);
231         DP_LOOP_CONTINUE_LOG(ret != GSError::GSERROR_OK,
232             "GetMetadata fail! key = %{public}d res = %{public}d", key, ret);
233 
234         ret = outBuffer->SetMetadata(key, values);
235         DP_LOOP_CONTINUE_LOG(ret != GSError::GSERROR_OK,
236             "SetMetadata fail! key = %{public}d res = %{public}d", key, ret);
237     }
238 }
239 
SetAuxiliaryPicture(const std::shared_ptr<PictureIntf> & picture,BufferHandle * bufferHandle,CameraAuxiliaryPictureType type)240 void PhotoProcessResult::SetAuxiliaryPicture(const std::shared_ptr<PictureIntf>& picture, BufferHandle *bufferHandle,
241     CameraAuxiliaryPictureType type)
242 {
243     DP_INFO_LOG("entered, AuxiliaryPictureType type = %{public}d", static_cast<int32_t>(type));
244     DP_CHECK_ERROR_RETURN_LOG(picture == nullptr || bufferHandle == nullptr, "bufferHandle is nullptr.");
245 
246     auto buffer = TransBufferHandleToSurfaceBuffer(bufferHandle);
247     picture->SetAuxiliaryPicture(buffer, type);
248 }
249 
AssemleAuxilaryPicture(const OHOS::HDI::Camera::V1_3::ImageBufferInfoExt & buffer,const std::shared_ptr<PictureIntf> & picture)250 void PhotoProcessResult::AssemleAuxilaryPicture(const OHOS::HDI::Camera::V1_3::ImageBufferInfoExt& buffer,
251     const std::shared_ptr<PictureIntf>& picture)
252 {
253     if (buffer.isGainMapValid) {
254         SetAuxiliaryPicture(picture, buffer.gainMapHandle->GetBufferHandle(),
255             CameraAuxiliaryPictureType::GAINMAP);
256     }
257     if (buffer.isDepthMapValid) {
258         SetAuxiliaryPicture(picture, buffer.depthMapHandle->GetBufferHandle(),
259             CameraAuxiliaryPictureType::DEPTH_MAP);
260     }
261     if (buffer.isUnrefocusImageValid) {
262         SetAuxiliaryPicture(picture, buffer.unrefocusImageHandle->GetBufferHandle(),
263             CameraAuxiliaryPictureType::UNREFOCUS_MAP);
264     }
265     if (buffer.isHighBitDepthLinearImageValid) {
266         SetAuxiliaryPicture(picture, buffer.highBitDepthLinearImageHandle->GetBufferHandle(),
267             CameraAuxiliaryPictureType::LINEAR_MAP);
268     }
269     if (buffer.isMakerInfoValid) {
270         auto makerInfoBuffer = TransBufferHandleToSurfaceBuffer(buffer.makerInfoHandle->GetBufferHandle());
271         picture->SetMaintenanceData(makerInfoBuffer);
272     }
273 }
274 
ReportEvent(const std::string & imageId)275 void PhotoProcessResult::ReportEvent(const std::string& imageId)
276 {
277     DPSEventReport::GetInstance().UpdateProcessDoneTime(imageId, userId_);
278 }
279 } // namespace DeferredProcessing
280 } // namespace CameraStandard
281 } // namespace OHOS