/* * 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_STREAM_H_ #define V4L2_CAMERA_HAL_V4L2_STREAM_H_ #include "common.h" #ifdef LOG_NDEBUG #undef LOG_NDEBUG #endif #if DBG_V4L2_STREAM #undef NDEBUG #define LOG_NDEBUG 0 #else #define LOG_NDEBUG 1 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "stream_format.h" #include "v4l2_gralloc.h" #include "v4l2_wrapper.h" #include "camera_config.h" #include "camera_stream.h" #include "type_camera.h" #ifdef USE_ISP #include "AWIspApi.h" #endif namespace v4l2_camera_hal { class V4L2Stream : public virtual android::RefBase { friend class V4L2Wrapper; friend class ConnectionStream; public: // Use this method to create V4L2Stream objects. Functionally equivalent // to "new V4L2Stream", except that it may return nullptr in case of failure. static V4L2Stream* NewV4L2Stream(const int id, const std::string device_path, std::shared_ptr pCameraCfg, int merge_status ); virtual ~V4L2Stream(); // Turn the stream on or off. virtual int StreamOn(); virtual int StreamOff(); virtual int flush(); // Manage controls. virtual int QueryControl(uint32_t control_id, v4l2_query_ext_ctrl* result); virtual int GetControl(uint32_t control_id, int32_t* value); virtual int SetControl(uint32_t control_id, int32_t desired, int32_t* result = nullptr); virtual int SetFlashMode(uint32_t mode); virtual int SetTakePictureCtrl(enum v4l2_take_picture value); virtual int SetAutoFocusInit(); virtual int SetAutoFocusRange(int af_range); virtual int SetAutoFocusStart(); virtual int SetAutoFocusStop(); virtual int Set3ALock(int lock); virtual int GetAutoFocusStatus(); virtual int SetAutoFocusRegions(cam_rect_t cam_regions); virtual int SetCropRect(cam_crop_rect_t cam_crop_rect); virtual int SetJpegCropRect(cam_crop_rect_t cam_crop_rect); virtual int SetParm(int mCapturemode, uint32_t width, uint32_t height); // Manage format. virtual int GetFormats(std::set* v4l2_formats); virtual int GetFormatFrameSizes(uint32_t v4l2_format, std::set, std::greater>>* sizes); // Durations are returned in ns. virtual int GetFormatFrameDurationRange( uint32_t v4l2_format, const std::array& size, std::array* duration_range); virtual int SetFormat(const StreamFormat& desired_format, uint32_t* result_max_buffers, bool merge_stream_flag); // Manage buffers. virtual int PrepareBuffer(); virtual int WaitCameraReady(); virtual int EnqueueBuffer(); virtual int DequeueBuffer(void ** src_addr_, struct timeval * ts); virtual int CopyYCbCrBuffer(android_ycbcr* dst_addr_ycbcr, void* src_addr); virtual int EncodeBuffer(void * dst_addr, void * src_addr, unsigned long mJpegBufferSizes, JPEG_ENC_t jpeg_enc); virtual int queueBuffer(v4l2_buffer* pdevice_buffer); virtual int dequeueBuffer(v4l2_buffer* pdevice_buffer); // Tools. int GetDeviceId() {return device_id_;} int GetDeviceWidth() {return format_->width();} int GetDeviceHeight() {return format_->height();} STREAM_SERIAL getStreamSerial() {return device_ss_;} private: std::shared_ptr mCameraConfig; // Constructor is private to allow failing on bad input. // Use NewV4L2Stream instead. V4L2Stream(const int id, const std::string device_path, std::shared_ptr pCameraCfg, int merge_status ); // Connect or disconnect to the device. Access by creating/destroying // a V4L2Wrapper::Connection object. int Connect(int merge_status); void Disconnect(); // Perform an ioctl call in a thread-safe fashion. template int IoctlLocked(int request, T data); // Request/release userspace buffer mode via VIDIOC_REQBUFS. int RequestBuffers(uint32_t num_buffers); inline bool connected() { return device_fd_ >= 0; } int parse_pair(const char *str, uint32_t *first, uint32_t *second, char delim); void initV4l2Str(); // The camera device path. For example, /dev/video0. const std::string device_path_; STREAM_SERIAL device_ss_; int device_fd_; // Pipe for wakeup epoll int read_fd_; int write_fd_; bool disconnect; cam_crop_rect_t jpeg_crop_rect; epoll_event *pEvents; // The open camera facing. const int device_id_; int reduce_call_num; uint32_t reducecallnum_dst_width; uint32_t reducecallnum_dst_height; uint32_t reducecallnum_src_width; uint32_t reducecallnum_src_height; // Whether or not the device supports the extended control query. bool extended_query_supported_; // The format this device is set up for. std::unique_ptr format_; unsigned long mTimeStampsFstreamon; // bool has_StreamOn; // bool mflush_buffers; bool isTakePicture; enum { BUFFER_UNINIT, BUFFER_PREPARE, BUFFER_QUEUE, BUFFER_DEQUEUE } buffer_state_; // Map indecies to buffer status. True if the index is in-flight. // |buffers_.size()| will always be the maximum number of buffers this device // can handle in its current format. std::vector buffers_pstream_; // Map indecies to buffer status. True if the index is in-flight. // |buffers_.size()| will always be the maximum number of buffers this device // can handle in its current format. std::vector buffers_; // Lock protecting use of the buffer tracker. std::mutex buffer_queue_lock_; std::mutex aw_ve_lock; std::queuebuffers_num_; std::condition_variable buffer_availabl_queue_; // Buffer manager. std::mutex cmd_queue_lock_; int buffer_cnt_inflight_; // Lock protecting use of the device. std::mutex device_lock_; // Debug tools for save buffers. void * buffers_addr[MAX_BUFFER_NUM]; int buffers_fd[MAX_BUFFER_NUM]; typedef struct v4l2_mem_map_t{ void * mem[MAX_BUFFER_NUM]; int length; int nShareBufFd[MAX_BUFFER_NUM]; int nDmaBufFd[MAX_BUFFER_NUM]; }v4l2_mem_map_t; v4l2_mem_map_t mMapMem; enum { CAMERA3_JPEG_3A_PARAM_BLOB_ID = 0xAAFFAAFF, CAMERA3_JPEG_ISP_MSG_BLOB_ID = 0xABFFABFF, }; typedef struct camera3_jpeg_3a_blob { uint32_t jpeg_3a_header_id; uint32_t jpeg_3a_size; char magic_str[8]; } camera3_jpeg_3a_blob_t; typedef struct camera3_jpeg_isp_msg_blob { uint32_t jpeg_isp_msg_header_id; uint32_t jpeg_isp_msg_size; char magic_str[8]; } camera3_jpeg_isp_msg_blob_t; #ifdef USE_ISP android::AWIspApi *mAWIspApi; int mIspId; #endif // Lock protecting connecting/disconnecting the device. std::mutex connection_lock_; // Reference count connections. int connection_count_; friend class Connection; #ifdef USE_ISP friend class android::AWIspApi; #endif DISALLOW_COPY_AND_ASSIGN(V4L2Stream); }; // Helper class to ensure all opened connections are closed. class ConnectionStream { friend class V4L2Stream; public: ConnectionStream(std::shared_ptr device, int merge_status) : device_(std::move(device)) { connect_result_ = device_->Connect(merge_status); } ~ConnectionStream() { if (connect_result_ == 0) { device_->Disconnect(); } } // Check whether the connection succeeded or not. inline int status() const { return connect_result_; } private: std::shared_ptr device_; int connect_result_; DISALLOW_COPY_AND_ASSIGN(ConnectionStream); }; } // namespace v4l2_camera_hal #endif // V4L2_CAMERA_HAL_V4L2_WRAPPER_H_