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