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