/* * Copyright (c) 2021 by Allwinnertech Co., Ltd. * * 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 V4L2_CAMERA_HAL_V4L2_CAMERA_H_ #define V4L2_CAMERA_HAL_V4L2_CAMERA_H_ #include "common.h" #ifdef LOG_NDEBUG #undef LOG_NDEBUG #endif #if DBG_V4L2_CAMERA #undef NDEBUG #define LOG_NDEBUG 0 #else #define LOG_NDEBUG 1 #endif #include #include #include #include #include #include #include #include #include #include #include #include "CameraMetadata.h" #include "camera.h" #include "metadata/metadata.h" #include "v4l2_wrapper.h" #include "camera_stream.h" #include "stream_manager.h" #include "camera_config.h" #define IS_USAGE_VIDEO(usage) (((usage) & (GRALLOC_USAGE_HW_VIDEO_ENCODER)) \ == GRALLOC_USAGE_HW_VIDEO_ENCODER) #define IS_USAGE_PREVIEW(usage) (((usage) & (GRALLOC_USAGE_HW_TEXTURE)) \ == GRALLOC_USAGE_HW_TEXTURE) #define IS_USAGE_ZSL(usage) (((usage) & (GRALLOC_USAGE_HW_CAMERA_ZSL)) \ == (GRALLOC_USAGE_HW_CAMERA_ZSL)) namespace v4l2_camera_hal { class StreamManager; class CameraStream; // V4L2Camera is a specific V4L2-supported camera device. The Camera object // contains all logic common between all cameras (e.g. front and back cameras), // while a specific camera device (e.g. V4L2Camera) holds all specific // metadata and logic about that device. class V4L2Camera : public default_camera_hal::Camera { friend class CameraStream; friend class StreamManager; public: // Use this method to create V4L2Camera objects. Functionally equivalent // to "new V4L2Camera", except that it may return nullptr in case of failure. static V4L2Camera* NewV4L2Camera(int id, std::shared_ptr pCameraCfg); int setFlashTorchMode(bool enabled); int closeFlashTorch(); ~V4L2Camera(); private: std::shared_ptr instance; // Constructor private to allow failing on bad input. // Use NewV4L2Camera instead. std::shared_ptr mCameraConfig; V4L2Camera(int id, std::shared_ptr v4l2_wrapper, std::unique_ptr metadata, std::shared_ptr pCameraCfg); // default_camera_hal::Camera virtual methods. // Connect to the device: open dev nodes, etc. int connect() override; // Disconnect from the device: close dev nodes, etc. void disconnect() override; // Initialize static camera characteristics for individual device. int initStaticInfo(CameraMetadata* out) override; // Initialize a template of the given type. int initTemplate(int type, CameraMetadata* out) override; // Initialize device info: resource cost and conflicting devices // (/conflicting devices length). void initDeviceInfo(camera_info_t* info) override; // Extra initialization of device when opened. int initDevice() override; // Verify stream configuration dataspaces and rotation values bool validateDataspacesAndRotations( const camera3_stream_configuration_t* stream_config) override; // Set up the streams, including seting usage & max_buffers int setupStreams(camera3_stream_configuration_t* stream_config) override; // Verify settings are valid for a capture or reprocessing. bool isValidRequestSettings(const CameraMetadata& settings) override; // Enqueue a request to receive data from the camera. int enqueueRequest( std::shared_ptr request) override; // Flush in flight buffers. int flushBuffers() override; int flushRequests(int err); int flushRequestsForCTS(int err); // Async request processing helpers. // Dequeue a request from the waiting queue. // Blocks until a request is available. std::shared_ptr dequeueRequest(); // Thread functions. Return true to loop, false to exit. // Pass buffers for enqueued requests to the device. bool enqueuePreviewBuffers(); // Retreive buffers from the device. bool dequeuePreviewBuffers(); bool enqueuePictureBuffers(); bool dequeuePictureBuffers(); bool slowThread(); bool enqueueThread(); bool dequeueThread(); void ReadyForBuffer(); bool previewThread(); bool pictureThread(); bool mainThread(); bool subThread(); int sResultCallback(uint32_t frameNumber, struct timeval UNUSED(ts)); // Tools for detect main stream. int max(std::vector vec); int min(std::vector vec); int maxHeight(camera3_stream_t ** streams, int num); int maxWidth(camera3_stream_t ** streams, int num); int fillStreamInfo(camera3_stream_t * stream); int findStreamModes(STREAM_SERIAL stream_serial, camera3_stream_configuration_t* stream_config); int findStreamModes(STREAM_SERIAL stream_serial, camera3_stream_configuration_t* stream_config, int *isBlob); void updateActiveArray(CameraMetadata *camera_meta_data, uint32_t tag); // V4L2 helper. std::shared_ptr device_; std::shared_ptr device_main_channel_; std::shared_ptr device_sub_channel_; std::unique_ptr connection_; int device_id_; enum SituationMode { INIT = 0, BEFORE_PREVIEW, AFTER_PREVIEW, BEFORE_PICTURE, AFTER_PICTURE, BEFORE_VIDEO, AFTER_VIDEO }; SituationMode mgSituationMode; std::unique_ptr metadata_; CameraMetadata* mMetadata; std::mutex in_flight_lock_; // Maps buffer index : request. std::unordered_map> in_flight_; // Threads require holding an Android strong pointer. android::sp buffer_preview_enqueuer_; android::sp buffer_preview_dequeuer_; // Threads require holding an Android strong pointer. android::sp buffer_picture_enqueuer_; android::sp buffer_picture_dequeuer_; // Threads require holding an Android strong pointer. android::sp buffer_preview_thread_; android::sp buffer_picture_thread_; android::sp main_stream_thread_; android::sp sub_stream_thread_; android::sp one_slow_thread_; android::sp multi_enqueue_thread_; android::sp multi_dequeue_thread_; int camera_fd; std::mutex camera_fd_lock_; int in_flight_buffer_count; std::condition_variable buffers_in_flight_; std::condition_variable tbuffers_in_flight_; bool buffers_in_flight_flag_; int32_t max_input_streams_; std::array max_output_streams_; // {raw, non-stalling, stalling}. // Map stream format : camera3_stream_t* about that stream. std::unordered_map mStreamlistMap; std::shared_ptr mStreamm; std::shared_ptr mStreams; std::shared_ptr mWrapper; std::shared_ptr connection[MAX_STREAM]; typedef enum { CAM_FLASH_MODE_OFF, CAM_FLASH_MODE_AUTO, CAM_FLASH_MODE_ON, CAM_FLASH_MODE_TORCH, CAM_FLASH_MODE_SINGLE, CAM_FLASH_MODE_VIDEO_OFF, CAM_FLASH_MODE_MAX } CameraFlashModeE; typedef enum { CAM_FLASH_STATE_UNAVAILABLE, CAM_FLASH_STATE_CHARGINT, CAM_FLASH_STATE_READY, CAM_FLASH_STATE_FIRED, CAM_FLASH_STATE_PARTIAL, CAM_FLASH_STATE_MAX } CameraFlashStateE; typedef struct { int32_t focus_frame_num; int32_t focused_times; int32_t focus_status; int32_t update_status; int32_t status_flag; int32_t update_status_times; cam_focus_mode_t camera_focus_mode; cam_focus_trigger_t camera_focus_trigger; } cam_focus_impl; enum RequestMode { PREVIEW_MODE = 0, RUN_PREVIEW_MODE, PICTURE_MODE, VIDEO_MODE, VIDEO_SNAP_SHOT_MODE, RUN_VIDEO_MODE, ERROR_MODE }; enum BuffersStatus { INIT_BUFFER = 0, PREPARE_BUFFER }; struct { BuffersStatus pbuffers; BuffersStatus tbuffers; BuffersStatus vbuffers; }mBeffer_status; enum StreamStatus { CLOSE_STREAM = 0, OPEN_STREAM }; struct { StreamStatus pstream; StreamStatus tstream; StreamStatus vstream; }mStream_status; enum StreamIedex { PSTREAM = 0, TSTREAM, VSTREAM, VHSTREAM, ESTREAM }; typedef RequestMode typeRequestMode; int FlashStatusFlag; int MarkFrameNum; std::mutex flash_status_lock_; std::mutex auto_focus_lock_; int ProbeFlashMode(CameraFlashModeE* camera_flash_mode, CameraMetadata* camera_meta_data, int* set_flash_flag, int frame_number); int ProcessFocusMode(CameraMetadata* camera_meta_data, int frame_number); int ProcessCropRegion(CameraMetadata* camera_meta_data, CameraStream* camera_stream); void convertFromRegions(cam_area_t* roi, const CameraMetadata &frame_settings, uint32_t tag); int analysisStreamNum( std::shared_ptr request, RequestMode mRequestMode); RequestMode analysisRequest( std::shared_ptr request); StreamIedex analysisStreamModes( camera3_stream_t* stream); int updateStatus(SituationMode mSituationMode); SituationMode getStatus(); bool mPicOnly; bool mVideoOnly; bool mVideoflag; int mTimeOutCount; int mRunStreamNum; bool isVideoSnap; // For steam on & stream off. std::shared_ptr stream_lock_; // Map stream format : camera3_stream_t* about that stream format. std::unordered_map mStreamFormatMap; // Map frameNumber: refcnt about the buffer. std::mutex frameNumber_request_lock_; std::unordered_map> mMapFrameNumRequest; CameraFlashStateE curFlashStateE; CameraFlashModeE curFlashModeE; CameraStream* mCameraStream[MAX_STREAM]; cam_focus_impl camFocusImpl; cam_area_t camAreaRoi; cam_crop_rect_t camCropRect; std::queue> rfequest_queue_stream_; std::queue> wfequest_queue_stream_; // For preview steam. std::mutex request_queue_stream_lock_; std::queue> request_queue_stream_; std::condition_variable requests_available_stream_; bool stream_buffers_hasprepare_; // For preview steam. std::queue> request_queue_pstream_; std::condition_variable requests_available_pstream_; bool pstream_buffers_hasprepare_; // For picture steam. std::queue> request_queue_tstream_; std::condition_variable requests_available_tstream_; bool tstream_buffers_hasprepare_; // For video steam. std::queue> request_queue_vstream_; std::queue> request_queue_vhstream_; std::condition_variable requests_available_vstream_; bool vstream_buffers_hasprepare_; std::shared_ptr trequest; // For destructor twice. std::shared_ptr mStreamManager_; bool mStreamTracker[MAX_STREAM]; bool mSourceStreamTracker[MAX_STREAM]; DISALLOW_COPY_AND_ASSIGN(V4L2Camera); }; } // namespace v4l2_camera_hal #endif // V4L2_CAMERA_HAL_V4L2_CAMERA_H_