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