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