1 /*
2 * Copyright (c) 2021-2022 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/video_output_napi.h"
17
18 #include <uv.h>
19
20 #include "camera_napi_const.h"
21 #include "camera_napi_object_types.h"
22 #include "camera_napi_param_parser.h"
23 #include "camera_napi_security_utils.h"
24 #include "camera_napi_template_utils.h"
25 #include "camera_napi_utils.h"
26 #include "camera_napi_worker_queue_keeper.h"
27 #include "camera_output_capability.h"
28 #include "listener_base.h"
29 #include "napi/native_api.h"
30 #include "napi/native_common.h"
31
32 namespace OHOS {
33 namespace CameraStandard {
34 namespace {
AsyncCompleteCallback(napi_env env,napi_status status,void * data)35 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
36 {
37 auto context = static_cast<VideoOutputAsyncContext*>(data);
38 CHECK_ERROR_RETURN_LOG(context == nullptr, "VideoOutputNapi AsyncCompleteCallback context is null");
39 MEDIA_INFO_LOG("VideoOutputNapi AsyncCompleteCallback %{public}s, status = %{public}d", context->funcName.c_str(),
40 context->status);
41 std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
42 jsContext->status = context->status;
43 if (!context->status) {
44 CameraNapiUtils::CreateNapiErrorObject(env, context->errorCode, context->errorMsg.c_str(), jsContext);
45 } else {
46 napi_get_undefined(env, &jsContext->data);
47 }
48 if (!context->funcName.empty() && context->taskId > 0) {
49 // Finish async trace
50 CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
51 jsContext->funcName = context->funcName;
52 }
53 if (context->work != nullptr) {
54 CameraNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef, context->work, *jsContext);
55 }
56 context->FreeHeldNapiValue(env);
57 delete context;
58 }
59 } // namespace
60
61 thread_local napi_ref VideoOutputNapi::sConstructor_ = nullptr;
62 thread_local sptr<VideoOutput> VideoOutputNapi::sVideoOutput_ = nullptr;
63 thread_local uint32_t VideoOutputNapi::videoOutputTaskId = CAMERA_VIDEO_OUTPUT_TASKID;
64
VideoCallbackListener(napi_env env)65 VideoCallbackListener::VideoCallbackListener(napi_env env) : ListenerBase(env) {}
66
UpdateJSCallbackAsync(VideoOutputEventType eventType,const VideoCallbackInfo & info) const67 void VideoCallbackListener::UpdateJSCallbackAsync(VideoOutputEventType eventType, const VideoCallbackInfo& info) const
68 {
69 MEDIA_DEBUG_LOG("UpdateJSCallbackAsync is called");
70 uv_loop_s* loop = nullptr;
71 napi_get_uv_event_loop(env_, &loop);
72 if (!loop) {
73 MEDIA_ERR_LOG("failed to get event loop");
74 return;
75 }
76 uv_work_t* work = new(std::nothrow) uv_work_t;
77 if (!work) {
78 MEDIA_ERR_LOG("failed to allocate work");
79 return;
80 }
81 std::unique_ptr<VideoOutputCallbackInfo> callbackInfo =
82 std::make_unique<VideoOutputCallbackInfo>(eventType, info, shared_from_this());
83 work->data = callbackInfo.get();
84 int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t* work) {}, [] (uv_work_t* work, int status) {
85 VideoOutputCallbackInfo* callbackInfo = reinterpret_cast<VideoOutputCallbackInfo *>(work->data);
86 if (callbackInfo) {
87 auto listener = callbackInfo->listener_.lock();
88 if (listener) {
89 listener->UpdateJSCallback(callbackInfo->eventType_, callbackInfo->info_);
90 }
91 delete callbackInfo;
92 }
93 delete work;
94 }, uv_qos_user_initiated);
95 if (ret) {
96 MEDIA_ERR_LOG("failed to execute work");
97 delete work;
98 } else {
99 callbackInfo.release();
100 }
101 }
102
OnFrameStarted() const103 void VideoCallbackListener::OnFrameStarted() const
104 {
105 CAMERA_SYNC_TRACE;
106 MEDIA_DEBUG_LOG("OnFrameStarted is called");
107 VideoCallbackInfo info;
108 UpdateJSCallbackAsync(VideoOutputEventType::VIDEO_FRAME_START, info);
109 }
110
OnFrameEnded(const int32_t frameCount) const111 void VideoCallbackListener::OnFrameEnded(const int32_t frameCount) const
112 {
113 CAMERA_SYNC_TRACE;
114 MEDIA_DEBUG_LOG("OnFrameEnded is called, frameCount: %{public}d", frameCount);
115 VideoCallbackInfo info;
116 info.frameCount = frameCount;
117 UpdateJSCallbackAsync(VideoOutputEventType::VIDEO_FRAME_END, info);
118 }
119
OnError(const int32_t errorCode) const120 void VideoCallbackListener::OnError(const int32_t errorCode) const
121 {
122 MEDIA_DEBUG_LOG("OnError is called, errorCode: %{public}d", errorCode);
123 VideoCallbackInfo info;
124 info.errorCode = errorCode;
125 UpdateJSCallbackAsync(VideoOutputEventType::VIDEO_FRAME_ERROR, info);
126 }
127
OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt captureEndedInfo) const128 void VideoCallbackListener::OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt captureEndedInfo) const
129 {
130 MEDIA_DEBUG_LOG("OnDeferredVideoEnhancementInfo is called");
131 VideoCallbackInfo info;
132 info.isDeferredVideoEnhancementAvailable = captureEndedInfo.isDeferredVideoEnhancementAvailable;
133 info.videoId = captureEndedInfo.videoId;
134 MEDIA_INFO_LOG("OnDeferredVideoEnhancementInfo isDeferredVideo:%{public}d videoId:%{public}s ",
135 info.isDeferredVideoEnhancementAvailable, info.videoId.c_str());
136 UpdateJSCallbackAsync(VideoOutputEventType::VIDEO_DEFERRED_ENHANCEMENT, info);
137 }
138
ExecuteOnDeferredVideoCb(const VideoCallbackInfo & info) const139 void VideoCallbackListener::ExecuteOnDeferredVideoCb(const VideoCallbackInfo& info) const
140 {
141 MEDIA_INFO_LOG("ExecuteOnDeferredVideoCb");
142 napi_value result[ARGS_TWO] = {nullptr, nullptr};
143 napi_value retVal;
144
145 napi_get_undefined(env_, &result[PARAM0]);
146 napi_get_undefined(env_, &result[PARAM1]);
147
148 napi_value propValue;
149 napi_create_object(env_, &result[PARAM1]);
150 napi_get_boolean(env_, info.isDeferredVideoEnhancementAvailable, &propValue);
151 napi_set_named_property(env_, result[PARAM1], "isDeferredVideoEnhancementAvailable", propValue);
152 napi_create_string_utf8(env_, info.videoId.c_str(), NAPI_AUTO_LENGTH, &propValue);
153 napi_set_named_property(env_, result[PARAM1], "videoId", propValue);
154
155 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
156 ExecuteCallback(CONST_VIDEO_DEFERRED_ENHANCEMENT, callbackNapiPara);
157 }
158
UpdateJSCallback(VideoOutputEventType eventType,const VideoCallbackInfo & info) const159 void VideoCallbackListener::UpdateJSCallback(VideoOutputEventType eventType, const VideoCallbackInfo& info) const
160 {
161 MEDIA_DEBUG_LOG("UpdateJSCallback is called");
162 switch (eventType) {
163 // case VideoOutputEventType::VIDEO_FRAME_START:
164 // case VideoOutputEventType::VIDEO_FRAME_END:
165 // case VideoOutputEventType::VIDEO_FRAME_ERROR:
166 // case VideoOutputEventType::VIDEO_INVALID_TYPE:
167 // break;
168 case VideoOutputEventType::VIDEO_DEFERRED_ENHANCEMENT:
169 ExecuteOnDeferredVideoCb(info);
170 break;
171 default:
172 MEDIA_ERR_LOG("Incorrect photo callback event type received from JS");
173 }
174
175 napi_value result[ARGS_ONE];
176 napi_value retVal;
177 napi_value propValue;
178 std::string eventName = VideoOutputEventTypeHelper.GetKeyString(eventType);
179 if (eventName.empty()) {
180 MEDIA_WARNING_LOG(
181 "VideoCallbackListener::UpdateJSCallback, event type is invalid %d", static_cast<int32_t>(eventType));
182 return;
183 }
184 if (eventType == VideoOutputEventType::VIDEO_FRAME_ERROR) {
185 napi_create_object(env_, &result[PARAM0]);
186 napi_create_int32(env_, info.errorCode, &propValue);
187 napi_set_named_property(env_, result[PARAM0], "code", propValue);
188 } else {
189 napi_get_undefined(env_, &result[PARAM0]);
190 }
191 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
192 ExecuteCallback(eventName, callbackNapiPara);
193 }
194
VideoOutputNapi()195 VideoOutputNapi::VideoOutputNapi() : env_(nullptr) {}
196
~VideoOutputNapi()197 VideoOutputNapi::~VideoOutputNapi()
198 {
199 MEDIA_DEBUG_LOG("~VideoOutputNapi is called");
200 }
201
VideoOutputNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)202 void VideoOutputNapi::VideoOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
203 {
204 MEDIA_DEBUG_LOG("VideoOutputNapiDestructor is called");
205 VideoOutputNapi* videoOutput = reinterpret_cast<VideoOutputNapi*>(nativeObject);
206 if (videoOutput != nullptr) {
207 delete videoOutput;
208 }
209 }
210
Init(napi_env env,napi_value exports)211 napi_value VideoOutputNapi::Init(napi_env env, napi_value exports)
212 {
213 MEDIA_DEBUG_LOG("Init is called");
214 napi_status status;
215 napi_value ctorObj;
216 int32_t refCount = 1;
217
218 napi_property_descriptor video_output_props[] = {
219 DECLARE_NAPI_FUNCTION("start", Start),
220 DECLARE_NAPI_FUNCTION("stop", Stop),
221 DECLARE_NAPI_FUNCTION("setFrameRate", SetFrameRate),
222 DECLARE_NAPI_FUNCTION("getActiveFrameRate", GetActiveFrameRate),
223 DECLARE_NAPI_FUNCTION("getSupportedFrameRates", GetSupportedFrameRates),
224 DECLARE_NAPI_FUNCTION("isMirrorSupported", IsMirrorSupported),
225 DECLARE_NAPI_FUNCTION("enableMirror", EnableMirror),
226 DECLARE_NAPI_FUNCTION("release", Release),
227 DECLARE_NAPI_FUNCTION("on", On),
228 DECLARE_NAPI_FUNCTION("once", Once),
229 DECLARE_NAPI_FUNCTION("off", Off),
230 DECLARE_NAPI_FUNCTION("getActiveProfile", GetActiveProfile),
231 DECLARE_NAPI_FUNCTION("getSupportedVideoMetaTypes", GetSupportedVideoMetaTypes),
232 DECLARE_NAPI_FUNCTION("attachMetaSurface", AttachMetaSurface),
233 DECLARE_NAPI_FUNCTION("getVideoRotation", GetVideoRotation),
234 DECLARE_NAPI_FUNCTION("isAutoDeferredVideoEnhancementSupported", IsAutoDeferredVideoEnhancementSupported),
235 DECLARE_NAPI_FUNCTION("isAutoDeferredVideoEnhancementEnabled", IsAutoDeferredVideoEnhancementEnabled),
236 DECLARE_NAPI_FUNCTION("enableAutoDeferredVideoEnhancement", EnableAutoDeferredVideoEnhancement)
237 };
238
239 status = napi_define_class(env, CAMERA_VIDEO_OUTPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
240 VideoOutputNapiConstructor, nullptr,
241 sizeof(video_output_props) / sizeof(video_output_props[PARAM0]),
242 video_output_props, &ctorObj);
243 if (status == napi_ok) {
244 status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
245 if (status == napi_ok) {
246 status = napi_set_named_property(env, exports, CAMERA_VIDEO_OUTPUT_NAPI_CLASS_NAME, ctorObj);
247 if (status == napi_ok) {
248 return exports;
249 }
250 }
251 }
252 MEDIA_ERR_LOG("Init call Failed!");
253 return nullptr;
254 }
255
256 // Constructor callback
VideoOutputNapiConstructor(napi_env env,napi_callback_info info)257 napi_value VideoOutputNapi::VideoOutputNapiConstructor(napi_env env, napi_callback_info info)
258 {
259 MEDIA_DEBUG_LOG("VideoOutputNapiConstructor is called");
260 napi_status status;
261 napi_value result = nullptr;
262 napi_value thisVar = nullptr;
263
264 napi_get_undefined(env, &result);
265 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
266
267 if (status == napi_ok && thisVar != nullptr) {
268 std::unique_ptr<VideoOutputNapi> obj = std::make_unique<VideoOutputNapi>();
269 if (obj != nullptr) {
270 obj->env_ = env;
271 obj->videoOutput_ = sVideoOutput_;
272
273 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
274 VideoOutputNapi::VideoOutputNapiDestructor, nullptr, nullptr);
275 if (status == napi_ok) {
276 obj.release();
277 return thisVar;
278 } else {
279 MEDIA_ERR_LOG("Failure wrapping js to native napi");
280 }
281 }
282 }
283 MEDIA_ERR_LOG("VideoOutputNapiConstructor call Failed!");
284 return result;
285 }
286
GetVideoOutput()287 sptr<VideoOutput> VideoOutputNapi::GetVideoOutput()
288 {
289 return videoOutput_;
290 }
291
IsVideoOutput(napi_env env,napi_value obj)292 bool VideoOutputNapi::IsVideoOutput(napi_env env, napi_value obj)
293 {
294 MEDIA_DEBUG_LOG("IsVideoOutput is called");
295 bool result = false;
296 napi_status status;
297 napi_value constructor = nullptr;
298
299 status = napi_get_reference_value(env, sConstructor_, &constructor);
300 if (status == napi_ok) {
301 status = napi_instanceof(env, obj, constructor, &result);
302 if (status != napi_ok) {
303 result = false;
304 }
305 }
306 return result;
307 }
308
GetActiveProfile(napi_env env,napi_callback_info info)309 napi_value VideoOutputNapi::GetActiveProfile(napi_env env, napi_callback_info info)
310 {
311 MEDIA_DEBUG_LOG("VideoOutputNapi::GetActiveProfile is called");
312 VideoOutputNapi* videoOutputNapi = nullptr;
313 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
314 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
315 MEDIA_ERR_LOG("VideoOutputNapi::GetActiveProfile parse parameter occur error");
316 return nullptr;
317 }
318 auto profile = videoOutputNapi->videoOutput_->GetVideoProfile();
319 if (profile == nullptr) {
320 return CameraNapiUtils::GetUndefinedValue(env);
321 }
322 return CameraNapiObjVideoProfile(*profile).GenerateNapiValue(env);
323 }
324
CreateJSArray(napi_env env,napi_status status,std::vector<VideoMetaType> nativeArray)325 static napi_value CreateJSArray(napi_env env, napi_status status, std::vector<VideoMetaType> nativeArray)
326 {
327 MEDIA_DEBUG_LOG("CreateJSArray is called");
328 napi_value jsArray = nullptr;
329 napi_value item = nullptr;
330
331 if (nativeArray.empty()) {
332 MEDIA_ERR_LOG("nativeArray is empty");
333 }
334
335 status = napi_create_array(env, &jsArray);
336 if (status == napi_ok) {
337 for (size_t i = 0; i < nativeArray.size(); i++) {
338 napi_create_int32(env, nativeArray[i], &item);
339 if (napi_set_element(env, jsArray, i, item) != napi_ok) {
340 MEDIA_ERR_LOG("Failed to create profile napi wrapper object");
341 return nullptr;
342 }
343 }
344 }
345 return jsArray;
346 }
347
GetSupportedVideoMetaTypes(napi_env env,napi_callback_info info)348 napi_value VideoOutputNapi::GetSupportedVideoMetaTypes(napi_env env, napi_callback_info info)
349 {
350 MEDIA_DEBUG_LOG("GetSupportedVideoMetaTypes is called");
351 napi_status status;
352 napi_value result;
353 size_t argc = ARGS_ZERO;
354 napi_value argv[ARGS_ZERO];
355 napi_value thisVar = nullptr;
356
357 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
358 NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
359
360 napi_get_undefined(env, &result);
361 VideoOutputNapi* videoOutputNapi = nullptr;
362 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
363 if (status == napi_ok && videoOutputNapi != nullptr) {
364 std::vector<VideoMetaType> videoMetaType = videoOutputNapi->videoOutput_->GetSupportedVideoMetaTypes();
365 result = CreateJSArray(env, status, videoMetaType);
366 } else {
367 MEDIA_ERR_LOG("GetSupportedVideoMetaTypes call failed!");
368 }
369 return result;
370 }
371
AttachMetaSurface(napi_env env,napi_callback_info info)372 napi_value VideoOutputNapi::AttachMetaSurface(napi_env env, napi_callback_info info)
373 {
374 CAMERA_SYNC_TRACE;
375 napi_status status;
376 napi_value result;
377 size_t argc = ARGS_TWO;
378 napi_value argv[ARGS_TWO] = {0};
379 napi_value thisVar = nullptr;
380
381 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
382
383 napi_get_undefined(env, &result);
384 VideoOutputNapi* videoOutputNapi = nullptr;
385 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
386 if (status == napi_ok && videoOutputNapi != nullptr) {
387 char buffer[PATH_MAX];
388 size_t surfaceId;
389 napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &surfaceId);
390 uint32_t videoMetaType;
391 napi_get_value_uint32(env, argv[PARAM1], &videoMetaType);
392
393 uint64_t iSurfaceId;
394 std::istringstream iss((std::string(buffer)));
395 iss >> iSurfaceId;
396 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
397 if (surface == nullptr) {
398 MEDIA_ERR_LOG("failed to get surface from SurfaceUtils");
399 }
400 videoOutputNapi->videoOutput_->AttachMetaSurface(surface, static_cast<VideoMetaType>(videoMetaType));
401 } else {
402 MEDIA_ERR_LOG("VideoOutputNapi::AttachMetaSurface failed!");
403 }
404 return result;
405 }
406
CreateVideoOutput(napi_env env,VideoProfile & profile,std::string surfaceId)407 napi_value VideoOutputNapi::CreateVideoOutput(napi_env env, VideoProfile &profile, std::string surfaceId)
408 {
409 MEDIA_DEBUG_LOG("CreateVideoOutput is called");
410 CAMERA_SYNC_TRACE;
411 napi_status status;
412 napi_value result = nullptr;
413 napi_value constructor;
414
415 status = napi_get_reference_value(env, sConstructor_, &constructor);
416 if (status == napi_ok) {
417 uint64_t iSurfaceId;
418 std::istringstream iss(surfaceId);
419 iss >> iSurfaceId;
420 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
421 if (surface == nullptr) {
422 MEDIA_ERR_LOG("failed to get surface from SurfaceUtils");
423 return result;
424 }
425 surface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
426 int retCode = CameraManager::GetInstance()->CreateVideoOutput(profile, surface, &sVideoOutput_);
427 if (!CameraNapiUtils::CheckError(env, retCode)) {
428 return nullptr;
429 }
430 if (sVideoOutput_ == nullptr) {
431 MEDIA_ERR_LOG("failed to create VideoOutput");
432 return result;
433 }
434 status = napi_new_instance(env, constructor, 0, nullptr, &result);
435 sVideoOutput_ = nullptr;
436 if (status == napi_ok && result != nullptr) {
437 return result;
438 } else {
439 MEDIA_ERR_LOG("Failed to create video output instance");
440 }
441 }
442 napi_get_undefined(env, &result);
443 MEDIA_ERR_LOG("CreateVideoOutput call Failed!");
444 return result;
445 }
446
CreateVideoOutput(napi_env env,std::string surfaceId)447 napi_value VideoOutputNapi::CreateVideoOutput(napi_env env, std::string surfaceId)
448 {
449 MEDIA_DEBUG_LOG("VideoOutputNapi::CreateVideoOutput is called");
450 CAMERA_SYNC_TRACE;
451 napi_status status;
452 napi_value result = nullptr;
453 napi_value constructor;
454
455 status = napi_get_reference_value(env, sConstructor_, &constructor);
456 if (status == napi_ok) {
457 uint64_t iSurfaceId;
458 std::istringstream iss(surfaceId);
459 iss >> iSurfaceId;
460 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
461 if (surface == nullptr) {
462 MEDIA_ERR_LOG("failed to get surface from SurfaceUtils");
463 return result;
464 }
465 int retCode = CameraManager::GetInstance()->CreateVideoOutputWithoutProfile(surface, &sVideoOutput_);
466 if (!CameraNapiUtils::CheckError(env, retCode)) {
467 return nullptr;
468 }
469 if (sVideoOutput_ == nullptr) {
470 MEDIA_ERR_LOG("failed to create VideoOutput");
471 return result;
472 }
473 status = napi_new_instance(env, constructor, 0, nullptr, &result);
474 sVideoOutput_ = nullptr;
475 if (status == napi_ok && result != nullptr) {
476 return result;
477 } else {
478 MEDIA_ERR_LOG("Failed to create video output instance");
479 }
480 }
481 napi_get_undefined(env, &result);
482 MEDIA_ERR_LOG("CreateVideoOutput call Failed!");
483 return result;
484 }
485
Start(napi_env env,napi_callback_info info)486 napi_value VideoOutputNapi::Start(napi_env env, napi_callback_info info)
487 {
488 MEDIA_INFO_LOG("Start is called");
489 std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
490 "VideoOutputNapi::Start", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
491 auto asyncFunction =
492 std::make_shared<CameraNapiAsyncFunction>(env, "Start", asyncContext->callbackRef, asyncContext->deferred);
493 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
494 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
495 MEDIA_ERR_LOG("VideoOutputNapi::Start invalid argument");
496 return nullptr;
497 }
498 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
499 napi_status status = napi_create_async_work(
500 env, nullptr, asyncFunction->GetResourceName(),
501 [](napi_env env, void* data) {
502 MEDIA_INFO_LOG("VideoOutputNapi::Start running on worker");
503 auto context = static_cast<VideoOutputAsyncContext*>(data);
504 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Start async info is nullptr");
505 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
506 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
507 context->errorCode = context->objectInfo->videoOutput_->Start();
508 context->status = true;
509 MEDIA_INFO_LOG("VideoOutputNapi::Start errorCode:%{public}d", context->errorCode);
510 });
511 },
512 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
513 if (status != napi_ok) {
514 MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Start");
515 asyncFunction->Reset();
516 } else {
517 asyncContext->queueTask =
518 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Start");
519 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
520 asyncContext.release();
521 }
522 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
523 return asyncFunction->GetPromise();
524 }
525 return CameraNapiUtils::GetUndefinedValue(env);
526 }
527
Stop(napi_env env,napi_callback_info info)528 napi_value VideoOutputNapi::Stop(napi_env env, napi_callback_info info)
529 {
530 MEDIA_INFO_LOG("Stop is called");
531 std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
532 "VideoOutputNapi::Stop", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
533 auto asyncFunction =
534 std::make_shared<CameraNapiAsyncFunction>(env, "Stop", asyncContext->callbackRef, asyncContext->deferred);
535 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
536 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
537 MEDIA_ERR_LOG("VideoOutputNapi::Stop invalid argument");
538 return nullptr;
539 }
540 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
541 napi_status status = napi_create_async_work(
542 env, nullptr, asyncFunction->GetResourceName(),
543 [](napi_env env, void* data) {
544 MEDIA_INFO_LOG("VideoOutputNapi::Stop running on worker");
545 auto context = static_cast<VideoOutputAsyncContext*>(data);
546 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Stop async info is nullptr");
547 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
548 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
549 context->errorCode = context->objectInfo->videoOutput_->Stop();
550 context->status = true;
551 MEDIA_INFO_LOG("VideoOutputNapi::Stop errorCode:%{public}d", context->errorCode);
552 });
553 },
554 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
555 if (status != napi_ok) {
556 MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Stop");
557 asyncFunction->Reset();
558 } else {
559 asyncContext->queueTask =
560 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Stop");
561 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
562 asyncContext.release();
563 }
564 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
565 return asyncFunction->GetPromise();
566 }
567 return CameraNapiUtils::GetUndefinedValue(env);
568 }
569
SetFrameRate(napi_env env,napi_callback_info info)570 napi_value VideoOutputNapi::SetFrameRate(napi_env env, napi_callback_info info)
571 {
572 MEDIA_DEBUG_LOG("SetFrameRate is called");
573 CAMERA_SYNC_TRACE;
574 napi_status status;
575 napi_value result;
576 size_t argc = ARGS_TWO;
577 napi_value argv[ARGS_TWO] = {0};
578 napi_value thisVar = nullptr;
579
580 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
581 NAPI_ASSERT(env, (argc == ARGS_TWO), "requires 2 parameters maximum.");
582
583 napi_get_undefined(env, &result);
584 VideoOutputNapi* videoOutputNapi = nullptr;
585 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
586 if (status == napi_ok && videoOutputNapi != nullptr) {
587 int32_t minFrameRate;
588 napi_get_value_int32(env, argv[PARAM0], &minFrameRate);
589 int32_t maxFrameRate;
590 napi_get_value_int32(env, argv[PARAM1], &maxFrameRate);
591 int32_t retCode = videoOutputNapi->videoOutput_->SetFrameRate(minFrameRate, maxFrameRate);
592 if (!CameraNapiUtils::CheckError(env, retCode)) {
593 MEDIA_ERR_LOG("VideoOutputNapi::SetFrameRate! %{public}d", retCode);
594 return result;
595 }
596 } else {
597 MEDIA_ERR_LOG("SetFrameRate call Failed!");
598 }
599 return result;
600 }
601
GetActiveFrameRate(napi_env env,napi_callback_info info)602 napi_value VideoOutputNapi::GetActiveFrameRate(napi_env env, napi_callback_info info)
603 {
604 MEDIA_DEBUG_LOG("GetFrameRate is called");
605 CAMERA_SYNC_TRACE;
606 napi_status status;
607 napi_value result;
608 size_t argc = ARGS_ZERO;
609 napi_value argv[ARGS_ZERO];
610 napi_value thisVar = nullptr;
611
612 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
613 NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
614
615 napi_get_undefined(env, &result);
616 VideoOutputNapi* videoOutputNapi = nullptr;
617 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
618 if (status == napi_ok && videoOutputNapi != nullptr) {
619 std::vector<int32_t> frameRateRange = videoOutputNapi->videoOutput_->GetFrameRateRange();
620 CameraNapiUtils::CreateFrameRateJSArray(env, frameRateRange, result);
621 } else {
622 MEDIA_ERR_LOG("GetFrameRate call failed!");
623 }
624 return result;
625 }
626
GetSupportedFrameRates(napi_env env,napi_callback_info info)627 napi_value VideoOutputNapi::GetSupportedFrameRates(napi_env env, napi_callback_info info)
628 {
629 MEDIA_DEBUG_LOG("GetSupportedFrameRates is called");
630
631 CAMERA_SYNC_TRACE;
632 napi_status status;
633 napi_value result;
634 size_t argc = ARGS_ZERO;
635 napi_value argv[ARGS_ZERO];
636 napi_value thisVar = nullptr;
637
638 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
639 NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
640 napi_get_undefined(env, &result);
641 VideoOutputNapi* videoOutputNapi = nullptr;
642 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
643 if (status == napi_ok && videoOutputNapi != nullptr) {
644 std::vector<std::vector<int32_t>> supportedFrameRatesRange =
645 videoOutputNapi->videoOutput_->GetSupportedFrameRates();
646 result = CameraNapiUtils::CreateSupportFrameRatesJSArray(env, supportedFrameRatesRange);
647 } else {
648 MEDIA_ERR_LOG("GetSupportedFrameRates call failed!");
649 }
650 return result;
651 }
652
GetVideoRotation(napi_env env,napi_callback_info info)653 napi_value VideoOutputNapi::GetVideoRotation(napi_env env, napi_callback_info info)
654 {
655 MEDIA_DEBUG_LOG("GetVideoRotation is called!");
656 CAMERA_SYNC_TRACE;
657 napi_status status;
658 napi_value result = nullptr;
659 size_t argc = ARGS_ONE;
660 napi_value argv[ARGS_ONE] = {0};
661 napi_value thisVar = nullptr;
662 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
663
664 napi_get_undefined(env, &result);
665 VideoOutputNapi* videoOutputNapi = nullptr;
666 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
667 if (status == napi_ok && videoOutputNapi != nullptr) {
668 int32_t imageRotation;
669 napi_status ret = napi_get_value_int32(env, argv[PARAM0], &imageRotation);
670 if (ret != napi_ok) {
671 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
672 "GetVideoRotation parameter missing or parameter type incorrect.");
673 return result;
674 }
675 int32_t retCode = videoOutputNapi->videoOutput_->GetVideoRotation(imageRotation);
676 if (retCode == SERVICE_FATL_ERROR) {
677 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR,
678 "GetVideoRotation Camera service fatal error.");
679 return result;
680 }
681 napi_create_int32(env, retCode, &result);
682 MEDIA_INFO_LOG("VideoOutputNapi GetVideoRotation! %{public}d", retCode);
683 } else {
684 MEDIA_ERR_LOG("VideoOutputNapi GetVideoRotation! called failed!");
685 }
686 return result;
687 }
688
IsMirrorSupported(napi_env env,napi_callback_info info)689 napi_value VideoOutputNapi::IsMirrorSupported(napi_env env, napi_callback_info info)
690 {
691 auto result = CameraNapiUtils::GetUndefinedValue(env);
692 if (!CameraNapiSecurity::CheckSystemApp(env)) {
693 MEDIA_ERR_LOG("SystemApi IsMirrorSupported is called!");
694 return result;
695 }
696 MEDIA_DEBUG_LOG("VideoOutputNapi::IsMirrorSupported is called");
697
698 VideoOutputNapi* videoOutputNapi = nullptr;
699 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
700 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
701 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported parse parameter occur error");
702 return result;
703 }
704 if (videoOutputNapi->videoOutput_ == nullptr) {
705 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported get native object fail");
706 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
707 return result;
708 }
709 bool isMirrorSupported = videoOutputNapi->videoOutput_->IsMirrorSupported();
710 if (isMirrorSupported) {
711 napi_get_boolean(env, true, &result);
712 return result;
713 }
714 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported is not supported");
715 napi_get_boolean(env, false, &result);
716 return result;
717 }
718
EnableMirror(napi_env env,napi_callback_info info)719 napi_value VideoOutputNapi::EnableMirror(napi_env env, napi_callback_info info)
720 {
721 auto result = CameraNapiUtils::GetUndefinedValue(env);
722 if (!CameraNapiSecurity::CheckSystemApp(env)) {
723 MEDIA_ERR_LOG("SystemApi EnableMirror is called!");
724 return result;
725 }
726 MEDIA_DEBUG_LOG("VideoOutputNapi::EnableMirror is called");
727 VideoOutputNapi* videoOutputNapi = nullptr;
728 bool isEnable;
729 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi, isEnable);
730 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
731 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported parse parameter occur error");
732 return result;
733 }
734 if (videoOutputNapi->videoOutput_ == nullptr) {
735 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported get native object fail");
736 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
737 return result;
738 }
739
740 int32_t retCode = videoOutputNapi->videoOutput_->enableMirror(isEnable);
741 if (!CameraNapiUtils::CheckError(env, retCode)) {
742 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto fail %{public}d", retCode);
743 }
744 return result;
745 }
746
Release(napi_env env,napi_callback_info info)747 napi_value VideoOutputNapi::Release(napi_env env, napi_callback_info info)
748 {
749 MEDIA_INFO_LOG("VideoOutputNapi::Release is called");
750 std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
751 "VideoOutputNapi::Release", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
752 auto asyncFunction =
753 std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
754 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
755 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
756 MEDIA_ERR_LOG("VideoOutputNapi::Release invalid argument");
757 return nullptr;
758 }
759 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
760 napi_status status = napi_create_async_work(
761 env, nullptr, asyncFunction->GetResourceName(),
762 [](napi_env env, void* data) {
763 MEDIA_INFO_LOG("VideoOutputNapi::Release running on worker");
764 auto context = static_cast<VideoOutputAsyncContext*>(data);
765 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Release async info is nullptr");
766 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
767 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
768 context->errorCode = context->objectInfo->videoOutput_->Release();
769 context->status = context->errorCode == CameraErrorCode::SUCCESS;
770 });
771 },
772 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
773 if (status != napi_ok) {
774 MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Release");
775 asyncFunction->Reset();
776 } else {
777 asyncContext->queueTask =
778 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Release");
779 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
780 asyncContext.release();
781 }
782 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
783 return asyncFunction->GetPromise();
784 }
785 return CameraNapiUtils::GetUndefinedValue(env);
786 }
787
RegisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)788 void VideoOutputNapi::RegisterFrameStartCallbackListener(
789 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
790 {
791 if (videoCallback_ == nullptr) {
792 videoCallback_ = make_shared<VideoCallbackListener>(env);
793 videoOutput_->SetCallback(videoCallback_);
794 }
795 videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_START, callback, isOnce);
796 }
797
UnregisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)798 void VideoOutputNapi::UnregisterFrameStartCallbackListener(
799 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
800 {
801 if (videoCallback_ == nullptr) {
802 MEDIA_ERR_LOG("videoCallback is null");
803 return;
804 }
805 videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_START, callback);
806 }
807
RegisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)808 void VideoOutputNapi::RegisterFrameEndCallbackListener(
809 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
810 {
811 if (videoCallback_ == nullptr) {
812 videoCallback_ = make_shared<VideoCallbackListener>(env);
813 videoOutput_->SetCallback(videoCallback_);
814 }
815 videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_END, callback, isOnce);
816 }
UnregisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)817 void VideoOutputNapi::UnregisterFrameEndCallbackListener(
818 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
819 {
820 if (videoCallback_ == nullptr) {
821 MEDIA_ERR_LOG("videoCallback is null");
822 return;
823 }
824 videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_END, callback);
825 }
826
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)827 void VideoOutputNapi::RegisterErrorCallbackListener(
828 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
829 {
830 if (videoCallback_ == nullptr) {
831 videoCallback_ = make_shared<VideoCallbackListener>(env);
832 videoOutput_->SetCallback(videoCallback_);
833 }
834 videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_ERROR, callback, isOnce);
835 }
836
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)837 void VideoOutputNapi::UnregisterErrorCallbackListener(
838 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
839 {
840 if (videoCallback_ == nullptr) {
841 MEDIA_ERR_LOG("videoCallback is null");
842 return;
843 }
844 videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_ERROR, callback);
845 }
846
RegisterDeferredVideoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)847 void VideoOutputNapi::RegisterDeferredVideoCallbackListener(
848 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
849 {
850 if (videoCallback_ == nullptr) {
851 videoCallback_ = make_shared<VideoCallbackListener>(env);
852 videoOutput_->SetCallback(videoCallback_);
853 }
854 videoCallback_->SaveCallbackReference(CONST_VIDEO_DEFERRED_ENHANCEMENT, callback, isOnce);
855 }
856
UnregisterDeferredVideoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)857 void VideoOutputNapi::UnregisterDeferredVideoCallbackListener(
858 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
859 {
860 if (videoCallback_ == nullptr) {
861 MEDIA_ERR_LOG("videoCallback is null");
862 return;
863 }
864 videoCallback_->RemoveCallbackRef(CONST_VIDEO_DEFERRED_ENHANCEMENT, callback);
865 }
866
GetEmitterFunctions()867 const VideoOutputNapi::EmitterFunctions& VideoOutputNapi::GetEmitterFunctions()
868 {
869 static const EmitterFunctions funMap = {
870 { CONST_VIDEO_FRAME_START, {
871 &VideoOutputNapi::RegisterFrameStartCallbackListener,
872 &VideoOutputNapi::UnregisterFrameStartCallbackListener } },
873 { CONST_VIDEO_FRAME_END, {
874 &VideoOutputNapi::RegisterFrameEndCallbackListener,
875 &VideoOutputNapi::UnregisterFrameEndCallbackListener } },
876 { CONST_VIDEO_FRAME_ERROR, {
877 &VideoOutputNapi::RegisterErrorCallbackListener,
878 &VideoOutputNapi::UnregisterErrorCallbackListener } },
879 { CONST_VIDEO_DEFERRED_ENHANCEMENT, {
880 &VideoOutputNapi::RegisterDeferredVideoCallbackListener,
881 &VideoOutputNapi::UnregisterDeferredVideoCallbackListener } }};
882 return funMap;
883 }
884
On(napi_env env,napi_callback_info info)885 napi_value VideoOutputNapi::On(napi_env env, napi_callback_info info)
886 {
887 return ListenerTemplate<VideoOutputNapi>::On(env, info);
888 }
889
Once(napi_env env,napi_callback_info info)890 napi_value VideoOutputNapi::Once(napi_env env, napi_callback_info info)
891 {
892 return ListenerTemplate<VideoOutputNapi>::Once(env, info);
893 }
894
Off(napi_env env,napi_callback_info info)895 napi_value VideoOutputNapi::Off(napi_env env, napi_callback_info info)
896 {
897 return ListenerTemplate<VideoOutputNapi>::Off(env, info);
898 }
899
IsAutoDeferredVideoEnhancementSupported(napi_env env,napi_callback_info info)900 napi_value VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported(napi_env env, napi_callback_info info)
901 {
902 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
903 if (!CameraNapiSecurity::CheckSystemApp(env)) {
904 MEDIA_ERR_LOG("SystemApi IsAutoDeferredVideoEnhancementSupported is called!");
905 return result;
906 }
907 MEDIA_DEBUG_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported is called");
908
909 VideoOutputNapi* videoOutputNapi = nullptr;
910 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
911 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
912 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported parse parameter occur error");
913 return result;
914 }
915 if (videoOutputNapi->videoOutput_ == nullptr) {
916 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported get native object fail");
917 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
918 return result;
919 }
920 int32_t res = videoOutputNapi->videoOutput_->IsAutoDeferredVideoEnhancementSupported();
921 if (res > 1) {
922 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
923 return result;
924 }
925 napi_get_boolean(env, res, &result);
926 return result;
927 }
928
IsAutoDeferredVideoEnhancementEnabled(napi_env env,napi_callback_info info)929 napi_value VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled(napi_env env, napi_callback_info info)
930 {
931 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
932 if (!CameraNapiSecurity::CheckSystemApp(env)) {
933 MEDIA_ERR_LOG("SystemApi IsAutoDeferredVideoEnhancementEnabled is called!");
934 return result;
935 }
936 MEDIA_DEBUG_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled is called");
937
938 VideoOutputNapi* videoOutputNapi = nullptr;
939 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
940 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
941 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled parse parameter occur error");
942 return result;
943 }
944 if (videoOutputNapi->videoOutput_ == nullptr) {
945 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled get native object fail");
946 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
947 return result;
948 }
949 int32_t res = videoOutputNapi->videoOutput_->IsAutoDeferredVideoEnhancementEnabled();
950 if (res > 1) {
951 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
952 return result;
953 }
954 napi_get_boolean(env, res, &result);
955 return result;
956 }
957
EnableAutoDeferredVideoEnhancement(napi_env env,napi_callback_info info)958 napi_value VideoOutputNapi::EnableAutoDeferredVideoEnhancement(napi_env env, napi_callback_info info)
959 {
960 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
961 if (!CameraNapiSecurity::CheckSystemApp(env)) {
962 MEDIA_ERR_LOG("SystemApi EnableAutoDeferredVideoEnhancement is called!");
963 return result;
964 }
965 napi_status status;
966 size_t argc = ARGS_ONE;
967 napi_value argv[ARGS_ONE] = {0};
968 napi_value thisVar = nullptr;
969 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
970 if (argc != ARGS_ONE) {
971 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "requires one parameter");
972 return result;
973 }
974 int32_t res = 0;
975 napi_get_undefined(env, &result);
976 VideoOutputNapi* videoOutputNapi = nullptr;
977 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
978 if (status == napi_ok && videoOutputNapi != nullptr) {
979 bool isEnable;
980 napi_get_value_bool(env, argv[PARAM0], &isEnable);
981 res = videoOutputNapi->videoOutput_->EnableAutoDeferredVideoEnhancement(isEnable);
982 }
983 if (res > 0) {
984 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
985 }
986 return result;
987 }
988 } // namespace CameraStandard
989 } // namespace OHOS
990