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 #ifndef VIDEO_OUTPUT_NAPI_H_
17 #define VIDEO_OUTPUT_NAPI_H_
18 
19 #include "camera_napi_template_utils.h"
20 #include "camera_napi_utils.h"
21 #include "input/camera_manager.h"
22 #include "listener_base.h"
23 #include "output/video_output.h"
24 #include "surface_utils.h"
25 
26 namespace OHOS {
27 namespace CameraStandard {
28 static const char CAMERA_VIDEO_OUTPUT_NAPI_CLASS_NAME[] = "VideoOutput";
29 static const std::string CONST_VIDEO_FRAME_START = "frameStart";
30 static const std::string CONST_VIDEO_FRAME_END = "frameEnd";
31 static const std::string CONST_VIDEO_FRAME_ERROR = "error";
32 static const std::string CONST_VIDEO_DEFERRED_ENHANCEMENT = "deferredVideoEnhancementInfo";
33 
34 struct VideoCallbackInfo {
35     int32_t frameCount = 0;
36     int32_t errorCode = 0;
37     bool isDeferredVideoEnhancementAvailable = false;
38     std::string videoId = "";
39 };
40 
41 enum VideoOutputEventType {
42     VIDEO_FRAME_START,
43     VIDEO_FRAME_END,
44     VIDEO_FRAME_ERROR,
45     VIDEO_INVALID_TYPE,
46     VIDEO_DEFERRED_ENHANCEMENT
47 };
48 
49 static EnumHelper<VideoOutputEventType> VideoOutputEventTypeHelper({
50         {VIDEO_FRAME_START, CONST_VIDEO_FRAME_START},
51         {VIDEO_FRAME_END, CONST_VIDEO_FRAME_END},
52         {VIDEO_FRAME_ERROR, CONST_VIDEO_FRAME_ERROR},
53         {VIDEO_DEFERRED_ENHANCEMENT, CONST_VIDEO_DEFERRED_ENHANCEMENT},
54     },
55     VideoOutputEventType::VIDEO_INVALID_TYPE
56 );
57 
58 class VideoCallbackListener : public VideoStateCallback,
59                               public ListenerBase,
60                               public std::enable_shared_from_this<VideoCallbackListener> {
61 public:
62     explicit VideoCallbackListener(napi_env env);
63     ~VideoCallbackListener() = default;
64 
65     void OnFrameStarted() const override;
66     void OnFrameEnded(const int32_t frameCount) const override;
67     void OnError(const int32_t errorCode) const override;
68     void OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt info) const override;
69 
70 private:
71     void UpdateJSCallback(VideoOutputEventType eventType, const VideoCallbackInfo& info) const;
72     void UpdateJSCallbackAsync(VideoOutputEventType eventType, const VideoCallbackInfo& info) const;
73     void ExecuteOnDeferredVideoCb(const VideoCallbackInfo& info) const;
74 };
75 
76 struct VideoOutputCallbackInfo {
77     VideoOutputEventType eventType_;
78     VideoCallbackInfo info_;
79     weak_ptr<const VideoCallbackListener> listener_;
VideoOutputCallbackInfoVideoOutputCallbackInfo80     VideoOutputCallbackInfo(VideoOutputEventType eventType, VideoCallbackInfo info,
81         shared_ptr<const VideoCallbackListener> listener)
82         : eventType_(eventType), info_(info), listener_(listener) {}
83 };
84 
85 class VideoOutputNapi : public CameraNapiEventEmitter<VideoOutputNapi> {
86 public:
87     static napi_value Init(napi_env env, napi_value exports);
88     static napi_value CreateVideoOutput(napi_env env, VideoProfile& profile, std::string surfaceId);
89     static napi_value CreateVideoOutput(napi_env env, std::string surfaceId);
90     static bool IsVideoOutput(napi_env env, napi_value obj);
91     static napi_value GetActiveProfile(napi_env env, napi_callback_info info);
92     static napi_value SetFrameRate(napi_env env, napi_callback_info info);
93     static napi_value GetActiveFrameRate(napi_env env, napi_callback_info info);
94     static napi_value GetSupportedFrameRates(napi_env, napi_callback_info info);
95     static napi_value On(napi_env env, napi_callback_info info);
96     static napi_value Once(napi_env env, napi_callback_info info);
97     static napi_value Off(napi_env env, napi_callback_info info);
98     static napi_value IsMirrorSupported(napi_env env, napi_callback_info info);
99     static napi_value EnableMirror(napi_env env, napi_callback_info info);
100     static napi_value GetSupportedVideoMetaTypes(napi_env env, napi_callback_info info);
101     static napi_value AttachMetaSurface(napi_env env, napi_callback_info info);
102     static napi_value IsAutoDeferredVideoEnhancementSupported(napi_env env, napi_callback_info info);
103     static napi_value IsAutoDeferredVideoEnhancementEnabled(napi_env env, napi_callback_info info);
104     static napi_value EnableAutoDeferredVideoEnhancement(napi_env env, napi_callback_info info);
105     static napi_value GetSupportedRotations(napi_env env, napi_callback_info info);
106     static napi_value IsRotationSupported(napi_env env, napi_callback_info info);
107     static napi_value SetRotation(napi_env env, napi_callback_info info);
108     VideoOutputNapi();
109     ~VideoOutputNapi() override;
110     sptr<VideoOutput> GetVideoOutput();
111     const EmitterFunctions& GetEmitterFunctions() override;
112     static napi_value GetVideoRotation(napi_env env, napi_callback_info info);
113 
114 private:
115     static void VideoOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint);
116     static napi_value VideoOutputNapiConstructor(napi_env env, napi_callback_info info);
117 
118     static napi_value Start(napi_env env, napi_callback_info info);
119     static napi_value Stop(napi_env env, napi_callback_info info);
120     static napi_value Release(napi_env env, napi_callback_info info);
121 
122     void RegisterFrameStartCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
123         const std::vector<napi_value>& args, bool isOnce);
124     void UnregisterFrameStartCallbackListener(
125         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
126     void RegisterFrameEndCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
127         const std::vector<napi_value>& args, bool isOnce);
128     void UnregisterFrameEndCallbackListener(
129         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
130     void RegisterErrorCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
131         const std::vector<napi_value>& args, bool isOnce);
132     void UnregisterErrorCallbackListener(
133         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
134     void RegisterDeferredVideoCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
135         const std::vector<napi_value>& args, bool isOnce);
136     void UnregisterDeferredVideoCallbackListener(
137         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
138 
139     static thread_local napi_ref sConstructor_;
140     static thread_local sptr<VideoOutput> sVideoOutput_;
141 
142     napi_env env_;
143     sptr<VideoOutput> videoOutput_;
144     std::shared_ptr<VideoCallbackListener> videoCallback_;
145     static thread_local uint32_t videoOutputTaskId;
146 };
147 
148 struct VideoOutputAsyncContext : public AsyncContext {
VideoOutputAsyncContextVideoOutputAsyncContext149     VideoOutputAsyncContext(std::string funcName, int32_t taskId) : AsyncContext(funcName, taskId) {};
150     VideoOutputNapi* objectInfo = nullptr;
151     std::string errorMsg;
152     std::vector<int32_t> vecFrameRateRangeList;
153 };
154 } // namespace CameraStandard
155 } // namespace OHOS
156 #endif /* VIDEO_OUTPUT_NAPI_H_ */
157