input/camera_api: consider camera malfunctioning case 26/309926/1
authorInki Dae <inki.dae@samsung.com>
Thu, 18 Apr 2024 07:19:24 +0000 (16:19 +0900)
committerInki Dae <inki.dae@samsung.com>
Thu, 18 Apr 2024 07:19:24 +0000 (16:19 +0900)
Consider camera device malfunctioning case by using timeout and
re-trying checking current camera state.

Change-Id: Icb757700b6674672447a0a9240b3a753887adf9e
Signed-off-by: Inki Dae <inki.dae@samsung.com>
input/backends/camera_api/include/CameraApiBackend.h
input/backends/camera_api/src/CameraApiBackend.cpp

index 24e4dd3def3473b903e82cae1cbc961b4bbda2c6..6b215c1bdc4ead740e425882d7dc98ff79e5c0cc 100644 (file)
@@ -41,6 +41,7 @@ private:
        void *_userData;
        std::mutex _capture_mutex;
        std::condition_variable _capture_event;
+       bool _isCaptured { false };
        cv::Mat _cvCaptureImage;
        camera_pixel_format_e _defaultPreviewPixelFormat { CAMERA_PIXEL_FORMAT_I420 };
        camera_pixel_format_e _defaultCapturePixelFormat { CAMERA_PIXEL_FORMAT_I420 };
index ecbaca378eca57672af013ebf800ab196448671a..c89491593963d89715f59da7b27765f21ea240ba 100644 (file)
@@ -253,6 +253,7 @@ void CameraApiBackend::captureCb(camera_image_data_s *image, camera_image_data_s
 
        cv::cvtColor(cv_src, context->_cvCaptureImage, cv::COLOR_YUV2BGR_I420);
 
+       context->_isCaptured = true;
        context->_capture_event.notify_one();
 }
 
@@ -285,7 +286,10 @@ void CameraApiBackend::capture(BaseDataType &out_data)
 
        unique_lock<mutex> lock(_capture_mutex);
 
-       _capture_event.wait(lock);
+       _isCaptured = false;
+       auto event_ret = _capture_event.wait_for(lock, chrono::milliseconds(3000), [this] { return _isCaptured; });
+       if (!event_ret)
+               throw InvalidOperation("Camera device not working");
 
        auto &image_data = dynamic_cast<ImageDataType &>(out_data);
 
@@ -298,14 +302,21 @@ void CameraApiBackend::capture(BaseDataType &out_data)
        // Wait for "Captured" state.
        // Ps. captureCompletedCb callback is called by main thread so we cannot use the callback
        //     to wait for "Captured" state with sync API.
+       const unsigned int max_try_count = 100;
        camera_state_e state {};
+       unsigned int try_count = 0;
+
+       while (++try_count < max_try_count) {
+               ret = camera_get_state(_camera, &state);
+               if (ret != CAMERA_ERROR_NONE || state == CAMERA_STATE_CAPTURED)
+                       break;
 
-       camera_get_state(_camera, &state);
-       while (state != CAMERA_STATE_CAPTURED) {
                this_thread::sleep_for(10ms);
-               camera_get_state(_camera, &state);
        }
 
+       if (ret != CAMERA_ERROR_NONE || try_count == max_try_count)
+               throw InvalidOperation("Camera device not working");
+
        // Change the state to "Previewing".
        ret = camera_start_preview(_camera);
        if (ret != CAMERA_ERROR_NONE) {