1 /*
2  * Copyright (c) 2021-2024 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 PHOTO_OUTPUT_NAPI_H_
17 #define PHOTO_OUTPUT_NAPI_H_
18 
19 #include <cstdint>
20 #include <memory>
21 
22 #include "camera_napi_event_emitter.h"
23 #include "camera_napi_template_utils.h"
24 #include "input/camera_device.h"
25 #include "input/camera_manager.h"
26 #include "listener_base.h"
27 #include "native_image.h"
28 #include "output/camera_output_capability.h"
29 #include "output/photo_output.h"
30 
31 namespace OHOS::Media {
32     class PixelMap;
33 }
34 namespace OHOS {
35 namespace CameraStandard {
36 const std::string dataWidth = "dataWidth";
37 const std::string dataHeight = "dataHeight";
38 static const std::string CONST_CAPTURE_START = "captureStart";
39 static const std::string CONST_CAPTURE_END = "captureEnd";
40 static const std::string CONST_CAPTURE_FRAME_SHUTTER = "frameShutter";
41 static const std::string CONST_CAPTURE_ERROR = "error";
42 static const std::string CONST_CAPTURE_PHOTO_AVAILABLE = "photoAvailable";
43 static const std::string CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE = "deferredPhotoProxyAvailable";
44 static const std::string CONST_CAPTURE_PHOTO_ASSET_AVAILABLE = "photoAssetAvailable";
45 static const std::string CONST_CAPTURE_FRAME_SHUTTER_END = "frameShutterEnd";
46 static const std::string CONST_CAPTURE_READY = "captureReady";
47 static const std::string CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION = "estimatedCaptureDuration";
48 static const std::string CONST_CAPTURE_START_WITH_INFO = "captureStartWithInfo";
49 
50 static const std::string CONST_CAPTURE_QUICK_THUMBNAIL = "quickThumbnail";
51 static const char CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME[] = "PhotoOutput";
52 
53 static const std::string CONST_GAINMAP_SURFACE = "gainmap";
54 static const std::string CONST_DEEP_SURFACE = "deep";
55 static const std::string CONST_EXIF_SURFACE = "exif";
56 static const std::string CONST_DEBUG_SURFACE = "debug";
57 
58 struct CallbackInfo {
59     int32_t captureID;
60     uint64_t timestamp = 0;
61     int32_t frameCount = 0;
62     int32_t errorCode;
63     int32_t duration;
64 };
65 
66 enum PhotoOutputEventType {
67     CAPTURE_START,
68     CAPTURE_END,
69     CAPTURE_FRAME_SHUTTER,
70     CAPTURE_FRAME_SHUTTER_END,
71     CAPTURE_READY,
72     CAPTURE_ERROR,
73     CAPTURE_INVALID_TYPE,
74     CAPTURE_PHOTO_AVAILABLE,
75     CAPTURE_DEFERRED_PHOTO_AVAILABLE,
76     CAPTURE_PHOTO_ASSET_AVAILABLE,
77     CAPTURE_ESTIMATED_CAPTURE_DURATION,
78     CAPTURE_START_WITH_INFO
79 };
80 
81 static EnumHelper<PhotoOutputEventType> PhotoOutputEventTypeHelper({
82         {CAPTURE_START, CONST_CAPTURE_START},
83         {CAPTURE_END, CONST_CAPTURE_END},
84         {CAPTURE_FRAME_SHUTTER, CONST_CAPTURE_FRAME_SHUTTER},
85         {CAPTURE_ERROR, CONST_CAPTURE_ERROR},
86         {CAPTURE_PHOTO_AVAILABLE, CONST_CAPTURE_PHOTO_AVAILABLE},
87         {CAPTURE_DEFERRED_PHOTO_AVAILABLE, CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE},
88         {CAPTURE_PHOTO_ASSET_AVAILABLE, CONST_CAPTURE_PHOTO_ASSET_AVAILABLE},
89         {CAPTURE_FRAME_SHUTTER_END, CONST_CAPTURE_FRAME_SHUTTER_END},
90         {CAPTURE_READY, CONST_CAPTURE_READY},
91         {CAPTURE_ESTIMATED_CAPTURE_DURATION, CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION},
92         {CAPTURE_START_WITH_INFO, CONST_CAPTURE_START_WITH_INFO}
93     },
94     PhotoOutputEventType::CAPTURE_INVALID_TYPE
95 );
96 enum SurfaceType {
97     GAINMAP_SURFACE = 0,
98     DEEP_SURFACE = 1,
99     EXIF_SURFACE = 2,
100     DEBUG_SURFACE = 3,
101     INVALID_SURFACE = -1,
102 };
103 
104 static EnumHelper<SurfaceType> SurfaceTypeHelper({
105         {GAINMAP_SURFACE, CONST_GAINMAP_SURFACE},
106         {DEEP_SURFACE, CONST_DEEP_SURFACE},
107         {EXIF_SURFACE, CONST_EXIF_SURFACE},
108         {DEBUG_SURFACE, CONST_DEBUG_SURFACE},
109     },
110     SurfaceType::INVALID_SURFACE
111 );
112 
113 class PhotoBufferProcessor : public Media::IBufferProcessor {
114 public:
PhotoBufferProcessor(sptr<Surface> photoSurface)115     explicit PhotoBufferProcessor(sptr<Surface> photoSurface) : photoSurface_(photoSurface) {}
~PhotoBufferProcessor()116     ~PhotoBufferProcessor()
117     {
118         photoSurface_ = nullptr;
119     }
BufferRelease(sptr<SurfaceBuffer> & buffer)120     void BufferRelease(sptr<SurfaceBuffer>& buffer) override
121     {
122         if (photoSurface_ != nullptr) {
123             photoSurface_->ReleaseBuffer(buffer, -1);
124         }
125     }
126 
127 private:
128     sptr<Surface> photoSurface_ = nullptr;
129 };
130 
131 class PhotoListener : public IBufferConsumerListener,
132                       public ListenerBase,
133                       public std::enable_shared_from_this<PhotoListener> {
134 public:
135     explicit PhotoListener(napi_env env, const sptr<Surface> photoSurface, wptr<PhotoOutput> photoOutput);
136     virtual ~PhotoListener();
137     void OnBufferAvailable() override;
138     void SaveCallback(const std::string eventName, napi_value callback);
139     void RemoveCallback(const std::string eventName, napi_value callback);
140     void ExecuteDeepCopySurfaceBuffer();
141     std::shared_ptr<DeferredProcessing::TaskManager> taskManager_ = nullptr;
142 
143 private:
144     sptr<Surface> photoSurface_;
145     wptr<PhotoOutput> photoOutput_;
146     shared_ptr<PhotoBufferProcessor> bufferProcessor_;
147     void UpdateJSCallback(sptr<Surface> photoSurface) const;
148     void UpdateJSCallbackAsync(sptr<Surface> photoSurface) const;
149     void UpdatePictureJSCallback(int32_t captureId, const string uri, int32_t cameraShotType,
150         const std::string burstKey) const;
151     void UpdateMainPictureStageOneJSCallback(sptr<SurfaceBuffer> surfaceBuffer, int64_t timestamp) const;
152     void ExecutePhoto(sptr<SurfaceBuffer> surfaceBfuffer, int64_t timestamp) const;
153     void ExecuteDeferredPhoto(sptr<SurfaceBuffer> surfaceBuffer) const;
154     void DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer,
155         int32_t captureId) const;
156     void ExecutePhotoAsset(sptr<SurfaceBuffer> surfaceBuffer, bool isHighQuality, int64_t timestamp) const;
157     void CreateMediaLibrary(sptr<SurfaceBuffer> surfaceBuffer, BufferHandle* bufferHandle, bool isHighQuality,
158         std::string& uri, int32_t& cameraShotType, std::string &burstKey, int64_t timestamp) const;
159     void AssembleAuxiliaryPhoto(int64_t timestamp, int32_t captureId);
160     int32_t GetAuxiliaryPhotoCount(sptr<SurfaceBuffer> surfaceBuffer);
161     sptr<CameraPhotoProxy> CreateCameraPhotoProxy(sptr<SurfaceBuffer> surfaceBuffer);
162     uint8_t callbackFlag_ = 0;
163 };
164 
165 class RawPhotoListener : public IBufferConsumerListener, public ListenerBase {
166 public:
167     explicit RawPhotoListener(napi_env env, const sptr<Surface> rawPhotoSurface);
168     ~RawPhotoListener() = default;
169     void OnBufferAvailable() override;
170 
171 private:
172     sptr<Surface> rawPhotoSurface_;
173     shared_ptr<PhotoBufferProcessor> bufferProcessor_;
174     void UpdateJSCallback(sptr<Surface> rawPhotoSurface) const;
175     void UpdateJSCallbackAsync(sptr<Surface> rawPhotoSurface) const;
176     void ExecuteRawPhoto(sptr<SurfaceBuffer> rawPhotoSurface) const;
177 };
178 
179 class AuxiliaryPhotoListener : public IBufferConsumerListener {
180 public:
181     explicit AuxiliaryPhotoListener(const std::string surfaceName, const sptr<Surface> surface,
182         wptr<PhotoOutput> photoOutput);
183     ~AuxiliaryPhotoListener() = default;
184     void OnBufferAvailable() override;
185     void ExecuteDeepCopySurfaceBuffer();
186 private:
187     void DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer, int32_t) const;
188     std::string surfaceName_;
189     sptr<Surface> surface_;
190     wptr<PhotoOutput> photoOutput_;
191     shared_ptr<PhotoBufferProcessor> bufferProcessor_;
192 };
193 
194 class PictureListener : public RefBase {
195 public:
196     explicit PictureListener() = default;
197     ~PictureListener() = default;
198     void InitPictureListeners(napi_env env, wptr<PhotoOutput> photoOutput);
199     sptr<AuxiliaryPhotoListener> gainmapImageListener;
200     sptr<AuxiliaryPhotoListener> deepImageListener;
201     sptr<AuxiliaryPhotoListener> exifImageListener;
202     sptr<AuxiliaryPhotoListener> debugImageListener;
203 };
204 
205 class PhotoOutputCallback : public PhotoStateCallback,
206                             public ListenerBase,
207                             public std::enable_shared_from_this<PhotoOutputCallback> {
208 public:
209     explicit PhotoOutputCallback(napi_env env);
210     ~PhotoOutputCallback() = default;
211 
212     void OnCaptureStarted(const int32_t captureID) const override;
213     void OnCaptureStarted(const int32_t captureID, uint32_t exposureTime) const override;
214     void OnCaptureEnded(const int32_t captureID, const int32_t frameCount) const override;
215     void OnFrameShutter(const int32_t captureId, const uint64_t timestamp) const override;
216     void OnFrameShutterEnd(const int32_t captureId, const uint64_t timestamp) const override;
217     void OnCaptureReady(const int32_t captureId, const uint64_t timestamp) const override;
218     void OnCaptureError(const int32_t captureId, const int32_t errorCode) const override;
219     void OnEstimatedCaptureDuration(const int32_t duration) const override;
220 
221 private:
222     void UpdateJSCallback(PhotoOutputEventType eventType, const CallbackInfo& info) const;
223     void UpdateJSCallbackAsync(PhotoOutputEventType eventType, const CallbackInfo& info) const;
224     void ExecuteCaptureStartCb(const CallbackInfo& info) const;
225     void ExecuteCaptureStartWithInfoCb(const CallbackInfo& info) const;
226     void ExecuteCaptureEndCb(const CallbackInfo& info) const;
227     void ExecuteFrameShutterCb(const CallbackInfo& info) const;
228     void ExecuteCaptureErrorCb(const CallbackInfo& info) const;
229     void ExecuteFrameShutterEndCb(const CallbackInfo& info) const;
230     void ExecuteCaptureReadyCb(const CallbackInfo& info) const;
231     void ExecuteEstimatedCaptureDurationCb(const CallbackInfo& info) const;
232 };
233 
234 struct PhotoOutputCallbackInfo {
235     PhotoOutputEventType eventType_;
236     CallbackInfo info_;
237     weak_ptr<const PhotoOutputCallback> listener_;
PhotoOutputCallbackInfoPhotoOutputCallbackInfo238     PhotoOutputCallbackInfo(
239         PhotoOutputEventType eventType, CallbackInfo info, shared_ptr<const PhotoOutputCallback> listener)
240         : eventType_(eventType), info_(info), listener_(listener)
241     {}
242 };
243 
244 class ThumbnailListener : public IBufferConsumerListener, public ListenerBase {
245 public:
246     explicit ThumbnailListener(napi_env env, const sptr<PhotoOutput> photoOutput);
247     ~ThumbnailListener() = default;
248     void OnBufferAvailable() override;
249 
250 private:
251     wptr<PhotoOutput> photoOutput_;
252     void UpdateJSCallback() const;
253     void UpdateJSCallbackAsync();
254     void UpdateJSCallback(unique_ptr<Media::PixelMap>) const;
255     void UpdateJSCallbackAsync(unique_ptr<Media::PixelMap>);
256     void ExecuteDeepCopySurfaceBuffer();
257 };
258 
259 struct ThumbnailListenerInfo {
260     wptr<ThumbnailListener> listener_;
261     unique_ptr<Media::PixelMap> pixelMap_;
ThumbnailListenerInfoThumbnailListenerInfo262     ThumbnailListenerInfo(sptr<ThumbnailListener> listener, unique_ptr<Media::PixelMap> pixelMap)
263         : listener_(listener), pixelMap_(std::move(pixelMap))
264     {}
265 };
266 
267 struct PhotoListenerInfo {
268     sptr<Surface> photoSurface_;
269     const PhotoListener* listener_;
PhotoListenerInfoPhotoListenerInfo270     PhotoListenerInfo(sptr<Surface> photoSurface, const PhotoListener* listener)
271         : photoSurface_(photoSurface), listener_(listener)
272     {}
273     int32_t captureId = 0;
274     std::string uri = "";
275     int32_t cameraShotType = 0;
276     std::string burstKey = "";
277     sptr<SurfaceBuffer> surfaceBuffer = nullptr;
278     int64_t timestamp = 0;
279 };
280 
281 struct RawPhotoListenerInfo {
282     sptr<Surface> rawPhotoSurface_;
283     const RawPhotoListener* listener_;
RawPhotoListenerInfoRawPhotoListenerInfo284     RawPhotoListenerInfo(sptr<Surface> rawPhotoSurface, const RawPhotoListener* listener)
285         : rawPhotoSurface_(rawPhotoSurface), listener_(listener)
286     {}
287 };
288 
289 struct PhotoOutputAsyncContext;
290 class PhotoOutputNapi : public CameraNapiEventEmitter<PhotoOutputNapi> {
291 public:
292     static napi_value Init(napi_env env, napi_value exports);
293     static napi_value CreatePhotoOutput(napi_env env, Profile& profile, std::string surfaceId);
294     static napi_value CreatePhotoOutput(napi_env env, std::string surfaceId);
295 
296     static napi_value Capture(napi_env env, napi_callback_info info);
297     static napi_value BurstCapture(napi_env env, napi_callback_info info);
298     static napi_value ConfirmCapture(napi_env env, napi_callback_info info);
299     static napi_value Release(napi_env env, napi_callback_info info);
300     static napi_value IsMirrorSupported(napi_env env, napi_callback_info info);
301     static napi_value EnableMirror(napi_env env, napi_callback_info info);
302     static napi_value EnableQuickThumbnail(napi_env env, napi_callback_info info);
303     static napi_value IsQuickThumbnailSupported(napi_env env, napi_callback_info info);
304     static napi_value EnableRawDelivery(napi_env env, napi_callback_info info);
305     static napi_value IsRawDeliverySupported(napi_env env, napi_callback_info info);
306     static napi_value DeferImageDeliveryFor(napi_env env, napi_callback_info info);
307     static napi_value IsDeferredImageDeliverySupported(napi_env env, napi_callback_info info);
308     static napi_value IsDeferredImageDeliveryEnabled(napi_env env, napi_callback_info info);
309     static napi_value GetSupportedMovingPhotoVideoCodecTypes(napi_env env, napi_callback_info info);
310     static napi_value SetMovingPhotoVideoCodecType(napi_env env, napi_callback_info info);
311     static napi_value IsDepthDataDeliverySupported(napi_env env, napi_callback_info info);
312     static napi_value EnableDepthDataDelivery(napi_env env, napi_callback_info info);
313     static bool IsPhotoOutput(napi_env env, napi_value obj);
314     static napi_value GetActiveProfile(napi_env env, napi_callback_info info);
315     static napi_value On(napi_env env, napi_callback_info info);
316     static napi_value Once(napi_env env, napi_callback_info info);
317     static napi_value Off(napi_env env, napi_callback_info info);
318     static napi_value GetPhotoRotation(napi_env env, napi_callback_info info);
319 
320     static napi_value IsAutoHighQualityPhotoSupported(napi_env env, napi_callback_info info);
321     static napi_value EnableAutoHighQualityPhoto(napi_env env, napi_callback_info info);
322 
323     static napi_value IsAutoCloudImageEnhancementSupported(napi_env env, napi_callback_info info);
324     static napi_value EnableAutoCloudImageEnhancement(napi_env env, napi_callback_info info);
325     static napi_value IsMovingPhotoSupported(napi_env env, napi_callback_info info);
326     static napi_value EnableMovingPhoto(napi_env env, napi_callback_info info);
327 
328     PhotoOutputNapi();
329     ~PhotoOutputNapi() override;
330 
331     sptr<PhotoOutput> GetPhotoOutput();
332     bool GetEnableMirror();
333 
334     const EmitterFunctions& GetEmitterFunctions() override;
335 
336 private:
337     static void PhotoOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint);
338     static napi_value PhotoOutputNapiConstructor(napi_env env, napi_callback_info info);
339     void CreateMultiChannelPictureLisenter(napi_env env);
340     void CreateSingleChannelPhotoLisenter(napi_env env);
341     void RegisterQuickThumbnailCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
342         const std::vector<napi_value>& args, bool isOnce);
343     void UnregisterQuickThumbnailCallbackListener(
344         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
345     void RegisterPhotoAvailableCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
346         const std::vector<napi_value>& args, bool isOnce);
347     void UnregisterPhotoAvailableCallbackListener(
348         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
349     void RegisterDeferredPhotoProxyAvailableCallbackListener(const std::string& eventName, napi_env env,
350         napi_value callback, const std::vector<napi_value>& args, bool isOnce);
351     void UnregisterDeferredPhotoProxyAvailableCallbackListener(
352         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
353     void RegisterPhotoAssetAvailableCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
354         const std::vector<napi_value>& args, bool isOnce);
355     void UnregisterPhotoAssetAvailableCallbackListener(
356         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
357     void RegisterCaptureStartCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
358         const std::vector<napi_value>& args, bool isOnce);
359     void UnregisterCaptureStartCallbackListener(
360         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
361     void RegisterCaptureEndCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
362         const std::vector<napi_value>& args, bool isOnce);
363     void UnregisterCaptureEndCallbackListener(
364         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
365     void RegisterFrameShutterCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
366         const std::vector<napi_value>& args, bool isOnce);
367     void UnregisterFrameShutterCallbackListener(
368         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
369     void RegisterErrorCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
370         const std::vector<napi_value>& args, bool isOnce);
371     void UnregisterErrorCallbackListener(
372         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
373     void RegisterFrameShutterEndCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
374         const std::vector<napi_value>& args, bool isOnce);
375     void UnregisterFrameShutterEndCallbackListener(
376         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
377     void RegisterReadyCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
378         const std::vector<napi_value>& args, bool isOnce);
379     void UnregisterReadyCallbackListener(
380         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
381     void RegisterEstimatedCaptureDurationCallbackListener(const std::string& eventName, napi_env env,
382         napi_value callback, const std::vector<napi_value>& args, bool isOnce);
383     void UnregisterEstimatedCaptureDurationCallbackListener(
384         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
385     void RegisterCaptureStartWithInfoCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
386         const std::vector<napi_value>& args, bool isOnce);
387     void UnregisterCaptureStartWithInfoCallbackListener(
388         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
389 
390     static thread_local napi_ref sConstructor_;
391     static thread_local sptr<PhotoOutput> sPhotoOutput_;
392     static thread_local sptr<Surface> sPhotoSurface_;
393 
394     sptr<PhotoOutput> photoOutput_;
395     std::shared_ptr<Profile> profile_;
396     bool isQuickThumbnailEnabled_ = false;
397     bool isDeferredPhotoEnabled_ = false;
398     bool isMirrorEnabled_ = false;
399     sptr<ThumbnailListener> thumbnailListener_;
400     sptr<PhotoListener> photoListener_;
401     sptr<RawPhotoListener> rawPhotoListener_;
402     sptr<PictureListener> pictureListener_;
403     std::shared_ptr<PhotoOutputCallback> photoOutputCallback_;
404     static thread_local uint32_t photoOutputTaskId;
405     static thread_local napi_ref rawCallback_;
406 };
407 
408 struct PhotoOutputNapiCaptureSetting {
409     int32_t quality = -1;
410 };
411 
412 struct PhotoOutputAsyncContext : public AsyncContext {
PhotoOutputAsyncContextPhotoOutputAsyncContext413     PhotoOutputAsyncContext(std::string funcName, int32_t taskId) : AsyncContext(funcName, taskId) {};
414     int32_t quality = -1;
415     int32_t rotation = -1;
416     bool isMirror = false;
417     bool isMirrorSettedByUser = false;
418     bool hasPhotoSettings = false;
419     bool isSupported = false;
420     shared_ptr<Location> location;
421     PhotoOutputNapi* objectInfo = nullptr;
422     std::string surfaceId;
423 };
424 } // namespace CameraStandard
425 } // namespace OHOS
426 #endif /* PHOTO_OUTPUT_NAPI_H_ */
427