• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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