| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_CAMERA_DEVICE__SESSION_H_ |
| #define HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_CAMERA_DEVICE__SESSION_H_ |
| |
| #include <android/hardware/graphics/mapper/2.0/IMapper.h> |
| #include <android/hardware/graphics/mapper/3.0/IMapper.h> |
| #include <android/hardware/graphics/mapper/4.0/IMapper.h> |
| |
| #include <memory> |
| #include <set> |
| #include <shared_mutex> |
| #include <vector> |
| |
| #include "camera_buffer_allocator_hwl.h" |
| #include "camera_device_session_hwl.h" |
| #include "capture_session.h" |
| #include "capture_session_utils.h" |
| #include "hal_camera_metadata.h" |
| #include "hal_types.h" |
| #include "hwl_types.h" |
| #include "pending_requests_tracker.h" |
| #include "stream_buffer_cache_manager.h" |
| #include "thermal_types.h" |
| #include "zoom_ratio_mapper.h" |
| |
| namespace android { |
| namespace google_camera_hal { |
| |
| // Defines callbacks to be invoked by a CameraDeviceSession. |
| struct CameraDeviceSessionCallback { |
| // Callback to notify when a camera device produces a capture result. |
| ProcessCaptureResultFunc process_capture_result; |
| |
| // Callback to notify shutters or errors. |
| NotifyFunc notify; |
| |
| // Callback to request stream buffers. |
| RequestStreamBuffersFunc request_stream_buffers; |
| |
| // Callback to return stream buffers. |
| ReturnStreamBuffersFunc return_stream_buffers; |
| }; |
| |
| // Defines callbacks to get thermal information. |
| struct ThermalCallback { |
| // Register a thermal changed callback. |
| RegisterThermalChangedCallbackFunc register_thermal_changed_callback; |
| |
| // Unregister the thermal changed callback. |
| UnregisterThermalChangedCallbackFunc unregister_thermal_changed_callback; |
| }; |
| |
| // Entry point for getting an external capture session. |
| using GetCaptureSessionFactoryFunc = ExternalCaptureSessionFactory* (*)(); |
| |
| // CameraDeviceSession implements functions needed for the HIDL camera device |
| // session interface, ICameraDeviceSession. It contains the methods to configure |
| // and request captures from an active camera device. |
| class CameraDeviceSession { |
| public: |
| // Create a CameraDeviceSession. |
| // device_session_hwl is a CameraDeviceSessionHwl that will be managed by this |
| // class. |
| // If device_session_hwl is nullptr, this method will return nullptr. |
| // camera_allocator_hwl is owned by the caller and must be valid during the |
| // lifetime of CameraDeviceSession |
| static std::unique_ptr<CameraDeviceSession> Create( |
| std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl, |
| std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries, |
| CameraBufferAllocatorHwl* camera_allocator_hwl = nullptr); |
| |
| virtual ~CameraDeviceSession(); |
| |
| // Set session callbacks |
| // Must be called before ConfigureStreams(). |
| // session_callback will be invoked for capture results and messages. |
| // thermal_callback will be invoked for getting thermal information. |
| void SetSessionCallback(const CameraDeviceSessionCallback& session_callback, |
| const ThermalCallback& thermal_callback); |
| |
| // Construct the default request settings for a request template type. |
| status_t ConstructDefaultRequestSettings( |
| RequestTemplate type, |
| std::unique_ptr<HalCameraMetadata>* default_settings); |
| |
| // Configure streams. |
| // stream_config is the requested stream configuration. |
| // hal_configured_streams is filled by this method with configured stream. |
| status_t ConfigureStreams(const StreamConfiguration& stream_config, |
| std::vector<HalStream>* hal_configured_streams); |
| |
| // Process a capture request. |
| // num_processed_requests is filled by this method with the number of |
| // processed requests. |
| status_t ProcessCaptureRequest(const std::vector<CaptureRequest>& requests, |
| uint32_t* num_processed_requests); |
| |
| // Remove the buffer caches kept in the camera device session. |
| void RemoveBufferCache(const std::vector<BufferCache>& buffer_caches); |
| |
| // Flush all pending requests. |
| status_t Flush(); |
| |
| // Check reconfiguration is required or not |
| // old_session is old session parameter |
| // new_session is new session parameter |
| // If reconfiguration is required, set reconfiguration_required to true |
| // If reconfiguration is not required, set reconfiguration_required to false |
| status_t IsReconfigurationRequired(const HalCameraMetadata* old_session, |
| const HalCameraMetadata* new_session, |
| bool* reconfiguration_required); |
| |
| std::unique_ptr<google::camera_common::Profiler> GetProfiler(uint32_t camere_id, |
| int option); |
| |
| protected: |
| CameraDeviceSession() = default; |
| |
| private: |
| // Define buffer cache hashing in order to use BufferCache as a key of an |
| // unordered map. |
| struct BufferCacheHashing { |
| unsigned long operator()(const BufferCache& buffer_cache) const { |
| std::string s = "s" + std::to_string(buffer_cache.stream_id) + "b" + |
| std::to_string(buffer_cache.buffer_id); |
| return std::hash<std::string>{}(s); |
| } |
| }; |
| |
| status_t Initialize( |
| std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl, |
| CameraBufferAllocatorHwl* camera_allocator_hwl, |
| std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries); |
| |
| // Initialize the latest available gralloc buffer mapper. |
| status_t InitializeBufferMapper(); |
| |
| // Initialize callbacks from HWL and callbacks to the client. |
| void InitializeCallbacks(); |
| |
| // Initialize buffer management support. |
| status_t InitializeBufferManagement(HalCameraMetadata* characteristics); |
| |
| // Update all buffer handles in buffers with the imported buffer handles. |
| // Must be protected by imported_buffer_handle_map_lock_. |
| status_t UpdateBufferHandlesLocked(std::vector<StreamBuffer>* buffers); |
| |
| // Import the buffer handles in the request. |
| status_t ImportRequestBufferHandles(const CaptureRequest& request); |
| |
| // Import the buffer handles of buffers. |
| status_t ImportBufferHandles(const std::vector<StreamBuffer>& buffers); |
| |
| // Import the buffer handle of a buffer. |
| // Must be protected by imported_buffer_handle_map_lock_. |
| template <class T, class U> |
| status_t ImportBufferHandleLocked(const sp<T> buffer_mapper, |
| const StreamBuffer& buffer); |
| |
| // Create a request with updated buffer handles and modified settings. |
| // Must be protected by session_lock_. |
| status_t CreateCaptureRequestLocked(const CaptureRequest& request, |
| CaptureRequest* updated_request); |
| |
| // Add a buffer handle to the imported buffer handle map. If the buffer cache |
| // is already in the map but the buffer handle doesn't match, it will |
| // return BAD_VALUE. |
| // Must be protected by imported_buffer_handle_map_lock_. |
| status_t AddImportedBufferHandlesLocked(const BufferCache& buffer_cache, |
| buffer_handle_t buffer_handle); |
| |
| // Return if the buffer handle for a certain buffer ID is imported. |
| // Must be protected by imported_buffer_handle_map_lock_. |
| bool IsBufferImportedLocked(int32_t stream_id, uint32_t buffer_id); |
| |
| // Free all imported buffer handles belonging to the stream id. |
| // Must be protected by imported_buffer_handle_map_lock_. |
| template <class T> |
| void FreeBufferHandlesLocked(const sp<T> buffer_mapper, int32_t stream_id); |
| |
| template <class T> |
| void FreeImportedBufferHandles(const sp<T> buffer_mapper); |
| |
| // Clean up stale streams with new stream configuration. |
| // Must be protected by session_lock_. |
| void CleanupStaleStreamsLocked(const std::vector<Stream>& new_streams); |
| |
| // Append output intent to request settings. |
| // Must be protected by session_lock_. |
| void AppendOutputIntentToSettingsLocked(const CaptureRequest& request, |
| CaptureRequest* updated_request); |
| |
| // Invoked by HWL to request stream buffers when buffer management is |
| // supported. |
| status_t RequestStreamBuffers(int32_t stream_id, uint32_t num_buffers, |
| std::vector<StreamBuffer>* buffers, |
| StreamBufferRequestError* request_status); |
| |
| // Invoked by HWL to return stream buffers when buffer management is |
| // supported. |
| void ReturnStreamBuffers(const std::vector<StreamBuffer>& buffers); |
| |
| // Update imported buffer handle map for the requested buffers and update |
| // the buffer handle in requested buffers. |
| status_t UpdateRequestedBufferHandles(std::vector<StreamBuffer>* buffers); |
| |
| // Request buffers from stream buffer cache manager |
| status_t RequestBuffersFromStreamBufferCacheManager( |
| int32_t stream_id, uint32_t num_buffers, |
| std::vector<StreamBuffer>* buffers, uint32_t frame_number); |
| |
| // Register configured streams into stream buffer cache manager |
| status_t RegisterStreamsIntoCacheManagerLocked( |
| const StreamConfiguration& stream_config, |
| const std::vector<HalStream>& hal_stream); |
| |
| // Update the inflight requests/streams and notify SBC for flushing if the |
| // inflight requests/streams map is empty. |
| status_t UpdatePendingRequest(CaptureResult* result); |
| |
| // Process the notification returned from the HWL |
| void Notify(const NotifyMessage& result); |
| |
| // Process the capture result returned from the HWL |
| void ProcessCaptureResult(std::unique_ptr<CaptureResult> result); |
| |
| // Notify error message with error code for stream of frame[frame_number]. |
| // Caller is responsible to make sure this function is called only once for any frame. |
| void NotifyErrorMessage(uint32_t frame_number, int32_t stream_id, |
| ErrorCode error_code); |
| |
| // Notify buffer error for all output streams in request |
| void NotifyBufferError(const CaptureRequest& request); |
| |
| // Notify buffer error for stream_id in frame_number |
| void NotifyBufferError(uint32_t frame_number, int32_t stream_id, |
| uint64_t buffer_id); |
| |
| // Try to check if result contains dummy buffer or dummy buffer from this |
| // result has been observed. If so, handle this result specifically. Set |
| // result_handled as true. |
| status_t TryHandleDummyResult(CaptureResult* result, bool* result_handled); |
| |
| // Check if all streams in the current session are active in SBC manager |
| status_t HandleInactiveStreams(const CaptureRequest& request, |
| bool* all_active); |
| |
| // Check the capture request before sending it to HWL. Only needed when HAL |
| // Buffer Management is supported. The SBC manager determines if it is |
| // necessasry to process the request still by checking if all streams are |
| // still active for buffer requests. |
| void CheckRequestForStreamBufferCacheManager(const CaptureRequest& request, |
| bool* need_to_process); |
| |
| // Return true if a request is valid. Must be exclusively protected by |
| // session_lock_. |
| status_t ValidateRequestLocked(const CaptureRequest& request); |
| |
| // Invoked when thermal status changes. |
| void NotifyThrottling(const Temperature& temperature); |
| |
| // Unregister thermal callback. |
| void UnregisterThermalCallback(); |
| |
| // Load HAL external capture session libraries. |
| status_t LoadExternalCaptureSession( |
| std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries); |
| |
| void InitializeZoomRatioMapper(HalCameraMetadata* characteristics); |
| |
| // For all the stream ID groups, derive the mapping between all stream IDs |
| // within that group to one single stream ID for easier tracking. |
| void DeriveGroupedStreamIdMap(); |
| |
| uint32_t camera_id_ = 0; |
| std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl_; |
| |
| // Graphics buffer mapper used to import and free buffers. |
| sp<android::hardware::graphics::mapper::V2_0::IMapper> buffer_mapper_v2_; |
| sp<android::hardware::graphics::mapper::V3_0::IMapper> buffer_mapper_v3_; |
| sp<android::hardware::graphics::mapper::V4_0::IMapper> buffer_mapper_v4_; |
| |
| // Assuming callbacks to framework is thread-safe, the shared mutex is only |
| // used to protect member variable writing and reading. |
| std::shared_mutex session_callback_lock_; |
| // Session callback to the client. Protected by session_callback_lock_ |
| CameraDeviceSessionCallback session_callback_; |
| |
| // Camera Device Session callback to the camera device session. Protected by |
| // session_callback_lock_ |
| CameraDeviceSessionCallback camera_device_session_callback_; |
| |
| // Callback to get thermal information. Protected by session_callback_lock_. |
| ThermalCallback thermal_callback_; |
| |
| // Session callback from HWL session. Protected by session_callback_lock_ |
| HwlSessionCallback hwl_session_callback_; |
| |
| // imported_buffer_handle_map_lock_ protects the following variables as noted. |
| std::mutex imported_buffer_handle_map_lock_; |
| |
| // Store the imported buffer handles from camera framework. Protected by |
| // imported_buffer_handle_map_lock. |
| std::unordered_map<BufferCache, buffer_handle_t, BufferCacheHashing> |
| imported_buffer_handle_map_; |
| |
| // session_lock_ protects the following variables as noted. |
| std::mutex session_lock_; |
| |
| // capture_session_lock_ protects the following variables as noted. |
| std::shared_mutex capture_session_lock_; |
| |
| std::unique_ptr<CaptureSession> |
| capture_session_; // Protected by capture_session_lock_. |
| |
| // Map from a stream ID to the configured stream received from frameworks. |
| // Protected by session_lock_. |
| std::unordered_map<int32_t, Stream> configured_streams_map_; |
| |
| // Map from all stream IDs within a stream group to one single stream ID for |
| // easier request/buffer tracking. For example, if a stream group contains 3 |
| // streams: {1, 2, 3}, The mapping could be {2->1, 3->1}. All requests and |
| // buffers for stream 2 and stream 3 will be mapped to stream 1 for tracking. |
| std::unordered_map<int32_t, int32_t> grouped_stream_id_map_; |
| |
| // Last valid settings in capture request. Must be protected by session_lock_. |
| std::unique_ptr<HalCameraMetadata> last_request_settings_; |
| |
| // If thermal status has become >= ThrottlingSeverity::Severe since stream |
| // configuration. |
| // Must be protected by session_lock_. |
| uint8_t thermal_throttling_ = false; |
| |
| // If device session has notified capture session about thermal throttling. |
| // Must be protected by session_lock_. |
| bool thermal_throttling_notified_ = false; |
| |
| // Predefined wrapper capture session entry points |
| static std::vector<WrapperCaptureSessionEntryFuncs> kWrapperCaptureSessionEntries; |
| |
| // Predefined capture session entry points |
| static std::vector<CaptureSessionEntryFuncs> kCaptureSessionEntries; |
| |
| // External capture session entry points |
| std::vector<ExternalCaptureSessionFactory*> external_capture_session_entries_; |
| |
| // Opened library handles that should be closed on destruction |
| std::vector<void*> external_capture_session_lib_handles_; |
| |
| // hwl allocator |
| CameraBufferAllocatorHwl* camera_allocator_hwl_ = nullptr; |
| |
| // If buffer management API support. |
| bool buffer_management_supported_ = false; |
| |
| // Pending requests tracker used when buffer management API is enabled. |
| // Protected by session_lock_. |
| std::unique_ptr<PendingRequestsTracker> pending_requests_tracker_; |
| |
| // Stream buffer cache manager supports the HAL Buffer Management by caching |
| // buffers acquired from framework |
| std::unique_ptr<StreamBufferCacheManager> stream_buffer_cache_manager_; |
| |
| // If we receives valid settings since stream configuration. |
| // Protected by session_lock_. |
| bool has_valid_settings_ = false; |
| |
| // If the previous output intent had a stream with video encoder usage. |
| bool prev_output_intent_has_video_ = false; |
| |
| // request_record_lock_ protects the following variables as noted |
| std::mutex request_record_lock_; |
| |
| // Map from frame number to a set of stream ids, which exist in |
| // request[frame number] |
| // Protected by request_record_lock_; |
| std::map<uint32_t, std::set<int32_t>> pending_request_streams_; |
| |
| // Set of requests that have been notified for ERROR_REQUEST during buffer |
| // request stage. |
| // Protected by request_record_lock_; |
| std::set<uint32_t> error_notified_requests_; |
| |
| // Set of dummy buffer observed |
| std::set<buffer_handle_t> dummy_buffer_observed_; |
| |
| // The last shutter timestamp in nanoseconds if systrace is enabled. Reset |
| // after stream configuration. |
| int64_t last_timestamp_ns_for_trace_ = 0; |
| |
| // Operation mode of stream configuration |
| StreamConfigurationMode operation_mode_ = StreamConfigurationMode::kNormal; |
| |
| // Whether this stream configuration is a multi-res reprocessing configuration |
| bool multi_res_reprocess_ = false; |
| |
| // Flush is running or not |
| std::atomic<bool> is_flushing_ = false; |
| |
| // Zoom ratio mapper |
| ZoomRatioMapper zoom_ratio_mapper_; |
| |
| // Record the result metadata of pending request |
| // Protected by request_record_lock_; |
| std::set<uint32_t> pending_results_; |
| |
| // Record the shutters need to ignore for error result case |
| // Protected by request_record_lock_; |
| std::set<uint32_t> ignore_shutters_; |
| |
| // Stream use cases supported by this camera device |
| std::set<int64_t> stream_use_cases_; |
| |
| static constexpr int32_t kInvalidStreamId = -1; |
| |
| // Whether measure the time of buffer allocation |
| bool measure_buffer_allocation_time_ = false; |
| }; |
| |
| } // namespace google_camera_hal |
| } // namespace android |
| |
| #endif // HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_CAMERA_DEVICE__SESSION_H_ |