| // Copyright 2017 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_CAMERA3_TEST_CAMERA3_SERVICE_H_ |
| #define CAMERA_CAMERA3_TEST_CAMERA3_SERVICE_H_ |
| |
| #include <semaphore.h> |
| |
| #include <list> |
| #include <memory> |
| #include <unordered_map> |
| #include <unordered_set> |
| #include <utility> |
| #include <vector> |
| |
| #include "camera3_test/camera3_device_fixture.h" |
| |
| namespace camera3_test { |
| |
| const int32_t kNumberOfOutputStreamBuffers = 3; |
| const int32_t kPreviewOutputStreamIdx = 0; |
| const int32_t kRecordingOutputStreamIdx = 1; |
| // The still capture output stream can be at index 1 or 2, depending on whether |
| // there is video recording. |
| enum { PREVIEW_STOPPED, PREVIEW_STARTING, PREVIEW_STARTED, PREVIEW_STOPPING }; |
| #define INCREASE_INDEX(idx) \ |
| (idx) = (idx == number_of_capture_requests_ - 1) ? 0 : (idx) + 1 |
| |
| struct MetadataKeyValue { |
| int32_t key; |
| const void* data; |
| size_t data_count; |
| MetadataKeyValue(int32_t k, const void* d, size_t c) |
| : key(k), data(d), data_count(c) {} |
| }; |
| |
| class Camera3Service { |
| public: |
| explicit Camera3Service(std::vector<int> cam_ids) |
| : cam_ids_(cam_ids), initialized_(false) {} |
| |
| ~Camera3Service(); |
| |
| typedef base::Callback<void(int cam_id, |
| uint32_t frame_number, |
| ScopedCameraMetadata metadata, |
| cros::ScopedBufferHandle buffer)> |
| ProcessStillCaptureResultCallback; |
| |
| typedef base::Callback<void( |
| int cam_id, uint32_t frame_number, ScopedCameraMetadata metadata)> |
| ProcessRecordingResultCallback; |
| |
| typedef base::Callback<void( |
| int cam_id, uint32_t frame_number, ScopedCameraMetadata metadata)> |
| ProcessPreviewResultCallback; |
| |
| // Initialize service and corresponding devices and register processing |
| // still capture and recording result callback |
| int Initialize( |
| ProcessStillCaptureResultCallback still_capture_cb, |
| ProcessRecordingResultCallback recording_cb, |
| ProcessPreviewResultCallback preview_cb = ProcessPreviewResultCallback()); |
| |
| // Destroy service and corresponding devices |
| void Destroy(); |
| |
| // Start camera preview with given preview resolution |preview_resolution| |
| // Set the width of |still_capture_resolution| or |recording_resolution| to 0 |
| // if taking still pictures or recording is not needed. |
| int StartPreview(int cam_id, |
| const ResolutionInfo& preview_resolution, |
| const ResolutionInfo& still_capture_resolution, |
| const ResolutionInfo& recording_resolution); |
| |
| // Stop camera preview |
| void StopPreview(int cam_id); |
| |
| // Start auto focus |
| void StartAutoFocus(int cam_id); |
| |
| // Wait for auto focus done |
| int WaitForAutoFocusDone(int cam_id); |
| |
| // Wait for AWB converged and lock AWB |
| int WaitForAWBConvergedAndLock(int cam_id); |
| |
| // Start AE precapture |
| void StartAEPrecapture(int cam_id); |
| |
| // Wait for AE stable |
| int WaitForAEStable(int cam_id); |
| |
| // Start Face detection |
| void StartFaceDetection(int cam_id); |
| |
| // Stop Face detection |
| void StopFaceDetection(int cam_id); |
| |
| // Take still capture with settings |metadata| |
| void TakeStillCapture(int cam_id, const camera_metadata_t* metadata); |
| |
| // Start recording |
| int StartRecording(int cam_id, const camera_metadata_t* metadata); |
| |
| // Stop recording |
| void StopRecording(int cam_id); |
| |
| // Wait for |num_frames| number of preview frames with |timeout_ms| |
| // milliseconds of timeout for each frame. |
| int WaitForPreviewFrames(int cam_id, |
| uint32_t num_frames, |
| uint32_t timeout_ms); |
| |
| // Get device static information |
| const Camera3Device::StaticInfo* GetStaticInfo(int cam_id); |
| |
| // Get device default request settings |
| const camera_metadata_t* ConstructDefaultRequestSettings(int cam_id, |
| int type); |
| |
| private: |
| std::vector<int> cam_ids_; |
| |
| base::Lock lock_; |
| |
| bool initialized_; |
| |
| class Camera3DeviceService; |
| std::unordered_map<int, std::unique_ptr<Camera3DeviceService>> |
| cam_dev_service_map_; |
| |
| DISALLOW_IMPLICIT_CONSTRUCTORS(Camera3Service); |
| }; |
| |
| class Camera3Service::Camera3DeviceService { |
| public: |
| Camera3DeviceService(int cam_id, |
| ProcessStillCaptureResultCallback still_capture_cb, |
| ProcessRecordingResultCallback recording_cb, |
| ProcessPreviewResultCallback preview_cb) |
| : cam_id_(cam_id), |
| cam_device_(cam_id), |
| service_thread_("Camera3 Test Service Thread"), |
| process_still_capture_result_cb_(still_capture_cb), |
| process_recording_result_cb_(recording_cb), |
| process_preview_result_cb_(preview_cb), |
| preview_state_(PREVIEW_STOPPED), |
| number_of_capture_requests_(0), |
| number_of_in_flight_requests_(0), |
| still_capture_metadata_(nullptr), |
| recording_metadata_(nullptr) {} |
| |
| int Initialize(); |
| |
| void Destroy(); |
| |
| // Start camera preview with given preview resolution |preview_resolution| |
| // Set the width of |still_capture_resolution| or |recording_resolution| to 0 |
| // if taking still pictures or recording is not needed. |
| int StartPreview(const ResolutionInfo& preview_resolution, |
| const ResolutionInfo& still_capture_resolution, |
| const ResolutionInfo& recording_resolution); |
| |
| // Stop camera preview |
| void StopPreview(); |
| |
| // Start auto focus |
| void StartAutoFocus(); |
| |
| // Wait for auto focus done |
| int WaitForAutoFocusDone(); |
| |
| // Wait for AWB converged and lock AWB |
| int WaitForAWBConvergedAndLock(); |
| |
| // Start AE precapture |
| void StartAEPrecapture(); |
| |
| // Wait for AE stable |
| int WaitForAEStable(); |
| |
| // Start Face Detection |
| void StartFaceDetection(); |
| |
| // Stopt Face Detection |
| void StopFaceDetection(); |
| |
| // Take still capture with settings |metadata| |
| void TakeStillCapture(const camera_metadata_t* metadata); |
| |
| // Start recording |
| int StartRecording(const camera_metadata_t* metadata); |
| |
| // Stop recording |
| void StopRecording(); |
| |
| // Wait for |num_frames| number of preview frames with |timeout_ms| |
| // milliseconds of timeout for each frame. |
| int WaitForPreviewFrames(uint32_t num_frames, uint32_t timeout_ms); |
| |
| // Get static information |
| const Camera3Device::StaticInfo* GetStaticInfo() const; |
| |
| // Get default request settings |
| const camera_metadata_t* ConstructDefaultRequestSettings(int type); |
| |
| private: |
| // Process result metadata and output buffers |
| void ProcessResultMetadataOutputBuffers( |
| uint32_t frame_number, |
| ScopedCameraMetadata metadata, |
| std::vector<cros::ScopedBufferHandle> buffers); |
| |
| void StartPreviewOnServiceThread(ResolutionInfo preview_resolution, |
| ResolutionInfo still_capture_resolution, |
| ResolutionInfo recording_resolution, |
| int* result); |
| |
| void StartAutoFocusOnServiceThread(); |
| |
| void StopPreviewOnServiceThread(base::Callback<void()> cb); |
| |
| void AddMetadataListenerOnServiceThread(int32_t key, |
| std::unordered_set<int32_t> values, |
| base::Callback<void()> cb, |
| int32_t* result); |
| |
| void DeleteMetadataListenerOnServiceThread( |
| int32_t key, std::unordered_set<int32_t> values); |
| |
| void LockAWBOnServiceThread(); |
| |
| void StartAEPrecaptureOnServiceThread(); |
| |
| void StartFaceDetectionOnServiceThread(); |
| |
| void StopFaceDetectionOnServiceThread(); |
| |
| void TakeStillCaptureOnServiceThread(const camera_metadata_t* metadata, |
| base::Callback<void()> cb); |
| |
| void StartRecordingOnServiceThread(const camera_metadata_t* metadata, |
| base::Callback<void(int)> cb); |
| |
| void StopRecordingOnServiceThread(base::Callback<void()> cb); |
| |
| // This function can be called by PrepareStillCaptureAndStartPreview() or |
| // ProcessResultMetadataOutputBuffers() to process one preview request. |
| // It will check whether there was a still capture request or preview |
| // repeating/one-shot setting changes and construct the capture request |
| // accordingly. |
| void ProcessPreviewRequestOnServiceThread(); |
| |
| void ProcessResultMetadataOutputBuffersOnServiceThread( |
| uint32_t frame_number, |
| ScopedCameraMetadata metadata, |
| std::vector<cros::ScopedBufferHandle> buffers); |
| |
| int cam_id_; |
| |
| Camera3Device cam_device_; |
| |
| cros::CameraThread service_thread_; |
| |
| ProcessStillCaptureResultCallback process_still_capture_result_cb_; |
| |
| ProcessRecordingResultCallback process_recording_result_cb_; |
| |
| ProcessPreviewResultCallback process_preview_result_cb_; |
| |
| int32_t preview_state_; |
| |
| base::Callback<void()> stop_preview_cb_; |
| |
| std::vector<const camera3_stream_t*> streams_; |
| |
| uint32_t number_of_capture_requests_; |
| |
| // Keep |number_of_capture_requests_| number of capture request and a boolean |
| // indicating whether it is used (in the pipeline) or not |
| std::vector<std::pair<camera3_capture_request_t, bool>> capture_requests_; |
| |
| // Keep track of two stream buffers for each capture request. The preview |
| // buffer is at index 0 while still capture one at index 1. |
| std::vector<std::vector<camera3_stream_buffer_t>> output_stream_buffers_; |
| |
| // Number of capture requests that are being processed by HAL |
| size_t number_of_in_flight_requests_; |
| |
| // Metadata for repeating preview requests |
| ScopedCameraMetadata repeating_preview_metadata_; |
| |
| // Metadata for one-shot preview requests. It can be used to trigger AE |
| // precapture and auto focus. |
| ScopedCameraMetadata oneshot_preview_metadata_; |
| |
| // Metadata for still capture requests |
| const camera_metadata_t* still_capture_metadata_; |
| |
| base::Callback<void()> still_capture_cb_; |
| |
| // Metadata for recording requests |
| const camera_metadata_t* recording_metadata_; |
| |
| base::Callback<void()> stop_recording_cb_; |
| |
| struct MetadataListener { |
| int32_t key; |
| std::unordered_set<int32_t> values; |
| base::Callback<void()> cb; |
| int32_t* result; |
| MetadataListener(int32_t k, |
| const std::unordered_set<int32_t>& v, |
| base::Callback<void()> c, |
| int32_t* r) |
| : key(k), values(v), cb(c), result(r) {} |
| }; |
| |
| std::list<MetadataListener> metadata_listener_list_; |
| |
| sem_t preview_frame_sem_; |
| |
| DISALLOW_IMPLICIT_CONSTRUCTORS(Camera3DeviceService); |
| }; |
| |
| } // namespace camera3_test |
| |
| #endif // CAMERA_CAMERA3_TEST_CAMERA3_SERVICE_H_ |