[WebRTC][Camera] Initialize `camera_device_manager_h` on request 03/318003/7 submit/tizen/20240923.161432
authorMichal Jurkiewicz <m.jurkiewicz@samsung.com>
Fri, 13 Sep 2024 11:56:38 +0000 (13:56 +0200)
committerBot Blink <blinkbot@samsung.com>
Mon, 23 Sep 2024 14:15:14 +0000 (14:15 +0000)
Unneeded initialization of `camera_device_manager_h` may increase load
time of application that does not use camera.

Initialize `camera_device_manager_h` upon first use.

Bug: https://jira-eu.sec.samsung.net/browse/VDGAME-582
Change-Id: I71e324878d2fd6803ef1dfd3fe90ee8e39d3456d
Signed-off-by: Michal Jurkiewicz <m.jurkiewicz@samsung.com>
media/capture/video/tizen/video_capture_device_factory_tizen_tv.cc
media/capture/video/tizen/video_capture_device_factory_tizen_tv.h

index 1532fbddcbf5cb1adb2b49b4796298d271404746..d22f6745a454502d788c4c16649dbed7bd86b67e 100644 (file)
@@ -24,29 +24,23 @@ constexpr VideoCaptureError kCameraCreateError = VideoCaptureError::
 
 }  // namespace
 
-VideoCaptureDeviceFactoryTizenTv::VideoCaptureDeviceFactoryTizenTv() {
-  int err = camera_device_manager_initialize(&handle_);
-  if (err != CAMERA_ERROR_NONE) {
-    TIZEN_MEDIA_LOG(ERROR) << "Cannot initialize camera device manager: "
-                           << err;
-    // Ensure that library doesn't return us some garbage.
-    handle_ = nullptr;
-  }
-}
+VideoCaptureDeviceFactoryTizenTv::VideoCaptureDeviceFactoryTizenTv() = default;
 
 VideoCaptureDeviceFactoryTizenTv::~VideoCaptureDeviceFactoryTizenTv() {
   base::AutoLock lock(devices_lock_);
   devices_cache_.clear();
+}
 
-  if (handle_) {
-    camera_device_manager_deinitialize(handle_);
-  }
+void VideoCaptureDeviceFactoryTizenTv::CameraDeviceManagerDeleter::operator()(
+    camera_device_manager_h manager) {
+  camera_device_manager_deinitialize(manager);
 }
 
 VideoCaptureErrorOrDevice VideoCaptureDeviceFactoryTizenTv::CreateDevice(
     const VideoCaptureDeviceDescriptor& device_descriptor) {
   // Ensure that other thread won't try allocating camera device.
   base::AutoLock lock(devices_lock_);
+
   auto cached_device_it = devices_cache_.find(device_descriptor);
   if (cached_device_it != devices_cache_.end()) {
     TIZEN_MEDIA_LOG(INFO) << "CreateDevice: "
@@ -61,7 +55,8 @@ VideoCaptureErrorOrDevice VideoCaptureDeviceFactoryTizenTv::CreateDevice(
   TIZEN_MEDIA_LOG(INFO) << "CreateDevice: "
                         << device_descriptor.GetNameAndModel();
   camera_device_list_s list;
-  int err = camera_device_manager_get_device_list(handle_, &list);
+  int err =
+      camera_device_manager_get_device_list(GetDeviceManagerHandle(), &list);
   if (err != CAMERA_ERROR_NONE) {
     TIZEN_MEDIA_LOG(ERROR) << "Cannot get device list: " << err;
     return VideoCaptureErrorOrDevice(kCameraCreateError);
@@ -94,6 +89,29 @@ VideoCaptureErrorOrDevice VideoCaptureDeviceFactoryTizenTv::CreateDevice(
   return VideoCaptureErrorOrDevice(kCameraCreateError);
 }
 
+camera_device_manager_h
+VideoCaptureDeviceFactoryTizenTv::GetDeviceManagerHandle() {
+  if (handle_.has_value()) {
+    return handle_->get();
+  }
+
+  camera_device_manager_h handle_ptr = nullptr;
+  int err = camera_device_manager_initialize(&handle_ptr);
+  if (err == CAMERA_ERROR_NONE) {
+    // Successfully initialized |camera_device_manager_h|. Updating |handle_|.
+    handle_ = CameraDeviceManagerType(handle_ptr);
+  } else {
+    TIZEN_MEDIA_LOG(ERROR) << "Cannot initialize camera device manager: "
+                           << err;
+
+    // Zero-initialize |handle_| here to prevent further calls to
+    // |camera_device_manager_initialize| method.
+    handle_ = nullptr;
+  }
+
+  return handle_->get();
+}
+
 std::vector<VideoCaptureDeviceInfo>
 VideoCaptureDeviceFactoryTizenTv::GetDevices() {
   std::vector<VideoCaptureDeviceInfo> result;
@@ -102,7 +120,8 @@ VideoCaptureDeviceFactoryTizenTv::GetDevices() {
   // Ensure that other thread won't try allocating camera device.
   base::AutoLock lock(devices_lock_);
 
-  int err = camera_device_manager_get_device_list(handle_, &list);
+  int err =
+      camera_device_manager_get_device_list(GetDeviceManagerHandle(), &list);
   if (err != CAMERA_ERROR_NONE) {
     TIZEN_MEDIA_LOG(ERROR) << "Cannot get device list: " << err;
     return {};
index 8eb481931ee813ae801f1af4fe0c514f64caeca4..06c2403e513b9b5c60be7275212924415f240e2c 100644 (file)
@@ -9,6 +9,7 @@
 #include <media/camera_internal.h>
 
 #include <map>
+#include <optional>
 
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
@@ -44,13 +45,26 @@ class VideoCaptureDeviceFactoryTizenTv : public VideoCaptureDeviceFactory {
   void ReleaseCachedDevice(
       const VideoCaptureDeviceDescriptor& device_descriptor);
 
-  camera_device_manager_h handle_ = nullptr;
+  struct CameraDeviceManagerDeleter {
+    void operator()(camera_device_manager_h manager);
+  };
+
+  using CameraDeviceManagerType =
+      std::unique_ptr<std::remove_pointer<camera_device_manager_h>::type,
+                      CameraDeviceManagerDeleter>;
 
   base::Lock devices_lock_;
+
   std::map<VideoCaptureDeviceDescriptor, VideoCaptureFormats>
       supported_formats_cache_ GUARDED_BY(devices_lock_);
   std::map<VideoCaptureDeviceDescriptor, CameraDeviceHolder> devices_cache_
       GUARDED_BY(devices_lock_);
+  camera_device_manager_h GetDeviceManagerHandle()
+      EXCLUSIVE_LOCKS_REQUIRED(devices_lock_);
+
+  // Note: Do not use this class member directly. Use |GetDeviceManagerHandle()|
+  // method instead to get properly initialized object.
+  std::optional<CameraDeviceManagerType> handle_ GUARDED_BY(devices_lock_);
 };
 
 }  // namespace media