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