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 MEDIA_DEBUG_LOG("VideoOutputNapi::IsMirrorSupported is called");
696
697 VideoOutputNapi* videoOutputNapi = nullptr;
698 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
699 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
700 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported parse parameter occur error");
701 return result;
702 }
703 if (videoOutputNapi->videoOutput_ == nullptr) {
704 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported get native object fail");
705 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
706 return result;
707 }
708 bool isMirrorSupported = videoOutputNapi->videoOutput_->IsMirrorSupported();
709 if (isMirrorSupported) {
710 napi_get_boolean(env, true, &result);
711 return result;
712 }
713 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported is not supported");
714 napi_get_boolean(env, false, &result);
715 return result;
716 }
717
EnableMirror(napi_env env,napi_callback_info info)718 napi_value VideoOutputNapi::EnableMirror(napi_env env, napi_callback_info info)
719 {
720 auto result = CameraNapiUtils::GetUndefinedValue(env);
721 MEDIA_DEBUG_LOG("VideoOutputNapi::EnableMirror is called");
722 VideoOutputNapi* videoOutputNapi = nullptr;
723 bool isEnable;
724 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi, isEnable);
725 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
726 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported parse parameter occur error");
727 return result;
728 }
729 if (videoOutputNapi->videoOutput_ == nullptr) {
730 MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported get native object fail");
731 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
732 return result;
733 }
734
735 int32_t retCode = videoOutputNapi->videoOutput_->enableMirror(isEnable);
736 if (!CameraNapiUtils::CheckError(env, retCode)) {
737 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto fail %{public}d", retCode);
738 }
739 return result;
740 }
741
Release(napi_env env,napi_callback_info info)742 napi_value VideoOutputNapi::Release(napi_env env, napi_callback_info info)
743 {
744 MEDIA_INFO_LOG("VideoOutputNapi::Release is called");
745 std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
746 "VideoOutputNapi::Release", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
747 auto asyncFunction =
748 std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
749 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
750 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
751 MEDIA_ERR_LOG("VideoOutputNapi::Release invalid argument");
752 return nullptr;
753 }
754 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
755 napi_status status = napi_create_async_work(
756 env, nullptr, asyncFunction->GetResourceName(),
757 [](napi_env env, void* data) {
758 MEDIA_INFO_LOG("VideoOutputNapi::Release running on worker");
759 auto context = static_cast<VideoOutputAsyncContext*>(data);
760 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Release async info is nullptr");
761 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
762 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
763 context->errorCode = context->objectInfo->videoOutput_->Release();
764 context->status = context->errorCode == CameraErrorCode::SUCCESS;
765 });
766 },
767 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
768 if (status != napi_ok) {
769 MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Release");
770 asyncFunction->Reset();
771 } else {
772 asyncContext->queueTask =
773 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Release");
774 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
775 asyncContext.release();
776 }
777 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
778 return asyncFunction->GetPromise();
779 }
780 return CameraNapiUtils::GetUndefinedValue(env);
781 }
782
RegisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)783 void VideoOutputNapi::RegisterFrameStartCallbackListener(
784 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
785 {
786 if (videoCallback_ == nullptr) {
787 videoCallback_ = make_shared<VideoCallbackListener>(env);
788 videoOutput_->SetCallback(videoCallback_);
789 }
790 videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_START, callback, isOnce);
791 }
792
UnregisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)793 void VideoOutputNapi::UnregisterFrameStartCallbackListener(
794 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
795 {
796 if (videoCallback_ == nullptr) {
797 MEDIA_ERR_LOG("videoCallback is null");
798 return;
799 }
800 videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_START, callback);
801 }
802
RegisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)803 void VideoOutputNapi::RegisterFrameEndCallbackListener(
804 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
805 {
806 if (videoCallback_ == nullptr) {
807 videoCallback_ = make_shared<VideoCallbackListener>(env);
808 videoOutput_->SetCallback(videoCallback_);
809 }
810 videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_END, callback, isOnce);
811 }
UnregisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)812 void VideoOutputNapi::UnregisterFrameEndCallbackListener(
813 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
814 {
815 if (videoCallback_ == nullptr) {
816 MEDIA_ERR_LOG("videoCallback is null");
817 return;
818 }
819 videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_END, callback);
820 }
821
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)822 void VideoOutputNapi::RegisterErrorCallbackListener(
823 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
824 {
825 if (videoCallback_ == nullptr) {
826 videoCallback_ = make_shared<VideoCallbackListener>(env);
827 videoOutput_->SetCallback(videoCallback_);
828 }
829 videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_ERROR, callback, isOnce);
830 }
831
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)832 void VideoOutputNapi::UnregisterErrorCallbackListener(
833 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
834 {
835 if (videoCallback_ == nullptr) {
836 MEDIA_ERR_LOG("videoCallback is null");
837 return;
838 }
839 videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_ERROR, callback);
840 }
841
RegisterDeferredVideoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)842 void VideoOutputNapi::RegisterDeferredVideoCallbackListener(
843 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
844 {
845 if (videoCallback_ == nullptr) {
846 videoCallback_ = make_shared<VideoCallbackListener>(env);
847 videoOutput_->SetCallback(videoCallback_);
848 }
849 videoCallback_->SaveCallbackReference(CONST_VIDEO_DEFERRED_ENHANCEMENT, callback, isOnce);
850 }
851
UnregisterDeferredVideoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)852 void VideoOutputNapi::UnregisterDeferredVideoCallbackListener(
853 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
854 {
855 if (videoCallback_ == nullptr) {
856 MEDIA_ERR_LOG("videoCallback is null");
857 return;
858 }
859 videoCallback_->RemoveCallbackRef(CONST_VIDEO_DEFERRED_ENHANCEMENT, callback);
860 }
861
GetEmitterFunctions()862 const VideoOutputNapi::EmitterFunctions& VideoOutputNapi::GetEmitterFunctions()
863 {
864 static const EmitterFunctions funMap = {
865 { CONST_VIDEO_FRAME_START, {
866 &VideoOutputNapi::RegisterFrameStartCallbackListener,
867 &VideoOutputNapi::UnregisterFrameStartCallbackListener } },
868 { CONST_VIDEO_FRAME_END, {
869 &VideoOutputNapi::RegisterFrameEndCallbackListener,
870 &VideoOutputNapi::UnregisterFrameEndCallbackListener } },
871 { CONST_VIDEO_FRAME_ERROR, {
872 &VideoOutputNapi::RegisterErrorCallbackListener,
873 &VideoOutputNapi::UnregisterErrorCallbackListener } },
874 { CONST_VIDEO_DEFERRED_ENHANCEMENT, {
875 &VideoOutputNapi::RegisterDeferredVideoCallbackListener,
876 &VideoOutputNapi::UnregisterDeferredVideoCallbackListener } }};
877 return funMap;
878 }
879
On(napi_env env,napi_callback_info info)880 napi_value VideoOutputNapi::On(napi_env env, napi_callback_info info)
881 {
882 return ListenerTemplate<VideoOutputNapi>::On(env, info);
883 }
884
Once(napi_env env,napi_callback_info info)885 napi_value VideoOutputNapi::Once(napi_env env, napi_callback_info info)
886 {
887 return ListenerTemplate<VideoOutputNapi>::Once(env, info);
888 }
889
Off(napi_env env,napi_callback_info info)890 napi_value VideoOutputNapi::Off(napi_env env, napi_callback_info info)
891 {
892 return ListenerTemplate<VideoOutputNapi>::Off(env, info);
893 }
894
IsAutoDeferredVideoEnhancementSupported(napi_env env,napi_callback_info info)895 napi_value VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported(napi_env env, napi_callback_info info)
896 {
897 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
898 if (!CameraNapiSecurity::CheckSystemApp(env)) {
899 MEDIA_ERR_LOG("SystemApi IsAutoDeferredVideoEnhancementSupported is called!");
900 return result;
901 }
902 MEDIA_DEBUG_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported is called");
903
904 VideoOutputNapi* videoOutputNapi = nullptr;
905 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
906 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
907 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported parse parameter occur error");
908 return result;
909 }
910 if (videoOutputNapi->videoOutput_ == nullptr) {
911 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported get native object fail");
912 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
913 return result;
914 }
915 int32_t res = videoOutputNapi->videoOutput_->IsAutoDeferredVideoEnhancementSupported();
916 if (res > 1) {
917 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
918 return result;
919 }
920 napi_get_boolean(env, res, &result);
921 return result;
922 }
923
IsAutoDeferredVideoEnhancementEnabled(napi_env env,napi_callback_info info)924 napi_value VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled(napi_env env, napi_callback_info info)
925 {
926 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
927 if (!CameraNapiSecurity::CheckSystemApp(env)) {
928 MEDIA_ERR_LOG("SystemApi IsAutoDeferredVideoEnhancementEnabled is called!");
929 return result;
930 }
931 MEDIA_DEBUG_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled is called");
932
933 VideoOutputNapi* videoOutputNapi = nullptr;
934 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
935 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
936 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled parse parameter occur error");
937 return result;
938 }
939 if (videoOutputNapi->videoOutput_ == nullptr) {
940 MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled get native object fail");
941 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
942 return result;
943 }
944 int32_t res = videoOutputNapi->videoOutput_->IsAutoDeferredVideoEnhancementEnabled();
945 if (res > 1) {
946 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
947 return result;
948 }
949 napi_get_boolean(env, res, &result);
950 return result;
951 }
952
EnableAutoDeferredVideoEnhancement(napi_env env,napi_callback_info info)953 napi_value VideoOutputNapi::EnableAutoDeferredVideoEnhancement(napi_env env, napi_callback_info info)
954 {
955 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
956 if (!CameraNapiSecurity::CheckSystemApp(env)) {
957 MEDIA_ERR_LOG("SystemApi EnableAutoDeferredVideoEnhancement is called!");
958 return result;
959 }
960 napi_status status;
961 size_t argc = ARGS_ONE;
962 napi_value argv[ARGS_ONE] = {0};
963 napi_value thisVar = nullptr;
964 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
965 if (argc != ARGS_ONE) {
966 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "requires one parameter");
967 return result;
968 }
969 int32_t res = 0;
970 napi_get_undefined(env, &result);
971 VideoOutputNapi* videoOutputNapi = nullptr;
972 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
973 if (status == napi_ok && videoOutputNapi != nullptr) {
974 bool isEnable;
975 napi_get_value_bool(env, argv[PARAM0], &isEnable);
976 res = videoOutputNapi->videoOutput_->EnableAutoDeferredVideoEnhancement(isEnable);
977 }
978 if (res > 0) {
979 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
980 }
981 return result;
982 }
983
GetSupportedRotations(napi_env env,napi_callback_info info)984 napi_value VideoOutputNapi::GetSupportedRotations(napi_env env, napi_callback_info info)
985 {
986 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
987 if (!CameraNapiSecurity::CheckSystemApp(env)) {
988 MEDIA_ERR_LOG("SystemApi GetSupportedRotations is called!");
989 return result;
990 }
991 MEDIA_DEBUG_LOG("VideoOutputNapi::GetSupportedRotations is called");
992
993 VideoOutputNapi* videoOutputNapi = nullptr;
994 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
995 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
996 MEDIA_ERR_LOG("VideoOutputNapi::GetSupportedRotations parse parameter occur error");
997 return result;
998 }
999 if (videoOutputNapi->videoOutput_ == nullptr) {
1000 MEDIA_ERR_LOG("VideoOutputNapi::GetSupportedRotations get native object fail");
1001 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
1002 return result;
1003 }
1004 std::vector<int32_t> supportedRotations;
1005 int32_t retCode = videoOutputNapi->videoOutput_->GetSupportedRotations(supportedRotations);
1006 if (!CameraNapiUtils::CheckError(env, retCode)) {
1007 return nullptr;
1008 }
1009 napi_status status = napi_create_array(env, &result);
1010 CHECK_ERROR_RETURN_RET_LOG(status != napi_ok, result, "napi_create_array call Failed!");
1011 for (size_t i = 0; i < supportedRotations.size(); i++) {
1012 int32_t value = supportedRotations[i];
1013 napi_value element;
1014 napi_create_int32(env, value, &element);
1015 napi_set_element(env, result, i, element);
1016 }
1017 return result;
1018 }
1019
IsRotationSupported(napi_env env,napi_callback_info info)1020 napi_value VideoOutputNapi::IsRotationSupported(napi_env env, napi_callback_info info)
1021 {
1022 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
1023 if (!CameraNapiSecurity::CheckSystemApp(env)) {
1024 MEDIA_ERR_LOG("SystemApi IsRotationSupported is called!");
1025 return result;
1026 }
1027 MEDIA_DEBUG_LOG("VideoOutputNapi::IsRotationSupported is called");
1028
1029 VideoOutputNapi* videoOutputNapi = nullptr;
1030 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
1031 if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
1032 MEDIA_ERR_LOG("VideoOutputNapi::IsRotationSupported parse parameter occur error");
1033 return result;
1034 }
1035 if (videoOutputNapi->videoOutput_ == nullptr) {
1036 MEDIA_ERR_LOG("VideoOutputNapi::IsRotationSupported get native object fail");
1037 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
1038 return result;
1039 }
1040 bool isSupported = false;
1041 int32_t retCode = videoOutputNapi->videoOutput_->IsRotationSupported(isSupported);
1042 if (!CameraNapiUtils::CheckError(env, retCode)) {
1043 MEDIA_ERR_LOG("VideoOutputNapi::IsRotationSupported fail %{public}d", retCode);
1044 }
1045 napi_get_boolean(env, isSupported, &result);
1046 return result;
1047 }
1048
SetRotation(napi_env env,napi_callback_info info)1049 napi_value VideoOutputNapi::SetRotation(napi_env env, napi_callback_info info)
1050 {
1051 napi_value result = CameraNapiUtils::GetUndefinedValue(env);
1052 if (!CameraNapiSecurity::CheckSystemApp(env)) {
1053 MEDIA_ERR_LOG("SystemApi SetRotation is called!");
1054 return result;
1055 }
1056 MEDIA_DEBUG_LOG("VideoOutputNapi::SetRotation is called");
1057 VideoOutputNapi* videoOutputNapi = nullptr;
1058 int32_t rotation;
1059 CameraNapiParamParser jsParamParser(env, info, videoOutputNapi, rotation);
1060 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
1061 MEDIA_ERR_LOG("VideoOutputNapi::SetRotation parse parameter occur error");
1062 return result;
1063 }
1064 if (videoOutputNapi->videoOutput_ == nullptr) {
1065 MEDIA_ERR_LOG("VideoOutputNapi::SetRotation get native object fail");
1066 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
1067 return result;
1068 }
1069 int32_t retCode = videoOutputNapi->videoOutput_->SetRotation(rotation);
1070 if (!CameraNapiUtils::CheckError(env, retCode)) {
1071 MEDIA_ERR_LOG("VideoOutputNapi::SetRotation fail %{public}d", retCode);
1072 }
1073 return result;
1074 }
1075 } // namespace CameraStandard
1076 } // namespace OHOS
1077