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 DECLARE_NAPI_FUNCTION("getSupportedRotations", GetSupportedRotations),
238 DECLARE_NAPI_FUNCTION("isRotationSupported", IsRotationSupported),
239 DECLARE_NAPI_FUNCTION("setRotation", SetRotation),
240 };
241
242 status = napi_define_class(env, CAMERA_VIDEO_OUTPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
243 VideoOutputNapiConstructor, nullptr,
244 sizeof(video_output_props) / sizeof(video_output_props[PARAM0]),
245 video_output_props, &ctorObj);
246 if (status == napi_ok) {
247 status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
248 if (status == napi_ok) {
249 status = napi_set_named_property(env, exports, CAMERA_VIDEO_OUTPUT_NAPI_CLASS_NAME, ctorObj);
250 if (status == napi_ok) {
251 return exports;
252 }
253 }
254 }
255 MEDIA_ERR_LOG("Init call Failed!");
256 return nullptr;
257 }
258
259 // Constructor callback
VideoOutputNapiConstructor(napi_env env,napi_callback_info info)260 napi_value VideoOutputNapi::VideoOutputNapiConstructor(napi_env env, napi_callback_info info)
261 {
262 MEDIA_DEBUG_LOG("VideoOutputNapiConstructor is called");
263 napi_status status;
264 napi_value result = nullptr;
265 napi_value thisVar = nullptr;
266
267 napi_get_undefined(env, &result);
268 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
269
270 if (status == napi_ok && thisVar != nullptr) {
271 std::unique_ptr<VideoOutputNapi> obj = std::make_unique<VideoOutputNapi>();
272 if (obj != nullptr) {
273 obj->env_ = env;
274 obj->videoOutput_ = sVideoOutput_;
275
276 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
277 VideoOutputNapi::VideoOutputNapiDestructor, nullptr, nullptr);
278 if (status == napi_ok) {
279 obj.release();
280 return thisVar;
281 } else {
282 MEDIA_ERR_LOG("Failure wrapping js to native napi");
283 }
284 }
285 }
286 MEDIA_ERR_LOG("VideoOutputNapiConstructor call Failed!");
287 return result;
288 }
289
GetVideoOutput()290 sptr<VideoOutput> VideoOutputNapi::GetVideoOutput()
291 {
292 return videoOutput_;
293 }
294
IsVideoOutput(napi_env env,napi_value obj)295 bool VideoOutputNapi::IsVideoOutput(napi_env env, napi_value obj)
296 {
297 MEDIA_DEBUG_LOG("IsVideoOutput is called");
298 bool result = false;
299 napi_status status;
300 napi_value constructor = nullptr;
301
302 status = napi_get_reference_value(env, sConstructor_, &constructor);
303 if (status == napi_ok) {
304 status = napi_instanceof(env, obj, constructor, &result);
305 if (status != napi_ok) {
306 result = false;
307 }
308 }
309 return result;
310 }
311
GetActiveProfile(napi_env env,napi_callback_info info)312 napi_value VideoOutputNapi::GetActiveProfile(napi_env env, napi_callback_info info)
313 {
314 MEDIA_DEBUG_LOG("VideoOutputNapi::GetActiveProfile is called");
315 VideoOutputNapi* videoOutputNapi = nullptr;
316 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
317 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
318 MEDIA_ERR_LOG("VideoOutputNapi::GetActiveProfile parse parameter occur error");
319 return nullptr;
320 }
321 auto profile = videoOutputNapi->videoOutput_->GetVideoProfile();
322 if (profile == nullptr) {
323 return CameraNapiUtils::GetUndefinedValue(env);
324 }
325 return CameraNapiObjVideoProfile(*profile).GenerateNapiValue(env);
326 }
327
CreateJSArray(napi_env env,napi_status status,std::vector<VideoMetaType> nativeArray)328 static napi_value CreateJSArray(napi_env env, napi_status status, std::vector<VideoMetaType> nativeArray)
329 {
330 MEDIA_DEBUG_LOG("CreateJSArray is called");
331 napi_value jsArray = nullptr;
332 napi_value item = nullptr;
333
334 if (nativeArray.empty()) {
335 MEDIA_ERR_LOG("nativeArray is empty");
336 }
337
338 status = napi_create_array(env, &jsArray);
339 if (status == napi_ok) {
340 for (size_t i = 0; i < nativeArray.size(); i++) {
341 napi_create_int32(env, nativeArray[i], &item);
342 if (napi_set_element(env, jsArray, i, item) != napi_ok) {
343 MEDIA_ERR_LOG("Failed to create profile napi wrapper object");
344 return nullptr;
345 }
346 }
347 }
348 return jsArray;
349 }
350
GetSupportedVideoMetaTypes(napi_env env,napi_callback_info info)351 napi_value VideoOutputNapi::GetSupportedVideoMetaTypes(napi_env env, napi_callback_info info)
352 {
353 MEDIA_DEBUG_LOG("GetSupportedVideoMetaTypes is called");
354 napi_status status;
355 napi_value result;
356 size_t argc = ARGS_ZERO;
357 napi_value argv[ARGS_ZERO];
358 napi_value thisVar = nullptr;
359
360 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
361 NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
362
363 napi_get_undefined(env, &result);
364 VideoOutputNapi* videoOutputNapi = nullptr;
365 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
366 if (status == napi_ok && videoOutputNapi != nullptr) {
367 std::vector<VideoMetaType> videoMetaType = videoOutputNapi->videoOutput_->GetSupportedVideoMetaTypes();
368 result = CreateJSArray(env, status, videoMetaType);
369 } else {
370 MEDIA_ERR_LOG("GetSupportedVideoMetaTypes call failed!");
371 }
372 return result;
373 }
374
AttachMetaSurface(napi_env env,napi_callback_info info)375 napi_value VideoOutputNapi::AttachMetaSurface(napi_env env, napi_callback_info info)
376 {
377 CAMERA_SYNC_TRACE;
378 napi_status status;
379 napi_value result;
380 size_t argc = ARGS_TWO;
381 napi_value argv[ARGS_TWO] = {0};
382 napi_value thisVar = nullptr;
383
384 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
385
386 napi_get_undefined(env, &result);
387 VideoOutputNapi* videoOutputNapi = nullptr;
388 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
389 if (status == napi_ok && videoOutputNapi != nullptr) {
390 char buffer[PATH_MAX];
391 size_t surfaceId;
392 napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &surfaceId);
393 uint32_t videoMetaType;
394 napi_get_value_uint32(env, argv[PARAM1], &videoMetaType);
395
396 uint64_t iSurfaceId;
397 std::istringstream iss((std::string(buffer)));
398 iss >> iSurfaceId;
399 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
400 if (surface == nullptr) {
401 MEDIA_ERR_LOG("failed to get surface from SurfaceUtils");
402 }
403 videoOutputNapi->videoOutput_->AttachMetaSurface(surface, static_cast<VideoMetaType>(videoMetaType));
404 } else {
405 MEDIA_ERR_LOG("VideoOutputNapi::AttachMetaSurface failed!");
406 }
407 return result;
408 }
409
CreateVideoOutput(napi_env env,VideoProfile & profile,std::string surfaceId)410 napi_value VideoOutputNapi::CreateVideoOutput(napi_env env, VideoProfile &profile, std::string surfaceId)
411 {
412 MEDIA_DEBUG_LOG("CreateVideoOutput is called");
413 CAMERA_SYNC_TRACE;
414 napi_status status;
415 napi_value result = nullptr;
416 napi_value constructor;
417
418 status = napi_get_reference_value(env, sConstructor_, &constructor);
419 if (status == napi_ok) {
420 uint64_t iSurfaceId;
421 std::istringstream iss(surfaceId);
422 iss >> iSurfaceId;
423 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
424 if (surface == nullptr) {
425 MEDIA_ERR_LOG("failed to get surface from SurfaceUtils");
426 return result;
427 }
428 surface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
429 int retCode = CameraManager::GetInstance()->CreateVideoOutput(profile, surface, &sVideoOutput_);
430 if (!CameraNapiUtils::CheckError(env, retCode)) {
431 return nullptr;
432 }
433 if (sVideoOutput_ == nullptr) {
434 MEDIA_ERR_LOG("failed to create VideoOutput");
435 return result;
436 }
437 status = napi_new_instance(env, constructor, 0, nullptr, &result);
438 sVideoOutput_ = nullptr;
439 if (status == napi_ok && result != nullptr) {
440 return result;
441 } else {
442 MEDIA_ERR_LOG("Failed to create video output instance");
443 }
444 }
445 napi_get_undefined(env, &result);
446 MEDIA_ERR_LOG("CreateVideoOutput call Failed!");
447 return result;
448 }
449
CreateVideoOutput(napi_env env,std::string surfaceId)450 napi_value VideoOutputNapi::CreateVideoOutput(napi_env env, std::string surfaceId)
451 {
452 MEDIA_DEBUG_LOG("VideoOutputNapi::CreateVideoOutput is called");
453 CAMERA_SYNC_TRACE;
454 napi_status status;
455 napi_value result = nullptr;
456 napi_value constructor;
457
458 status = napi_get_reference_value(env, sConstructor_, &constructor);
459 if (status == napi_ok) {
460 uint64_t iSurfaceId;
461 std::istringstream iss(surfaceId);
462 iss >> iSurfaceId;
463 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
464 if (surface == nullptr) {
465 MEDIA_ERR_LOG("failed to get surface from SurfaceUtils");
466 return result;
467 }
468 int retCode = CameraManager::GetInstance()->CreateVideoOutputWithoutProfile(surface, &sVideoOutput_);
469 if (!CameraNapiUtils::CheckError(env, retCode)) {
470 return nullptr;
471 }
472 if (sVideoOutput_ == nullptr) {
473 MEDIA_ERR_LOG("failed to create VideoOutput");
474 return result;
475 }
476 status = napi_new_instance(env, constructor, 0, nullptr, &result);
477 sVideoOutput_ = nullptr;
478 if (status == napi_ok && result != nullptr) {
479 return result;
480 } else {
481 MEDIA_ERR_LOG("Failed to create video output instance");
482 }
483 }
484 napi_get_undefined(env, &result);
485 MEDIA_ERR_LOG("CreateVideoOutput call Failed!");
486 return result;
487 }
488
Start(napi_env env,napi_callback_info info)489 napi_value VideoOutputNapi::Start(napi_env env, napi_callback_info info)
490 {
491 MEDIA_INFO_LOG("Start is called");
492 std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
493 "VideoOutputNapi::Start", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
494 auto asyncFunction =
495 std::make_shared<CameraNapiAsyncFunction>(env, "Start", asyncContext->callbackRef, asyncContext->deferred);
496 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
497 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
498 MEDIA_ERR_LOG("VideoOutputNapi::Start invalid argument");
499 return nullptr;
500 }
501 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
502 napi_status status = napi_create_async_work(
503 env, nullptr, asyncFunction->GetResourceName(),
504 [](napi_env env, void* data) {
505 MEDIA_INFO_LOG("VideoOutputNapi::Start running on worker");
506 auto context = static_cast<VideoOutputAsyncContext*>(data);
507 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Start async info is nullptr");
508 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
509 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
510 context->errorCode = context->objectInfo->videoOutput_->Start();
511 context->status = true;
512 MEDIA_INFO_LOG("VideoOutputNapi::Start errorCode:%{public}d", context->errorCode);
513 });
514 },
515 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
516 if (status != napi_ok) {
517 MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Start");
518 asyncFunction->Reset();
519 } else {
520 asyncContext->queueTask =
521 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Start");
522 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
523 asyncContext.release();
524 }
525 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
526 return asyncFunction->GetPromise();
527 }
528 return CameraNapiUtils::GetUndefinedValue(env);
529 }
530
Stop(napi_env env,napi_callback_info info)531 napi_value VideoOutputNapi::Stop(napi_env env, napi_callback_info info)
532 {
533 MEDIA_INFO_LOG("Stop is called");
534 std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
535 "VideoOutputNapi::Stop", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
536 auto asyncFunction =
537 std::make_shared<CameraNapiAsyncFunction>(env, "Stop", asyncContext->callbackRef, asyncContext->deferred);
538 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
539 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
540 MEDIA_ERR_LOG("VideoOutputNapi::Stop invalid argument");
541 return nullptr;
542 }
543 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
544 napi_status status = napi_create_async_work(
545 env, nullptr, asyncFunction->GetResourceName(),
546 [](napi_env env, void* data) {
547 MEDIA_INFO_LOG("VideoOutputNapi::Stop running on worker");
548 auto context = static_cast<VideoOutputAsyncContext*>(data);
549 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Stop async info is nullptr");
550 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
551 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
552 context->errorCode = context->objectInfo->videoOutput_->Stop();
553 context->status = true;
554 MEDIA_INFO_LOG("VideoOutputNapi::Stop errorCode:%{public}d", context->errorCode);
555 });
556 },
557 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
558 if (status != napi_ok) {
559 MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Stop");
560 asyncFunction->Reset();
561 } else {
562 asyncContext->queueTask =
563 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Stop");
564 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
565 asyncContext.release();
566 }
567 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
568 return asyncFunction->GetPromise();
569 }
570 return CameraNapiUtils::GetUndefinedValue(env);
571 }
572
SetFrameRate(napi_env env,napi_callback_info info)573 napi_value VideoOutputNapi::SetFrameRate(napi_env env, napi_callback_info info)
574 {
575 MEDIA_DEBUG_LOG("SetFrameRate is called");
576 CAMERA_SYNC_TRACE;
577 napi_status status;
578 napi_value result;
579 size_t argc = ARGS_TWO;
580 napi_value argv[ARGS_TWO] = {0};
581 napi_value thisVar = nullptr;
582
583 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
584 NAPI_ASSERT(env, (argc == ARGS_TWO), "requires 2 parameters maximum.");
585
586 napi_get_undefined(env, &result);
587 VideoOutputNapi* videoOutputNapi = nullptr;
588 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
589 if (status == napi_ok && videoOutputNapi != nullptr) {
590 int32_t minFrameRate;
591 napi_get_value_int32(env, argv[PARAM0], &minFrameRate);
592 int32_t maxFrameRate;
593 napi_get_value_int32(env, argv[PARAM1], &maxFrameRate);
594 int32_t retCode = videoOutputNapi->videoOutput_->SetFrameRate(minFrameRate, maxFrameRate);
595 if (!CameraNapiUtils::CheckError(env, retCode)) {
596 MEDIA_ERR_LOG("VideoOutputNapi::SetFrameRate! %{public}d", retCode);
597 return result;
598 }
599 } else {
600 MEDIA_ERR_LOG("SetFrameRate call Failed!");
601 }
602 return result;
603 }
604
GetActiveFrameRate(napi_env env,napi_callback_info info)605 napi_value VideoOutputNapi::GetActiveFrameRate(napi_env env, napi_callback_info info)
606 {
607 MEDIA_DEBUG_LOG("GetFrameRate is called");
608 CAMERA_SYNC_TRACE;
609 napi_status status;
610 napi_value result;
611 size_t argc = ARGS_ZERO;
612 napi_value argv[ARGS_ZERO];
613 napi_value thisVar = nullptr;
614
615 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
616 NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
617
618 napi_get_undefined(env, &result);
619 VideoOutputNapi* videoOutputNapi = nullptr;
620 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
621 if (status == napi_ok && videoOutputNapi != nullptr) {
622 std::vector<int32_t> frameRateRange = videoOutputNapi->videoOutput_->GetFrameRateRange();
623 CameraNapiUtils::CreateFrameRateJSArray(env, frameRateRange, result);
624 } else {
625 MEDIA_ERR_LOG("GetFrameRate call failed!");
626 }
627 return result;
628 }
629
GetSupportedFrameRates(napi_env env,napi_callback_info info)630 napi_value VideoOutputNapi::GetSupportedFrameRates(napi_env env, napi_callback_info info)
631 {
632 MEDIA_DEBUG_LOG("GetSupportedFrameRates is called");
633
634 CAMERA_SYNC_TRACE;
635 napi_status status;
636 napi_value result;
637 size_t argc = ARGS_ZERO;
638 napi_value argv[ARGS_ZERO];
639 napi_value thisVar = nullptr;
640
641 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
642 NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
643 napi_get_undefined(env, &result);
644 VideoOutputNapi* videoOutputNapi = nullptr;
645 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
646 if (status == napi_ok && videoOutputNapi != nullptr) {
647 std::vector<std::vector<int32_t>> supportedFrameRatesRange =
648 videoOutputNapi->videoOutput_->GetSupportedFrameRates();
649 result = CameraNapiUtils::CreateSupportFrameRatesJSArray(env, supportedFrameRatesRange);
650 } else {
651 MEDIA_ERR_LOG("GetSupportedFrameRates call failed!");
652 }
653 return result;
654 }
655
GetVideoRotation(napi_env env,napi_callback_info info)656 napi_value VideoOutputNapi::GetVideoRotation(napi_env env, napi_callback_info info)
657 {
658 MEDIA_DEBUG_LOG("GetVideoRotation is called!");
659 CAMERA_SYNC_TRACE;
660 napi_status status;
661 napi_value result = nullptr;
662 size_t argc = ARGS_ONE;
663 napi_value argv[ARGS_ONE] = {0};
664 napi_value thisVar = nullptr;
665 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
666
667 napi_get_undefined(env, &result);
668 VideoOutputNapi* videoOutputNapi = nullptr;
669 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
670 if (status == napi_ok && videoOutputNapi != nullptr) {
671 int32_t imageRotation;
672 napi_status ret = napi_get_value_int32(env, argv[PARAM0], &imageRotation);
673 if (ret != napi_ok) {
674 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
675 "GetVideoRotation parameter missing or parameter type incorrect.");
676 return result;
677 }
678 int32_t retCode = videoOutputNapi->videoOutput_->GetVideoRotation(imageRotation);
679 if (retCode == SERVICE_FATL_ERROR) {
680 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR,
681 "GetVideoRotation Camera service fatal error.");
682 return result;
683 }
684 napi_create_int32(env, retCode, &result);
685 MEDIA_INFO_LOG("VideoOutputNapi GetVideoRotation! %{public}d", retCode);
686 } else {
687 MEDIA_ERR_LOG("VideoOutputNapi GetVideoRotation! called failed!");
688 }
689 return result;
690 }
691
IsMirrorSupported(napi_env env,napi_callback_info info)692 napi_value VideoOutputNapi::IsMirrorSupported(napi_env env, napi_callback_info info)
693 {
694 auto result = CameraNapiUtils::GetUndefinedValue(env);
695 if (!CameraNapiSecurity::CheckSystemApp(env)) {
696 MEDIA_ERR_LOG("SystemApi IsMirrorSupported is called!");
697 return result;
698 }
699 MEDIA_DEBUG_LOG("VideoOutputNapi::IsMirrorSupported is called");
700
701 VideoOutputNapi* videoOutputNapi = nullptr;
702 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
703 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
704 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported parse parameter occur error");
705 return result;
706 }
707 if (videoOutputNapi->videoOutput_ == nullptr) {
708 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported get native object fail");
709 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
710 return result;
711 }
712 bool isMirrorSupported = videoOutputNapi->videoOutput_->IsMirrorSupported();
713 if (isMirrorSupported) {
714 napi_get_boolean(env, true, &result);
715 return result;
716 }
717 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported is not supported");
718 napi_get_boolean(env, false, &result);
719 return result;
720 }
721
EnableMirror(napi_env env,napi_callback_info info)722 napi_value VideoOutputNapi::EnableMirror(napi_env env, napi_callback_info info)
723 {
724 auto result = CameraNapiUtils::GetUndefinedValue(env);
725 if (!CameraNapiSecurity::CheckSystemApp(env)) {
726 MEDIA_ERR_LOG("SystemApi EnableMirror is called!");
727 return result;
728 }
729 MEDIA_DEBUG_LOG("VideoOutputNapi::EnableMirror is called");
730 VideoOutputNapi* videoOutputNapi = nullptr;
731 bool isEnable;
732 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi, isEnable);
733 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
734 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported parse parameter occur error");
735 return result;
736 }
737 if (videoOutputNapi->videoOutput_ == nullptr) {
738 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported get native object fail");
739 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
740 return result;
741 }
742
743 int32_t retCode = videoOutputNapi->videoOutput_->enableMirror(isEnable);
744 if (!CameraNapiUtils::CheckError(env, retCode)) {
745 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto fail %{public}d", retCode);
746 }
747 return result;
748 }
749
Release(napi_env env,napi_callback_info info)750 napi_value VideoOutputNapi::Release(napi_env env, napi_callback_info info)
751 {
752 MEDIA_INFO_LOG("VideoOutputNapi::Release is called");
753 std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
754 "VideoOutputNapi::Release", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
755 auto asyncFunction =
756 std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
757 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
758 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
759 MEDIA_ERR_LOG("VideoOutputNapi::Release invalid argument");
760 return nullptr;
761 }
762 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
763 napi_status status = napi_create_async_work(
764 env, nullptr, asyncFunction->GetResourceName(),
765 [](napi_env env, void* data) {
766 MEDIA_INFO_LOG("VideoOutputNapi::Release running on worker");
767 auto context = static_cast<VideoOutputAsyncContext*>(data);
768 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Release async info is nullptr");
769 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
770 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
771 context->errorCode = context->objectInfo->videoOutput_->Release();
772 context->status = context->errorCode == CameraErrorCode::SUCCESS;
773 });
774 },
775 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
776 if (status != napi_ok) {
777 MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Release");
778 asyncFunction->Reset();
779 } else {
780 asyncContext->queueTask =
781 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Release");
782 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
783 asyncContext.release();
784 }
785 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
786 return asyncFunction->GetPromise();
787 }
788 return CameraNapiUtils::GetUndefinedValue(env);
789 }
790
RegisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)791 void VideoOutputNapi::RegisterFrameStartCallbackListener(
792 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
793 {
794 if (videoCallback_ == nullptr) {
795 videoCallback_ = make_shared<VideoCallbackListener>(env);
796 videoOutput_->SetCallback(videoCallback_);
797 }
798 videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_START, callback, isOnce);
799 }
800
UnregisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)801 void VideoOutputNapi::UnregisterFrameStartCallbackListener(
802 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
803 {
804 if (videoCallback_ == nullptr) {
805 MEDIA_ERR_LOG("videoCallback is null");
806 return;
807 }
808 videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_START, callback);
809 }
810
RegisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)811 void VideoOutputNapi::RegisterFrameEndCallbackListener(
812 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
813 {
814 if (videoCallback_ == nullptr) {
815 videoCallback_ = make_shared<VideoCallbackListener>(env);
816 videoOutput_->SetCallback(videoCallback_);
817 }
818 videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_END, callback, isOnce);
819 }
UnregisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)820 void VideoOutputNapi::UnregisterFrameEndCallbackListener(
821 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
822 {
823 if (videoCallback_ == nullptr) {
824 MEDIA_ERR_LOG("videoCallback is null");
825 return;
826 }
827 videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_END, callback);
828 }
829
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)830 void VideoOutputNapi::RegisterErrorCallbackListener(
831 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
832 {
833 if (videoCallback_ == nullptr) {
834 videoCallback_ = make_shared<VideoCallbackListener>(env);
835 videoOutput_->SetCallback(videoCallback_);
836 }
837 videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_ERROR, callback, isOnce);
838 }
839
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)840 void VideoOutputNapi::UnregisterErrorCallbackListener(
841 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
842 {
843 if (videoCallback_ == nullptr) {
844 MEDIA_ERR_LOG("videoCallback is null");
845 return;
846 }
847 videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_ERROR, callback);
848 }
849
RegisterDeferredVideoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)850 void VideoOutputNapi::RegisterDeferredVideoCallbackListener(
851 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
852 {
853 if (videoCallback_ == nullptr) {
854 videoCallback_ = make_shared<VideoCallbackListener>(env);
855 videoOutput_->SetCallback(videoCallback_);
856 }
857 videoCallback_->SaveCallbackReference(CONST_VIDEO_DEFERRED_ENHANCEMENT, callback, isOnce);
858 }
859
UnregisterDeferredVideoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)860 void VideoOutputNapi::UnregisterDeferredVideoCallbackListener(
861 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
862 {
863 if (videoCallback_ == nullptr) {
864 MEDIA_ERR_LOG("videoCallback is null");
865 return;
866 }
867 videoCallback_->RemoveCallbackRef(CONST_VIDEO_DEFERRED_ENHANCEMENT, callback);
868 }
869
GetEmitterFunctions()870 const VideoOutputNapi::EmitterFunctions& VideoOutputNapi::GetEmitterFunctions()
871 {
872 static const EmitterFunctions funMap = {
873 { CONST_VIDEO_FRAME_START, {
874 &VideoOutputNapi::RegisterFrameStartCallbackListener,
875 &VideoOutputNapi::UnregisterFrameStartCallbackListener } },
876 { CONST_VIDEO_FRAME_END, {
877 &VideoOutputNapi::RegisterFrameEndCallbackListener,
878 &VideoOutputNapi::UnregisterFrameEndCallbackListener } },
879 { CONST_VIDEO_FRAME_ERROR, {
880 &VideoOutputNapi::RegisterErrorCallbackListener,
881 &VideoOutputNapi::UnregisterErrorCallbackListener } },
882 { CONST_VIDEO_DEFERRED_ENHANCEMENT, {
883 &VideoOutputNapi::RegisterDeferredVideoCallbackListener,
884 &VideoOutputNapi::UnregisterDeferredVideoCallbackListener } }};
885 return funMap;
886 }
887
On(napi_env env,napi_callback_info info)888 napi_value VideoOutputNapi::On(napi_env env, napi_callback_info info)
889 {
890 return ListenerTemplate<VideoOutputNapi>::On(env, info);
891 }
892
Once(napi_env env,napi_callback_info info)893 napi_value VideoOutputNapi::Once(napi_env env, napi_callback_info info)
894 {
895 return ListenerTemplate<VideoOutputNapi>::Once(env, info);
896 }
897
Off(napi_env env,napi_callback_info info)898 napi_value VideoOutputNapi::Off(napi_env env, napi_callback_info info)
899 {
900 return ListenerTemplate<VideoOutputNapi>::Off(env, info);
901 }
902
IsAutoDeferredVideoEnhancementSupported(napi_env env,napi_callback_info info)903 napi_value VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported(napi_env env, napi_callback_info info)
904 {
905 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
906 if (!CameraNapiSecurity::CheckSystemApp(env)) {
907 MEDIA_ERR_LOG("SystemApi IsAutoDeferredVideoEnhancementSupported is called!");
908 return result;
909 }
910 MEDIA_DEBUG_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported is called");
911
912 VideoOutputNapi* videoOutputNapi = nullptr;
913 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
914 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
915 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported parse parameter occur error");
916 return result;
917 }
918 if (videoOutputNapi->videoOutput_ == nullptr) {
919 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported get native object fail");
920 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
921 return result;
922 }
923 int32_t res = videoOutputNapi->videoOutput_->IsAutoDeferredVideoEnhancementSupported();
924 if (res > 1) {
925 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
926 return result;
927 }
928 napi_get_boolean(env, res, &result);
929 return result;
930 }
931
IsAutoDeferredVideoEnhancementEnabled(napi_env env,napi_callback_info info)932 napi_value VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled(napi_env env, napi_callback_info info)
933 {
934 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
935 if (!CameraNapiSecurity::CheckSystemApp(env)) {
936 MEDIA_ERR_LOG("SystemApi IsAutoDeferredVideoEnhancementEnabled is called!");
937 return result;
938 }
939 MEDIA_DEBUG_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled is called");
940
941 VideoOutputNapi* videoOutputNapi = nullptr;
942 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
943 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
944 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled parse parameter occur error");
945 return result;
946 }
947 if (videoOutputNapi->videoOutput_ == nullptr) {
948 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled get native object fail");
949 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
950 return result;
951 }
952 int32_t res = videoOutputNapi->videoOutput_->IsAutoDeferredVideoEnhancementEnabled();
953 if (res > 1) {
954 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
955 return result;
956 }
957 napi_get_boolean(env, res, &result);
958 return result;
959 }
960
EnableAutoDeferredVideoEnhancement(napi_env env,napi_callback_info info)961 napi_value VideoOutputNapi::EnableAutoDeferredVideoEnhancement(napi_env env, napi_callback_info info)
962 {
963 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
964 if (!CameraNapiSecurity::CheckSystemApp(env)) {
965 MEDIA_ERR_LOG("SystemApi EnableAutoDeferredVideoEnhancement is called!");
966 return result;
967 }
968 napi_status status;
969 size_t argc = ARGS_ONE;
970 napi_value argv[ARGS_ONE] = {0};
971 napi_value thisVar = nullptr;
972 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
973 if (argc != ARGS_ONE) {
974 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "requires one parameter");
975 return result;
976 }
977 int32_t res = 0;
978 napi_get_undefined(env, &result);
979 VideoOutputNapi* videoOutputNapi = nullptr;
980 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
981 if (status == napi_ok && videoOutputNapi != nullptr) {
982 bool isEnable;
983 napi_get_value_bool(env, argv[PARAM0], &isEnable);
984 res = videoOutputNapi->videoOutput_->EnableAutoDeferredVideoEnhancement(isEnable);
985 }
986 if (res > 0) {
987 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
988 }
989 return result;
990 }
991
GetSupportedRotations(napi_env env,napi_callback_info info)992 napi_value VideoOutputNapi::GetSupportedRotations(napi_env env, napi_callback_info info)
993 {
994 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
995 if (!CameraNapiSecurity::CheckSystemApp(env)) {
996 MEDIA_ERR_LOG("SystemApi GetSupportedRotations is called!");
997 return result;
998 }
999 MEDIA_DEBUG_LOG("VideoOutputNapi::GetSupportedRotations is called");
1000
1001 VideoOutputNapi* videoOutputNapi = nullptr;
1002 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
1003 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
1004 MEDIA_ERR_LOG("VideoOutputNapi::GetSupportedRotations parse parameter occur error");
1005 return result;
1006 }
1007 if (videoOutputNapi->videoOutput_ == nullptr) {
1008 MEDIA_ERR_LOG("VideoOutputNapi::GetSupportedRotations get native object fail");
1009 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
1010 return result;
1011 }
1012 std::vector<int32_t> supportedRotations;
1013 int32_t retCode = videoOutputNapi->videoOutput_->GetSupportedRotations(supportedRotations);
1014 if (!CameraNapiUtils::CheckError(env, retCode)) {
1015 return nullptr;
1016 }
1017 napi_status status = napi_create_array(env, &result);
1018 CHECK_ERROR_RETURN_RET_LOG(status != napi_ok, result, "napi_create_array call Failed!");
1019 for (size_t i = 0; i < supportedRotations.size(); i++) {
1020 int32_t value = supportedRotations[i];
1021 napi_value element;
1022 napi_create_int32(env, value, &element);
1023 napi_set_element(env, result, i, element);
1024 }
1025 return result;
1026 }
1027
IsRotationSupported(napi_env env,napi_callback_info info)1028 napi_value VideoOutputNapi::IsRotationSupported(napi_env env, napi_callback_info info)
1029 {
1030 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
1031 if (!CameraNapiSecurity::CheckSystemApp(env)) {
1032 MEDIA_ERR_LOG("SystemApi IsRotationSupported is called!");
1033 return result;
1034 }
1035 MEDIA_DEBUG_LOG("VideoOutputNapi::IsRotationSupported is called");
1036
1037 VideoOutputNapi* videoOutputNapi = nullptr;
1038 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
1039 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
1040 MEDIA_ERR_LOG("VideoOutputNapi::IsRotationSupported parse parameter occur error");
1041 return result;
1042 }
1043 if (videoOutputNapi->videoOutput_ == nullptr) {
1044 MEDIA_ERR_LOG("VideoOutputNapi::IsRotationSupported get native object fail");
1045 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
1046 return result;
1047 }
1048 bool isSupported = false;
1049 int32_t retCode = videoOutputNapi->videoOutput_->IsRotationSupported(isSupported);
1050 if (!CameraNapiUtils::CheckError(env, retCode)) {
1051 MEDIA_ERR_LOG("VideoOutputNapi::IsRotationSupported fail %{public}d", retCode);
1052 }
1053 napi_get_boolean(env, isSupported, &result);
1054 return result;
1055 }
1056
SetRotation(napi_env env,napi_callback_info info)1057 napi_value VideoOutputNapi::SetRotation(napi_env env, napi_callback_info info)
1058 {
1059 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
1060 if (!CameraNapiSecurity::CheckSystemApp(env)) {
1061 MEDIA_ERR_LOG("SystemApi SetRotation is called!");
1062 return result;
1063 }
1064 MEDIA_DEBUG_LOG("VideoOutputNapi::SetRotation is called");
1065 VideoOutputNapi* videoOutputNapi = nullptr;
1066 int32_t rotation;
1067 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi, rotation);
1068 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
1069 MEDIA_ERR_LOG("VideoOutputNapi::SetRotation parse parameter occur error");
1070 return result;
1071 }
1072 if (videoOutputNapi->videoOutput_ == nullptr) {
1073 MEDIA_ERR_LOG("VideoOutputNapi::SetRotation get native object fail");
1074 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
1075 return result;
1076 }
1077 int32_t retCode = videoOutputNapi->videoOutput_->SetRotation(rotation);
1078 if (!CameraNapiUtils::CheckError(env, retCode)) {
1079 MEDIA_ERR_LOG("VideoOutputNapi::SetRotation fail %{public}d", retCode);
1080 }
1081 return result;
1082 }
1083 } // namespace CameraStandard
1084 } // namespace OHOS
1085