1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef V4L2_CAMERA_HAL_V4L2_WRAPPER_H_ 18 #define V4L2_CAMERA_HAL_V4L2_WRAPPER_H_ 19 20 #include <array> 21 #include <memory> 22 #include <mutex> 23 #include <set> 24 #include <string> 25 #include <vector> 26 27 #include <android-base/unique_fd.h> 28 29 #include "arc/common_types.h" 30 #include "arc/frame_buffer.h" 31 #include "capture_request.h" 32 #include "common.h" 33 #include "stream_format.h" 34 35 namespace v4l2_camera_hal { 36 37 class V4L2Wrapper { 38 public: 39 // Use this method to create V4L2Wrapper objects. Functionally equivalent 40 // to "new V4L2Wrapper", except that it may return nullptr in case of failure. 41 static V4L2Wrapper* NewV4L2Wrapper(const std::string device_path); 42 virtual ~V4L2Wrapper(); 43 44 // Helper class to ensure all opened connections are closed. 45 class Connection { 46 public: 47 Connection(std::shared_ptr<V4L2Wrapper> device) 48 : device_(std::move(device)), connect_result_(device_->Connect()) {} 49 ~Connection() { 50 if (connect_result_ == 0) { 51 device_->Disconnect(); 52 } 53 } 54 // Check whether the connection succeeded or not. 55 inline int status() const { return connect_result_; } 56 57 private: 58 std::shared_ptr<V4L2Wrapper> device_; 59 const int connect_result_; 60 }; 61 62 // Turn the stream on or off. 63 virtual int StreamOn(); 64 virtual int StreamOff(); 65 // Manage controls. 66 virtual int QueryControl(uint32_t control_id, v4l2_query_ext_ctrl* result); 67 virtual int GetControl(uint32_t control_id, int32_t* value); 68 virtual int SetControl(uint32_t control_id, 69 int32_t desired, 70 int32_t* result = nullptr); 71 // Manage format. 72 virtual int GetFormats(std::set<uint32_t>* v4l2_formats); 73 virtual int GetQualifiedFormats(std::vector<uint32_t>* v4l2_formats); 74 virtual int GetFormatFrameSizes(uint32_t v4l2_format, 75 std::set<std::array<int32_t, 2>>* sizes); 76 77 // Durations are returned in ns. 78 virtual int GetFormatFrameDurationRange( 79 uint32_t v4l2_format, 80 const std::array<int32_t, 2>& size, 81 std::array<int64_t, 2>* duration_range); 82 virtual int SetFormat(const StreamFormat& desired_format, 83 uint32_t* result_max_buffers); 84 // Manage buffers. 85 virtual int EnqueueRequest( 86 std::shared_ptr<default_camera_hal::CaptureRequest> request); 87 virtual int DequeueRequest( 88 std::shared_ptr<default_camera_hal::CaptureRequest>* request); 89 virtual int GetInFlightBufferCount(); 90 91 private: 92 // Constructor is private to allow failing on bad input. 93 // Use NewV4L2Wrapper instead. 94 V4L2Wrapper(const std::string device_path); 95 96 // Connect or disconnect to the device. Access by creating/destroying 97 // a V4L2Wrapper::Connection object. 98 int Connect(); 99 void Disconnect(); 100 // Perform an ioctl call in a thread-safe fashion. 101 template <typename T> 102 int IoctlLocked(int request, T data); 103 // Request/release userspace buffer mode via VIDIOC_REQBUFS. 104 int RequestBuffers(uint32_t num_buffers); 105 106 inline bool connected() { return device_fd_.get() >= 0; } 107 108 // Format management. 109 const arc::SupportedFormats GetSupportedFormats(); 110 111 // The camera device path. For example, /dev/video0. 112 const std::string device_path_; 113 // The opened device fd. 114 android::base::unique_fd device_fd_; 115 // The underlying gralloc module. 116 // std::unique_ptr<V4L2Gralloc> gralloc_; 117 // Whether or not the device supports the extended control query. 118 bool extended_query_supported_; 119 // The format this device is set up for. 120 std::unique_ptr<StreamFormat> format_; 121 // Lock protecting use of the buffer tracker. 122 std::mutex buffer_queue_lock_; 123 // Lock protecting use of the device. 124 std::mutex device_lock_; 125 // Lock protecting connecting/disconnecting the device. 126 std::mutex connection_lock_; 127 // Reference count connections. 128 int connection_count_; 129 // Supported formats. 130 arc::SupportedFormats supported_formats_; 131 // Qualified formats. 132 arc::SupportedFormats qualified_formats_; 133 134 class RequestContext { 135 public: 136 RequestContext() 137 : active(false), 138 camera_buffer(std::make_shared<arc::AllocatedFrameBuffer>(0)){}; 139 ~RequestContext(){}; 140 // Indicates whether this request context is in use. 141 bool active; 142 // Buffer handles of the context. 143 std::shared_ptr<arc::AllocatedFrameBuffer> camera_buffer; 144 std::shared_ptr<default_camera_hal::CaptureRequest> request; 145 }; 146 147 // Map of in flight requests. 148 // |buffers_.size()| will always be the maximum number of buffers this device 149 // can handle in its current format. 150 std::vector<RequestContext> buffers_; 151 152 friend class Connection; 153 friend class V4L2WrapperMock; 154 155 DISALLOW_COPY_AND_ASSIGN(V4L2Wrapper); 156 }; 157 158 } // namespace v4l2_camera_hal 159 160 #endif // V4L2_CAMERA_HAL_V4L2_WRAPPER_H_ 161