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