| /* |
| * Copyright 2016 The Chromium OS Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef CAMERA_HAL_ADAPTER_CAMERA_DEVICE_ADAPTER_H_ |
| #define CAMERA_HAL_ADAPTER_CAMERA_DEVICE_ADAPTER_H_ |
| |
| #include <deque> |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <unordered_map> |
| #include <utility> |
| #include <vector> |
| |
| #include <hardware/camera3.h> |
| |
| #include <base/containers/flat_map.h> |
| #include <base/files/scoped_file.h> |
| #include <base/synchronization/lock.h> |
| #include <base/threading/thread.h> |
| #include <base/timer/timer.h> |
| #include <camera/camera_metadata.h> |
| #include <mojo/public/cpp/bindings/binding.h> |
| #include <system/camera_metadata.h> |
| |
| #include "common/utils/common_types.h" |
| #include "common/utils/cros_camera_mojo_utils.h" |
| #include "cros-camera/camera_buffer_manager.h" |
| #include "cros-camera/camera_metrics.h" |
| #include "hal_adapter/camera_metadata_inspector.h" |
| #include "hal_adapter/frame_number_mapper.h" |
| #include "hal_adapter/scoped_yuv_buffer_handle.h" |
| #include "hal_adapter/zsl_helper.h" |
| #include "mojo/camera3.mojom.h" |
| |
| namespace cros { |
| |
| class Camera3DeviceOpsDelegate; |
| |
| class Camera3CallbackOpsDelegate; |
| |
| // Flattened capture request |
| class Camera3CaptureRequest : public camera3_capture_request_t { |
| public: |
| explicit Camera3CaptureRequest(const camera3_capture_request_t& req); |
| |
| ~Camera3CaptureRequest() = default; |
| |
| private: |
| android::CameraMetadata settings_; |
| |
| camera3_stream_buffer_t input_buffer_; |
| |
| std::vector<camera3_stream_buffer_t> output_stream_buffers_; |
| }; |
| |
| // It is a watchdog-like monitor. It detects the kick event. If there is no |
| // kick event between 2 timeout it outputs log to indicate it. We can use it to |
| // detect if there is any continuous event stopped. e.g. capture request. |
| class CameraMonitor : public base::OneShotTimer { |
| public: |
| explicit CameraMonitor(const std::string& name); |
| CameraMonitor(const CameraMonitor&) = delete; |
| CameraMonitor& operator=(const CameraMonitor&) = delete; |
| |
| ~CameraMonitor() override = default; |
| |
| void Attach(); |
| void Detach(); |
| void StartMonitor(); |
| void Kick(); |
| |
| private: |
| void SetTaskRunnerOnThread(base::Callback<void()> callback); |
| void StartMonitorOnThread(); |
| void MonitorTimeout(); |
| |
| std::string name_; |
| // A thread that handles timeouts of request/response monitors. |
| base::Thread thread_; |
| |
| base::Lock lock_; |
| bool is_kicked_ GUARDED_BY(lock_); |
| }; |
| |
| class CameraDeviceAdapter : public camera3_callback_ops_t { |
| public: |
| explicit CameraDeviceAdapter(camera3_device_t* camera_device, |
| const camera_metadata_t* static_info, |
| base::Callback<void()> close_callback); |
| |
| ~CameraDeviceAdapter(); |
| |
| using HasReprocessEffectVendorTagCallback = |
| base::Callback<bool(const camera_metadata_t&)>; |
| using ReprocessEffectCallback = |
| base::Callback<int32_t(const camera_metadata_t&, |
| ScopedYUVBufferHandle*, |
| uint32_t, |
| uint32_t, |
| android::CameraMetadata*, |
| ScopedYUVBufferHandle*)>; |
| using AllocatedBuffers = |
| base::flat_map<uint64_t, std::vector<mojom::Camera3StreamBufferPtr>>; |
| // Starts the camera device adapter. This method must be called before all |
| // the other methods are called. |
| bool Start(HasReprocessEffectVendorTagCallback |
| has_reprocess_effect_vendor_tag_callback, |
| ReprocessEffectCallback reprocess_effect_callback); |
| |
| // Bind() is called by CameraHalAdapter in OpenDevice() on the mojo IPC |
| // handler thread in |module_delegate_|. |
| void Bind(mojom::Camera3DeviceOpsRequest device_ops_request); |
| |
| // Callback interface for Camera3DeviceOpsDelegate. |
| // These methods are callbacks for |device_ops_delegate_| and are executed on |
| // the mojo IPC handler thread in |device_ops_delegate_|. |
| |
| int32_t Initialize(mojom::Camera3CallbackOpsPtr callback_ops); |
| |
| int32_t ConfigureStreams( |
| mojom::Camera3StreamConfigurationPtr config, |
| mojom::Camera3StreamConfigurationPtr* updated_config); |
| |
| mojom::CameraMetadataPtr ConstructDefaultRequestSettings( |
| mojom::Camera3RequestTemplate type); |
| |
| int32_t ProcessCaptureRequest(mojom::Camera3CaptureRequestPtr request); |
| |
| void Dump(mojo::ScopedHandle fd); |
| |
| int32_t Flush(); |
| |
| int32_t RegisterBuffer(uint64_t buffer_id, |
| mojom::Camera3DeviceOps::BufferType type, |
| std::vector<mojo::ScopedHandle> fds, |
| uint32_t drm_format, |
| mojom::HalPixelFormat hal_pixel_format, |
| uint32_t width, |
| uint32_t height, |
| const std::vector<uint32_t>& strides, |
| const std::vector<uint32_t>& offsets); |
| |
| int32_t Close(); |
| |
| int32_t ConfigureStreamsAndGetAllocatedBuffers( |
| mojom::Camera3StreamConfigurationPtr config, |
| mojom::Camera3StreamConfigurationPtr* updated_config, |
| AllocatedBuffers* allocated_buffers); |
| |
| private: |
| // Implementation of camera3_callback_ops_t. |
| static void ProcessCaptureResult(const camera3_callback_ops_t* ops, |
| const camera3_capture_result_t* result); |
| |
| static void Notify(const camera3_callback_ops_t* ops, |
| const camera3_notify_msg_t* msg); |
| |
| // Allocates buffers for given |streams|. Returns true and the allocated |
| // buffers will be put in |allocated_buffers| if the allocation succeeds. |
| // Otherwise, false is returned. |
| bool AllocateBuffersForStreams( |
| const std::vector<mojom::Camera3StreamPtr>& streams, |
| AllocatedBuffers* allocated_buffers); |
| |
| // Frees all allocated stream buffers that are allocated locally. |
| void FreeAllocatedStreamBuffers(); |
| |
| int32_t RegisterBufferLocked(uint64_t buffer_id, |
| mojom::Camera3DeviceOps::BufferType type, |
| std::vector<mojo::ScopedHandle> fds, |
| uint32_t drm_format, |
| mojom::HalPixelFormat hal_pixel_format, |
| uint32_t width, |
| uint32_t height, |
| const std::vector<uint32_t>& strides, |
| const std::vector<uint32_t>& offsets); |
| int32_t RegisterBufferLocked(mojom::CameraBufferHandlePtr buffer); |
| |
| // NOTE: All the fds in |result| (e.g. fences and buffer handles) will be |
| // closed after the function returns. The caller needs to dup a fd in |
| // |result| if the fd will be accessed after calling ProcessCaptureResult. |
| mojom::Camera3CaptureResultPtr PrepareCaptureResult( |
| const camera3_capture_result_t* result); |
| |
| void PreprocessNotifyMsg(const camera3_notify_msg_t* msg, |
| std::vector<camera3_notify_msg_t>* msgs); |
| |
| mojom::Camera3NotifyMsgPtr PrepareNotifyMsg(const camera3_notify_msg_t* msg); |
| |
| // Caller must hold |buffer_handles_lock_|. |
| void RemoveBufferLocked(const camera3_stream_buffer_t& buffer); |
| |
| // Waits until |release_fence| is signaled and then deletes |buffer|. |
| void RemoveBufferOnFenceSyncThread( |
| base::ScopedFD release_fence, |
| std::unique_ptr<camera_buffer_handle_t> buffer); |
| |
| void ReprocessEffectsOnReprocessEffectThread( |
| std::unique_ptr<Camera3CaptureRequest> req); |
| |
| void ProcessReprocessRequestOnDeviceOpsThread( |
| std::unique_ptr<Camera3CaptureRequest> req, |
| base::Callback<void(int32_t)> callback); |
| |
| void NotifyAddedFrameError( |
| camera3_capture_request_t req, |
| std::vector<camera3_stream_buffer_t> output_buffers); |
| |
| void NotifyAddedFrameErrorOnNotifyErrorThread( |
| camera3_capture_request_t req, |
| std::vector<camera3_stream_buffer_t> output_buffers); |
| |
| void ResetDeviceOpsDelegateOnThread(); |
| void ResetCallbackOpsDelegateOnThread(); |
| |
| // The thread that all the camera3 device ops operate on. |
| base::Thread camera_device_ops_thread_; |
| |
| // The thread that all the Mojo communications of camera3 callback ops operate |
| // on. |
| base::Thread camera_callback_ops_thread_; |
| |
| // A thread to asynchronously wait for release fences and destroy |
| // corresponding buffer handles. |
| base::Thread fence_sync_thread_; |
| |
| // A thread to apply reprocessing effects |
| base::Thread reprocess_effect_thread_; |
| |
| // A thread to notify errors in added requests. |
| base::Thread notify_error_thread_; |
| |
| // The delegate that handles the Camera3DeviceOps mojo IPC. |
| std::unique_ptr<Camera3DeviceOpsDelegate> device_ops_delegate_; |
| |
| // The delegate that handles the Camera3CallbackOps mojo IPC. |
| std::unique_ptr<Camera3CallbackOpsDelegate> callback_ops_delegate_; |
| // Lock to protect |callback_ops_delegate_| as it is accessed on multiple |
| // threads. |
| base::Lock callback_ops_delegate_lock_; |
| |
| // The callback to run when the device is closed. |
| base::Callback<void()> close_callback_; |
| |
| // Set when the camera device is closed. No more calls to the device APIs may |
| // be made once |device_closed_| is set. |
| bool device_closed_; |
| |
| // The real camera device. |
| camera3_device_t* camera_device_; |
| |
| // The non-owning read-only view of the static camera characteristics of this |
| // device. |
| const camera_metadata_t* static_info_; |
| |
| // A helper class that includes various functions for the mechanisms of ZSL. |
| ZslHelper zsl_helper_; |
| |
| // The stream configured for ZSL requests. |
| camera3_stream_t* zsl_stream_; |
| |
| // A mapping from Andoird HAL for all the configured streams. |
| internal::ScopedStreams streams_; |
| |
| // A mutex to guard |streams_|. |
| base::Lock streams_lock_; |
| |
| // A mapping from the locally created buffer handle to the handle ID of the |
| // imported buffer. We need to return the correct handle ID in |
| // ProcessCaptureResult so the camera client, which allocated the imported |
| // buffer, can restore the buffer handle in the capture result before passing |
| // up to the upper layer. |
| std::unordered_map<uint64_t, std::unique_ptr<camera_buffer_handle_t>> |
| buffer_handles_; |
| |
| // A mapping that stores all buffer handles that are allocated when streams |
| // are configured locally. When the session is over, all of these handles |
| // should be freed. |
| std::map<uint64_t, buffer_handle_t> allocated_stream_buffers_; |
| |
| // A queue of reprocessing buffers. |
| std::deque<ScopedYUVBufferHandle> reprocess_handles_; |
| |
| // A queue of original input buffer handles replaced by reprocessing ones. |
| std::deque<uint64_t> input_buffer_handle_ids_; |
| |
| // A mapping from the frame number to the result metadata generated by |
| // reprocessing effects |
| std::unordered_map<uint32_t, android::CameraMetadata> |
| reprocess_result_metadata_; |
| |
| // A pending reprocessing request task for HAL to run. |
| base::OnceClosure process_reprocess_request_callback_; |
| base::Lock process_reprocess_request_callback_lock_; |
| |
| // A mutex to guard |buffer_handles_|. |
| base::Lock buffer_handles_lock_; |
| |
| // A mutex to guard |reprocess_handles_| and |input_buffer_handle_ids_|. |
| base::Lock reprocess_handles_lock_; |
| |
| // A mutex to guard |reprocess_result_metadata_|. |
| base::Lock reprocess_result_metadata_lock_; |
| |
| // The callback to check reprocessing effect vendor tags. |
| HasReprocessEffectVendorTagCallback has_reprocess_effect_vendor_tag_callback_; |
| |
| // The callback to handle reprocessing effect. |
| ReprocessEffectCallback reprocess_effect_callback_; |
| |
| // The metadata inspector to dump capture requests / results in realtime |
| // for debugging if enabled. |
| std::unique_ptr<CameraMetadataInspector> camera_metadata_inspector_; |
| |
| // Metrics for camera service. |
| std::unique_ptr<CameraMetrics> camera_metrics_; |
| |
| // Utility for mapping framework and HAL frame numbers. |
| FrameNumberMapper frame_number_mapper_; |
| |
| // ANDROID_PARTIAL_RESULT_COUNT from static metadata. |
| int32_t partial_result_count_; |
| |
| // Monitors for capture requests and capture results. If there is no capture |
| // requests/responses for a while the monitors will output a log to indicate |
| // this situation. |
| CameraMonitor capture_request_monitor_; |
| CameraMonitor capture_result_monitor_; |
| |
| DISALLOW_IMPLICIT_CONSTRUCTORS(CameraDeviceAdapter); |
| }; |
| |
| } // namespace cros |
| |
| #endif // CAMERA_HAL_ADAPTER_CAMERA_DEVICE_ADAPTER_H_ |