1 /*
2 * Copyright (c) 2021-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 "output/photo_output_napi.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <memory>
21 #include <mutex>
22 #include <string>
23 #include <unistd.h>
24 #include <unordered_set>
25 #include <uv.h>
26
27 #include "buffer_extra_data_impl.h"
28 #include "camera_buffer_handle_utils.h"
29 #include "camera_error_code.h"
30 #include "camera_log.h"
31 #include "camera_manager.h"
32 #include "camera_napi_const.h"
33 #include "camera_napi_object_types.h"
34 #include "camera_napi_param_parser.h"
35 #include "camera_napi_security_utils.h"
36 #include "camera_napi_template_utils.h"
37 #include "camera_napi_utils.h"
38 #include "camera_napi_worker_queue_keeper.h"
39 #include "camera_output_capability.h"
40 #include "camera_photo_proxy.h"
41 #include "camera_util.h"
42 #include "dp_utils.h"
43 #include "image_napi.h"
44 #include "image_packer.h"
45 #include "image_receiver.h"
46 #include "ipc_skeleton.h"
47 #include "js_native_api.h"
48 #include "js_native_api_types.h"
49 #include "listener_base.h"
50 #include "media_library_comm_napi.h"
51 #include "media_library_manager.h"
52 #include "metadata.h"
53 #include "output/deferred_photo_proxy_napi.h"
54 #include "output/photo_napi.h"
55 #include "photo_output.h"
56 #include "pixel_map_napi.h"
57 #include "refbase.h"
58 #include "securec.h"
59 #include "task_manager.h"
60 #include "video_key_info.h"
61 #include "camera_dynamic_loader.h"
62 #include "metadata_helper.h"
63 #include <drivers/interface/display/graphic/common/v1_0/cm_color_space.h>
64 #include "napi/native_node_api.h"
65 #include "picture_proxy.h"
66 #include "hdr_type.h"
67
68 namespace OHOS {
69 namespace CameraStandard {
70 using namespace std;
71 namespace {
72 using namespace HDI::Display::Graphic::Common::V1_0;
73 static const std::unordered_map<CM_ColorSpaceType, OHOS::ColorManager::ColorSpaceName> COLORSPACE_MAP = {
74 {CM_COLORSPACE_NONE, OHOS::ColorManager::ColorSpaceName::NONE},
75 {CM_BT601_EBU_FULL, OHOS::ColorManager::ColorSpaceName::BT601_EBU},
76 {CM_BT601_SMPTE_C_FULL, OHOS::ColorManager::ColorSpaceName::BT601_SMPTE_C},
77 {CM_BT709_FULL, OHOS::ColorManager::ColorSpaceName::BT709},
78 {CM_BT2020_HLG_FULL, OHOS::ColorManager::ColorSpaceName::BT2020_HLG},
79 {CM_BT2020_PQ_FULL, OHOS::ColorManager::ColorSpaceName::BT2020_PQ},
80 {CM_BT601_EBU_LIMIT, OHOS::ColorManager::ColorSpaceName::BT601_EBU_LIMIT},
81 {CM_BT601_SMPTE_C_LIMIT, OHOS::ColorManager::ColorSpaceName::BT601_SMPTE_C_LIMIT},
82 {CM_BT709_LIMIT, OHOS::ColorManager::ColorSpaceName::BT709_LIMIT},
83 {CM_BT2020_HLG_LIMIT, OHOS::ColorManager::ColorSpaceName::BT2020_HLG_LIMIT},
84 {CM_BT2020_PQ_LIMIT, OHOS::ColorManager::ColorSpaceName::BT2020_PQ_LIMIT},
85 {CM_SRGB_FULL, OHOS::ColorManager::ColorSpaceName::SRGB},
86 {CM_P3_FULL, OHOS::ColorManager::ColorSpaceName::DISPLAY_P3},
87 {CM_P3_HLG_FULL, OHOS::ColorManager::ColorSpaceName::P3_HLG},
88 {CM_P3_PQ_FULL, OHOS::ColorManager::ColorSpaceName::P3_PQ},
89 {CM_ADOBERGB_FULL, OHOS::ColorManager::ColorSpaceName::ADOBE_RGB},
90 {CM_SRGB_LIMIT, OHOS::ColorManager::ColorSpaceName::SRGB_LIMIT},
91 {CM_P3_LIMIT, OHOS::ColorManager::ColorSpaceName::DISPLAY_P3_LIMIT},
92 {CM_P3_HLG_LIMIT, OHOS::ColorManager::ColorSpaceName::P3_HLG_LIMIT},
93 {CM_P3_PQ_LIMIT, OHOS::ColorManager::ColorSpaceName::P3_PQ_LIMIT},
94 {CM_ADOBERGB_LIMIT, OHOS::ColorManager::ColorSpaceName::ADOBE_RGB_LIMIT},
95 {CM_LINEAR_SRGB, OHOS::ColorManager::ColorSpaceName::LINEAR_SRGB},
96 {CM_LINEAR_BT709, OHOS::ColorManager::ColorSpaceName::LINEAR_BT709},
97 {CM_LINEAR_P3, OHOS::ColorManager::ColorSpaceName::LINEAR_P3},
98 {CM_LINEAR_BT2020, OHOS::ColorManager::ColorSpaceName::LINEAR_BT2020},
99 {CM_DISPLAY_SRGB, OHOS::ColorManager::ColorSpaceName::DISPLAY_SRGB},
100 {CM_DISPLAY_P3_SRGB, OHOS::ColorManager::ColorSpaceName::DISPLAY_P3_SRGB},
101 {CM_DISPLAY_P3_HLG, OHOS::ColorManager::ColorSpaceName::DISPLAY_P3_HLG},
102 {CM_DISPLAY_P3_PQ, OHOS::ColorManager::ColorSpaceName::DISPLAY_P3_PQ},
103 {CM_DISPLAY_BT2020_SRGB, OHOS::ColorManager::ColorSpaceName::DISPLAY_BT2020_SRGB},
104 {CM_DISPLAY_BT2020_HLG, OHOS::ColorManager::ColorSpaceName::DISPLAY_BT2020_HLG},
105 {CM_DISPLAY_BT2020_PQ, OHOS::ColorManager::ColorSpaceName::DISPLAY_BT2020_PQ}
106 };
107
AsyncCompleteCallback(napi_env env,napi_status status,void * data)108 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
109 {
110 auto context = static_cast<PhotoOutputAsyncContext*>(data);
111 CHECK_ERROR_RETURN_LOG(context == nullptr, "CameraInputNapi AsyncCompleteCallback context is null");
112 MEDIA_INFO_LOG("CameraInputNapi AsyncCompleteCallback %{public}s, status = %{public}d", context->funcName.c_str(),
113 context->status);
114 std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
115 jsContext->status = context->status;
116
117 if (!context->status) {
118 CameraNapiUtils::CreateNapiErrorObject(env, context->errorCode, context->errorMsg.c_str(), jsContext);
119 } else {
120 napi_get_undefined(env, &jsContext->data);
121 }
122 if (!context->funcName.empty() && context->taskId > 0) {
123 // Finish async trace
124 CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
125 jsContext->funcName = context->funcName;
126 }
127 CHECK_EXECUTE(context->work != nullptr,
128 CameraNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef, context->work, *jsContext));
129 context->FreeHeldNapiValue(env);
130 delete context;
131 }
132
ProcessCapture(PhotoOutputAsyncContext * context,bool isBurst)133 void ProcessCapture(PhotoOutputAsyncContext* context, bool isBurst)
134 {
135 context->status = true;
136 sptr<PhotoOutput> photoOutput = context->objectInfo->GetPhotoOutput();
137 MEDIA_INFO_LOG("PhotoOutputAsyncContext objectInfo GetEnableMirror is %{public}d",
138 context->objectInfo->GetEnableMirror());
139 if (context->hasPhotoSettings) {
140 std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
141 CHECK_EXECUTE(context->quality != -1,
142 capSettings->SetQuality(static_cast<PhotoCaptureSetting::QualityLevel>(context->quality)));
143 CHECK_EXECUTE(context->rotation != -1,
144 capSettings->SetRotation(static_cast<PhotoCaptureSetting::RotationConfig>(context->rotation)));
145 if (!context->isMirrorSettedByUser) {
146 capSettings->SetMirror(context->objectInfo->GetEnableMirror());
147 } else {
148 capSettings->SetMirror(context->isMirror);
149 }
150 CHECK_EXECUTE(context->location != nullptr, capSettings->SetLocation(context->location));
151 if (isBurst) {
152 MEDIA_ERR_LOG("ProcessContext BurstCapture");
153 uint8_t burstState = 1; // 0:end 1:start
154 capSettings->SetBurstCaptureState(burstState);
155 }
156 context->errorCode = photoOutput->Capture(capSettings);
157 } else {
158 std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
159 capSettings->SetMirror(context->objectInfo->GetEnableMirror());
160 context->errorCode = photoOutput->Capture(capSettings);
161 }
162 context->status = context->errorCode == 0;
163 }
164
CopyMetaData(sptr<SurfaceBuffer> & inBuffer,sptr<SurfaceBuffer> & outBuffer)165 void CopyMetaData(sptr<SurfaceBuffer> &inBuffer, sptr<SurfaceBuffer> &outBuffer)
166 {
167 std::vector<uint32_t> keys = {};
168 CHECK_ERROR_RETURN_LOG(inBuffer == nullptr, "CopyMetaData: inBuffer is nullptr");
169 auto ret = inBuffer->ListMetadataKeys(keys);
170 CHECK_ERROR_RETURN_LOG(ret != GSError::GSERROR_OK,
171 "CopyMetaData: ListMetadataKeys fail! res=%{public}d", ret);
172 for (uint32_t key : keys) {
173 std::vector<uint8_t> values;
174 ret = inBuffer->GetMetadata(key, values);
175 if (ret != 0) {
176 MEDIA_INFO_LOG("GetMetadata fail! key = %{public}d res = %{public}d", key, ret);
177 continue;
178 }
179 ret = outBuffer->SetMetadata(key, values);
180 if (ret != 0) {
181 MEDIA_INFO_LOG("SetMetadata fail! key = %{public}d res = %{public}d", key, ret);
182 continue;
183 }
184 }
185 }
186
ValidQualityLevelFromJs(int32_t jsQuality)187 bool ValidQualityLevelFromJs(int32_t jsQuality)
188 {
189 MEDIA_INFO_LOG("PhotoOutputNapi::ValidQualityLevelFromJs quality level = %{public}d", jsQuality);
190 switch (jsQuality) {
191 case QUALITY_LEVEL_HIGH:
192 // Fallthrough
193 case QUALITY_LEVEL_MEDIUM:
194 // Fallthrough
195 case QUALITY_LEVEL_LOW:
196 return true;
197 default:
198 MEDIA_ERR_LOG("Invalid quality value received from application");
199 return false;
200 }
201 return false;
202 }
203
ValidImageRotationFromJs(int32_t jsRotation)204 bool ValidImageRotationFromJs(int32_t jsRotation)
205 {
206 MEDIA_INFO_LOG("js rotation = %{public}d", jsRotation);
207 switch (jsRotation) {
208 case ROTATION_0:
209 // Fallthrough
210 case ROTATION_90:
211 // Fallthrough
212 case ROTATION_180:
213 // Fallthrough
214 case ROTATION_270:
215 return true;
216 default:
217 MEDIA_ERR_LOG("Invalid rotation value received from application");
218 return false;
219 }
220 return false;
221 }
222 } // namespace
223
224 thread_local napi_ref PhotoOutputNapi::sConstructor_ = nullptr;
225 thread_local sptr<PhotoOutput> PhotoOutputNapi::sPhotoOutput_ = nullptr;
226 thread_local uint32_t PhotoOutputNapi::photoOutputTaskId = CAMERA_PHOTO_OUTPUT_TASKID;
227 thread_local napi_ref PhotoOutputNapi::rawCallback_ = nullptr;
228 static uv_sem_t g_captureStartSem;
229 static bool g_isSemInited;
230 static std::mutex g_photoImageMutex;
231 static std::mutex g_assembleImageMutex;
232 static int32_t g_captureId;
233
PhotoListener(napi_env env,const sptr<Surface> photoSurface,wptr<PhotoOutput> photoOutput)234 PhotoListener::PhotoListener(napi_env env, const sptr<Surface> photoSurface, wptr<PhotoOutput> photoOutput)
235 : ListenerBase(env), photoSurface_(photoSurface), photoOutput_(photoOutput)
236 {
237 if (bufferProcessor_ == nullptr && photoSurface != nullptr) {
238 bufferProcessor_ = std::make_shared<PhotoBufferProcessor>(photoSurface);
239 }
240 }
241
~PhotoListener()242 PhotoListener::~PhotoListener()
243 {
244 ClearTaskManager();
245 }
246
RawPhotoListener(napi_env env,const sptr<Surface> rawPhotoSurface)247 RawPhotoListener::RawPhotoListener(napi_env env, const sptr<Surface> rawPhotoSurface)
248 : ListenerBase(env), rawPhotoSurface_(rawPhotoSurface)
249 {
250 if (bufferProcessor_ == nullptr && rawPhotoSurface != nullptr) {
251 bufferProcessor_ = std::make_shared<PhotoBufferProcessor>(rawPhotoSurface);
252 }
253 }
254
AuxiliaryPhotoListener(const std::string surfaceName,const sptr<Surface> surface,wptr<PhotoOutput> photoOutput)255 AuxiliaryPhotoListener::AuxiliaryPhotoListener(const std::string surfaceName, const sptr<Surface> surface,
256 wptr<PhotoOutput> photoOutput) : surfaceName_(surfaceName), surface_(surface), photoOutput_(photoOutput)
257 {
258 if (bufferProcessor_ == nullptr && surface != nullptr) {
259 bufferProcessor_ = std::make_shared<PhotoBufferProcessor>(surface);
260 }
261 }
262
GetCaptureId(sptr<SurfaceBuffer> surfaceBuffer)263 int32_t GetCaptureId(sptr<SurfaceBuffer> surfaceBuffer)
264 {
265 int32_t captureId;
266 int32_t burstSeqId = -1;
267 int32_t maskBurstSeqId;
268 int32_t invalidSeqenceId = -1;
269 int32_t captureIdMask = 0x0000FFFF;
270 int32_t captureIdShit = 16;
271 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
272 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
273 if (burstSeqId != invalidSeqenceId && captureId >= 0) {
274 maskBurstSeqId = ((captureId & captureIdMask) << captureIdShit) | burstSeqId;
275 MEDIA_INFO_LOG("PhotoListener captureId:%{public}d, burstSeqId:%{public}d, maskBurstSeqId = %{public}d",
276 captureId, burstSeqId, maskBurstSeqId);
277 return maskBurstSeqId;
278 }
279 MEDIA_INFO_LOG("PhotoListener captureId:%{public}d, burstSeqId:%{public}d", captureId, burstSeqId);
280 return captureId;
281 }
282
InitPictureListeners(napi_env env,wptr<PhotoOutput> photoOutput)283 void PictureListener::InitPictureListeners(napi_env env, wptr<PhotoOutput> photoOutput)
284 {
285 CHECK_ERROR_RETURN_LOG(photoOutput == nullptr, "photoOutput is null");
286 SurfaceError ret;
287 string retStr = "";
288 std::string surfaceName = "";
289 if (photoOutput->gainmapSurface_ != nullptr) {
290 surfaceName = CONST_GAINMAP_SURFACE;
291 gainmapImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->gainmapSurface_,
292 photoOutput);
293 ret = photoOutput->gainmapSurface_->RegisterConsumerListener(
294 (sptr<IBufferConsumerListener>&)gainmapImageListener);
295 retStr = ret != SURFACE_ERROR_OK ? retStr + "[gainmap]" : retStr;
296 }
297 if (photoOutput->deepSurface_ != nullptr) {
298 surfaceName = CONST_DEEP_SURFACE;
299 deepImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->deepSurface_,
300 photoOutput);
301 ret = photoOutput->deepSurface_->RegisterConsumerListener(
302 (sptr<IBufferConsumerListener>&)deepImageListener);
303 retStr = ret != SURFACE_ERROR_OK ? retStr + "[deep]" : retStr;
304 }
305 if (photoOutput->exifSurface_ != nullptr) {
306 surfaceName = CONST_EXIF_SURFACE;
307 exifImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->exifSurface_,
308 photoOutput);
309 ret = photoOutput->exifSurface_->RegisterConsumerListener(
310 (sptr<IBufferConsumerListener>&)exifImageListener);
311 retStr = ret != SURFACE_ERROR_OK ? retStr + "[exif]" : retStr;
312 }
313 if (photoOutput->debugSurface_ != nullptr) {
314 surfaceName = CONST_DEBUG_SURFACE;
315 debugImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->debugSurface_,
316 photoOutput);
317 ret = photoOutput->debugSurface_->RegisterConsumerListener(
318 (sptr<IBufferConsumerListener>&)debugImageListener);
319 retStr = ret != SURFACE_ERROR_OK ? retStr + "[debug]" : retStr;
320 }
321 CHECK_ERROR_PRINT_LOG(retStr != "", "register surface consumer listener failed! type = %{public}s", retStr.c_str());
322 }
323
ClearTaskManager()324 void PhotoListener::ClearTaskManager()
325 {
326 std::lock_guard<std::mutex> lock(taskManagerMutex_);
327 if (taskManager_ != nullptr) {
328 taskManager_->CancelAllTasks();
329 taskManager_ = nullptr;
330 }
331 }
332
GetDefaultTaskManager()333 std::shared_ptr<DeferredProcessing::TaskManager> PhotoListener::GetDefaultTaskManager()
334 {
335 constexpr int32_t numThreads = 1;
336 std::lock_guard<std::mutex> lock(taskManagerMutex_);
337 if (taskManager_ == nullptr) {
338 taskManager_ = std::make_shared<DeferredProcessing::TaskManager>("PhotoListener", numThreads, false);
339 }
340 return taskManager_;
341 }
342
DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer,sptr<SurfaceBuffer> surfaceBuffer,int32_t captureId) const343 void AuxiliaryPhotoListener::DeepCopyBuffer(
344 sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer, int32_t captureId) const
345 {
346 CAMERA_SYNC_TRACE;
347 MEDIA_DEBUG_LOG("AuxiliaryPhotoListener::DeepCopyBuffer w=%{public}d, h=%{public}d, f=%{public}d "
348 "surfaceName=%{public}s captureId = %{public}d", surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(),
349 surfaceBuffer->GetFormat(), surfaceName_.c_str(), captureId);
350 BufferRequestConfig requestConfig = {
351 .width = surfaceBuffer->GetWidth(),
352 .height = surfaceBuffer->GetHeight(),
353 .strideAlignment = 0x8, // default stride is 8 Bytes.
354 .format = surfaceBuffer->GetFormat(),
355 .usage = surfaceBuffer->GetUsage(),
356 .timeout = 0,
357 .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
358 .transform = surfaceBuffer->GetSurfaceBufferTransform(),
359 };
360 auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
361 MEDIA_DEBUG_LOG("AuxiliaryPhotoListener::DeepCopyBuffer SurfaceBuffer alloc ret: %{public}d surfaceName=%{public}s "
362 "captureId = %{public}d", allocErrorCode, surfaceName_.c_str(), captureId);
363 CHECK_ERROR_PRINT_LOG(memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
364 surfaceBuffer->GetVirAddr(), surfaceBuffer->GetSize()) != EOK, "PhotoListener memcpy_s failed");
365 MEDIA_DEBUG_LOG("AuxiliaryPhotoListener::DeepCopyBuffer memcpy end surfaceName=%{public}s captureId = %{public}d",
366 surfaceName_.c_str(), captureId);
367 }
368
ExecuteDeepCopySurfaceBuffer()369 void AuxiliaryPhotoListener::ExecuteDeepCopySurfaceBuffer() __attribute__((no_sanitize("cfi")))
370 {
371 CAMERA_SYNC_TRACE;
372 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto ExecuteDeepCopySurfaceBuffer surfaceName = %{public}s",
373 surfaceName_.c_str());
374 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
375 int32_t fence = -1;
376 int64_t timestamp;
377 OHOS::Rect damage;
378 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s AcquireBuffer before", surfaceName_.c_str());
379 SurfaceError surfaceRet = surface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
380 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s AcquireBuffer end", surfaceName_.c_str());
381 CHECK_ERROR_RETURN_LOG(surfaceRet != SURFACE_ERROR_OK, "AuxiliaryPhotoListener Failed to acquire surface buffer");
382 int32_t captureId = GetCaptureId(surfaceBuffer);
383 int32_t dataSize = 0;
384 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, dataSize);
385 // deep copy buffer
386 sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
387 DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer, captureId);
388 BufferHandle* bufferHandle = newSurfaceBuffer->GetBufferHandle();
389 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s ReleaseBuffer captureId=%{public}d, before",
390 surfaceName_.c_str(), captureId);
391 surface_->ReleaseBuffer(surfaceBuffer, -1);
392 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s ReleaseBuffer captureId=%{public}d, end",
393 surfaceName_.c_str(), captureId);
394 CHECK_ERROR_PRINT_LOG(bufferHandle == nullptr, "invalid bufferHandle");
395 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s Map captureId=%{public}d, before",
396 surfaceName_.c_str(), captureId);
397 newSurfaceBuffer->Map();
398 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s Map captureId=%{public}d, end",
399 surfaceName_.c_str(), captureId);
400 if (surfaceName_ == CONST_EXIF_SURFACE) {
401 sptr<BufferExtraData> extraData = new BufferExtraDataImpl();
402 extraData->ExtraSet("exifDataSize", dataSize);
403 newSurfaceBuffer->SetExtraData(extraData);
404 MEDIA_INFO_LOG("AuxiliaryPhotoListener exifDataSize = %{public}d", dataSize);
405 }
406 MEDIA_INFO_LOG("AuxiliaryPhotoListener surfaceName_ = %{public}s w=%{public}d, h=%{public}d, f=%{public}d"
407 "captureId=%{public}d", surfaceName_.c_str(), newSurfaceBuffer->GetWidth(),
408 newSurfaceBuffer->GetHeight(), newSurfaceBuffer->GetFormat(), captureId);
409 {
410 std::lock_guard<std::mutex> lock(g_photoImageMutex);
411 auto photoOutput = photoOutput_.promote();
412 if (photoOutput->captureIdAuxiliaryCountMap_.count(captureId)) {
413 int32_t auxiliaryCount = photoOutput->captureIdAuxiliaryCountMap_[captureId];
414 int32_t expectCount = photoOutput->captureIdCountMap_[captureId];
415 if (auxiliaryCount == -1 || (expectCount != 0 && auxiliaryCount == expectCount)) {
416 MEDIA_INFO_LOG("AuxiliaryPhotoListener ReleaseBuffer, captureId=%{public}d", captureId);
417 return;
418 }
419 }
420 photoOutput->captureIdAuxiliaryCountMap_[captureId]++;
421 switch (SurfaceTypeHelper.ToEnum(surfaceName_)) {
422 case SurfaceType::GAINMAP_SURFACE: {
423 photoOutput->captureIdGainmapMap_[captureId] = newSurfaceBuffer;
424 MEDIA_INFO_LOG("AuxiliaryPhotoListener gainmapSurfaceBuffer_, captureId=%{public}d", captureId);
425 } break;
426 case SurfaceType::DEEP_SURFACE: {
427 photoOutput->captureIdDepthMap_[captureId] = newSurfaceBuffer;
428 MEDIA_INFO_LOG("AuxiliaryPhotoListener deepSurfaceBuffer_, captureId=%{public}d", captureId);
429 } break;
430 case SurfaceType::EXIF_SURFACE: {
431 photoOutput->captureIdExifMap_[captureId] = newSurfaceBuffer;
432 MEDIA_INFO_LOG("AuxiliaryPhotoListener exifSurfaceBuffer_, captureId=%{public}d", captureId);
433 } break;
434 case SurfaceType::DEBUG_SURFACE: {
435 photoOutput->captureIdDebugMap_[captureId] = newSurfaceBuffer;
436 MEDIA_INFO_LOG("AuxiliaryPhotoListener debugSurfaceBuffer_, captureId=%{public}d", captureId);
437 } break;
438 default:
439 break;
440 }
441 MEDIA_INFO_LOG("AuxiliaryPhotoListener auxiliaryPhotoCount = %{public}d, captureCount = %{public}d, "
442 "surfaceName=%{public}s, captureId=%{public}d",
443 photoOutput->captureIdAuxiliaryCountMap_[captureId], photoOutput->captureIdCountMap_[captureId],
444 surfaceName_.c_str(), captureId);
445 if (photoOutput->captureIdCountMap_[captureId] != 0 &&
446 photoOutput->captureIdAuxiliaryCountMap_[captureId] == photoOutput->captureIdCountMap_[captureId]) {
447 uint32_t handle = photoOutput->captureIdHandleMap_[captureId];
448 MEDIA_INFO_LOG("AuxiliaryPhotoListener StopMonitor, surfaceName=%{public}s, handle = %{public}d, "
449 "captureId = %{public}d",
450 surfaceName_.c_str(), handle, captureId);
451 DeferredProcessing::GetGlobalWatchdog().DoTimeout(handle);
452 DeferredProcessing::GetGlobalWatchdog().StopMonitor(handle);
453 photoOutput->captureIdAuxiliaryCountMap_[captureId] = -1;
454 MEDIA_INFO_LOG("AuxiliaryPhotoListener captureIdAuxiliaryCountMap_ = -1");
455 }
456 MEDIA_INFO_LOG("AuxiliaryPhotoListener auxiliaryPhotoCount = %{public}d, captureCount = %{public}d, "
457 "surfaceName=%{public}s, captureId=%{public}d",
458 photoOutput->captureIdAuxiliaryCountMap_[captureId], photoOutput->captureIdCountMap_[captureId],
459 surfaceName_.c_str(), captureId);
460 }
461 }
462
OnBufferAvailable()463 void AuxiliaryPhotoListener::OnBufferAvailable()
464 {
465 CAMERA_SYNC_TRACE;
466 MEDIA_INFO_LOG("AuxiliaryPhotoListener::OnBufferAvailable is called, surfaceName=%{public}s", surfaceName_.c_str());
467 CHECK_ERROR_RETURN_LOG(!surface_, "AuxiliaryPhotoListener napi photoSurface_ is null");
468 auto photoOutput = photoOutput_.promote();
469 if (photoOutput->taskManager_) {
470 wptr<AuxiliaryPhotoListener> thisPtr(this);
471 photoOutput->taskManager_->SubmitTask([thisPtr]() {
472 auto listener = thisPtr.promote();
473 CHECK_EXECUTE(listener, listener->ExecuteDeepCopySurfaceBuffer());
474 });
475 }
476 MEDIA_INFO_LOG("AuxiliaryPhotoListener::OnBufferAvailable is end, surfaceName=%{public}s", surfaceName_.c_str());
477 }
478
GetAuxiliaryPhotoCount(sptr<SurfaceBuffer> surfaceBuffer)479 int32_t PhotoListener::GetAuxiliaryPhotoCount(sptr<SurfaceBuffer> surfaceBuffer)
480 {
481 int32_t auxiliaryCount;
482 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageCount, auxiliaryCount);
483 MEDIA_INFO_LOG("PhotoListener auxiliaryCount:%{public}d", auxiliaryCount);
484 return auxiliaryCount;
485 }
486
CreateCameraPhotoProxy(sptr<SurfaceBuffer> surfaceBuffer)487 sptr<CameraPhotoProxy> CreateCameraPhotoProxy(sptr<SurfaceBuffer> surfaceBuffer)
488 {
489 int32_t isDegradedImage;
490 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
491 MEDIA_INFO_LOG("CreateCameraPhotoProxy isDegradedImage:%{public}d", isDegradedImage);
492 int64_t imageId = 0;
493 int32_t deferredProcessingType;
494 int32_t captureId;
495 int32_t burstSeqId = -1;
496 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageId, imageId);
497 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
498 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
499 // When not in burst mode, burstSequenceId is invalid (-1); otherwise,
500 // it is an incrementing serial number starting from 1
501 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
502 MEDIA_INFO_LOG("CreateCameraPhotoProxy imageId:%{public}" PRId64 ", "
503 "deferredProcessingType:%{public}d, captureId = %{public}d, burstSeqId = %{public}d",
504 imageId, deferredProcessingType, captureId, burstSeqId);
505 // get buffer handle and photo info
506 int32_t photoWidth;
507 int32_t photoHeight;
508 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, photoWidth);
509 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, photoHeight);
510 uint64_t size = static_cast<uint64_t>(surfaceBuffer->GetSize());
511 int32_t extraDataSize = 0;
512 auto res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, extraDataSize);
513 if (res != 0) {
514 MEDIA_INFO_LOG("ExtraGet dataSize error %{public}d", res);
515 } else if (extraDataSize <= 0) {
516 MEDIA_INFO_LOG("ExtraGet dataSize Ok, but size <= 0");
517 } else if (static_cast<uint64_t>(extraDataSize) > size) {
518 MEDIA_INFO_LOG("ExtraGet dataSize Ok,but dataSize %{public}d is bigger than bufferSize %{public}" PRIu64,
519 extraDataSize, size);
520 } else {
521 MEDIA_INFO_LOG("ExtraGet dataSize %{public}d", extraDataSize);
522 size = static_cast<uint64_t>(extraDataSize);
523 }
524 int32_t deferredImageFormat = 0;
525 res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredImageFormat, deferredImageFormat);
526 bool isHighQuality = (isDegradedImage == 0);
527 MEDIA_INFO_LOG("CreateCameraPhotoProxy deferredImageFormat:%{public}d, isHighQuality = %{public}d, "
528 "size:%{public}" PRId64, deferredImageFormat, isHighQuality, size);
529
530 sptr<CameraPhotoProxy> photoProxy = new(std::nothrow) CameraPhotoProxy(
531 nullptr, deferredImageFormat, photoWidth, photoHeight, isHighQuality, captureId, burstSeqId);
532 std::string imageIdStr = std::to_string(imageId);
533 photoProxy->SetDeferredAttrs(imageIdStr, deferredProcessingType, size, deferredImageFormat);
534 return photoProxy;
535 }
536
ExecuteDeepCopySurfaceBuffer()537 void PhotoListener::ExecuteDeepCopySurfaceBuffer() __attribute__((no_sanitize("cfi")))
538 {
539 CAMERA_SYNC_TRACE;
540 auto photoOutput = photoOutput_.promote();
541 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
542 sptr<SurfaceBuffer> newSurfaceBuffer = nullptr;
543 sptr<CameraPhotoProxy> photoProxy = nullptr;
544 int32_t auxiliaryCount = 0;
545 int32_t captureId = -1;
546 int32_t fence = -1;
547 int64_t timestamp;
548 OHOS::Rect damage;
549 MEDIA_DEBUG_LOG("ExecuteDeepCopySurfaceBuffer AcquireBuffer E");
550 SurfaceError surfaceRet = photoSurface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
551 MEDIA_DEBUG_LOG("ExecuteDeepCopySurfaceBuffer AcquireBuffer X");
552 if (surfaceRet != SURFACE_ERROR_OK) {
553 MEDIA_ERR_LOG("PhotoListener Failed to acquire surface buffer");
554 return;
555 }
556 auxiliaryCount = GetAuxiliaryPhotoCount(surfaceBuffer);
557 captureId = GetCaptureId(surfaceBuffer);
558 if (photoOutput != nullptr) {
559 photoOutput->AcquireBufferToPrepareProxy(captureId);
560 }
561 // deep copy buffer
562 newSurfaceBuffer = SurfaceBuffer::Create();
563 MEDIA_DEBUG_LOG("ExecuteDeepCopySurfaceBuffer DeepCopyBuffer E");
564 DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer, captureId);
565 MEDIA_DEBUG_LOG("ExecuteDeepCopySurfaceBuffer DeepCopyBuffer X");
566 MEDIA_DEBUG_LOG("ExecuteDeepCopySurfaceBuffer ReleaseBuffer E");
567 photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
568 MEDIA_DEBUG_LOG("ExecuteDeepCopySurfaceBuffer ReleaseBuffer X");
569 {
570 std::lock_guard<std::mutex> lock(g_photoImageMutex);
571 photoOutput = photoOutput_.promote();
572 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 3");
573 photoOutput->captureIdCountMap_[captureId] = auxiliaryCount;
574 photoOutput->captureIdAuxiliaryCountMap_[captureId]++;
575 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 4 captureId = %{public}d", captureId);
576 photoProxy = CreateCameraPhotoProxy(surfaceBuffer);
577 photoOutput->photoProxyMap_[captureId] = photoProxy;
578 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 5");
579 CHECK_ERROR_RETURN_LOG(!photoProxy, "photoProxy is nullptr");
580 if (photoProxy->isHighQuality_ && (callbackFlag_ & CAPTURE_PHOTO) != 0) {
581 UpdateMainPictureStageOneJSCallback(surfaceBuffer, timestamp);
582 return;
583 }
584
585 BufferHandle* bufferHandle = newSurfaceBuffer->GetBufferHandle();
586 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 6");
587 CHECK_ERROR_RETURN_LOG(bufferHandle == nullptr, "invalid bufferHandle");
588 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 7");
589 newSurfaceBuffer->Map();
590 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 8");
591 photoProxy->bufferHandle_ = bufferHandle;
592
593 std::shared_ptr<PictureIntf> pictureProxy = PictureProxy::CreatePictureProxy();
594 CHECK_ERROR_RETURN_LOG(pictureProxy == nullptr, "pictureProxy is nullptr");
595 pictureProxy->Create(newSurfaceBuffer);
596
597 Media::ImageInfo imageInfo;
598 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto MainSurface w=%{public}d, h=%{public}d, f=%{public}d",
599 newSurfaceBuffer->GetWidth(), newSurfaceBuffer->GetHeight(), newSurfaceBuffer->GetFormat());
600 photoOutput->captureIdPictureMap_[captureId] = pictureProxy;
601 uint32_t pictureHandle;
602 constexpr uint32_t delayMilli = 1 * 1000;
603 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto GetGlobalWatchdog StartMonitor, captureId=%{public}d",
604 captureId);
605 DeferredProcessing::GetGlobalWatchdog().StartMonitor(pictureHandle, delayMilli,
606 [this, captureId, timestamp](uint32_t handle) {
607 MEDIA_INFO_LOG("PhotoListener PhotoListener-Watchdog executed, handle: %{public}d, "
608 "captureId=%{public}d", static_cast<int>(handle), captureId);
609 AssembleAuxiliaryPhoto(timestamp, captureId);
610 auto photoOutput = photoOutput_.promote();
611 if (photoOutput && photoOutput->captureIdAuxiliaryCountMap_.count(captureId)) {
612 photoOutput->captureIdAuxiliaryCountMap_[captureId] = -1;
613 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto captureIdAuxiliaryCountMap_ = -1, "
614 "captureId=%{public}d", captureId);
615 }
616 });
617 photoOutput->captureIdHandleMap_[captureId] = pictureHandle;
618 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto, pictureHandle: %{public}d, captureId=%{public}d "
619 "captureIdCountMap = %{public}d, captureIdAuxiliaryCountMap = %{public}d",
620 pictureHandle, captureId, photoOutput->captureIdCountMap_[captureId],
621 photoOutput->captureIdAuxiliaryCountMap_[captureId]);
622 if (photoOutput->captureIdCountMap_[captureId] != 0 &&
623 photoOutput->captureIdAuxiliaryCountMap_[captureId] == photoOutput->captureIdCountMap_[captureId]) {
624 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto auxiliaryCount is complete, StopMonitor DoTimeout "
625 "handle = %{public}d, captureId = %{public}d", pictureHandle, captureId);
626 DeferredProcessing::GetGlobalWatchdog().DoTimeout(pictureHandle);
627 DeferredProcessing::GetGlobalWatchdog().StopMonitor(pictureHandle);
628 }
629 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto end");
630 }
631 }
632
OnBufferAvailable()633 void PhotoListener::OnBufferAvailable()
634 {
635 CAMERA_SYNC_TRACE;
636 MEDIA_INFO_LOG("PhotoListener::OnBufferAvailable is called");
637 auto photoOutput = photoOutput_.promote();
638 CHECK_ERROR_RETURN_LOG(photoSurface_ == nullptr || photoOutput == nullptr,
639 "PhotoListener photoSurface or photoOutput is null");
640 if (!photoOutput->IsYuvOrHeifPhoto()) {
641 UpdateJSCallbackAsync(photoSurface_);
642 MEDIA_INFO_LOG("PhotoListener::OnBufferAvailable is end");
643 return;
644 }
645 auto taskManager = GetDefaultTaskManager();
646 if (taskManager != nullptr) {
647 wptr<PhotoListener> thisPtr(this);
648 taskManager->SubmitTask([thisPtr]() {
649 auto listener = thisPtr.promote();
650 CHECK_EXECUTE(listener, listener->ExecuteDeepCopySurfaceBuffer());
651 });
652 }
653 MEDIA_INFO_LOG("PhotoListener::OnBufferAvailable is end");
654 }
655
FillNapiObjectWithCaptureId(napi_env env,int32_t captureId,napi_value & photoAsset)656 void FillNapiObjectWithCaptureId(napi_env env, int32_t captureId, napi_value &photoAsset)
657 {
658 napi_value propertyName, propertyValue;
659 napi_create_string_utf8(env, "captureId", NAPI_AUTO_LENGTH, &propertyName);
660 napi_create_int32(env, captureId, &propertyValue);
661 napi_set_property(env, photoAsset, propertyName, propertyValue);
662 MEDIA_INFO_LOG("FillNapiObjectWithCaptureId captureId %{public}d", captureId);
663 }
664
UpdatePictureJSCallback(int32_t captureId,const string uri,int32_t cameraShotType,const std::string burstKey) const665 void PhotoListener::UpdatePictureJSCallback(int32_t captureId, const string uri, int32_t cameraShotType,
666 const std::string burstKey) const
667 {
668 MEDIA_INFO_LOG("PhotoListener:UpdatePictureJSCallback called");
669 std::unique_ptr<PhotoListenerInfo> callbackInfo = std::make_unique<PhotoListenerInfo>(nullptr, shared_from_this());
670 callbackInfo->captureId = captureId;
671 callbackInfo->uri = uri;
672 callbackInfo->cameraShotType = cameraShotType;
673 callbackInfo->burstKey = burstKey;
674 PhotoListenerInfo *event = callbackInfo.get();
675 auto task = [event]() {
676 MEDIA_INFO_LOG("UpdatePictureJSCallback enter");
677 PhotoListenerInfo* callbackInfo = reinterpret_cast<PhotoListenerInfo*>(event);
678 auto listener = callbackInfo->listener_.lock();
679 if (callbackInfo && listener != nullptr) {
680 napi_value result[ARGS_TWO] = { nullptr, nullptr };
681 napi_value retVal;
682 napi_get_undefined(listener->env_, &result[PARAM0]);
683 napi_get_undefined(listener->env_, &result[PARAM1]);
684 result[PARAM1] = Media::MediaLibraryCommNapi::CreatePhotoAssetNapi(listener->env_,
685 callbackInfo->uri, callbackInfo->cameraShotType, callbackInfo->burstKey);
686 FillNapiObjectWithCaptureId(listener->env_, callbackInfo->captureId, result[PARAM1]);
687 MEDIA_INFO_LOG("UpdatePictureJSCallback result %{public}s, type %{public}d, burstKey %{public}s",
688 callbackInfo->uri.c_str(), callbackInfo->cameraShotType, callbackInfo->burstKey.c_str());
689 ExecuteCallbackNapiPara callbackPara {
690 .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
691 MEDIA_DEBUG_LOG("ExecuteCallback CONST_CAPTURE_PHOTO_ASSET_AVAILABLE E");
692 listener->ExecuteCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callbackPara);
693 MEDIA_DEBUG_LOG("ExecuteCallback CONST_CAPTURE_PHOTO_ASSET_AVAILABLE X");
694 MEDIA_INFO_LOG("PhotoListener:UpdateJSCallbackAsync() complete");
695 callbackInfo->listener_.reset();
696 delete callbackInfo;
697 }
698 };
699 if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
700 MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to execute work");
701 } else {
702 callbackInfo.release();
703 }
704 }
705
UpdateMainPictureStageOneJSCallback(sptr<SurfaceBuffer> surfaceBuffer,int64_t timestamp) const706 void PhotoListener::UpdateMainPictureStageOneJSCallback(sptr<SurfaceBuffer> surfaceBuffer, int64_t timestamp) const
707 {
708 MEDIA_INFO_LOG("PhotoListener:UpdateMainPictureStageOneJSCallback called");
709 std::unique_ptr<PhotoListenerInfo> callbackInfo = std::make_unique<PhotoListenerInfo>(nullptr, shared_from_this());
710 callbackInfo->surfaceBuffer = surfaceBuffer;
711 callbackInfo->timestamp = timestamp;
712 PhotoListenerInfo *event = callbackInfo.get();
713 auto task = [event]() {
714 PhotoListenerInfo* callbackInfo = reinterpret_cast<PhotoListenerInfo*>(event);
715 if (callbackInfo && !callbackInfo->listener_.expired()) {
716 MEDIA_INFO_LOG("ExecutePhotoAsset picture");
717 sptr<SurfaceBuffer> surfaceBuffer = callbackInfo->surfaceBuffer;
718 int64_t timestamp = callbackInfo->timestamp;
719 auto listener = callbackInfo->listener_.lock();
720 CHECK_EXECUTE(listener != nullptr, listener->ExecutePhoto(surfaceBuffer, timestamp));
721 callbackInfo->listener_.reset();
722 delete callbackInfo;
723 }
724 };
725 if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
726 MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to execute work");
727 } else {
728 callbackInfo.release();
729 }
730 }
731
LoggingSurfaceBufferInfo(sptr<SurfaceBuffer> buffer,std::string bufName)732 inline void LoggingSurfaceBufferInfo(sptr<SurfaceBuffer> buffer, std::string bufName)
733 {
734 if (buffer) {
735 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto %{public}s w=%{public}d, h=%{public}d, f=%{public}d", bufName.c_str(),
736 buffer->GetWidth(), buffer->GetHeight(), buffer->GetFormat());
737 }
738 };
739
GetLocationBySettings(std::shared_ptr<PhotoCaptureSetting> settings)740 std::shared_ptr<Location> GetLocationBySettings(std::shared_ptr<PhotoCaptureSetting> settings)
741 {
742 auto location = make_shared<Location>();
743 if (settings) {
744 settings->GetLocation(location);
745 MEDIA_INFO_LOG("GetLocationBySettings latitude:%{private}f, longitude:%{private}f",
746 location->latitude, location->longitude);
747 } else {
748 MEDIA_ERR_LOG("GetLocationBySettings failed!");
749 }
750 return location;
751 }
752
GetBurstSeqId(int32_t captureId)753 int32_t GetBurstSeqId(int32_t captureId)
754 {
755 const uint32_t burstSeqIdMask = 0xFFFF;
756 return captureId > 0 ? (static_cast<uint32_t>(captureId) & burstSeqIdMask) : captureId;
757 }
758
CleanAfterTransPicture(sptr<PhotoOutput> photoOutput,int32_t captureId)759 void CleanAfterTransPicture(sptr<PhotoOutput> photoOutput, int32_t captureId)
760 {
761 CHECK_ERROR_RETURN_LOG(!photoOutput, "CleanAfterTransPicture photoOutput is nullptr");
762 photoOutput->photoProxyMap_[captureId] = nullptr;
763 photoOutput->photoProxyMap_.erase(captureId);
764 photoOutput->captureIdPictureMap_.erase(captureId);
765 photoOutput->captureIdGainmapMap_.erase(captureId);
766 photoOutput->captureIdDepthMap_.erase(captureId);
767 photoOutput->captureIdExifMap_.erase(captureId);
768 photoOutput->captureIdDebugMap_.erase(captureId);
769 photoOutput->captureIdAuxiliaryCountMap_.erase(captureId);
770 photoOutput->captureIdCountMap_.erase(captureId);
771 photoOutput->captureIdHandleMap_.erase(captureId);
772 }
773
AssembleAuxiliaryPhoto(int64_t timestamp,int32_t captureId)774 void PhotoListener::AssembleAuxiliaryPhoto(int64_t timestamp, int32_t captureId) __attribute__((no_sanitize("cfi")))
775 {
776 CAMERA_SYNC_TRACE;
777 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto begin captureId %{public}d, burstSeqId %{public}d",
778 captureId, GetBurstSeqId(captureId));
779 std::lock_guard<std::mutex> lock(g_assembleImageMutex);
780 auto photoOutput = photoOutput_.promote();
781 if (photoOutput) {
782 auto location = GetLocationBySettings(photoOutput->GetDefaultCaptureSetting());
783 CHECK_EXECUTE(location && photoOutput->photoProxyMap_[captureId],
784 photoOutput->photoProxyMap_[captureId]->SetLocation(location->latitude, location->longitude));
785 std::shared_ptr<PictureIntf> picture = photoOutput->captureIdPictureMap_[captureId];
786 if (photoOutput->captureIdExifMap_[captureId] && picture) {
787 auto buffer = photoOutput->captureIdExifMap_[captureId];
788 LoggingSurfaceBufferInfo(buffer, "exifSurfaceBuffer");
789 picture->SetExifMetadata(buffer);
790 photoOutput->captureIdExifMap_[captureId] = nullptr;
791 }
792 if (photoOutput->captureIdGainmapMap_[captureId] && picture) {
793 LoggingSurfaceBufferInfo(photoOutput->captureIdGainmapMap_[captureId], "gainmapSurfaceBuffer");
794 picture->SetAuxiliaryPicture(photoOutput->captureIdGainmapMap_[captureId],
795 CameraAuxiliaryPictureType::GAINMAP);
796 photoOutput->captureIdGainmapMap_[captureId] = nullptr;
797 }
798 if (photoOutput->captureIdDepthMap_[captureId] && picture) {
799 LoggingSurfaceBufferInfo(photoOutput->captureIdDepthMap_[captureId], "deepSurfaceBuffer");
800 picture->SetAuxiliaryPicture(photoOutput->captureIdDepthMap_[captureId],
801 CameraAuxiliaryPictureType::DEPTH_MAP);
802 photoOutput->captureIdDepthMap_[captureId] = nullptr;
803 }
804 if (photoOutput->captureIdDebugMap_[captureId] && picture) {
805 auto buffer = photoOutput->captureIdDebugMap_[captureId];
806 LoggingSurfaceBufferInfo(buffer, "debugSurfaceBuffer");
807 picture->SetMaintenanceData(buffer);
808 photoOutput->captureIdDebugMap_[captureId] = nullptr;
809 }
810 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto end captureId %{public}d, burstSeqId %{public}d",
811 captureId, GetBurstSeqId(captureId));
812 if (!picture) {
813 MEDIA_ERR_LOG("CreateMediaLibrary picture is nullptr");
814 return;
815 }
816 std::string uri;
817 int32_t cameraShotType;
818 std::string burstKey = "";
819 MEDIA_DEBUG_LOG("AssembleAuxiliaryPhoto CreateMediaLibrary E");
820 photoOutput->CreateMediaLibrary(picture, photoOutput->photoProxyMap_[captureId],
821 uri, cameraShotType, burstKey, timestamp);
822 MEDIA_DEBUG_LOG("AssembleAuxiliaryPhoto CreateMediaLibrary X");
823 MEDIA_INFO_LOG("CreateMediaLibrary result %{public}s, type %{public}d", uri.c_str(), cameraShotType);
824 UpdatePictureJSCallback(captureId, uri, cameraShotType, burstKey);
825 photoOutput->NotifyOfflinePhotoOutput(captureId);
826 CleanAfterTransPicture(photoOutput, captureId);
827 }
828 }
829
ExecutePhoto(sptr<SurfaceBuffer> surfaceBuffer,int64_t timestamp) const830 void PhotoListener::ExecutePhoto(sptr<SurfaceBuffer> surfaceBuffer, int64_t timestamp) const
831 {
832 MEDIA_INFO_LOG("ExecutePhoto");
833 napi_value result[ARGS_TWO] = {nullptr, nullptr};
834 napi_value retVal;
835 napi_value mainImage = nullptr;
836 std::shared_ptr<Media::NativeImage> image = std::make_shared<Media::NativeImage>(surfaceBuffer,
837 bufferProcessor_, timestamp);
838 napi_get_undefined(env_, &result[PARAM0]);
839 napi_get_undefined(env_, &result[PARAM1]);
840 mainImage = Media::ImageNapi::Create(env_, image);
841 if (mainImage == nullptr) {
842 MEDIA_ERR_LOG("ImageNapi Create failed");
843 napi_get_undefined(env_, &mainImage);
844 }
845 napi_value photoValue = PhotoNapi::CreatePhoto(env_, mainImage);
846 FillNapiObjectWithCaptureId(env_, GetCaptureId(surfaceBuffer), photoValue);
847 result[PARAM1] = photoValue;
848 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
849 ExecuteCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callbackNapiPara);
850 photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
851 }
852
ExecuteDeferredPhoto(sptr<SurfaceBuffer> surfaceBuffer) const853 void PhotoListener::ExecuteDeferredPhoto(sptr<SurfaceBuffer> surfaceBuffer) const
854 {
855 MEDIA_INFO_LOG("ExecuteDeferredPhoto");
856 napi_value result[ARGS_TWO] = {nullptr, nullptr};
857 napi_value retVal;
858
859 BufferHandle* bufferHandle = surfaceBuffer->GetBufferHandle();
860 int64_t imageId;
861 int32_t deferredProcessingType;
862 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageId, imageId);
863 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
864 MEDIA_INFO_LOG("PhotoListener ExecuteDeferredPhoto imageId:%{public}" PRId64 ", deferredProcessingType:%{public}d",
865 imageId, deferredProcessingType);
866
867 // create pixelMap to encode
868 int32_t thumbnailWidth;
869 int32_t thumbnailHeight;
870 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, thumbnailWidth);
871 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, thumbnailHeight);
872 MEDIA_INFO_LOG("thumbnailWidth:%{public}d, thumbnailHeight: %{public}d", thumbnailWidth, thumbnailHeight);
873
874 MEDIA_DEBUG_LOG("w:%{public}d, h:%{public}d, s:%{public}d, fd:%{public}d, size: %{public}d, format: %{public}d",
875 bufferHandle->width, bufferHandle->height, bufferHandle->stride, bufferHandle->fd, bufferHandle->size,
876 bufferHandle->format);
877
878 napi_get_undefined(env_, &result[PARAM0]);
879 napi_get_undefined(env_, &result[PARAM1]);
880
881 // deep copy buffer
882 sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
883 DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer, 0);
884 BufferHandle *newBufferHandle = CameraCloneBufferHandle(newSurfaceBuffer->GetBufferHandle());
885 if (newBufferHandle == nullptr) {
886 napi_value errorCode;
887 napi_create_int32(env_, CameraErrorCode::INVALID_ARGUMENT, &errorCode);
888 result[PARAM0] = errorCode;
889 MEDIA_ERR_LOG("invalid bufferHandle");
890 }
891
892 // call js function
893 sptr<DeferredPhotoProxy> deferredPhotoProxy;
894 std::string imageIdStr = std::to_string(imageId);
895 deferredPhotoProxy = new(std::nothrow) DeferredPhotoProxy(newBufferHandle, imageIdStr, deferredProcessingType,
896 thumbnailWidth, thumbnailHeight);
897 if (deferredPhotoProxy == nullptr) {
898 napi_value errorCode;
899 napi_create_int32(env_, CameraErrorCode::SERVICE_FATL_ERROR, &errorCode);
900 result[PARAM0] = errorCode;
901 MEDIA_ERR_LOG("failed to new deferredPhotoProxy!");
902 }
903 result[PARAM1] = DeferredPhotoProxyNapi::CreateDeferredPhotoProxy(env_, deferredPhotoProxy);
904
905 ExecuteCallbackNapiPara callbackPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
906 ExecuteCallback(CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, callbackPara);
907
908 // return buffer to buffer queue
909 photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
910 }
911
DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer,sptr<SurfaceBuffer> surfaceBuffer,int32_t captureId) const912 void PhotoListener::DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer,
913 int32_t captureId) const
914 {
915 CAMERA_SYNC_TRACE;
916 MEDIA_DEBUG_LOG("PhotoListener::DeepCopyBuffer w=%{public}d, h=%{public}d, f=%{public}d surfaceName=%{public}s "
917 "captureId = %{public}d", surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), surfaceBuffer->GetFormat(),
918 "main", captureId);
919 BufferRequestConfig requestConfig = {
920 .width = surfaceBuffer->GetWidth(),
921 .height = surfaceBuffer->GetHeight(),
922 .strideAlignment = 0x8, // default stride is 8 Bytes.
923 .format = surfaceBuffer->GetFormat(),
924 .usage = surfaceBuffer->GetUsage(),
925 .timeout = 0,
926 .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
927 .transform = surfaceBuffer->GetSurfaceBufferTransform(),
928 };
929 auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
930 MEDIA_DEBUG_LOG("PhotoListener::DeepCopyBuffer SurfaceBuffer alloc ret: %{public}d surfaceName=%{public}s "
931 "captureId = %{public}d", allocErrorCode, "main", captureId);
932 CHECK_ERROR_PRINT_LOG(memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
933 surfaceBuffer->GetVirAddr(), surfaceBuffer->GetSize()) != EOK, "PhotoListener memcpy_s failed");
934 MEDIA_DEBUG_LOG("PhotoListener::DeepCopyBuffer memcpy_s end surfaceName=%{public}s captureId = %{public}d",
935 "main", captureId);
936 }
937
ExecutePhotoAsset(sptr<SurfaceBuffer> surfaceBuffer,bool isHighQuality,int64_t timestamp) const938 void PhotoListener::ExecutePhotoAsset(sptr<SurfaceBuffer> surfaceBuffer, bool isHighQuality, int64_t timestamp) const
939 {
940 CAMERA_SYNC_TRACE;
941 MEDIA_INFO_LOG("ExecutePhotoAsset");
942 napi_value result[ARGS_TWO] = { nullptr, nullptr };
943 napi_value retVal;
944 napi_get_undefined(env_, &result[PARAM0]);
945 napi_get_undefined(env_, &result[PARAM1]);
946 // deep copy buffer
947 sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
948 int32_t captureId = GetCaptureId(surfaceBuffer);
949 DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer, 0);
950 BufferHandle* bufferHandle = newSurfaceBuffer->GetBufferHandle();
951 if (bufferHandle == nullptr) {
952 napi_value errorCode;
953 napi_create_int32(env_, CameraErrorCode::INVALID_ARGUMENT, &errorCode);
954 result[PARAM0] = errorCode;
955 MEDIA_ERR_LOG("invalid bufferHandle");
956 }
957 newSurfaceBuffer->Map();
958 string uri = "";
959 int32_t cameraShotType = 0;
960 std::string burstKey = "";
961 CreateMediaLibrary(surfaceBuffer, bufferHandle, isHighQuality, uri, cameraShotType, burstKey, timestamp);
962 MEDIA_INFO_LOG("CreateMediaLibrary result uri:%{public}s cameraShotType:%{public}d burstKey:%{public}s",
963 uri.c_str(), cameraShotType, burstKey.c_str());
964 napi_value photoAssetValue = Media::MediaLibraryCommNapi::CreatePhotoAssetNapi(env_, uri, cameraShotType, burstKey);
965 FillNapiObjectWithCaptureId(env_, captureId, photoAssetValue);
966 result[PARAM1] = photoAssetValue;
967 ExecuteCallbackNapiPara callbackPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
968 ExecuteCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callbackPara);
969 // return buffer to buffer queue
970 photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
971 }
972
CreateMediaLibrary(sptr<SurfaceBuffer> surfaceBuffer,BufferHandle * bufferHandle,bool isHighQuality,std::string & uri,int32_t & cameraShotType,std::string & burstKey,int64_t timestamp) const973 void PhotoListener::CreateMediaLibrary(sptr<SurfaceBuffer> surfaceBuffer, BufferHandle *bufferHandle,
974 bool isHighQuality, std::string &uri, int32_t &cameraShotType, std::string &burstKey, int64_t timestamp) const
975 {
976 CAMERA_SYNC_TRACE;
977 CHECK_ERROR_RETURN_LOG(bufferHandle == nullptr, "bufferHandle is nullptr");
978 // get buffer handle and photo info
979 int32_t captureId;
980 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
981 int32_t burstSeqId = -1;
982 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
983 int64_t imageId = 0;
984 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageId, imageId);
985 int32_t deferredProcessingType;
986 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
987 MEDIA_INFO_LOG(
988 "PhotoListener ExecutePhotoAsset captureId:%{public}d "
989 "imageId:%{public}" PRId64 ", deferredProcessingType:%{public}d, burstSeqId:%{public}d",
990 captureId, imageId, deferredProcessingType, burstSeqId);
991 int32_t photoWidth;
992 int32_t photoHeight;
993 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, photoWidth);
994 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, photoHeight);
995 uint64_t size = static_cast<uint64_t>(surfaceBuffer->GetSize());
996 int32_t extraDataSize = 0;
997 auto res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, extraDataSize);
998 if (res != 0) {
999 MEDIA_INFO_LOG("ExtraGet dataSize error %{public}d", res);
1000 } else if (extraDataSize <= 0) {
1001 MEDIA_INFO_LOG("ExtraGet dataSize Ok, but size <= 0");
1002 } else if (static_cast<uint64_t>(extraDataSize) > size) {
1003 MEDIA_INFO_LOG("ExtraGet dataSize Ok,but dataSize %{public}d is bigger than bufferSize %{public}" PRIu64,
1004 extraDataSize, size);
1005 } else {
1006 MEDIA_INFO_LOG("ExtraGet dataSize %{public}d", extraDataSize);
1007 size = static_cast<uint64_t>(extraDataSize);
1008 }
1009 int32_t deferredImageFormat = 0;
1010 res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredImageFormat, deferredImageFormat);
1011 MEDIA_INFO_LOG("deferredImageFormat:%{public}d, width:%{public}d, height:%{public}d, size:%{public}" PRId64,
1012 deferredImageFormat, photoWidth, photoHeight, size);
1013 int32_t format = bufferHandle->format;
1014 sptr<CameraPhotoProxy> photoProxy;
1015 std::string imageIdStr = std::to_string(imageId);
1016 photoProxy = new(std::nothrow) CameraPhotoProxy(bufferHandle, format, photoWidth, photoHeight,
1017 isHighQuality, captureId, burstSeqId);
1018 CHECK_ERROR_RETURN_LOG(photoProxy == nullptr, "failed to new photoProxy");
1019 photoProxy->SetDeferredAttrs(imageIdStr, deferredProcessingType, size, deferredImageFormat);
1020 auto photoOutput = photoOutput_.promote();
1021 if (photoOutput) {
1022 auto settings = photoOutput->GetDefaultCaptureSetting();
1023 if (settings) {
1024 auto location = make_shared<Location>();
1025 settings->GetLocation(location);
1026 photoProxy->SetLocation(location->latitude, location->longitude);
1027 }
1028 photoOutput->CreateMediaLibrary(photoProxy, uri, cameraShotType, burstKey, timestamp);
1029 }
1030 }
1031
UpdateJSCallback(sptr<Surface> photoSurface) const1032 void PhotoListener::UpdateJSCallback(sptr<Surface> photoSurface) const
1033 {
1034 CAMERA_SYNC_TRACE;
1035 MEDIA_DEBUG_LOG("PhotoListener UpdateJSCallback enter");
1036 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
1037 int32_t fence = -1;
1038 int64_t timestamp;
1039 OHOS::Rect damage;
1040 SurfaceError surfaceRet = photoSurface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
1041 CHECK_ERROR_RETURN_LOG(surfaceRet != SURFACE_ERROR_OK, "PhotoListener Failed to acquire surface buffer");
1042 MEDIA_INFO_LOG("PhotoListener::UpdateJSCallback ts is:%{public}" PRId64, timestamp);
1043 int32_t isDegradedImage;
1044 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
1045 MEDIA_INFO_LOG("PhotoListener UpdateJSCallback isDegradedImage:%{public}d", isDegradedImage);
1046 if ((callbackFlag_ & CAPTURE_PHOTO_ASSET) != 0) {
1047 auto photoOutput = photoOutput_.promote();
1048 if (photoOutput != nullptr) {
1049 int32_t currentCaptureId = GetCaptureId(surfaceBuffer);
1050 photoOutput->AcquireBufferToPrepareProxy(currentCaptureId);
1051 }
1052 ExecutePhotoAsset(surfaceBuffer, isDegradedImage == 0, timestamp);
1053 } else if (isDegradedImage == 0 && (callbackFlag_ & CAPTURE_PHOTO) != 0) {
1054 ExecutePhoto(surfaceBuffer, timestamp);
1055 } else if (isDegradedImage != 0 && (callbackFlag_ & CAPTURE_DEFERRED_PHOTO) != 0) {
1056 ExecuteDeferredPhoto(surfaceBuffer);
1057 } else {
1058 MEDIA_INFO_LOG("PhotoListener on error callback");
1059 }
1060 }
1061
UpdateJSCallbackAsync(sptr<Surface> photoSurface) const1062 void PhotoListener::UpdateJSCallbackAsync(sptr<Surface> photoSurface) const
1063 {
1064 CAMERA_SYNC_TRACE;
1065 MEDIA_DEBUG_LOG("PhotoListener UpdateJSCallbackAsync enter");
1066 std::unique_ptr<PhotoListenerInfo> callbackInfo =
1067 std::make_unique<PhotoListenerInfo>(photoSurface, shared_from_this());
1068 PhotoListenerInfo *event = callbackInfo.get();
1069 MEDIA_DEBUG_LOG("PhotoListener UpdateJSCallbackAsync uv_queue_work_with_qos start");
1070 auto task = [event]() {
1071 PhotoListenerInfo* callbackInfo = reinterpret_cast<PhotoListenerInfo*>(event);
1072 if (callbackInfo) {
1073 auto listener = callbackInfo->listener_.lock();
1074 CHECK_EXECUTE(listener != nullptr, listener->UpdateJSCallback(callbackInfo->photoSurface_));
1075 MEDIA_INFO_LOG("PhotoListener:UpdateJSCallbackAsync() complete");
1076 callbackInfo->photoSurface_ = nullptr;
1077 callbackInfo->listener_.reset();
1078 delete callbackInfo;
1079 }
1080 };
1081 if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
1082 MEDIA_ERR_LOG("PhotoListener:UpdateJSCallbackAsync() failed to execute work");
1083 } else {
1084 callbackInfo.release();
1085 }
1086 }
1087
SaveCallback(const std::string eventName,napi_value callback)1088 void PhotoListener::SaveCallback(const std::string eventName, napi_value callback)
1089 {
1090 MEDIA_INFO_LOG("PhotoListener::SaveCallback is called eventName:%{public}s", eventName.c_str());
1091 auto eventTypeEnum = PhotoOutputEventTypeHelper.ToEnum(eventName);
1092 switch (eventTypeEnum) {
1093 case PhotoOutputEventType::CAPTURE_PHOTO_AVAILABLE:
1094 callbackFlag_ |= CAPTURE_PHOTO;
1095 break;
1096 case PhotoOutputEventType::CAPTURE_DEFERRED_PHOTO_AVAILABLE:
1097 callbackFlag_ |= CAPTURE_DEFERRED_PHOTO;
1098 break;
1099 case PhotoOutputEventType::CAPTURE_PHOTO_ASSET_AVAILABLE:
1100 callbackFlag_ |= CAPTURE_PHOTO_ASSET;
1101 break;
1102 default:
1103 MEDIA_ERR_LOG("Incorrect photo callback event type received from JS");
1104 return;
1105 }
1106 auto photoOutput = photoOutput_.promote();
1107 if (photoOutput) {
1108 photoOutput->SetCallbackFlag(callbackFlag_);
1109 } else {
1110 MEDIA_ERR_LOG("cannot get photoOutput");
1111 }
1112 SaveCallbackReference(eventName, callback, false);
1113 }
1114
RemoveCallback(const std::string eventName,napi_value callback)1115 void PhotoListener::RemoveCallback(const std::string eventName, napi_value callback)
1116 {
1117 MEDIA_INFO_LOG("PhotoListener::RemoveCallback is called eventName:%{public}s", eventName.c_str());
1118 if (eventName == CONST_CAPTURE_PHOTO_AVAILABLE) {
1119 callbackFlag_ &= ~CAPTURE_PHOTO;
1120 } else if (eventName == CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE) {
1121 callbackFlag_ &= ~CAPTURE_DEFERRED_PHOTO;
1122 } else if (eventName == CONST_CAPTURE_PHOTO_ASSET_AVAILABLE) {
1123 auto photoOutput = photoOutput_.promote();
1124 CHECK_EXECUTE(photoOutput != nullptr,
1125 photoOutput->DeferImageDeliveryFor(DeferredDeliveryImageType::DELIVERY_NONE));
1126 callbackFlag_ &= ~CAPTURE_PHOTO_ASSET;
1127 }
1128 RemoveCallbackRef(eventName, callback);
1129 }
1130
OnBufferAvailable()1131 void RawPhotoListener::OnBufferAvailable()
1132 {
1133 std::lock_guard<std::mutex> lock(g_photoImageMutex);
1134 CAMERA_SYNC_TRACE;
1135 MEDIA_INFO_LOG("RawPhotoListener::OnBufferAvailable is called");
1136 CHECK_ERROR_RETURN_LOG(!rawPhotoSurface_, "RawPhotoListener napi rawPhotoSurface_ is null");
1137 UpdateJSCallbackAsync(rawPhotoSurface_);
1138 }
1139
ExecuteRawPhoto(sptr<SurfaceBuffer> surfaceBuffer) const1140 void RawPhotoListener::ExecuteRawPhoto(sptr<SurfaceBuffer> surfaceBuffer) const
1141 {
1142 MEDIA_INFO_LOG("ExecuteRawPhoto");
1143 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1144 napi_value retVal;
1145 napi_value rawImage = nullptr;
1146 std::shared_ptr<Media::NativeImage> image = std::make_shared<Media::NativeImage>(surfaceBuffer, bufferProcessor_);
1147 napi_get_undefined(env_, &result[PARAM0]);
1148 napi_get_undefined(env_, &result[PARAM1]);
1149 rawImage = Media::ImageNapi::Create(env_, image);
1150 if (rawImage == nullptr) {
1151 MEDIA_ERR_LOG("ImageNapi Create failed");
1152 napi_get_undefined(env_, &rawImage);
1153 }
1154 result[PARAM1] = PhotoNapi::CreateRawPhoto(env_, rawImage);
1155 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1156 ExecuteCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callbackNapiPara);
1157 rawPhotoSurface_->ReleaseBuffer(surfaceBuffer, -1);
1158 }
1159
UpdateJSCallback(sptr<Surface> rawPhotoSurface) const1160 void RawPhotoListener::UpdateJSCallback(sptr<Surface> rawPhotoSurface) const
1161 {
1162 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
1163 int32_t fence = -1;
1164 int64_t timestamp;
1165 OHOS::Rect damage;
1166 SurfaceError surfaceRet = rawPhotoSurface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
1167 CHECK_ERROR_RETURN_LOG(surfaceRet != SURFACE_ERROR_OK, "RawPhotoListener Failed to acquire surface buffer");
1168
1169 int32_t isDegradedImage;
1170 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
1171 MEDIA_INFO_LOG("RawPhotoListener UpdateJSCallback isDegradedImage:%{public}d", isDegradedImage);
1172
1173 if (isDegradedImage == 0) {
1174 ExecuteRawPhoto(surfaceBuffer);
1175 } else {
1176 MEDIA_ERR_LOG("RawPhoto not support deferred photo");
1177 }
1178 }
1179
UpdateJSCallbackAsync(sptr<Surface> rawPhotoSurface) const1180 void RawPhotoListener::UpdateJSCallbackAsync(sptr<Surface> rawPhotoSurface) const
1181 {
1182 std::unique_ptr<RawPhotoListenerInfo> callbackInfo =
1183 std::make_unique<RawPhotoListenerInfo>(rawPhotoSurface, shared_from_this());
1184 RawPhotoListenerInfo *event = callbackInfo.get();
1185 auto task = [event]() {
1186 RawPhotoListenerInfo* callbackInfo = reinterpret_cast<RawPhotoListenerInfo*>(event);
1187 if (callbackInfo) {
1188 auto listener = callbackInfo->listener_.lock();
1189 CHECK_EXECUTE(listener != nullptr, listener->UpdateJSCallback(callbackInfo->rawPhotoSurface_));
1190 MEDIA_INFO_LOG("RawPhotoListener:UpdateJSCallbackAsync() complete");
1191 callbackInfo->rawPhotoSurface_ = nullptr;
1192 callbackInfo->listener_.reset();
1193 delete callbackInfo;
1194 }
1195 };
1196 if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
1197 MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to execute work");
1198 } else {
1199 callbackInfo.release();
1200 }
1201 }
1202
PhotoOutputCallback(napi_env env)1203 PhotoOutputCallback::PhotoOutputCallback(napi_env env) : ListenerBase(env) {}
1204
UpdateJSExecute(uv_work_t * work)1205 void UpdateJSExecute(uv_work_t* work)
1206 {
1207 PhotoOutputCallbackInfo* callbackInfo = reinterpret_cast<PhotoOutputCallbackInfo*>(work->data);
1208 if (callbackInfo) {
1209 if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START ||
1210 callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START_WITH_INFO) {
1211 g_captureId = callbackInfo->info_.captureID;
1212 MEDIA_DEBUG_LOG("UpdateJSExecute CAPTURE_START g_captureId:%{public}d", g_captureId);
1213 }
1214 CHECK_EXECUTE(callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_FRAME_SHUTTER &&
1215 g_captureId != callbackInfo->info_.captureID, uv_sem_wait(&g_captureStartSem));
1216 }
1217 }
1218
UpdateJSCallbackAsync(PhotoOutputEventType eventType,const CallbackInfo & info) const1219 void PhotoOutputCallback::UpdateJSCallbackAsync(PhotoOutputEventType eventType, const CallbackInfo &info) const
1220 {
1221 MEDIA_DEBUG_LOG("UpdateJSCallbackAsync is called");
1222 if (!g_isSemInited) {
1223 uv_sem_init(&g_captureStartSem, 0);
1224 g_isSemInited = true;
1225 }
1226 std::unique_ptr<PhotoOutputCallbackInfo> callbackInfo =
1227 std::make_unique<PhotoOutputCallbackInfo>(eventType, info, shared_from_this());
1228 PhotoOutputCallbackInfo *event = callbackInfo.get();
1229 auto task = [event]() {
1230 PhotoOutputCallbackInfo* callbackInfo = reinterpret_cast<PhotoOutputCallbackInfo *>(event);
1231 if (callbackInfo) {
1232 auto listener = callbackInfo->listener_.lock();
1233 if (listener) {
1234 listener->UpdateJSCallback(callbackInfo->eventType_, callbackInfo->info_);
1235 if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START ||
1236 callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START_WITH_INFO) {
1237 MEDIA_DEBUG_LOG("PhotoOutputEventType::CAPTURE_START work done execute!");
1238 uv_sem_post(&g_captureStartSem);
1239 } else if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_FRAME_SHUTTER) {
1240 MEDIA_DEBUG_LOG("PhotoOutputEventType::CAPTURE_FRAME_SHUTTER work done execute!");
1241 uv_sem_destroy(&g_captureStartSem);
1242 g_isSemInited = false;
1243 }
1244 }
1245 delete callbackInfo;
1246 }
1247 };
1248 if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
1249 MEDIA_ERR_LOG("failed to execute work");
1250 } else {
1251 callbackInfo.release();
1252 }
1253 }
1254
OnCaptureStarted(const int32_t captureID) const1255 void PhotoOutputCallback::OnCaptureStarted(const int32_t captureID) const
1256 {
1257 CAMERA_SYNC_TRACE;
1258 MEDIA_DEBUG_LOG("OnCaptureStarted is called!, captureID: %{public}d", captureID);
1259 CallbackInfo info;
1260 info.captureID = captureID;
1261 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_START_WITH_INFO, info);
1262 }
1263
OnCaptureStarted(const int32_t captureID,uint32_t exposureTime) const1264 void PhotoOutputCallback::OnCaptureStarted(const int32_t captureID, uint32_t exposureTime) const
1265 {
1266 CAMERA_SYNC_TRACE;
1267 MEDIA_DEBUG_LOG("OnCaptureStarted is called!, captureID: %{public}d", captureID);
1268 CallbackInfo info;
1269 info.captureID = captureID;
1270 info.timestamp = exposureTime;
1271 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_START, info);
1272 }
1273
OnCaptureEnded(const int32_t captureID,const int32_t frameCount) const1274 void PhotoOutputCallback::OnCaptureEnded(const int32_t captureID, const int32_t frameCount) const
1275 {
1276 CAMERA_SYNC_TRACE;
1277 MEDIA_INFO_LOG("OnCaptureEnded is called!, captureID: %{public}d, frameCount: %{public}d",
1278 captureID, frameCount);
1279 CallbackInfo info;
1280 info.captureID = captureID;
1281 info.frameCount = frameCount;
1282 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_END, info);
1283 }
1284
OnFrameShutter(const int32_t captureId,const uint64_t timestamp) const1285 void PhotoOutputCallback::OnFrameShutter(const int32_t captureId, const uint64_t timestamp) const
1286 {
1287 CAMERA_SYNC_TRACE;
1288 MEDIA_DEBUG_LOG(
1289 "OnFrameShutter is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
1290 CallbackInfo info;
1291 info.captureID = captureId;
1292 info.timestamp = timestamp;
1293 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_FRAME_SHUTTER, info);
1294 }
1295
OnFrameShutterEnd(const int32_t captureId,const uint64_t timestamp) const1296 void PhotoOutputCallback::OnFrameShutterEnd(const int32_t captureId, const uint64_t timestamp) const
1297 {
1298 CAMERA_SYNC_TRACE;
1299 MEDIA_DEBUG_LOG(
1300 "OnFrameShutterEnd is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
1301 CallbackInfo info;
1302 info.captureID = captureId;
1303 info.timestamp = timestamp;
1304 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_FRAME_SHUTTER_END, info);
1305 }
1306
OnCaptureReady(const int32_t captureId,const uint64_t timestamp) const1307 void PhotoOutputCallback::OnCaptureReady(const int32_t captureId, const uint64_t timestamp) const
1308 {
1309 CAMERA_SYNC_TRACE;
1310 MEDIA_DEBUG_LOG(
1311 "OnCaptureReady is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
1312 CallbackInfo info;
1313 info.captureID = captureId;
1314 info.timestamp = timestamp;
1315 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_READY, info);
1316 }
1317
OnCaptureError(const int32_t captureId,const int32_t errorCode) const1318 void PhotoOutputCallback::OnCaptureError(const int32_t captureId, const int32_t errorCode) const
1319 {
1320 MEDIA_DEBUG_LOG("OnCaptureError is called!, captureID: %{public}d, errorCode: %{public}d", captureId, errorCode);
1321 CallbackInfo info;
1322 info.captureID = captureId;
1323 info.errorCode = errorCode;
1324 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_ERROR, info);
1325 }
1326
OnEstimatedCaptureDuration(const int32_t duration) const1327 void PhotoOutputCallback::OnEstimatedCaptureDuration(const int32_t duration) const
1328 {
1329 MEDIA_DEBUG_LOG("OnEstimatedCaptureDuration is called!, duration: %{public}d", duration);
1330 CallbackInfo info;
1331 info.duration = duration;
1332 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_ESTIMATED_CAPTURE_DURATION, info);
1333 }
1334
OnOfflineDeliveryFinished(const int32_t captureId) const1335 void PhotoOutputCallback::OnOfflineDeliveryFinished(const int32_t captureId) const
1336 {
1337 CAMERA_SYNC_TRACE;
1338 MEDIA_DEBUG_LOG(
1339 "OnOfflineDeliveryFinished is called, captureID: %{public}d", captureId);
1340 CallbackInfo info;
1341 info.captureID = captureId;
1342 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_OFFLINE_DELIVERY_FINISHED, info);
1343 }
1344
ExecuteCaptureStartCb(const CallbackInfo & info) const1345 void PhotoOutputCallback::ExecuteCaptureStartCb(const CallbackInfo& info) const
1346 {
1347 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1348 napi_value retVal;
1349 napi_get_undefined(env_, &result[PARAM0]);
1350 if (IsEmpty(CONST_CAPTURE_START_WITH_INFO)) {
1351 napi_create_int32(env_, info.captureID, &result[PARAM1]);
1352 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO,
1353 .argv = result, .result = &retVal };
1354 ExecuteCallback(CONST_CAPTURE_START, callbackNapiPara);
1355 } else {
1356 napi_value propValue;
1357 napi_create_object(env_, &result[PARAM1]);
1358 napi_create_int32(env_, info.captureID, &propValue);
1359 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1360 int32_t invalidExposureTime = -1;
1361 napi_create_int32(env_, invalidExposureTime, &propValue);
1362 napi_set_named_property(env_, result[PARAM1], "time", propValue);
1363 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO,
1364 .argv = result, .result = &retVal };
1365 ExecuteCallback(CONST_CAPTURE_START_WITH_INFO, callbackNapiPara);
1366 }
1367 }
1368
ExecuteCaptureStartWithInfoCb(const CallbackInfo & info) const1369 void PhotoOutputCallback::ExecuteCaptureStartWithInfoCb(const CallbackInfo& info) const
1370 {
1371 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1372 napi_value retVal;
1373 napi_value propValue;
1374 napi_get_undefined(env_, &result[PARAM0]);
1375 napi_create_object(env_, &result[PARAM1]);
1376 napi_create_int32(env_, info.captureID, &propValue);
1377 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1378 napi_create_int32(env_, info.timestamp, &propValue);
1379 napi_set_named_property(env_, result[PARAM1], "time", propValue);
1380 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1381 ExecuteCallback(CONST_CAPTURE_START_WITH_INFO, callbackNapiPara);
1382 }
1383
ExecuteCaptureEndCb(const CallbackInfo & info) const1384 void PhotoOutputCallback::ExecuteCaptureEndCb(const CallbackInfo& info) const
1385 {
1386 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1387 napi_value retVal;
1388 napi_value propValue;
1389 napi_get_undefined(env_, &result[PARAM0]);
1390 napi_create_object(env_, &result[PARAM1]);
1391 napi_create_int32(env_, info.captureID, &propValue);
1392 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1393 napi_create_int32(env_, info.frameCount, &propValue);
1394 napi_set_named_property(env_, result[PARAM1], "frameCount", propValue);
1395 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1396 ExecuteCallback(CONST_CAPTURE_END, callbackNapiPara);
1397 }
1398
ExecuteFrameShutterCb(const CallbackInfo & info) const1399 void PhotoOutputCallback::ExecuteFrameShutterCb(const CallbackInfo& info) const
1400 {
1401 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1402 napi_value retVal;
1403 napi_value propValue;
1404 napi_get_undefined(env_, &result[PARAM0]);
1405 napi_create_object(env_, &result[PARAM1]);
1406 napi_create_int32(env_, info.captureID, &propValue);
1407 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1408 napi_create_int64(env_, info.timestamp, &propValue);
1409 napi_set_named_property(env_, result[PARAM1], "timestamp", propValue);
1410 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1411 ExecuteCallback(CONST_CAPTURE_FRAME_SHUTTER, callbackNapiPara);
1412 }
1413
ExecuteFrameShutterEndCb(const CallbackInfo & info) const1414 void PhotoOutputCallback::ExecuteFrameShutterEndCb(const CallbackInfo& info) const
1415 {
1416 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1417 napi_value retVal;
1418 napi_value propValue;
1419 napi_get_undefined(env_, &result[PARAM0]);
1420 napi_create_object(env_, &result[PARAM1]);
1421 napi_create_int32(env_, info.captureID, &propValue);
1422 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1423 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1424 ExecuteCallback(CONST_CAPTURE_FRAME_SHUTTER_END, callbackNapiPara);
1425 }
1426
ExecuteCaptureReadyCb(const CallbackInfo & info) const1427 void PhotoOutputCallback::ExecuteCaptureReadyCb(const CallbackInfo& info) const
1428 {
1429 napi_value result[ARGS_ONE] = { nullptr };
1430 napi_value retVal;
1431 napi_get_undefined(env_, &result[PARAM0]);
1432 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
1433 ExecuteCallback(CONST_CAPTURE_READY, callbackNapiPara);
1434 }
1435
ExecuteCaptureErrorCb(const CallbackInfo & info) const1436 void PhotoOutputCallback::ExecuteCaptureErrorCb(const CallbackInfo& info) const
1437 {
1438 napi_value errJsResult[ARGS_ONE] = { nullptr };
1439 napi_value retVal;
1440 napi_value propValue;
1441
1442 napi_create_object(env_, &errJsResult[PARAM0]);
1443 napi_create_int32(env_, info.errorCode, &propValue);
1444 napi_set_named_property(env_, errJsResult[PARAM0], "code", propValue);
1445 ExecuteCallbackNapiPara callbackNapiPara {
1446 .recv = nullptr, .argc = ARGS_ONE, .argv = errJsResult, .result = &retVal
1447 };
1448 ExecuteCallback(CONST_CAPTURE_ERROR, callbackNapiPara);
1449 }
1450
ExecuteEstimatedCaptureDurationCb(const CallbackInfo & info) const1451 void PhotoOutputCallback::ExecuteEstimatedCaptureDurationCb(const CallbackInfo& info) const
1452 {
1453 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1454 napi_value retVal;
1455 napi_get_undefined(env_, &result[PARAM0]);
1456 napi_create_int32(env_, info.duration, &result[PARAM1]);
1457 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1458 ExecuteCallback(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callbackNapiPara);
1459 }
1460
ExecuteOfflineDeliveryFinishedCb(const CallbackInfo & info) const1461 void PhotoOutputCallback::ExecuteOfflineDeliveryFinishedCb(const CallbackInfo& info) const
1462 {
1463 napi_value result[ARGS_ONE] = { nullptr };
1464 napi_value retVal;
1465 napi_get_undefined(env_, &result[PARAM0]);
1466 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
1467 ExecuteCallback(CONST_CAPTURE_OFFLINE_DELIVERY_FINISHED, callbackNapiPara);
1468 }
1469
UpdateJSCallback(PhotoOutputEventType eventType,const CallbackInfo & info) const1470 void PhotoOutputCallback::UpdateJSCallback(PhotoOutputEventType eventType, const CallbackInfo& info) const
1471 {
1472 MEDIA_DEBUG_LOG("UpdateJSCallback is called");
1473 switch (eventType) {
1474 case PhotoOutputEventType::CAPTURE_START:
1475 ExecuteCaptureStartCb(info);
1476 break;
1477 case PhotoOutputEventType::CAPTURE_END:
1478 ExecuteCaptureEndCb(info);
1479 break;
1480 case PhotoOutputEventType::CAPTURE_FRAME_SHUTTER:
1481 ExecuteFrameShutterCb(info);
1482 break;
1483 case PhotoOutputEventType::CAPTURE_ERROR:
1484 ExecuteCaptureErrorCb(info);
1485 break;
1486 case PhotoOutputEventType::CAPTURE_FRAME_SHUTTER_END:
1487 ExecuteFrameShutterEndCb(info);
1488 break;
1489 case PhotoOutputEventType::CAPTURE_READY:
1490 ExecuteCaptureReadyCb(info);
1491 break;
1492 case PhotoOutputEventType::CAPTURE_ESTIMATED_CAPTURE_DURATION:
1493 ExecuteEstimatedCaptureDurationCb(info);
1494 break;
1495 case PhotoOutputEventType::CAPTURE_START_WITH_INFO:
1496 ExecuteCaptureStartWithInfoCb(info);
1497 break;
1498 case PhotoOutputEventType::CAPTURE_OFFLINE_DELIVERY_FINISHED:
1499 ExecuteOfflineDeliveryFinishedCb(info);
1500 break;
1501 default:
1502 MEDIA_ERR_LOG("Incorrect photo callback event type received from JS");
1503 }
1504 }
1505
ThumbnailListener(napi_env env,const sptr<PhotoOutput> photoOutput)1506 ThumbnailListener::ThumbnailListener(napi_env env, const sptr<PhotoOutput> photoOutput)
1507 : ListenerBase(env), photoOutput_(photoOutput)
1508 {
1509 if (taskManager_ == nullptr) {
1510 constexpr int32_t numThreads = 1;
1511 taskManager_ = std::make_shared<DeferredProcessing::TaskManager>("ThumbnailListener",
1512 numThreads, true);
1513 }
1514 }
~ThumbnailListener()1515 ThumbnailListener::~ThumbnailListener()
1516 {
1517 if (taskManager_) {
1518 taskManager_->CancelAllTasks();
1519 taskManager_.reset();
1520 taskManager_ = nullptr;
1521 }
1522 }
1523
ClearTaskManager()1524 void ThumbnailListener::ClearTaskManager()
1525 {
1526 std::lock_guard<std::mutex> lock(taskManagerMutex_);
1527 if (taskManager_) {
1528 taskManager_->CancelAllTasks();
1529 taskManager_.reset();
1530 taskManager_ = nullptr;
1531 }
1532 }
1533
OnBufferAvailable()1534 void ThumbnailListener::OnBufferAvailable()
1535 {
1536 CAMERA_SYNC_TRACE;
1537 MEDIA_INFO_LOG("ThumbnailListener::OnBufferAvailable is called");
1538 wptr<ThumbnailListener> thisPtr(this);
1539 {
1540 std::lock_guard<std::mutex> lock(taskManagerMutex_);
1541 if (taskManager_ == nullptr) {
1542 MEDIA_ERR_LOG("ThumbnailListener::OnBufferAvailable taskManager_ is null");
1543 return;
1544 }
1545 taskManager_->SubmitTask([thisPtr]() {
1546 auto listener = thisPtr.promote();
1547 if (listener) {
1548 listener->ExecuteDeepCopySurfaceBuffer();
1549 }
1550 });
1551 }
1552 constexpr int32_t memSize = 20 * 1024;
1553 int32_t retCode = CameraManager::GetInstance()->RequireMemorySize(memSize);
1554 CHECK_ERROR_RETURN_LOG(retCode != 0, "ThumbnailListener::OnBufferAvailable RequireMemorySize failed");
1555 MEDIA_INFO_LOG("ThumbnailListener::OnBufferAvailable is end");
1556 }
1557
GetColorSpace(sptr<SurfaceBuffer> surfaceBuffer)1558 OHOS::ColorManager::ColorSpaceName GetColorSpace(sptr<SurfaceBuffer> surfaceBuffer)
1559 {
1560 OHOS::ColorManager::ColorSpaceName colorSpace = OHOS::ColorManager::ColorSpaceName::NONE;
1561 HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceType colorSpaceType;
1562 GSError gsErr = MetadataHelper::GetColorSpaceType(surfaceBuffer, colorSpaceType);
1563 if (gsErr != GSERROR_OK) {
1564 MEDIA_ERR_LOG("Failed to get colorSpaceType from surfaceBuffer!");
1565 return colorSpace;
1566 } else {
1567 MEDIA_INFO_LOG("Get current colorSpaceType is : %{public}d", colorSpaceType);
1568 }
1569 auto it = COLORSPACE_MAP.find(colorSpaceType);
1570 if (it != COLORSPACE_MAP.end()) {
1571 colorSpace = it->second;
1572 MEDIA_INFO_LOG("Current get colorSpaceName: %{public}d", colorSpace);
1573 } else {
1574 MEDIA_ERR_LOG("Current colorSpace is not supported!");
1575 return colorSpace;
1576 }
1577 return colorSpace;
1578 }
1579
ThumbnailSetColorSpaceAndRotate(std::unique_ptr<Media::PixelMap> & pixelMap,sptr<SurfaceBuffer> surfaceBuffer,OHOS::ColorManager::ColorSpaceName colorSpaceName)1580 void ThumbnailSetColorSpaceAndRotate(std::unique_ptr<Media::PixelMap>& pixelMap, sptr<SurfaceBuffer> surfaceBuffer,
1581 OHOS::ColorManager::ColorSpaceName colorSpaceName)
1582 {
1583 int32_t thumbnailrotation = 0;
1584 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataRotation, thumbnailrotation);
1585 MEDIA_DEBUG_LOG("ThumbnailListener current rotation is : %{public}d", thumbnailrotation);
1586 if (!pixelMap) {
1587 MEDIA_ERR_LOG("ThumbnailListener Failed to create PixelMap.");
1588 } else {
1589 pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(colorSpaceName));
1590 pixelMap->rotate(thumbnailrotation);
1591 }
1592 }
1593
ExecuteDeepCopySurfaceBuffer()1594 void ThumbnailListener::ExecuteDeepCopySurfaceBuffer()
1595 {
1596 CAMERA_SYNC_TRACE;
1597 auto photoOutput = photoOutput_.promote();
1598 CHECK_ERROR_RETURN_LOG(photoOutput == nullptr, "ThumbnailListener photoOutput is nullptr");
1599 auto surface = photoOutput->thumbnailSurface_;
1600 CHECK_ERROR_RETURN_LOG(surface == nullptr, "ThumbnailListener surface is nullptr");
1601 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
1602 int32_t fence = -1;
1603 int64_t timestamp;
1604 OHOS::Rect damage;
1605 MEDIA_DEBUG_LOG("ThumbnailListener surfaceName = Thumbnail AcquireBuffer before");
1606 SurfaceError surfaceRet = surface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
1607 MEDIA_DEBUG_LOG("ThumbnailListener surfaceName = Thumbnail AcquireBuffer end");
1608 CHECK_ERROR_RETURN_LOG(surfaceRet != SURFACE_ERROR_OK, "ThumbnailListener Failed to acquire surface buffer");
1609 int32_t burstSeqId = -1;
1610 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
1611 if (burstSeqId != -1) {
1612 surface->ReleaseBuffer(surfaceBuffer, -1);
1613 return;
1614 }
1615 int32_t thumbnailWidth = 0;
1616 int32_t thumbnailHeight = 0;
1617 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, thumbnailWidth);
1618 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, thumbnailHeight);
1619 int32_t captureId = GetCaptureId(surfaceBuffer);
1620 MEDIA_INFO_LOG("ThumbnailListener thumbnailWidth:%{public}d, thumbnailheight: %{public}d, captureId: %{public}d,"
1621 "burstSeqId: %{public}d", thumbnailWidth, thumbnailHeight, captureId, burstSeqId);
1622 OHOS::ColorManager::ColorSpaceName colorSpace = GetColorSpace(surfaceBuffer);
1623 CHECK_ERROR_RETURN_LOG(colorSpace == OHOS::ColorManager::ColorSpaceName::NONE, "Thumbnail GetcolorSpace failed!");
1624 bool isHdr = colorSpace == OHOS::ColorManager::ColorSpaceName::BT2020_HLG;
1625 sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
1626 DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer, thumbnailWidth, thumbnailHeight, isHdr);
1627 std::unique_ptr<Media::PixelMap> pixelMap = CreatePixelMapFromSurfaceBuffer(newSurfaceBuffer,
1628 thumbnailWidth, thumbnailHeight, isHdr);
1629 CHECK_ERROR_RETURN_LOG(pixelMap == nullptr, "ThumbnailListener create pixelMap is nullptr");
1630 ThumbnailSetColorSpaceAndRotate(pixelMap, surfaceBuffer, colorSpace);
1631 MEDIA_DEBUG_LOG("ThumbnailListener ReleaseBuffer begin");
1632 surface->ReleaseBuffer(surfaceBuffer, -1);
1633 MEDIA_DEBUG_LOG("ThumbnailListener ReleaseBuffer end");
1634 UpdateJSCallbackAsync(captureId, timestamp, std::move(pixelMap));
1635 auto photoProxy = CreateCameraPhotoProxy(surfaceBuffer);
1636 if (photoOutput->IsYuvOrHeifPhoto()) {
1637 constexpr int32_t yuvFormat = 3;
1638 photoProxy->format_ = yuvFormat;
1639 photoProxy->imageFormat_ = yuvFormat;
1640 photoOutput->UpdateMediaLibraryPhotoAssetProxy(photoProxy);
1641 }
1642 }
1643
DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer,sptr<SurfaceBuffer> surfaceBuffer,int32_t thumbnailWidth,int32_t thumbnailHeight,bool isHdr) const1644 void ThumbnailListener::DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer,
1645 int32_t thumbnailWidth, int32_t thumbnailHeight, bool isHdr) const
1646 {
1647 CAMERA_SYNC_TRACE;
1648 MEDIA_INFO_LOG("ThumbnailListener::DeepCopyBuffer w=%{public}d, h=%{public}d, f=%{public}d ",
1649 thumbnailWidth, thumbnailHeight, surfaceBuffer->GetFormat());
1650 int32_t thumbnailStride = 0;
1651 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataStride, thumbnailStride);
1652 MEDIA_INFO_LOG("ThumbnailListener::DeepCopyBuffer current stride : %{public}d", thumbnailStride);
1653 BufferRequestConfig requestConfig = {
1654 .width = thumbnailStride,
1655 .height = thumbnailHeight,
1656 .strideAlignment = thumbnailStride,
1657 .format = surfaceBuffer->GetFormat(),
1658 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_MMZ_CACHE,
1659 .timeout = 0,
1660 };
1661 CHECK_ERROR_RETURN_LOG(newSurfaceBuffer == nullptr, "Deep copy surfaceBuffer failed");
1662 GSError allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
1663 if (allocErrorCode != 0) {
1664 MEDIA_ERR_LOG("Create surfaceBuffer Alloc failed");
1665 return;
1666 }
1667 MEDIA_INFO_LOG("ThumbnailListener::DeepCopyBuffer SurfaceBuffer alloc ret : %{public}d",
1668 allocErrorCode);
1669 int32_t colorLength = thumbnailStride * thumbnailHeight * PIXEL_SIZE_HDR_YUV;
1670 colorLength = isHdr ? colorLength : colorLength / HDR_PIXEL_SIZE;
1671 if (memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
1672 surfaceBuffer->GetVirAddr(), colorLength) != EOK) {
1673 MEDIA_ERR_LOG("PhotoListener memcpy_s failed");
1674 return;
1675 }
1676 CopyMetaData(surfaceBuffer, newSurfaceBuffer);
1677 MEDIA_DEBUG_LOG("ThumbnailListener::DeepCopyBuffer SurfaceBuffer end");
1678 }
1679
CreatePixelMapFromSurfaceBuffer(sptr<SurfaceBuffer> & surfaceBuffer,int32_t width,int32_t height,bool isHdr)1680 unique_ptr<Media::PixelMap> ThumbnailListener::CreatePixelMapFromSurfaceBuffer(sptr<SurfaceBuffer> &surfaceBuffer,
1681 int32_t width, int32_t height, bool isHdr)
1682 {
1683 CHECK_ERROR_RETURN_RET_LOG(surfaceBuffer == nullptr, nullptr,
1684 "ThumbnailListener::CreatePixelMapFromSurfaceBuffer surfaceBuffer is nullptr");
1685 MEDIA_INFO_LOG("ThumbnailListener Width:%{public}d, height:%{public}d, isHdr:%{public}d, format:%{public}d",
1686 width, height, isHdr, surfaceBuffer->GetFormat());
1687 Media::InitializationOptions options {
1688 .size = { .width = width, .height = height } };
1689 options.srcPixelFormat = isHdr ? Media::PixelFormat::YCRCB_P010 : Media::PixelFormat::NV12;
1690 options.pixelFormat = isHdr ? Media::PixelFormat::YCRCB_P010 : Media::PixelFormat::NV12;
1691 options.useDMA = true;
1692 options.editable = isHdr;
1693 int32_t colorLength = width * height * PIXEL_SIZE_HDR_YUV;
1694 colorLength = isHdr ? colorLength : colorLength / HDR_PIXEL_SIZE;
1695 std::unique_ptr<Media::PixelMap> pixelMap = Media::PixelMap::Create(options);
1696 void* nativeBuffer = surfaceBuffer.GetRefPtr();
1697 RefBase *ref = reinterpret_cast<RefBase *>(nativeBuffer);
1698 ref->IncStrongRef(ref);
1699 if (isHdr) {
1700 pixelMap->SetHdrType(OHOS::Media::ImageHdrType::HDR_VIVID_SINGLE);
1701 }
1702 pixelMap->SetPixelsAddr(surfaceBuffer->GetVirAddr(), surfaceBuffer.GetRefPtr(), colorLength,
1703 Media::AllocatorType::DMA_ALLOC, nullptr);
1704
1705 MEDIA_DEBUG_LOG("ThumbnailListener::CreatePixelMapFromSurfaceBuffer end");
1706 return SetPixelMapYuvInfo(surfaceBuffer, std::move(pixelMap), isHdr);
1707 }
1708
SetPixelMapYuvInfo(sptr<SurfaceBuffer> & surfaceBuffer,unique_ptr<Media::PixelMap> pixelMap,bool isHdr)1709 unique_ptr<Media::PixelMap> ThumbnailListener::SetPixelMapYuvInfo(sptr<SurfaceBuffer> &surfaceBuffer,
1710 unique_ptr<Media::PixelMap> pixelMap, bool isHdr)
1711 {
1712 MEDIA_INFO_LOG("ThumbnailListener::SetPixelMapYuvInf enter");
1713 uint8_t ratio = isHdr ? HDR_PIXEL_SIZE : SDR_PIXEL_SIZE;
1714 int32_t srcWidth = pixelMap->GetWidth();
1715 int32_t srcHeight = pixelMap->GetHeight();
1716 Media::YUVDataInfo yuvDataInfo = { .yWidth = srcWidth,
1717 .yHeight = srcHeight,
1718 .uvWidth = srcWidth / 2,
1719 .uvHeight = srcHeight / 2,
1720 .yStride = srcWidth,
1721 .uvStride = srcWidth,
1722 .uvOffset = srcWidth * srcHeight};
1723 if (surfaceBuffer == nullptr) {
1724 pixelMap->SetImageYUVInfo(yuvDataInfo);
1725 return pixelMap;
1726 }
1727 OH_NativeBuffer_Planes *planes = nullptr;
1728 GSError retVal = surfaceBuffer->GetPlanesInfo(reinterpret_cast<void**>(&planes));
1729 if (retVal != OHOS::GSERROR_OK || planes == nullptr) {
1730 pixelMap->SetImageYUVInfo(yuvDataInfo);
1731 return pixelMap;
1732 }
1733
1734 yuvDataInfo.yStride = planes->planes[PLANE_Y].columnStride / ratio;
1735 yuvDataInfo.uvStride = planes->planes[PLANE_U].columnStride / ratio;
1736 yuvDataInfo.yOffset = planes->planes[PLANE_Y].offset / ratio;
1737 yuvDataInfo.uvOffset = planes->planes[PLANE_U].offset / ratio;
1738
1739 pixelMap->SetImageYUVInfo(yuvDataInfo);
1740 MEDIA_INFO_LOG("ThumbnailListener::SetPixelMapYuvInf end");
1741 return pixelMap;
1742 }
1743
UpdateJSCallbackAsync(int32_t captureId,int64_t timestamp,unique_ptr<Media::PixelMap> pixelMap)1744 void ThumbnailListener::UpdateJSCallbackAsync(int32_t captureId, int64_t timestamp,
1745 unique_ptr<Media::PixelMap> pixelMap)
1746 {
1747 std::unique_ptr<ThumbnailListenerInfo> callbackInfo =
1748 std::make_unique<ThumbnailListenerInfo>(this, captureId, timestamp, std::move(pixelMap));
1749 ThumbnailListenerInfo *event = callbackInfo.get();
1750 auto task = [event]() {
1751 ThumbnailListenerInfo* callbackInfo = reinterpret_cast<ThumbnailListenerInfo*>(event);
1752 if (callbackInfo) {
1753 auto listener = callbackInfo->listener_.promote();
1754 if (listener != nullptr) {
1755 listener->UpdateJSCallback(callbackInfo->captureId_, callbackInfo->timestamp_,
1756 std::move(callbackInfo->pixelMap_));
1757 MEDIA_INFO_LOG("ThumbnailListener:UpdateJSCallbackAsync() complete");
1758 }
1759 delete callbackInfo;
1760 }
1761 };
1762 if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
1763 MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to execute work");
1764 } else {
1765 callbackInfo.release();
1766 }
1767 }
1768
FillPixelMapWithCaptureIdAndTimestamp(napi_env env,int32_t captureId,int64_t timestamp,napi_value pixelMapNapi)1769 void FillPixelMapWithCaptureIdAndTimestamp(napi_env env, int32_t captureId, int64_t timestamp, napi_value pixelMapNapi)
1770 {
1771 napi_valuetype valueType = napi_undefined;
1772 if (napi_typeof(env, pixelMapNapi, &valueType) != napi_ok || valueType == napi_undefined) {
1773 MEDIA_ERR_LOG("FillPixelMapWithCaptureIdAndTimestamp err, pixelMapNapi is undefined = %{public}d",
1774 valueType == napi_undefined);
1775 return;
1776 }
1777 napi_value propertyName, propertyValue;
1778 napi_get_undefined(env, &propertyName);
1779 napi_get_undefined(env, &propertyValue);
1780 napi_create_string_utf8(env, "captureId", NAPI_AUTO_LENGTH, &propertyName);
1781 napi_create_int32(env, captureId, &propertyValue);
1782 napi_set_property(env, pixelMapNapi, propertyName, propertyValue);
1783 MEDIA_INFO_LOG("FillPixelMapWithCaptureIdAndTimestamp captureId %{public}d", captureId);
1784
1785 napi_create_string_utf8(env, "timestamp", NAPI_AUTO_LENGTH, &propertyName);
1786 napi_create_int64(env, timestamp, &propertyValue);
1787 napi_set_property(env, pixelMapNapi, propertyName, propertyValue);
1788 }
1789
UpdateJSCallback(int32_t captureId,int64_t timestamp,unique_ptr<Media::PixelMap> pixelMap) const1790 void ThumbnailListener::UpdateJSCallback(int32_t captureId, int64_t timestamp,
1791 unique_ptr<Media::PixelMap> pixelMap) const
1792 {
1793 CHECK_ERROR_RETURN_LOG(pixelMap == nullptr, "ThumbnailListener::UpdateJSCallback surfaceBuffer is nullptr");
1794 napi_value result[ARGS_TWO] = { 0 };
1795 napi_get_undefined(env_, &result[0]);
1796 napi_get_undefined(env_, &result[1]);
1797 napi_value retVal;
1798 MEDIA_INFO_LOG("enter ImageNapi::Create start");
1799 napi_value valueParam = Media::PixelMapNapi::CreatePixelMap(env_, std::move(pixelMap));
1800 if (valueParam == nullptr) {
1801 MEDIA_ERR_LOG("ImageNapi Create failed");
1802 napi_get_undefined(env_, &valueParam);
1803 }
1804 FillPixelMapWithCaptureIdAndTimestamp(env_, captureId, timestamp, valueParam);
1805 napi_value valueCaptureId = nullptr;
1806 napi_create_int32(env_, captureId, &valueCaptureId);
1807 if (valueCaptureId == nullptr) {
1808 MEDIA_ERR_LOG("napi_create_int64 failed");
1809 napi_get_undefined(env_, &valueCaptureId);
1810 }
1811 MEDIA_INFO_LOG("enter ImageNapi::Create end");
1812 napi_value obj = nullptr;
1813 napi_create_object(env_, &obj);
1814 napi_set_named_property(env_, obj, "thumbnailImage", valueParam);
1815 napi_set_named_property(env_, obj, "captureId", valueCaptureId);
1816 result[1] = obj;
1817 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1818 ExecuteCallback(CONST_CAPTURE_QUICK_THUMBNAIL, callbackNapiPara);
1819 }
1820
UpdateJSCallback() const1821 void ThumbnailListener::UpdateJSCallback() const
1822 {
1823 auto photoOutput = photoOutput_.promote();
1824 CHECK_ERROR_RETURN_LOG(photoOutput == nullptr, "ThumbnailListener::UpdateJSCallback photoOutput is nullptr");
1825 napi_value result[ARGS_TWO] = { 0 };
1826 napi_get_undefined(env_, &result[0]);
1827 napi_get_undefined(env_, &result[1]);
1828 napi_value retVal;
1829 MEDIA_INFO_LOG("enter ImageNapi::Create start");
1830 int32_t fence = -1;
1831 int64_t timestamp;
1832 OHOS::Rect damage;
1833 sptr<SurfaceBuffer> thumbnailBuffer = nullptr;
1834 SurfaceError surfaceRet = photoOutput->thumbnailSurface_->AcquireBuffer(thumbnailBuffer, fence, timestamp, damage);
1835 CHECK_ERROR_RETURN_LOG(surfaceRet != SURFACE_ERROR_OK, "ThumbnailListener Failed to acquire surface buffer");
1836 int32_t thumbnailWidth;
1837 int32_t thumbnailHeight;
1838 thumbnailBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, thumbnailWidth);
1839 thumbnailBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, thumbnailHeight);
1840 int32_t captureId = GetCaptureId(thumbnailBuffer);
1841 Media::InitializationOptions opts;
1842 opts.srcPixelFormat = Media::PixelFormat::RGBA_8888;
1843 opts.pixelFormat = Media::PixelFormat::RGBA_8888;
1844 opts.size = { .width = thumbnailWidth, .height = thumbnailHeight };
1845 MEDIA_INFO_LOG("thumbnailWidth:%{public}d, thumbnailheight: %{public}d", thumbnailWidth, thumbnailHeight);
1846 const int32_t formatSize = 4;
1847 auto pixelMap = Media::PixelMap::Create(static_cast<const uint32_t*>(thumbnailBuffer->GetVirAddr()),
1848 thumbnailWidth * thumbnailHeight * formatSize, 0, thumbnailWidth, opts, true);
1849 napi_value valueParam = Media::PixelMapNapi::CreatePixelMap(env_, std::move(pixelMap));
1850 if (valueParam == nullptr) {
1851 MEDIA_ERR_LOG("ImageNapi Create failed");
1852 napi_get_undefined(env_, &valueParam);
1853 }
1854 FillPixelMapWithCaptureIdAndTimestamp(env_, captureId, timestamp, valueParam);
1855 MEDIA_INFO_LOG("enter ImageNapi::Create end");
1856 result[1] = valueParam;
1857
1858 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1859 ExecuteCallback(CONST_CAPTURE_QUICK_THUMBNAIL, callbackNapiPara);
1860 photoOutput->thumbnailSurface_->ReleaseBuffer(thumbnailBuffer, -1);
1861 }
1862
UpdateJSCallbackAsync()1863 void ThumbnailListener::UpdateJSCallbackAsync()
1864 {
1865 std::unique_ptr<ThumbnailListenerInfo> callbackInfo = std::make_unique<ThumbnailListenerInfo>(this, 0, 0, nullptr);
1866 ThumbnailListenerInfo *event = callbackInfo.get();
1867 auto task = [event]() {
1868 ThumbnailListenerInfo* callbackInfo = reinterpret_cast<ThumbnailListenerInfo*>(event);
1869 if (callbackInfo) {
1870 auto listener = callbackInfo->listener_.promote();
1871 if (listener != nullptr) {
1872 listener->UpdateJSCallback();
1873 MEDIA_INFO_LOG("ThumbnailListener:UpdateJSCallbackAsync() complete");
1874 }
1875 delete callbackInfo;
1876 }
1877 };
1878 if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
1879 MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to execute work");
1880 } else {
1881 callbackInfo.release();
1882 }
1883 }
1884
PhotoOutputNapi()1885 PhotoOutputNapi::PhotoOutputNapi() {}
1886
~PhotoOutputNapi()1887 PhotoOutputNapi::~PhotoOutputNapi()
1888 {
1889 if (pictureListener_) {
1890 pictureListener_->gainmapImageListener = nullptr;
1891 pictureListener_->deepImageListener = nullptr;
1892 pictureListener_->exifImageListener = nullptr;
1893 pictureListener_->debugImageListener = nullptr;
1894 }
1895 pictureListener_ = nullptr;
1896 MEDIA_DEBUG_LOG("~PhotoOutputNapi is called");
1897 }
1898
PhotoOutputNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)1899 void PhotoOutputNapi::PhotoOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
1900 {
1901 MEDIA_DEBUG_LOG("PhotoOutputNapiDestructor is called");
1902 PhotoOutputNapi* photoOutput = reinterpret_cast<PhotoOutputNapi*>(nativeObject);
1903 if (photoOutput != nullptr) {
1904 delete photoOutput;
1905 }
1906 }
1907
Init(napi_env env,napi_value exports)1908 napi_value PhotoOutputNapi::Init(napi_env env, napi_value exports)
1909 {
1910 MEDIA_DEBUG_LOG("Init is called");
1911 napi_status status;
1912 napi_value ctorObj;
1913 int32_t refCount = 1;
1914
1915 napi_property_descriptor photo_output_props[] = {
1916 DECLARE_NAPI_FUNCTION("isMovingPhotoSupported", IsMovingPhotoSupported),
1917 DECLARE_NAPI_FUNCTION("enableMovingPhoto", EnableMovingPhoto),
1918 DECLARE_NAPI_FUNCTION("capture", Capture),
1919 DECLARE_NAPI_FUNCTION("burstCapture", BurstCapture),
1920 DECLARE_NAPI_FUNCTION("confirmCapture", ConfirmCapture),
1921 DECLARE_NAPI_FUNCTION("release", Release),
1922 DECLARE_NAPI_FUNCTION("isMirrorSupported", IsMirrorSupported),
1923 DECLARE_NAPI_FUNCTION("enableMirror", EnableMirror),
1924 DECLARE_NAPI_FUNCTION("enableQuickThumbnail", EnableQuickThumbnail),
1925 DECLARE_NAPI_FUNCTION("isQuickThumbnailSupported", IsQuickThumbnailSupported),
1926 DECLARE_NAPI_FUNCTION("enableRawDelivery", EnableRawDelivery),
1927 DECLARE_NAPI_FUNCTION("isRawDeliverySupported", IsRawDeliverySupported),
1928 DECLARE_NAPI_FUNCTION("getSupportedMovingPhotoVideoCodecTypes", GetSupportedMovingPhotoVideoCodecTypes),
1929 DECLARE_NAPI_FUNCTION("setMovingPhotoVideoCodecType", SetMovingPhotoVideoCodecType),
1930 DECLARE_NAPI_FUNCTION("on", On),
1931 DECLARE_NAPI_FUNCTION("once", Once),
1932 DECLARE_NAPI_FUNCTION("off", Off),
1933 DECLARE_NAPI_FUNCTION("deferImageDelivery", DeferImageDeliveryFor),
1934 DECLARE_NAPI_FUNCTION("deferImageDeliveryFor", DeferImageDeliveryFor),
1935 DECLARE_NAPI_FUNCTION("isDeferredImageDeliverySupported", IsDeferredImageDeliverySupported),
1936 DECLARE_NAPI_FUNCTION("isDeferredImageDeliveryEnabled", IsDeferredImageDeliveryEnabled),
1937 DECLARE_NAPI_FUNCTION("isAutoHighQualityPhotoSupported", IsAutoHighQualityPhotoSupported),
1938 DECLARE_NAPI_FUNCTION("enableAutoHighQualityPhoto", EnableAutoHighQualityPhoto),
1939 DECLARE_NAPI_FUNCTION("getActiveProfile", GetActiveProfile),
1940 DECLARE_NAPI_FUNCTION("getPhotoRotation", GetPhotoRotation),
1941 DECLARE_NAPI_FUNCTION("isAutoCloudImageEnhancementSupported", IsAutoCloudImageEnhancementSupported),
1942 DECLARE_NAPI_FUNCTION("enableAutoCloudImageEnhancement", EnableAutoCloudImageEnhancement),
1943 DECLARE_NAPI_FUNCTION("isDepthDataDeliverySupported", IsDepthDataDeliverySupported),
1944 DECLARE_NAPI_FUNCTION("enableDepthDataDelivery", EnableDepthDataDelivery),
1945 DECLARE_NAPI_FUNCTION("isAutoAigcPhotoSupported", IsAutoAigcPhotoSupported),
1946 DECLARE_NAPI_FUNCTION("enableAutoAigcPhoto", EnableAutoAigcPhoto),
1947 DECLARE_NAPI_FUNCTION("isOfflineSupported", IsOfflineSupported),
1948 DECLARE_NAPI_FUNCTION("enableOffline", EnableOfflinePhoto)
1949 };
1950
1951 status = napi_define_class(env, CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH, PhotoOutputNapiConstructor,
1952 nullptr, sizeof(photo_output_props) / sizeof(photo_output_props[PARAM0]), photo_output_props, &ctorObj);
1953 if (status == napi_ok) {
1954 status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
1955 if (status == napi_ok) {
1956 status = napi_set_named_property(env, exports, CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME, ctorObj);
1957 CHECK_ERROR_RETURN_RET(status == napi_ok, exports);
1958 }
1959 }
1960 MEDIA_ERR_LOG("Init call Failed!");
1961 return nullptr;
1962 }
1963
1964 // Constructor callback
PhotoOutputNapiConstructor(napi_env env,napi_callback_info info)1965 napi_value PhotoOutputNapi::PhotoOutputNapiConstructor(napi_env env, napi_callback_info info)
1966 {
1967 MEDIA_DEBUG_LOG("PhotoOutputNapiConstructor is called");
1968 napi_status status;
1969 napi_value result = nullptr;
1970 napi_value thisVar = nullptr;
1971
1972 napi_get_undefined(env, &result);
1973 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
1974
1975 if (status == napi_ok && thisVar != nullptr) {
1976 std::unique_ptr<PhotoOutputNapi> obj = std::make_unique<PhotoOutputNapi>();
1977 obj->photoOutput_ = sPhotoOutput_;
1978 obj->profile_ = sPhotoOutput_->GetPhotoProfile();
1979 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
1980 PhotoOutputNapi::PhotoOutputNapiDestructor, nullptr, nullptr);
1981 if (status == napi_ok) {
1982 obj.release();
1983 return thisVar;
1984 } else {
1985 MEDIA_ERR_LOG("Failure wrapping js to native napi");
1986 }
1987 }
1988 MEDIA_ERR_LOG("PhotoOutputNapiConstructor call Failed!");
1989 return result;
1990 }
1991
GetPhotoOutput()1992 sptr<PhotoOutput> PhotoOutputNapi::GetPhotoOutput()
1993 {
1994 return photoOutput_;
1995 }
1996
GetEnableMirror()1997 bool PhotoOutputNapi::GetEnableMirror()
1998 {
1999 return isMirrorEnabled_;
2000 }
2001
IsPhotoOutput(napi_env env,napi_value obj)2002 bool PhotoOutputNapi::IsPhotoOutput(napi_env env, napi_value obj)
2003 {
2004 MEDIA_DEBUG_LOG("IsPhotoOutput is called");
2005 bool result = false;
2006 napi_status status;
2007 napi_value constructor = nullptr;
2008
2009 status = napi_get_reference_value(env, sConstructor_, &constructor);
2010 if (status == napi_ok) {
2011 status = napi_instanceof(env, obj, constructor, &result);
2012 if (status != napi_ok) {
2013 result = false;
2014 }
2015 }
2016 return result;
2017 }
2018
CreateMultiChannelPictureLisenter(napi_env env)2019 void PhotoOutputNapi::CreateMultiChannelPictureLisenter(napi_env env)
2020 {
2021 if (pictureListener_ == nullptr) {
2022 MEDIA_INFO_LOG("new photoListener and register surface consumer listener");
2023 sptr<PictureListener> pictureListener = new (std::nothrow) PictureListener();
2024 pictureListener->InitPictureListeners(env, photoOutput_);
2025 if (photoListener_ == nullptr) {
2026 sptr<PhotoListener> photoListener = new (std::nothrow)
2027 PhotoListener(env, photoOutput_->GetPhotoSurface(), photoOutput_);
2028 SurfaceError ret = photoOutput_->GetPhotoSurface()->RegisterConsumerListener(
2029 (sptr<IBufferConsumerListener> &)photoListener);
2030 CHECK_ERROR_PRINT_LOG(ret != SURFACE_ERROR_OK, "register surface consumer listener failed!");
2031 photoListener_ = photoListener;
2032 pictureListener_ = pictureListener;
2033 }
2034 if (photoOutput_->taskManager_ == nullptr) {
2035 constexpr int32_t auxiliaryPictureCount = 4;
2036 photoOutput_->taskManager_ = std::make_shared<DeferredProcessing::TaskManager>("AuxilaryPictureListener",
2037 auxiliaryPictureCount, false);
2038 }
2039 }
2040 }
2041
CreateSingleChannelPhotoLisenter(napi_env env)2042 void PhotoOutputNapi::CreateSingleChannelPhotoLisenter(napi_env env)
2043 {
2044 if (photoListener_ == nullptr) {
2045 MEDIA_INFO_LOG("new photoListener and register surface consumer listener");
2046 sptr<PhotoListener> photoListener = new (std::nothrow)
2047 PhotoListener(env, photoOutput_->GetPhotoSurface(), photoOutput_);
2048 SurfaceError ret =
2049 photoOutput_->GetPhotoSurface()->RegisterConsumerListener((sptr<IBufferConsumerListener> &)photoListener);
2050 CHECK_ERROR_PRINT_LOG(ret != SURFACE_ERROR_OK, "register surface consumer listener failed!");
2051 photoListener_ = photoListener;
2052 }
2053 }
2054
CreatePhotoOutput(napi_env env,Profile & profile,std::string surfaceId)2055 napi_value PhotoOutputNapi::CreatePhotoOutput(napi_env env, Profile& profile, std::string surfaceId)
2056 {
2057 MEDIA_DEBUG_LOG("CreatePhotoOutput is called, profile CameraFormat= %{public}d", profile.GetCameraFormat());
2058 CAMERA_SYNC_TRACE;
2059 napi_value result = nullptr;
2060 napi_get_undefined(env, &result);
2061 napi_value constructor;
2062 napi_status status = napi_get_reference_value(env, sConstructor_, &constructor);
2063 if (status == napi_ok) {
2064 MEDIA_INFO_LOG("CreatePhotoOutput surfaceId: %{public}s", surfaceId.c_str());
2065 sptr<Surface> photoSurface;
2066 if (surfaceId == "") {
2067 MEDIA_INFO_LOG("create surface as consumer");
2068 photoSurface = Surface::CreateSurfaceAsConsumer("photoOutput");
2069 } else {
2070 MEDIA_INFO_LOG("get surface by surfaceId");
2071 photoSurface = Media::ImageReceiver::getSurfaceById(surfaceId);
2072 }
2073 CHECK_ERROR_RETURN_RET_LOG(photoSurface == nullptr, result, "failed to get surface");
2074 photoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
2075 sptr<IBufferProducer> surfaceProducer = photoSurface->GetProducer();
2076 MEDIA_INFO_LOG("profile width: %{public}d, height: %{public}d, format = %{public}d, "
2077 "surface width: %{public}d, height: %{public}d", profile.GetSize().width,
2078 profile.GetSize().height, static_cast<int32_t>(profile.GetCameraFormat()),
2079 photoSurface->GetDefaultWidth(), photoSurface->GetDefaultHeight());
2080 int retCode =
2081 CameraManager::GetInstance()->CreatePhotoOutput(profile, surfaceProducer, &sPhotoOutput_, photoSurface);
2082 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiUtils::CheckError(env, retCode) || sPhotoOutput_ == nullptr,
2083 result, "failed to create CreatePhotoOutput");
2084 CHECK_EXECUTE(surfaceId == "", sPhotoOutput_->SetNativeSurface(true));
2085 CHECK_EXECUTE(sPhotoOutput_->IsYuvOrHeifPhoto(), sPhotoOutput_->CreateMultiChannel());
2086 status = napi_new_instance(env, constructor, 0, nullptr, &result);
2087 sPhotoOutput_ = nullptr;
2088 CHECK_ERROR_RETURN_RET_LOG(status == napi_ok && result != nullptr, result,
2089 "Success to create photo output instance");
2090 }
2091 MEDIA_ERR_LOG("CreatePhotoOutput call Failed!");
2092 return result;
2093 }
2094
CreatePhotoOutput(napi_env env,std::string surfaceId)2095 napi_value PhotoOutputNapi::CreatePhotoOutput(napi_env env, std::string surfaceId)
2096 {
2097 MEDIA_INFO_LOG("CreatePhotoOutput with only surfaceId is called");
2098 CAMERA_SYNC_TRACE;
2099 napi_status status;
2100 napi_value result = nullptr;
2101 napi_value constructor;
2102 napi_get_undefined(env, &result);
2103 status = napi_get_reference_value(env, sConstructor_, &constructor);
2104 if (status == napi_ok) {
2105 MEDIA_INFO_LOG("CreatePhotoOutput surfaceId: %{public}s", surfaceId.c_str());
2106 sptr<Surface> photoSurface;
2107 if (surfaceId == "") {
2108 MEDIA_INFO_LOG("create surface as consumer");
2109 photoSurface = Surface::CreateSurfaceAsConsumer("photoOutput");
2110 } else {
2111 MEDIA_INFO_LOG("get surface by surfaceId");
2112 photoSurface = Media::ImageReceiver::getSurfaceById(surfaceId);
2113 }
2114 CHECK_ERROR_RETURN_RET_LOG(photoSurface == nullptr, result, "failed to get surface");
2115 sptr<IBufferProducer> surfaceProducer = photoSurface->GetProducer();
2116 MEDIA_INFO_LOG("surface width: %{public}d, height: %{public}d", photoSurface->GetDefaultWidth(),
2117 photoSurface->GetDefaultHeight());
2118 int retCode = CameraManager::GetInstance()->CreatePhotoOutputWithoutProfile(
2119 surfaceProducer, &sPhotoOutput_, photoSurface);
2120 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiUtils::CheckError(env, retCode) || sPhotoOutput_ == nullptr,
2121 result, "failed to create CreatePhotoOutput");
2122 CHECK_EXECUTE(surfaceId == "", sPhotoOutput_->SetNativeSurface(true));
2123 status = napi_new_instance(env, constructor, 0, nullptr, &result);
2124 sPhotoOutput_ = nullptr;
2125 CHECK_ERROR_RETURN_RET_LOG(status == napi_ok && result != nullptr, result,
2126 "Success to create photo output instance");
2127 }
2128 MEDIA_ERR_LOG("CreatePhotoOutput call Failed!");
2129 return result;
2130 }
2131
ParseCaptureSettings(napi_env env,napi_callback_info info,PhotoOutputAsyncContext * asyncContext,std::shared_ptr<CameraNapiAsyncFunction> & asyncFunction,bool isSettingOptional)2132 bool ParseCaptureSettings(napi_env env, napi_callback_info info, PhotoOutputAsyncContext* asyncContext,
2133 std::shared_ptr<CameraNapiAsyncFunction>& asyncFunction, bool isSettingOptional)
2134 {
2135 Location settingsLocation;
2136 CameraNapiObject settingsLocationNapiOjbect { {
2137 { "latitude", &settingsLocation.latitude },
2138 { "longitude", &settingsLocation.longitude },
2139 { "altitude", &settingsLocation.altitude },
2140 } };
2141 CameraNapiObject settingsNapiOjbect { {
2142 { "quality", &asyncContext->quality },
2143 { "rotation", &asyncContext->rotation },
2144 { "location", &settingsLocationNapiOjbect },
2145 { "mirror", &asyncContext->isMirror },
2146 } };
2147 unordered_set<std::string> optionalKeys = { "quality", "rotation", "location", "mirror" };
2148 settingsNapiOjbect.SetOptionalKeys(optionalKeys);
2149
2150 asyncFunction =
2151 std::make_shared<CameraNapiAsyncFunction>(env, "Capture", asyncContext->callbackRef, asyncContext->deferred);
2152 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction, settingsNapiOjbect);
2153 if (jsParamParser.IsStatusOk()) {
2154 if (settingsNapiOjbect.IsKeySetted("quality") && !ValidQualityLevelFromJs(asyncContext->quality)) {
2155 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "quality field not legal");
2156 return false;
2157 }
2158 if (settingsNapiOjbect.IsKeySetted("rotation") && !ValidImageRotationFromJs(asyncContext->rotation)) {
2159 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "rotation field not legal");
2160 return false;
2161 }
2162 if (settingsNapiOjbect.IsKeySetted("mirror") && asyncContext->isMirror) {
2163 MEDIA_INFO_LOG("GetMirrorStatus is ok!");
2164 asyncContext->isMirrorSettedByUser = true;
2165 }
2166 MEDIA_INFO_LOG("ParseCaptureSettings with capture settings pass");
2167 asyncContext->hasPhotoSettings = true;
2168 if (settingsNapiOjbect.IsKeySetted("location")) {
2169 asyncContext->location = std::make_shared<Location>(settingsLocation);
2170 }
2171 } else if (isSettingOptional) {
2172 MEDIA_WARNING_LOG("ParseCaptureSettings check capture settings fail, try capture without settings");
2173 jsParamParser = CameraNapiParamParser(env, info, asyncContext->objectInfo, asyncFunction);
2174 } else {
2175 // Do nothing.
2176 }
2177 CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"), false,
2178 "ParseCaptureSettings invalid argument");
2179 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
2180 return true;
2181 }
2182
Capture(napi_env env,napi_callback_info info)2183 napi_value PhotoOutputNapi::Capture(napi_env env, napi_callback_info info)
2184 {
2185 MEDIA_INFO_LOG("Capture is called");
2186 std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
2187 "PhotoOutputNapi::Capture", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
2188 std::shared_ptr<CameraNapiAsyncFunction> asyncFunction;
2189 CHECK_ERROR_RETURN_RET_LOG(!ParseCaptureSettings(env, info, asyncContext.get(), asyncFunction, true), nullptr,
2190 "PhotoOutputNapi::Capture parse parameters fail.");
2191 napi_status status = napi_create_async_work(
2192 env, nullptr, asyncFunction->GetResourceName(),
2193 [](napi_env env, void* data) {
2194 MEDIA_INFO_LOG("PhotoOutputNapi::Capture running on worker");
2195 auto context = static_cast<PhotoOutputAsyncContext*>(data);
2196 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "PhotoOutputNapi::Capture async info is nullptr");
2197 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
2198 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(
2199 context->queueTask, [&context]() { ProcessCapture(context, false); });
2200 },
2201 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
2202 if (status != napi_ok) {
2203 MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::Capture");
2204 asyncFunction->Reset();
2205 } else {
2206 asyncContext->queueTask =
2207 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::Capture");
2208 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
2209 asyncContext.release();
2210 }
2211 CHECK_ERROR_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
2212 asyncFunction->GetPromise());
2213 return CameraNapiUtils::GetUndefinedValue(env);
2214 }
2215
BurstCapture(napi_env env,napi_callback_info info)2216 napi_value PhotoOutputNapi::BurstCapture(napi_env env, napi_callback_info info)
2217 {
2218 MEDIA_INFO_LOG("BurstCapture is called");
2219 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
2220 "SystemApi EnableAutoHighQualityPhoto is called!");
2221 std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
2222 "PhotoOutputNapi::BurstCapture", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
2223 std::shared_ptr<CameraNapiAsyncFunction> asyncFunction;
2224 CHECK_ERROR_RETURN_RET_LOG(!ParseCaptureSettings(env, info, asyncContext.get(), asyncFunction, false),
2225 nullptr, "PhotoOutputNapi::BurstCapture parse parameters fail.");
2226 napi_status status = napi_create_async_work(
2227 env, nullptr, asyncFunction->GetResourceName(),
2228 [](napi_env env, void* data) {
2229 MEDIA_INFO_LOG("PhotoOutputNapi::BurstCapture running on worker");
2230 auto context = static_cast<PhotoOutputAsyncContext*>(data);
2231 CHECK_ERROR_RETURN_LOG(
2232 context->objectInfo == nullptr, "PhotoOutputNapi::BurstCapture async info is nullptr");
2233 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
2234 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(
2235 context->queueTask, [&context]() { ProcessCapture(context, true); });
2236 },
2237 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
2238 if (status != napi_ok) {
2239 MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::BurstCapture");
2240 asyncFunction->Reset();
2241 } else {
2242 asyncContext->queueTask =
2243 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::BurstCapture");
2244 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
2245 asyncContext.release();
2246 }
2247 CHECK_ERROR_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
2248 asyncFunction->GetPromise());
2249 return CameraNapiUtils::GetUndefinedValue(env);
2250 }
2251
ConfirmCapture(napi_env env,napi_callback_info info)2252 napi_value PhotoOutputNapi::ConfirmCapture(napi_env env, napi_callback_info info)
2253 {
2254 MEDIA_INFO_LOG("ConfirmCapture is called");
2255 napi_status status;
2256 napi_value result = nullptr;
2257 size_t argc = ARGS_ZERO;
2258 napi_value argv[ARGS_ZERO] = {};
2259 napi_value thisVar = nullptr;
2260
2261 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2262
2263 napi_get_undefined(env, &result);
2264 PhotoOutputNapi* photoOutputNapi = nullptr;
2265 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2266 if (status == napi_ok && photoOutputNapi != nullptr) {
2267 int32_t retCode = photoOutputNapi->photoOutput_->ConfirmCapture();
2268 CHECK_ERROR_RETURN_RET(!CameraNapiUtils::CheckError(env, retCode), result);
2269 }
2270 return result;
2271 }
2272
Release(napi_env env,napi_callback_info info)2273 napi_value PhotoOutputNapi::Release(napi_env env, napi_callback_info info)
2274 {
2275 MEDIA_INFO_LOG("Release is called");
2276 std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
2277 "PhotoOutputNapi::Release", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
2278 auto asyncFunction =
2279 std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
2280 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
2281 CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"), nullptr,
2282 "PhotoOutputNapi::Release invalid argument");
2283 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
2284 napi_status status = napi_create_async_work(
2285 env, nullptr, asyncFunction->GetResourceName(),
2286 [](napi_env env, void* data) {
2287 MEDIA_INFO_LOG("PhotoOutputNapi::Release running on worker");
2288 auto context = static_cast<PhotoOutputAsyncContext*>(data);
2289 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "PhotoOutputNapi::Release async info is nullptr");
2290 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
2291 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
2292 context->errorCode = context->objectInfo->photoOutput_->Release();
2293 context->status = context->errorCode == CameraErrorCode::SUCCESS;
2294 });
2295 },
2296 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
2297 if (status != napi_ok) {
2298 MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::Release");
2299 asyncFunction->Reset();
2300 } else {
2301 asyncContext->queueTask =
2302 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::Release");
2303 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
2304 asyncContext.release();
2305 }
2306 CHECK_ERROR_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
2307 asyncFunction->GetPromise());
2308 return CameraNapiUtils::GetUndefinedValue(env);
2309 }
2310
IsMirrorSupported(napi_env env,napi_callback_info info)2311 napi_value PhotoOutputNapi::IsMirrorSupported(napi_env env, napi_callback_info info)
2312 {
2313 MEDIA_INFO_LOG("IsMirrorSupported is called");
2314 napi_status status;
2315 napi_value result = nullptr;
2316 size_t argc = ARGS_ZERO;
2317 napi_value argv[ARGS_ZERO];
2318 napi_value thisVar = nullptr;
2319
2320 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2321
2322 napi_get_undefined(env, &result);
2323 PhotoOutputNapi* photoOutputNapi = nullptr;
2324 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2325 if (status == napi_ok && photoOutputNapi != nullptr) {
2326 bool isSupported = photoOutputNapi->photoOutput_->IsMirrorSupported();
2327 napi_get_boolean(env, isSupported, &result);
2328 } else {
2329 MEDIA_ERR_LOG("IsMirrorSupported call Failed!");
2330 }
2331 return result;
2332 }
2333
EnableMirror(napi_env env,napi_callback_info info)2334 napi_value PhotoOutputNapi::EnableMirror(napi_env env, napi_callback_info info)
2335 {
2336 auto result = CameraNapiUtils::GetUndefinedValue(env);
2337 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableMirror is called");
2338 bool isMirror = false;
2339 PhotoOutputNapi* photoOutputNapi = nullptr;
2340 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isMirror);
2341 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
2342 MEDIA_ERR_LOG("PhotoOutputNapi::EnableMirror invalid argument");
2343 return nullptr;
2344 }
2345 auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2346 if (session != nullptr) {
2347 photoOutputNapi->isMirrorEnabled_ = isMirror;
2348 int32_t retCode = photoOutputNapi->photoOutput_->EnableMirror(isMirror);
2349 if (!CameraNapiUtils::CheckError(env, retCode)) {
2350 return result;
2351 }
2352 }
2353 return result;
2354 }
2355
IsQuickThumbnailSupported(napi_env env,napi_callback_info info)2356 napi_value PhotoOutputNapi::IsQuickThumbnailSupported(napi_env env, napi_callback_info info)
2357 {
2358 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2359 MEDIA_ERR_LOG("SystemApi IsQuickThumbnailSupported is called!");
2360 return nullptr;
2361 }
2362 napi_status status;
2363 napi_value result = nullptr;
2364 size_t argc = ARGS_ZERO;
2365 napi_value argv[ARGS_ZERO];
2366 napi_value thisVar = nullptr;
2367
2368 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2369
2370 napi_get_undefined(env, &result);
2371 PhotoOutputNapi* photoOutputNapi = nullptr;
2372 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2373 if (status == napi_ok && photoOutputNapi != nullptr) {
2374 int32_t retCode = photoOutputNapi->photoOutput_->IsQuickThumbnailSupported();
2375 bool isSupported = (retCode == 0);
2376 CHECK_ERROR_RETURN_RET(retCode > 0 && !CameraNapiUtils::CheckError(env, retCode), result);
2377 napi_get_boolean(env, isSupported, &result);
2378 }
2379 return result;
2380 }
2381
DeferImageDeliveryFor(napi_env env,napi_callback_info info)2382 napi_value PhotoOutputNapi::DeferImageDeliveryFor(napi_env env, napi_callback_info info)
2383 {
2384 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
2385 "SystemApi DeferImageDeliveryFor is called!");
2386 napi_status status;
2387 napi_value result = nullptr;
2388 size_t argc = ARGS_ONE;
2389 napi_value argv[ARGS_ONE] = {0};
2390 napi_value thisVar = nullptr;
2391 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2392 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2393 napi_get_undefined(env, &result);
2394 PhotoOutputNapi* photoOutputNapi = nullptr;
2395 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2396 if (status == napi_ok && photoOutputNapi != nullptr) {
2397 int32_t deliveryType;
2398 napi_get_value_int32(env, argv[PARAM0], &deliveryType);
2399 photoOutputNapi->photoOutput_->DeferImageDeliveryFor(static_cast<DeferredDeliveryImageType>(deliveryType));
2400 photoOutputNapi->isDeferredPhotoEnabled_ = deliveryType == DELIVERY_PHOTO;
2401 }
2402 return result;
2403 }
2404
IsDeferredImageDeliverySupported(napi_env env,napi_callback_info info)2405 napi_value PhotoOutputNapi::IsDeferredImageDeliverySupported(napi_env env, napi_callback_info info)
2406 {
2407 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
2408 "SystemApi IsDeferredImageDeliverySupported is called!");
2409 napi_status status;
2410 napi_value result = nullptr;
2411 size_t argc = ARGS_ONE;
2412 napi_value argv[ARGS_ONE] = {0};
2413 napi_value thisVar = nullptr;
2414 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2415 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2416 napi_get_undefined(env, &result);
2417 PhotoOutputNapi* photoOutputNapi = nullptr;
2418 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2419 if (status == napi_ok && photoOutputNapi != nullptr) {
2420 int32_t deliveryType;
2421 napi_get_value_int32(env, argv[PARAM0], &deliveryType);
2422 int32_t retCode = photoOutputNapi->photoOutput_->IsDeferredImageDeliverySupported(
2423 static_cast<DeferredDeliveryImageType>(deliveryType));
2424 bool isSupported = (retCode == 0);
2425 CHECK_ERROR_RETURN_RET(retCode > 0 && !CameraNapiUtils::CheckError(env, retCode), result);
2426 napi_get_boolean(env, isSupported, &result);
2427 }
2428 return result;
2429 }
2430
IsDeferredImageDeliveryEnabled(napi_env env,napi_callback_info info)2431 napi_value PhotoOutputNapi::IsDeferredImageDeliveryEnabled(napi_env env, napi_callback_info info)
2432 {
2433 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
2434 "SystemApi IsDeferredImageDeliveryEnabled is called!");
2435 napi_status status;
2436 napi_value result = nullptr;
2437 size_t argc = ARGS_ONE;
2438 napi_value argv[ARGS_ONE] = {0};
2439 napi_value thisVar = nullptr;
2440 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2441 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2442 napi_get_undefined(env, &result);
2443 PhotoOutputNapi* photoOutputNapi = nullptr;
2444 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2445 if (status == napi_ok && photoOutputNapi != nullptr) {
2446 int32_t deliveryType;
2447 napi_get_value_int32(env, argv[PARAM0], &deliveryType);
2448 int32_t retCode = photoOutputNapi->photoOutput_->IsDeferredImageDeliveryEnabled(
2449 static_cast<DeferredDeliveryImageType>(deliveryType));
2450 bool isSupported = (retCode == 0);
2451 CHECK_ERROR_RETURN_RET(retCode > 0 && !CameraNapiUtils::CheckError(env, retCode), result);
2452 napi_get_boolean(env, isSupported, &result);
2453 }
2454 return result;
2455 }
2456
GetPhotoRotation(napi_env env,napi_callback_info info)2457 napi_value PhotoOutputNapi::GetPhotoRotation(napi_env env, napi_callback_info info)
2458 {
2459 MEDIA_DEBUG_LOG("GetPhotoRotation is called!");
2460 napi_status status;
2461 napi_value result = nullptr;
2462 size_t argc = ARGS_ONE;
2463 napi_value argv[ARGS_ONE] = {0};
2464 napi_value thisVar = nullptr;
2465 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2466
2467 napi_get_undefined(env, &result);
2468 PhotoOutputNapi* photoOutputNapi = nullptr;
2469 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2470 if (status == napi_ok && photoOutputNapi != nullptr) {
2471 int32_t value;
2472 napi_status ret = napi_get_value_int32(env, argv[PARAM0], &value);
2473 if (ret != napi_ok) {
2474 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
2475 "GetPhotoRotation parameter missing or parameter type incorrect.");
2476 return result;
2477 }
2478 int32_t retCode = photoOutputNapi->photoOutput_->GetPhotoRotation(value);
2479 if (retCode == SERVICE_FATL_ERROR) {
2480 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR,
2481 "GetPhotoRotation Camera service fatal error.");
2482 return result;
2483 }
2484 napi_create_int32(env, retCode, &result);
2485 MEDIA_INFO_LOG("PhotoOutputNapi GetPhotoRotation! %{public}d", retCode);
2486 } else {
2487 MEDIA_ERR_LOG("PhotoOutputNapi GetPhotoRotation! called failed!");
2488 }
2489 return result;
2490 }
2491
IsMovingPhotoSupported(napi_env env,napi_callback_info info)2492 napi_value PhotoOutputNapi::IsMovingPhotoSupported(napi_env env, napi_callback_info info)
2493 {
2494 MEDIA_DEBUG_LOG("IsMotionPhotoSupported is called");
2495 napi_status status;
2496 napi_value result = nullptr;
2497 size_t argc = ARGS_ZERO;
2498 napi_value argv[ARGS_ZERO];
2499 napi_value thisVar = nullptr;
2500
2501 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2502
2503 napi_get_undefined(env, &result);
2504 PhotoOutputNapi* photoOutputNapi = nullptr;
2505 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2506 CHECK_ERROR_RETURN_RET_LOG(status != napi_ok || photoOutputNapi == nullptr, result,
2507 "IsMotionPhotoSupported photoOutputNapi is null!");
2508 auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2509 if (session != nullptr) {
2510 bool isSupported = session->IsMovingPhotoSupported();
2511 napi_get_boolean(env, isSupported, &result);
2512 } else {
2513 napi_get_boolean(env, false, &result);
2514 MEDIA_ERR_LOG("IsMotionPhotoSupported call Failed!");
2515 }
2516 return result;
2517 }
2518
EnableMovingPhoto(napi_env env,napi_callback_info info)2519 napi_value PhotoOutputNapi::EnableMovingPhoto(napi_env env, napi_callback_info info)
2520 {
2521 MEDIA_DEBUG_LOG("enableMovingPhoto is called");
2522 napi_status status;
2523 napi_value result = nullptr;
2524 size_t argc = ARGS_ONE;
2525 napi_value argv[ARGS_ONE] = { 0 };
2526 napi_value thisVar = nullptr;
2527 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2528 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2529 napi_valuetype valueType = napi_undefined;
2530 napi_typeof(env, argv[0], &valueType);
2531 CHECK_ERROR_RETURN_RET(valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT), result);
2532 napi_get_undefined(env, &result);
2533 PhotoOutputNapi* photoOutputNapi = nullptr;
2534 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2535 CHECK_ERROR_RETURN_RET_LOG(status != napi_ok || photoOutputNapi == nullptr, result,
2536 "EnableMovingPhoto photoOutputNapi is null!");
2537 auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2538 if (session != nullptr) {
2539 bool isEnableMovingPhoto;
2540 napi_get_value_bool(env, argv[PARAM0], &isEnableMovingPhoto);
2541 if (photoOutputNapi->GetPhotoOutput()) {
2542 photoOutputNapi->GetPhotoOutput()->EnableMovingPhoto(isEnableMovingPhoto);
2543 }
2544 session->LockForControl();
2545 int32_t retCode = session->EnableMovingPhoto(isEnableMovingPhoto);
2546 session->UnlockForControl();
2547 CHECK_ERROR_RETURN_RET(retCode != 0 && !CameraNapiUtils::CheckError(env, retCode), result);
2548 }
2549 return result;
2550 }
2551
GetSupportedMovingPhotoVideoCodecTypes(napi_env env,napi_callback_info info)2552 napi_value PhotoOutputNapi::GetSupportedMovingPhotoVideoCodecTypes(napi_env env, napi_callback_info info)
2553 {
2554 MEDIA_DEBUG_LOG("IsMotionPhotoSupported is called");
2555 napi_status status;
2556 napi_value result = nullptr;
2557 size_t argc = ARGS_ZERO;
2558 napi_value argv[ARGS_ZERO];
2559 napi_value thisVar = nullptr;
2560
2561 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2562
2563 napi_get_undefined(env, &result);
2564 PhotoOutputNapi* photoOutputNapi = nullptr;
2565 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2566 CHECK_ERROR_RETURN_RET_LOG(status != napi_ok || photoOutputNapi == nullptr, result,
2567 "IsMotionPhotoSupported photoOutputNapi is null!");
2568 vector<int32_t> videoCodecTypes = {VideoCodecType::VIDEO_ENCODE_TYPE_AVC, VideoCodecType::VIDEO_ENCODE_TYPE_HEVC};
2569 result = CameraNapiUtils::CreateJSArray(env, status, videoCodecTypes);
2570 if (status != napi_ok) {
2571 result = CameraNapiUtils::CreateJSArray(env, status, {});
2572 }
2573 return result;
2574 }
2575
SetMovingPhotoVideoCodecType(napi_env env,napi_callback_info info)2576 napi_value PhotoOutputNapi::SetMovingPhotoVideoCodecType(napi_env env, napi_callback_info info)
2577 {
2578 MEDIA_DEBUG_LOG("SetMovingPhotoVideoCodecType is called");
2579 napi_status status;
2580 napi_value result = nullptr;
2581 size_t argc = ARGS_ONE;
2582 napi_value argv[ARGS_ONE] = { 0 };
2583 napi_value thisVar = nullptr;
2584 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2585 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2586 napi_valuetype valueType = napi_undefined;
2587 napi_typeof(env, argv[0], &valueType);
2588 CHECK_ERROR_RETURN_RET(valueType != napi_number && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT), result);
2589 napi_get_undefined(env, &result);
2590 PhotoOutputNapi* photoOutputNapi = nullptr;
2591 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2592 CHECK_ERROR_RETURN_RET_LOG(status != napi_ok || photoOutputNapi == nullptr, result,
2593 "SetMovingPhotoVideoCodecType photoOutputNapi is null!");
2594 if (photoOutputNapi->GetPhotoOutput() != nullptr) {
2595 int32_t codecType;
2596 napi_get_value_int32(env, argv[PARAM0], &codecType);
2597 int32_t retCode = photoOutputNapi->GetPhotoOutput()->SetMovingPhotoVideoCodecType(codecType);
2598 CHECK_ERROR_RETURN_RET(retCode != 0 && !CameraNapiUtils::CheckError(env, retCode), result);
2599 }
2600 return result;
2601 }
2602
EnableQuickThumbnail(napi_env env,napi_callback_info info)2603 napi_value PhotoOutputNapi::EnableQuickThumbnail(napi_env env, napi_callback_info info)
2604 {
2605 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
2606 "SystemApi EnableQuickThumbnail is called!");
2607 napi_status status;
2608 napi_value result = nullptr;
2609 size_t argc = ARGS_ONE;
2610 napi_value argv[ARGS_ONE] = { 0 };
2611 napi_value thisVar = nullptr;
2612 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2613 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2614 napi_valuetype valueType = napi_undefined;
2615 napi_typeof(env, argv[0], &valueType);
2616 CHECK_ERROR_RETURN_RET(valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT), result);
2617 napi_get_undefined(env, &result);
2618 PhotoOutputNapi* photoOutputNapi = nullptr;
2619 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2620 bool thumbnailSwitch;
2621 if (status == napi_ok && photoOutputNapi != nullptr) {
2622 napi_get_value_bool(env, argv[PARAM0], &thumbnailSwitch);
2623 photoOutputNapi->isQuickThumbnailEnabled_ = thumbnailSwitch;
2624 int32_t retCode = photoOutputNapi->photoOutput_->SetThumbnail(thumbnailSwitch);
2625 CHECK_ERROR_RETURN_RET(retCode != 0 && !CameraNapiUtils::CheckError(env, retCode), result);
2626 }
2627 return result;
2628 }
2629
IsRawDeliverySupported(napi_env env,napi_callback_info info)2630 napi_value PhotoOutputNapi::IsRawDeliverySupported(napi_env env, napi_callback_info info)
2631 {
2632 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
2633 "SystemApi IsRawDeliverySupported is called!");
2634 napi_status status;
2635 napi_value result = nullptr;
2636 size_t argc = ARGS_ZERO;
2637 napi_value argv[ARGS_ZERO];
2638 napi_value thisVar = nullptr;
2639
2640 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2641
2642 napi_get_undefined(env, &result);
2643 bool isSupported = false;
2644 PhotoOutputNapi* photoOutputNapi = nullptr;
2645 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2646 if (status == napi_ok && photoOutputNapi != nullptr) {
2647 int32_t retCode = photoOutputNapi->photoOutput_->IsRawDeliverySupported(isSupported);
2648 CHECK_ERROR_RETURN_RET(!CameraNapiUtils::CheckError(env, retCode), nullptr);
2649 }
2650 napi_get_boolean(env, isSupported, &result);
2651 return result;
2652 }
2653
EnableRawDelivery(napi_env env,napi_callback_info info)2654 napi_value PhotoOutputNapi::EnableRawDelivery(napi_env env, napi_callback_info info)
2655 {
2656 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
2657 "SystemApi EnableRawDelivery is called!");
2658 napi_status status;
2659 napi_value result = nullptr;
2660 size_t argc = ARGS_ONE;
2661 napi_value argv[ARGS_ONE] = { 0 };
2662 napi_value thisVar = nullptr;
2663 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2664 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2665 napi_valuetype valueType = napi_undefined;
2666 napi_typeof(env, argv[0], &valueType);
2667 CHECK_ERROR_RETURN_RET(valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT), result);
2668 napi_get_undefined(env, &result);
2669 PhotoOutputNapi* photoOutputNapi = nullptr;
2670 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2671 bool rawDeliverySwitch;
2672 if (status == napi_ok && photoOutputNapi != nullptr) {
2673 napi_get_value_bool(env, argv[PARAM0], &rawDeliverySwitch);
2674 int32_t retCode = photoOutputNapi->photoOutput_->EnableRawDelivery(rawDeliverySwitch);
2675 CHECK_ERROR_RETURN_RET(retCode != 0 && !CameraNapiUtils::CheckError(env, retCode), result);
2676 }
2677 MEDIA_INFO_LOG("new rawPhotoListener and register surface consumer listener");
2678 CHECK_ERROR_RETURN_RET_LOG(photoOutputNapi == nullptr, result, "photoOutputNapi is null!");
2679 auto rawSurface = photoOutputNapi->photoOutput_->rawPhotoSurface_;
2680 CHECK_ERROR_RETURN_RET_LOG(rawSurface == nullptr, result, "rawPhotoSurface_ is null!");
2681 sptr<RawPhotoListener> rawPhotoListener = new (std::nothrow) RawPhotoListener(env, rawSurface);
2682 CHECK_ERROR_RETURN_RET_LOG(rawPhotoListener == nullptr, result, "failed to new rawPhotoListener");
2683 SurfaceError ret = rawSurface->RegisterConsumerListener((sptr<IBufferConsumerListener>&)rawPhotoListener);
2684 CHECK_ERROR_PRINT_LOG(ret != SURFACE_ERROR_OK, "register surface consumer listener failed!");
2685 photoOutputNapi->rawPhotoListener_ = rawPhotoListener;
2686 napi_value callback;
2687 napi_get_reference_value(env, rawCallback_, &callback);
2688 photoOutputNapi->rawPhotoListener_->SaveCallbackReference(CONST_CAPTURE_PHOTO_AVAILABLE, callback, false);
2689 return result;
2690 }
2691
GetActiveProfile(napi_env env,napi_callback_info info)2692 napi_value PhotoOutputNapi::GetActiveProfile(napi_env env, napi_callback_info info)
2693 {
2694 MEDIA_DEBUG_LOG("PhotoOutputNapi::GetActiveProfile is called");
2695 PhotoOutputNapi* photoOutputNapi = nullptr;
2696 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
2697 CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
2698 nullptr, "PhotoOutputNapi::GetActiveProfile parse parameter occur error");
2699 auto profile = photoOutputNapi->photoOutput_->GetPhotoProfile();
2700 CHECK_ERROR_RETURN_RET(profile == nullptr, CameraNapiUtils::GetUndefinedValue(env));
2701 return CameraNapiObjProfile(*profile).GenerateNapiValue(env);
2702 }
2703
RegisterQuickThumbnailCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2704 void PhotoOutputNapi::RegisterQuickThumbnailCallbackListener(
2705 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2706 {
2707 CHECK_ERROR_RETURN_LOG(!CameraNapiSecurity::CheckSystemApp(env), "SystemApi quickThumbnail on is called!");
2708
2709 // Set callback for exposureStateChange
2710 if (thumbnailListener_ == nullptr) {
2711 if (!isQuickThumbnailEnabled_) {
2712 MEDIA_ERR_LOG("quickThumbnail is not enabled!");
2713 napi_throw_error(env, std::to_string(SESSION_NOT_RUNNING).c_str(), "");
2714 return;
2715 }
2716 thumbnailListener_ = new ThumbnailListener(env, photoOutput_);
2717 photoOutput_->SetThumbnailListener((sptr<IBufferConsumerListener>&)thumbnailListener_);
2718 }
2719 thumbnailListener_->SaveCallbackReference(eventName, callback, isOnce);
2720 }
2721
UnregisterQuickThumbnailCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2722 void PhotoOutputNapi::UnregisterQuickThumbnailCallbackListener(
2723 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2724 {
2725 CHECK_ERROR_RETURN_LOG(!CameraNapiSecurity::CheckSystemApp(env), "SystemApi quickThumbnail off is called!");
2726 if (!isQuickThumbnailEnabled_) {
2727 MEDIA_ERR_LOG("quickThumbnail is not enabled!");
2728 napi_throw_error(env, std::to_string(SESSION_NOT_RUNNING).c_str(), "");
2729 return;
2730 }
2731 if (thumbnailListener_ != nullptr) {
2732 thumbnailListener_->RemoveCallbackRef(eventName, callback);
2733 if (thumbnailListener_->taskManager_) {
2734 thumbnailListener_->ClearTaskManager();
2735 }
2736 }
2737 }
2738
RegisterPhotoAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2739 void PhotoOutputNapi::RegisterPhotoAvailableCallbackListener(
2740 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2741 {
2742 CHECK_ERROR_RETURN_LOG(photoOutput_->GetPhotoSurface() == nullptr, "PhotoSurface_ is null!");
2743 if (photoListener_ == nullptr) {
2744 MEDIA_INFO_LOG("new photoListener and register surface consumer listener");
2745 sptr<PhotoListener> photoListener = new (std::nothrow)
2746 PhotoListener(env, photoOutput_->GetPhotoSurface(), photoOutput_);
2747 CHECK_ERROR_RETURN_LOG(photoListener == nullptr, "photoListener is null!");
2748 SurfaceError ret =
2749 photoOutput_->GetPhotoSurface()->RegisterConsumerListener((sptr<IBufferConsumerListener> &)photoListener);
2750 CHECK_ERROR_PRINT_LOG(ret != SURFACE_ERROR_OK, "register surface consumer listener failed!");
2751 photoListener_ = photoListener;
2752 }
2753 photoListener_->SaveCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callback);
2754
2755 // Preconfig can't support rawPhotoListener.
2756 if (photoOutput_ != nullptr && profile_ != nullptr) {
2757 napi_ref rawCallback;
2758 napi_create_reference(env, callback, 1, &rawCallback);
2759 rawCallback_ = rawCallback;
2760 CHECK_EXECUTE(profile_->GetCameraFormat() == CAMERA_FORMAT_YUV_420_SP, CreateMultiChannelPictureLisenter(env));
2761 }
2762 }
2763
UnregisterPhotoAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2764 void PhotoOutputNapi::UnregisterPhotoAvailableCallbackListener(
2765 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2766 {
2767 if (photoListener_ != nullptr) {
2768 photoListener_->RemoveCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callback);
2769 if (photoListener_->IsEmpty(CONST_CAPTURE_PHOTO_AVAILABLE)) {
2770 photoListener_->ClearTaskManager();
2771 }
2772 }
2773 CHECK_EXECUTE(rawPhotoListener_ != nullptr,
2774 rawPhotoListener_->RemoveCallbackRef(CONST_CAPTURE_PHOTO_AVAILABLE, callback));
2775 }
2776
RegisterDeferredPhotoProxyAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2777 void PhotoOutputNapi::RegisterDeferredPhotoProxyAvailableCallbackListener(
2778 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2779 {
2780 CHECK_ERROR_RETURN_LOG(photoOutput_->GetPhotoSurface() == nullptr, "PhotoSurface is null!");
2781 if (photoListener_ == nullptr) {
2782 MEDIA_INFO_LOG("new deferred photoListener and register surface consumer listener");
2783 sptr<PhotoListener> photoListener = new (std::nothrow)
2784 PhotoListener(env, photoOutput_->GetPhotoSurface(), photoOutput_);
2785 CHECK_ERROR_RETURN_LOG(photoListener == nullptr, "failed to new photoListener!");
2786 SurfaceError ret =
2787 photoOutput_->GetPhotoSurface()->RegisterConsumerListener((sptr<IBufferConsumerListener> &)photoListener);
2788 CHECK_ERROR_PRINT_LOG(ret != SURFACE_ERROR_OK, "register surface consumer listener failed!");
2789 photoListener_ = photoListener;
2790 }
2791 photoListener_->SaveCallback(CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, callback);
2792 }
2793
UnregisterDeferredPhotoProxyAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2794 void PhotoOutputNapi::UnregisterDeferredPhotoProxyAvailableCallbackListener(
2795 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2796 {
2797 CHECK_EXECUTE(photoListener_ != nullptr,
2798 photoListener_->RemoveCallback(CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, callback));
2799 }
2800
RegisterPhotoAssetAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2801 void PhotoOutputNapi::RegisterPhotoAssetAvailableCallbackListener(
2802 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2803 {
2804 CHECK_ERROR_RETURN_LOG(photoOutput_->GetPhotoSurface() == nullptr, "PhotoSurface is null!");
2805 CHECK_ERROR_RETURN_LOG(photoOutput_ == nullptr, "photoOutput_ is null!");
2806 if (photoOutput_->IsYuvOrHeifPhoto()) {
2807 CreateMultiChannelPictureLisenter(env);
2808 } else {
2809 CreateSingleChannelPhotoLisenter(env);
2810 }
2811 photoListener_->SaveCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callback);
2812 }
2813
UnregisterPhotoAssetAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2814 void PhotoOutputNapi::UnregisterPhotoAssetAvailableCallbackListener(
2815 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2816 {
2817 if (photoListener_ != nullptr) {
2818 photoListener_->RemoveCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callback);
2819 if (photoListener_->IsEmpty(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE)) {
2820 photoListener_->ClearTaskManager();
2821 }
2822 }
2823 if (photoOutput_) {
2824 if (photoOutput_->taskManager_) {
2825 photoOutput_->taskManager_->CancelAllTasks();
2826 photoOutput_->taskManager_.reset();
2827 photoOutput_->taskManager_ = nullptr;
2828 }
2829 }
2830 }
2831
RegisterCaptureStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2832 void PhotoOutputNapi::RegisterCaptureStartCallbackListener(
2833 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2834 {
2835 if (photoOutputCallback_ == nullptr) {
2836 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2837 photoOutput_->SetCallback(photoOutputCallback_);
2838 }
2839 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_START, callback, isOnce);
2840 }
2841
UnregisterCaptureStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2842 void PhotoOutputNapi::UnregisterCaptureStartCallbackListener(
2843 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2844 {
2845 CHECK_ERROR_RETURN_LOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
2846 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_START, callback);
2847 }
2848
RegisterCaptureStartWithInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2849 void PhotoOutputNapi::RegisterCaptureStartWithInfoCallbackListener(
2850 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2851 {
2852 if (photoOutputCallback_ == nullptr) {
2853 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2854 photoOutput_->SetCallback(photoOutputCallback_);
2855 }
2856 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_START_WITH_INFO, callback, isOnce);
2857 }
2858
UnregisterCaptureStartWithInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2859 void PhotoOutputNapi::UnregisterCaptureStartWithInfoCallbackListener(
2860 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2861 {
2862 CHECK_ERROR_RETURN_LOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
2863 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_START_WITH_INFO, callback);
2864 }
2865
RegisterCaptureEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2866 void PhotoOutputNapi::RegisterCaptureEndCallbackListener(
2867 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2868 {
2869 if (photoOutputCallback_ == nullptr) {
2870 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2871 photoOutput_->SetCallback(photoOutputCallback_);
2872 }
2873 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_END, callback, isOnce);
2874 }
2875
UnregisterCaptureEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2876 void PhotoOutputNapi::UnregisterCaptureEndCallbackListener(
2877 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2878 {
2879 CHECK_ERROR_RETURN_LOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
2880 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_END, callback);
2881 }
2882
RegisterFrameShutterCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2883 void PhotoOutputNapi::RegisterFrameShutterCallbackListener(
2884 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2885 {
2886 if (photoOutputCallback_ == nullptr) {
2887 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2888 photoOutput_->SetCallback(photoOutputCallback_);
2889 }
2890 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_FRAME_SHUTTER, callback, isOnce);
2891 }
2892
UnregisterFrameShutterCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2893 void PhotoOutputNapi::UnregisterFrameShutterCallbackListener(
2894 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2895 {
2896 CHECK_ERROR_RETURN_LOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
2897 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_FRAME_SHUTTER, callback);
2898 }
2899
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2900 void PhotoOutputNapi::RegisterErrorCallbackListener(
2901 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2902 {
2903 if (photoOutputCallback_ == nullptr) {
2904 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2905 photoOutput_->SetCallback(photoOutputCallback_);
2906 }
2907 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_ERROR, callback, isOnce);
2908 }
2909
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2910 void PhotoOutputNapi::UnregisterErrorCallbackListener(
2911 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2912 {
2913 CHECK_ERROR_RETURN_LOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
2914 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_ERROR, callback);
2915 }
2916
RegisterFrameShutterEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2917 void PhotoOutputNapi::RegisterFrameShutterEndCallbackListener(
2918 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2919 {
2920 if (photoOutputCallback_ == nullptr) {
2921 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2922 photoOutput_->SetCallback(photoOutputCallback_);
2923 }
2924 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_FRAME_SHUTTER_END, callback, isOnce);
2925 }
2926
UnregisterFrameShutterEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2927 void PhotoOutputNapi::UnregisterFrameShutterEndCallbackListener(
2928 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2929 {
2930 CHECK_ERROR_RETURN_LOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
2931 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_FRAME_SHUTTER_END, callback);
2932 }
2933
RegisterReadyCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2934 void PhotoOutputNapi::RegisterReadyCallbackListener(
2935 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2936 {
2937 if (photoOutputCallback_ == nullptr) {
2938 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2939 photoOutput_->SetCallback(photoOutputCallback_);
2940 }
2941 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_READY, callback, isOnce);
2942 }
2943
UnregisterReadyCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2944 void PhotoOutputNapi::UnregisterReadyCallbackListener(
2945 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2946 {
2947 CHECK_ERROR_RETURN_LOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
2948 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_READY, callback);
2949 }
2950
RegisterEstimatedCaptureDurationCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2951 void PhotoOutputNapi::RegisterEstimatedCaptureDurationCallbackListener(
2952 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2953 {
2954 if (photoOutputCallback_ == nullptr) {
2955 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2956 photoOutput_->SetCallback(photoOutputCallback_);
2957 }
2958 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callback, isOnce);
2959 }
2960
UnregisterEstimatedCaptureDurationCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2961 void PhotoOutputNapi::UnregisterEstimatedCaptureDurationCallbackListener(
2962 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2963 {
2964 CHECK_ERROR_RETURN_LOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
2965 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callback);
2966 }
2967
GetEmitterFunctions()2968 const PhotoOutputNapi::EmitterFunctions& PhotoOutputNapi::GetEmitterFunctions()
2969 {
2970 static const EmitterFunctions funMap = {
2971 { CONST_CAPTURE_QUICK_THUMBNAIL, {
2972 &PhotoOutputNapi::RegisterQuickThumbnailCallbackListener,
2973 &PhotoOutputNapi::UnregisterQuickThumbnailCallbackListener } },
2974 { CONST_CAPTURE_PHOTO_AVAILABLE, {
2975 &PhotoOutputNapi::RegisterPhotoAvailableCallbackListener,
2976 &PhotoOutputNapi::UnregisterPhotoAvailableCallbackListener } },
2977 { CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, {
2978 &PhotoOutputNapi::RegisterDeferredPhotoProxyAvailableCallbackListener,
2979 &PhotoOutputNapi::UnregisterDeferredPhotoProxyAvailableCallbackListener } },
2980 { CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, {
2981 &PhotoOutputNapi::RegisterPhotoAssetAvailableCallbackListener,
2982 &PhotoOutputNapi::UnregisterPhotoAssetAvailableCallbackListener } },
2983 { CONST_CAPTURE_START, {
2984 &PhotoOutputNapi::RegisterCaptureStartCallbackListener,
2985 &PhotoOutputNapi::UnregisterCaptureStartCallbackListener } },
2986 { CONST_CAPTURE_END, {
2987 &PhotoOutputNapi::RegisterCaptureEndCallbackListener,
2988 &PhotoOutputNapi::UnregisterCaptureEndCallbackListener } },
2989 { CONST_CAPTURE_FRAME_SHUTTER, {
2990 &PhotoOutputNapi::RegisterFrameShutterCallbackListener,
2991 &PhotoOutputNapi::UnregisterFrameShutterCallbackListener } },
2992 { CONST_CAPTURE_ERROR, {
2993 &PhotoOutputNapi::RegisterErrorCallbackListener,
2994 &PhotoOutputNapi::UnregisterErrorCallbackListener } },
2995 { CONST_CAPTURE_FRAME_SHUTTER_END, {
2996 &PhotoOutputNapi::RegisterFrameShutterEndCallbackListener,
2997 &PhotoOutputNapi::UnregisterFrameShutterEndCallbackListener } },
2998 { CONST_CAPTURE_READY, {
2999 &PhotoOutputNapi::RegisterReadyCallbackListener,
3000 &PhotoOutputNapi::UnregisterReadyCallbackListener } },
3001 { CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, {
3002 &PhotoOutputNapi::RegisterEstimatedCaptureDurationCallbackListener,
3003 &PhotoOutputNapi::UnregisterEstimatedCaptureDurationCallbackListener } },
3004 { CONST_CAPTURE_START_WITH_INFO, {
3005 &PhotoOutputNapi::RegisterCaptureStartWithInfoCallbackListener,
3006 &PhotoOutputNapi::UnregisterCaptureStartWithInfoCallbackListener } },
3007 { CONST_CAPTURE_OFFLINE_DELIVERY_FINISHED, {
3008 &PhotoOutputNapi::RegisterOfflineDeliveryFinishedCallbackListener,
3009 &PhotoOutputNapi::UnregisterOfflineDeliveryFinishedCallbackListener } } };
3010 return funMap;
3011 }
3012
On(napi_env env,napi_callback_info info)3013 napi_value PhotoOutputNapi::On(napi_env env, napi_callback_info info)
3014 {
3015 return ListenerTemplate<PhotoOutputNapi>::On(env, info);
3016 }
3017
Once(napi_env env,napi_callback_info info)3018 napi_value PhotoOutputNapi::Once(napi_env env, napi_callback_info info)
3019 {
3020 return ListenerTemplate<PhotoOutputNapi>::Once(env, info);
3021 }
3022
Off(napi_env env,napi_callback_info info)3023 napi_value PhotoOutputNapi::Off(napi_env env, napi_callback_info info)
3024 {
3025 return ListenerTemplate<PhotoOutputNapi>::Off(env, info);
3026 }
3027
IsAutoHighQualityPhotoSupported(napi_env env,napi_callback_info info)3028 napi_value PhotoOutputNapi::IsAutoHighQualityPhotoSupported(napi_env env, napi_callback_info info)
3029 {
3030 auto result = CameraNapiUtils::GetUndefinedValue(env);
3031 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), result,
3032 "SystemApi IsAutoHighQualityPhotoSupported is called!");
3033 MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported is called");
3034 PhotoOutputNapi* photoOutputNapi = nullptr;
3035 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
3036 CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
3037 result, "PhotoOutputNapi::IsAutoHighQualityPhotoSupported parse parameter occur error");
3038 if (photoOutputNapi->photoOutput_ == nullptr) {
3039 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported get native object fail");
3040 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3041 return result;
3042 }
3043
3044 int32_t isAutoHighQualityPhotoSupported;
3045 int32_t retCode = photoOutputNapi->photoOutput_->IsAutoHighQualityPhotoSupported(isAutoHighQualityPhotoSupported);
3046 if (retCode == 0 && isAutoHighQualityPhotoSupported != -1) {
3047 napi_get_boolean(env, true, &result);
3048 return result;
3049 }
3050 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported is not supported");
3051 napi_get_boolean(env, false, &result);
3052 return result;
3053 }
3054
EnableAutoHighQualityPhoto(napi_env env,napi_callback_info info)3055 napi_value PhotoOutputNapi::EnableAutoHighQualityPhoto(napi_env env, napi_callback_info info)
3056 {
3057 auto result = CameraNapiUtils::GetUndefinedValue(env);
3058 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), result,
3059 "SystemApi EnableAutoHighQualityPhoto is called!");
3060 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto is called");
3061 PhotoOutputNapi* photoOutputNapi = nullptr;
3062 bool isEnable;
3063 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
3064 CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
3065 result, "PhotoOutputNapi::EnableAutoHighQualityPhoto parse parameter occur error");
3066 if (photoOutputNapi->photoOutput_ == nullptr) {
3067 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto get native object fail");
3068 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3069 return result;
3070 }
3071
3072 int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoHighQualityPhoto(isEnable);
3073 CHECK_ERROR_PRINT_LOG(!CameraNapiUtils::CheckError(env, retCode),
3074 "PhotoOutputNapi::EnableAutoHighQualityPhoto fail %{public}d", retCode);
3075 return result;
3076 }
3077
IsAutoCloudImageEnhancementSupported(napi_env env,napi_callback_info info)3078 napi_value PhotoOutputNapi::IsAutoCloudImageEnhancementSupported(napi_env env, napi_callback_info info)
3079 {
3080 auto result = CameraNapiUtils::GetUndefinedValue(env);
3081 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), result,
3082 "SystemApi IsAutoCloudImageEnhancementSupported is called!");
3083 MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported is called");
3084 PhotoOutputNapi* photoOutputNapi = nullptr;
3085 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
3086 CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
3087 result, "PhotoOutputNapi::IsAutoCloudImageEnhancementSupported parse parameter occur error");
3088 if (photoOutputNapi->photoOutput_ == nullptr) {
3089 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported get native object fail");
3090 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3091 return result;
3092 }
3093
3094 bool isAutoCloudImageEnhancementSupported = false;
3095 int32_t retCode =
3096 photoOutputNapi->photoOutput_->IsAutoCloudImageEnhancementSupported(
3097 isAutoCloudImageEnhancementSupported);
3098 CHECK_ERROR_RETURN_RET(!CameraNapiUtils::CheckError(env, retCode), nullptr);
3099 napi_get_boolean(env, isAutoCloudImageEnhancementSupported, &result);
3100 MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported is %{public}d",
3101 isAutoCloudImageEnhancementSupported);
3102 return result;
3103 }
3104
EnableAutoCloudImageEnhancement(napi_env env,napi_callback_info info)3105 napi_value PhotoOutputNapi::EnableAutoCloudImageEnhancement(napi_env env, napi_callback_info info)
3106 {
3107 auto result = CameraNapiUtils::GetUndefinedValue(env);
3108 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), result,
3109 "SystemApi EnableAutoCloudImageEnhancement is called!");
3110 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement is called");
3111 PhotoOutputNapi* photoOutputNapi = nullptr;
3112 bool isEnable;
3113 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
3114 CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
3115 result, "PhotoOutputNapi::EnableAutoCloudImageEnhancement parse parameter occur error");
3116 if (photoOutputNapi->photoOutput_ == nullptr) {
3117 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement get native object fail");
3118 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3119 return result;
3120 }
3121
3122 int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoCloudImageEnhancement(isEnable);
3123 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiUtils::CheckError(env, retCode), result,
3124 "PhotoOutputNapi::EnableAutoCloudImageEnhancement fail %{public}d", retCode);
3125 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement success");
3126 return result;
3127 }
3128
IsDepthDataDeliverySupported(napi_env env,napi_callback_info info)3129 napi_value PhotoOutputNapi::IsDepthDataDeliverySupported(napi_env env, napi_callback_info info)
3130 {
3131 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
3132 "SystemApi IsDepthDataDeliverySupported is called!");
3133 MEDIA_DEBUG_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported is called");
3134 PhotoOutputNapi* photoOutputNapi = nullptr;
3135 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
3136 CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
3137 nullptr, "PhotoOutputNapi::IsDepthDataDeliverySupported parse parameter occur error");
3138 if (photoOutputNapi->photoOutput_ == nullptr) {
3139 MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported get native object fail");
3140 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3141 return nullptr;
3142 }
3143 napi_value result = nullptr;
3144 int32_t retCode = photoOutputNapi->photoOutput_->IsDepthDataDeliverySupported();
3145 if (retCode == 0) {
3146 napi_get_boolean(env, true, &result);
3147 return result;
3148 }
3149 MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported is not supported");
3150 napi_get_boolean(env, false, &result);
3151 return result;
3152 }
3153
EnableDepthDataDelivery(napi_env env,napi_callback_info info)3154 napi_value PhotoOutputNapi::EnableDepthDataDelivery(napi_env env, napi_callback_info info)
3155 {
3156 CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
3157 "SystemApi EnableDepthDataDelivery is called!");
3158 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableDepthDataDelivery is called");
3159 PhotoOutputNapi* photoOutputNapi = nullptr;
3160 bool isEnable;
3161 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
3162 CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"), nullptr,
3163 "PhotoOutputNapi::EnableDepthDataDelivery parse parameter occur error");
3164 if (photoOutputNapi->photoOutput_ == nullptr) {
3165 MEDIA_ERR_LOG("PhotoOutputNapi::EnableDepthDataDelivery get native object fail");
3166 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3167 return nullptr;
3168 }
3169
3170 int32_t retCode = photoOutputNapi->photoOutput_->EnableDepthDataDelivery(isEnable);
3171 CHECK_ERROR_PRINT_LOG(!CameraNapiUtils::CheckError(env, retCode),
3172 "PhotoOutputNapi::EnableDepthDataDelivery fail %{public}d", retCode);
3173 return CameraNapiUtils::GetUndefinedValue(env);
3174 }
3175
IsAutoAigcPhotoSupported(napi_env env,napi_callback_info info)3176 napi_value PhotoOutputNapi::IsAutoAigcPhotoSupported(napi_env env, napi_callback_info info)
3177 {
3178 auto result = CameraNapiUtils::GetUndefinedValue(env);
3179 if (!CameraNapiSecurity::CheckSystemApp(env)) {
3180 MEDIA_ERR_LOG("SystemApi IsAutoAigcPhotoSupported is called!");
3181 return result;
3182 }
3183 MEDIA_INFO_LOG("PhotoOutputNapi::IsAutoAigcPhotoSupported is called");
3184 PhotoOutputNapi* photoOutputNapi = nullptr;
3185 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
3186 if (!jsParamParser.AssertStatus(PARAMETER_ERROR, "parse parameter occur error")) {
3187 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoAigcPhotoSupported parse parameter occur error");
3188 return result;
3189 }
3190 if (photoOutputNapi->photoOutput_ == nullptr) {
3191 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoAigcPhotoSupported get native object fail");
3192 CameraNapiUtils::ThrowError(env, PARAMETER_ERROR, "get native object fail");
3193 return result;
3194 }
3195 bool isAutoAigcPhotoSupported = false;
3196 int32_t retCode =
3197 photoOutputNapi->photoOutput_->IsAutoAigcPhotoSupported(
3198 isAutoAigcPhotoSupported);
3199 if (!CameraNapiUtils::CheckError(env, retCode)) {
3200 return nullptr;
3201 }
3202 napi_get_boolean(env, isAutoAigcPhotoSupported, &result);
3203 MEDIA_INFO_LOG("PhotoOutputNapi::IsAutoAigcPhotoSupported is %{public}d",
3204 isAutoAigcPhotoSupported);
3205 return result;
3206 }
3207
EnableAutoAigcPhoto(napi_env env,napi_callback_info info)3208 napi_value PhotoOutputNapi::EnableAutoAigcPhoto(napi_env env, napi_callback_info info)
3209 {
3210 auto result = CameraNapiUtils::GetUndefinedValue(env);
3211 if (!CameraNapiSecurity::CheckSystemApp(env)) {
3212 MEDIA_ERR_LOG("SystemApi EnableAutoAigcPhoto is called!");
3213 return result;
3214 }
3215 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoAigcPhoto is called");
3216 PhotoOutputNapi* photoOutputNapi = nullptr;
3217 bool isEnable;
3218 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
3219 if (!jsParamParser.AssertStatus(PARAMETER_ERROR, "parse parameter occur error")) {
3220 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoAigcPhoto parse parameter occur error");
3221 return result;
3222 }
3223 if (photoOutputNapi->photoOutput_ == nullptr) {
3224 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoAigcPhoto get native object fail");
3225 CameraNapiUtils::ThrowError(env, PARAMETER_ERROR, "get native object fail");
3226 return result;
3227 }
3228
3229 int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoAigcPhoto(isEnable);
3230 if (!CameraNapiUtils::CheckError(env, retCode)) {
3231 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoAigcPhoto fail %{public}d", retCode);
3232 return result;
3233 }
3234 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoAigcPhoto success");
3235 return result;
3236 }
3237
RegisterOfflineDeliveryFinishedCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)3238 void PhotoOutputNapi::RegisterOfflineDeliveryFinishedCallbackListener(
3239 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
3240 {
3241 if (photoOutputCallback_ == nullptr) {
3242 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
3243 photoOutput_->SetCallback(photoOutputCallback_);
3244 }
3245 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_OFFLINE_DELIVERY_FINISHED, callback, isOnce);
3246 }
3247
UnregisterOfflineDeliveryFinishedCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)3248 void PhotoOutputNapi::UnregisterOfflineDeliveryFinishedCallbackListener(
3249 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
3250 {
3251 if (photoOutputCallback_ == nullptr) {
3252 MEDIA_ERR_LOG("photoOutputCallback is null");
3253 return;
3254 }
3255 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_OFFLINE_DELIVERY_FINISHED, callback);
3256 }
3257
IsOfflineSupported(napi_env env,napi_callback_info info)3258 napi_value PhotoOutputNapi::IsOfflineSupported(napi_env env, napi_callback_info info)
3259 {
3260 if (!CameraNapiSecurity::CheckSystemApp(env)) {
3261 MEDIA_ERR_LOG("SystemApi IsOfflineSupported is called!");
3262 return nullptr;
3263 }
3264 MEDIA_INFO_LOG("PhotoOutputNapi::IsOfflineSupported is called");
3265 PhotoOutputNapi* photoOutputNapi = nullptr;
3266 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
3267 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
3268 MEDIA_ERR_LOG("PhotoOutputNapi::IsOfflineSupported parse parameter occur error");
3269 return nullptr;
3270 }
3271 if (photoOutputNapi->photoOutput_ == nullptr) {
3272 MEDIA_ERR_LOG("PhotoOutputNapi::IsOfflineSupported get native object fail");
3273 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3274 return nullptr;
3275 }
3276 napi_value result = nullptr;
3277 bool isSupported = photoOutputNapi->photoOutput_->IsOfflineSupported();
3278 napi_get_boolean(env, isSupported, &result);
3279 MEDIA_ERR_LOG("PhotoOutputNapi::IsOfflineSupported is support %{public}d", isSupported);
3280 return result;
3281 }
3282
EnableOfflinePhoto(napi_env env,napi_callback_info info)3283 napi_value PhotoOutputNapi::EnableOfflinePhoto(napi_env env, napi_callback_info info)
3284 {
3285 if (!CameraNapiSecurity::CheckSystemApp(env)) {
3286 MEDIA_ERR_LOG("SystemApi IsOfflineSupported is called!");
3287 return nullptr;
3288 }
3289 MEDIA_INFO_LOG("EnableOfflinePhoto is called");
3290 napi_status status;
3291 napi_value result = nullptr;
3292 size_t argc = ARGS_ONE;
3293 napi_value argv[ARGS_ONE] = { 0 };
3294 napi_value thisVar = nullptr;
3295 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
3296 napi_get_undefined(env, &result);
3297 PhotoOutputNapi* photoOutputNapi = nullptr;
3298 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
3299 if (status != napi_ok || photoOutputNapi == nullptr) {
3300 MEDIA_ERR_LOG("EnableOfflinePhoto photoOutputNapi is null!");
3301 return result;
3302 }
3303 auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
3304 if (session != nullptr && photoOutputNapi->GetPhotoOutput()) {
3305 photoOutputNapi->GetPhotoOutput()->EnableOfflinePhoto();
3306 }
3307 return result;
3308 }
3309 } // namespace CameraStandard
3310 } // namespace OHOS